mopa/feed-bundle
MopaFeedBundle adds RSS and Atom feed generation to your PHP application, letting you expose news, blog posts, or any content collection as standards-compliant feeds with flexible templates and minimal configuration.
First, the reality check. mopa/feed-bundle is a Symfony bundle, not a Laravel package. There is no ServiceProvider, no config/feed.php to publish, no facade, no php artisan commands that will appear in your app. It was built for the Symfony 2.x service container, Doctrine MongoDB ODM, and a Ratchet-based websocket server, and it carries 0 stars / 0 dependents — treat it as an abandoned reference implementation, not a dependency.
That leaves two realistic entry points:
composer.json allows, enable the bundle in that app's kernel, configure Doctrine MongoDB ODM plus the mopa_feed config block, and run its websocket console command as a long-lived process. Your Laravel app talks to it over HTTP/Redis, never over Composer.mongodb/laravel-mongodb).Where to look first, in order:
composer.json — the hard version ceilings. If it demands Symfony 2.x and PHP 5.x, the sidecar path is likely dead too, and you're in "reference only" territory.Resources/config/ — the service definitions tell you the real architecture faster than any README: which service builds feed items, which one persists them, which one broadcasts.phiamo/FeedBundle.First use case to validate the concept: "new comment on a post" → append a feed item → push it to everyone subscribed to that post's feed. If you can't trace that path end-to-end in an afternoon, stop and port instead.
Feed model. The bundle's mental model is an activity stream: feed items reference a source entity by class + id (plus a type/timestamp), and are grouped into feeds (per-user, per-object, or global). This is fan-out-on-write — every relevant event materialises one row/document per subscriber feed. Copy that schema even if you don't copy the code.
Annotation-driven sources → Laravel observers. The bundle marks entities with annotations so a listener auto-generates feed items on persist. The Laravel equivalent is an Observer (created/updated) or a domain event + listener. Prefer explicit events — annotations are the part of this package that aged worst (@Feed docblocks vs. PHP 8 attributes).
Bridging Laravel to a sidecar. Never call the sidecar inside a DB transaction. Write to an outbox table (or dispatch a queued job with afterCommit()), then have the job POST to the socket service or publish to Redis. Payload should be minimal: {feed_id, item_id, type, actor_id, occurred_at, payload}.
Channel naming and subscription. One channel per feed id (feed.post.42, feed.user.7). The client sends a subscribe frame; the server authorises it. Do not trust client-supplied channel names or ids — authorise every subscription server-side against the same rules your Laravel policies/Broadcast::channel callbacks enforce.
Auth across framework boundaries. A shared session is not realistic between a Laravel app and a Symfony sidecar. Issue a short-lived signed token (HMAC or JWT) from Laravel, pass it in the websocket handshake, and validate + authorise on the socket server at subscribe time. Refresh before expiry and reconnect.
If you port, the mapping is one-to-one:
| Bundle concept | Laravel equivalent |
|---|---|
| Symfony event subscriber on ODM persist | Eloquent observer / domain event |
| ODM feed document | feed_items table or Mongo collection |
| Ratchet websocket server | Laravel Reverb / Pusher |
| Bundle console command | php artisan reverb:start under supervisor |
| Annotation config | Explicit listener registration |
Scaling notes that apply either way: fan-out belongs on a queue worker, not the request cycle; run multiple socket nodes behind a load balancer only with Redis pub/sub to fan messages across nodes; and cap fan-out per event (see gotchas).
composer require mopa/feed-bundle in your app "just to read the source" — vendor it into a scratch directory or read it on GitHub.$lastItemId".item_id, and ordering ties on identical timestamps need a secondary sort key.supervisorctl tail, and inspect frames in browser DevTools → WS, or wscat. Persist every broadcast payload to a log table for a week — replaying a real payload beats reasoning about it.composer.json you'll inherit in two years.How can I help you explore Laravel packages today?