Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Traction Bundle Laravel Package

noetix/traction-bundle

Noetix Traction Bundle is a Symfony bundle that integrates Traction into PHP applications. It packages configuration and services so you can install via Composer, enable the bundle, and build against its integration points.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this as reference code, not a dependency. It is a Symfony2-era bundle, archived, with 2 stars and zero dependents — there is no maintenance path, no security response, and no compatibility work for modern PHP. Read it, lift what you need, and move on.

Where to look first, in order:

  1. composer.json — the require block is the most valuable file in the repo. It tells you which Symfony minor (likely 2.x), which Guzzle major (likely 3.x or 4.x), and which underlying Traction API client — if any — the bundle wraps. That underlying client is what you actually want.
  2. DependencyInjection/Configuration.php — the canonical list of config keys (base URL, credentials/token, timeouts). This is your spec.
  3. Resources/config/services.yml — the service IDs and constructor arguments. This tells you what to inject and what the public surface is.
  4. The client/API class under Client/, Api/, or Service/ — read the public methods; that is your real integration surface.

Minimal Symfony2 usage, if you genuinely had to run it in situ:

// app/AppKernel.php
new Noetix\TractionBundle\NoetixTractionBundle(),

// app/config/config.yml
noetix_traction:
    base_url: %traction_base_url%
    token:    %traction_token%

Then inject the client service into your own service rather than reaching for the container.

The Laravel path (recommended): do not install this bundle. Composer will fight you on symfony/symfony and Guzzle constraints. Instead, copy the client class out of the repo, and drive it from a small wrapper bound in a service provider using Laravel's Http client or a current Guzzle. First use case: one authenticated read — a GET against a single resource — asserted from php artisan tinker. Confirm auth and response shape before writing anything else.

Implementation Patterns

Wrap, never inject the vendor client directly. Define an interface (TractionClient) in your app and a single adapter implementation. The archived client becomes an implementation detail you can replace in an afternoon.

Config-driven construction. Mirror the bundle's config tree in config/services.php:

'traction' => [
    'base_url' => env('TRACTION_URL'),
    'token'    => env('TRACTION_TOKEN'),
    'timeout'  => env('TRACTION_TIMEOUT', 10),
],

Bind in a provider with $this->app->singleton(TractionClient::class, ...). Use the interface as the injection type everywhere else.

Decorator layers pay for themselves here. Because the underlying transport is old, put retry and caching in decorators around your interface rather than inside the client:

  • RetryingTractionClient — retry on 429/5xx with backoff.
  • CachedTractionClient — cache idempotent reads with a short TTL.
  • LoggingTractionClient — log method, path, status, duration, correlation ID. Never log the token or full bodies.

Writes go through the queue. Any POST/PUT/DELETE should be a job with explicit retry and failure handling. Synchronous writes against an unmaintained HTTP client is how you get hung workers.

Testing. Fake the transport, not the interface, for the adapter's own tests (Http::fake() or Guzzle's MockHandler with recorded fixtures); fake the interface for everything downstream. Keep one opt-in contract test that hits a sandbox if one exists — that is your early warning that the API drifted.

If you must stay on Symfony2: define named clients via a compiler pass if you talk to multiple Traction instances, tag an event subscriber for request logging, and use KernelTestCase + the container to assert wiring. Override the bundle's service definition in your app's services.yml rather than editing vendor code — that is the sanctioned extension point.

Gotchas and Tips

  • Dependency hell is the headline. Symfony 2.x plus Guzzle 3/4 will not coexist with Laravel 6+ or PHP 8. Expect composer why-not to be your first five minutes. Do not spend them; extract instead.
  • Guards you must add yourself. Guzzle 3-era code often lacks sane timeouts and connection reuse. Set connect_timeout, timeout, and http_errors explicitly. A default of "wait forever" is a production outage waiting for a slow upstream.
  • Exception types leak. Older clients throw raw Guzzle\Http\Exception\*. Catch them at the adapter boundary and rethrow as domain exceptions (TractionUnavailable, TractionRejected) so callers never catch (\Exception).
  • Alias mismatch. The config root is derived from the DI extension alias, not the bundle name. If your config block is silently ignored, check getAlias() in DependencyInjection/*Extension.php — a wrong key fails quietly in Symfony 2.
  • Manual bundle registration. Pre-Flex Symfony requires the AppKernel entry; forgetting it yields "service not found," not a helpful error.
  • Return-shape ambiguity. Many bundles of this vintage return parsed arrays for some methods and response objects for others. Read each method; don't assume uniformity, and normalise in your adapter.
  • Secrets belong in parameters.yml/.env, never in the committed config block. The bundle's own docs (if any) frequently show the token inline.
  • Debugging: attach a Guzzle log middleware in local only, and capture the upstream's request ID into your logs so you can correlate with their support.
  • Extension points that survive porting: the config key names, the client interface, and the DTO/mapping layer. The bundle boilerplate (*Bundle.php, DependencyInjection/, Resources/config/) is the only part you throw away.
  • Pin and document. If you vendor the client class, put a comment at the top with the upstream commit SHA and the date. Future-you will want to know how stale it is.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core