swp/bridge
SWP Bridge is a lightweight Laravel/PHP package that provides a simple, flexible bridge for connecting application components. It streamlines integration, reduces boilerplate, and keeps your code clean and maintainable across projects.
Start by reading the source, not the README—this is a subtree split, so the package README is usually empty or a one-liner pointing back to the monorepo. Run composer require swp/bridge and then ls vendor/swp/bridge/src before anything else. That directory is the whole package.
The component exists to decouple "content" (articles ingested from Superdesk) from "where it gets published" (routes, destinations, output channels). The first thing to look for is the set of interfaces it exposes—typically a publishable-article contract and a destination/publisher contract. Those two interfaces are the seam you will build against.
Your first real use case: implement a concrete publisher. In Laravel terms, pick one of your existing outlets (an API endpoint, a queue topic, a storage folder) and write a class that implements the bridge's destination interface, translating the bridge's article payload into whatever your outlet expects. Bind it in a service provider and run a single article through it as a smoke test before wiring up anything else. Do not try to run this against the real Superdesk feed on day one; hand-construct a minimal article object first.
The package is Symfony-flavoured by origin but framework-agnostic in practice. Nothing in it should stop you using it from Laravel, but nothing in it will help you either—there is no service provider, no facade, no config file shipped.
Adapter-first. Treat the bridge as a set of ports. Create a small Publishing namespace in your app with three pieces: a BridgeArticleFactory that turns your Eloquent models (or incoming Superdesk JSON) into objects implementing the bridge's article interface; a BridgePublisher that implements the destination interface and forwards to Laravel's queue, HTTP client, or filesystem; and a PublishingServiceProvider that binds them via the container. This keeps the bridge's types out of your domain layer.
Constructor injection over inheritance. The bridge contracts are interfaces, not abstract classes, so prefer implementing them on thin adapter classes that wrap your own services. That way your real publishing logic stays testable without the bridge in the way.
Queue the hand-off. Publishing to a destination is I/O; do it in a job. The bridge gives you the data shape, not the transport. Pattern: PublishArticleJob accepts a serialisable DTO, hydrates a bridge article object inside handle(), then delegates to your destination implementation. This avoids serialising bridge objects into the queue, which is fragile because they may carry dependencies not marked serialisable.
Multi-destination fan-out. If you publish to several destinations (article body, social, RSS), implement one destination class per target and iterate over a registered collection. This is the intended integration model: the bridge defines the article side once and lets destinations proliferate independently.
Testing seam. Write a NullPublisher and a RecordingPublisher (collects published articles in memory) as test doubles. Use the recording one in feature tests to assert one article was handed to each destination, rather than mocking the bridge's interfaces directly—fewer brittle expectations.
Event hooks. After a successful publish, dispatch your own ArticlePublished event and let listeners handle caching, search indexing, and webhook firing. The bridge should not know about any of that.
Licence is AGPL-3.0. This is the big one. AGPL is copyleft and, for a network-served application, obliges you to offer source to users interacting with it. If you are publishing content over HTTP, this is not a "just link to it" situation. Run this past whoever owns licensing before you commit. Many teams end up re-implementing the interface contract from scratch (the interfaces themselves are trivial) rather than shipping AGPL code.
Effectively abandoned. Last release was June 2018. There will be no fixes for PHP 8.1+ deprecations, no typed properties, no mixed/never return types. Expect to pin to an older PHP if you use it as-is, or to swallow deprecation notices. Check every dependency it pulls in; some will have moved on.
Zero dependents and one star means there is no community to lean on. GitHub issues are dead. If something is broken, you own it. Vendor-patch or fork; do not file an issue.
Subtree split behaviour. Do not edit files inside vendor/swp/bridge—they are regenerated from the monorepo and your edits vanish on composer update. If you need a change, fork or use a Composer patches plugin. Also be aware that composer show swp/bridge will show a source URL pointing at the monorepo, not this repo, and the monorepo is the only place with history and docs.
Missing framework glue. There is no config/bridge.php, no service provider, no published migrations. Everything is wiring you write. Resist the urge to build a facades-and-config package around it on day one; a single service provider class is enough until you have three consumers.
Object identity and serialisation. If the article objects hold references to Symfony services or PSR-6 cache pools, they will not survive queue serialisation. Keep bridge objects short-lived—hydrate, publish, discard—and make sure whatever you put in a job is a plain array or DTO.
Destination errors are your problem. The bridge will not retry, dedupe, or record attempt numbers—that is transport logic. Wrap publishes in retry()/backoff() and log the destination name and article id together; without that, debugging a failed multi-destination fan-out is guesswork.
Extension points are thin. The only reliable seams are the interfaces themselves. There is no plugin registry, no event dispatcher, no decorator convention shipped. Design your own extension story and keep it inside your application, not inside anything that subclasses bridge classes—those classes may change or vanish.
Version pinning. Given the age, pin to the exact version you tested ("swp/bridge": "1.x" with a composer.lock committed) and avoid ^ ranges that could pull a surprise if the monorepo is ever tagged again.
How can I help you explore Laravel packages today?