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

Redirect Bundle Laravel Package

opifer/redirect-bundle

Opifer RedirectBundle is a Symfony package for creating and managing URL redirects. It lets applications map old paths to new destinations, handle redirect responses, and avoid broken links when content moves. Useful for SEO-friendly URL changes and legacy route support.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a read-only subtree split of the Opifer CMS monorepo. The last release is 0.1.4, a patch that swaps the bundle's RedirectableUrlMatcher for a plain UrlMatcher — an internal routing refactor, not a sign of renewed maintenance. The package remains archived with zero dependents, so treat it as reference source code, not a maintained dependency. If you are on a legacy Symfony 2.x app and want a working redirect manager, the practical path is: install it if it still resolves, read it, and be ready to vendor it into your own namespace.

Minimal steps (Symfony 2/3 conventions, since it predates Flex):

  1. composer require opifer/redirect-bundle — expect friction on PHP 7.2+ and Symfony 3.4+; check composer.json constraints first.
  2. Register the bundle in app/AppKernel.php:
    new Opifer\RedirectBundle\OpiferRedirectBundle(),
    
  3. Import the bundle's routing for the admin/CRUD endpoints (typically Resources/config/routing.xml) under a firewall-protected prefix.
  4. Update the schema: php app/console doctrine:schema:update --force (or generate a migration) — you should see a redirect table appear.
  5. Create one row and test it: old-path → new-path. Hit the old path and confirm the 3xx + Location header.

Where to look first, in order:

  • Entity/ — the Redirect entity fields (from/to path, status code, possibly host or regex flags). This defines what the bundle can actually do.
  • Routing/ — the matcher. As of 0.1.4 this is a plain UrlMatcher; the older RedirectableUrlMatcher variant is gone. Confirm whether anything still touches routing at all, or whether interception is purely kernel.request / kernel.exception.
  • EventListener/ or EventSubscriber/ — how interception works. Most bundles of this era listen on kernel.request (match path, redirect) and/or kernel.exception (catch NotFoundHttpException, i.e. redirect-on-404). With the matcher simplified in 0.1.4, this is where the real logic lives.
  • Resources/config/ — service wiring and the bundle's DI alias (likely opifer_redirect). This is where you learn what is configurable vs. hardcoded.
  • Controller/ / Form/ — the admin CRUD, if you plan to reuse it or replace it with your own UI.

First real use case: a CMS migration where old article URLs changed. Seed the table from a CSV of old_path,new_path,status and verify a sample of 301s plus the absence of redirect loops.

Implementation Patterns

Admin-managed redirects. Reuse the bundled controller and form type behind ROLE_ADMIN, or write a thin CRUD in your own admin to avoid coupling to the bundle's templates (which will look dated). Either way, keep the entity — it's the only part you genuinely want.

Seed/bulk import instead of manual entry. For anything beyond a handful of URLs, load redirects via Doctrine fixtures or a migration from a spreadsheet export. Add a unique constraint check on the "from" path in application code before insert — duplicate source paths are the single most common source of confusing behavior.

Interception strategy. Two viable patterns:

  • Request listener: normalize $request->getPathInfo() (trim trailing slash, lowercase, strip query string consistently) and look up an exact match. Cheap, predictable.
  • Exception listener: let Symfony 404, then catch NotFoundHttpException and redirect. This catches only unhandled 404s and preserves normal routing priorities, but it silently loses the redirect if another listener converts the exception first.

Pick one and be consistent; running both without coordination leads to double-handling.

Don't rebuild routing-level interception. Prior versions of this bundle resolved redirects inside a custom matcher (the RedirectableUrlMatcher removed in 0.1.4). If your app depended on that — a matcher_class / router option pointing at the bundle's matcher, or an expectation that redirects happen before controller resolution — 0.1.4 silently drops that behavior. The listener patterns above are the stable, matcher-independent approach; prefer them even if you pin an older tag.

Cache the map. A database query on every request is wasteful, and a query on every 404 still adds latency during a bad-crawl event. Load all redirects into an array keyed by normalized path at container/cache warmup, or memoize per-request. Invalidate via a Doctrine postPersist/postUpdate/postRemove listener that clears the cache key.

Push hot paths out of PHP. For high-traffic or SEO-critical redirects, generate nginx rewrite/return 301 rules from the same table as a build step. Keep the bundle as the source of truth, not the runtime path.

Wrap it. Put your own Redirector service in front of the bundle's lookup logic so you can add analytics logging, loop detection, and host matching without patching vendor code. This is also your escape hatch when you eventually replace the bundle.

Multi-domain caveat. If the entity only stores a path, you cannot distinguish example.com/foo from example.org/foo. If you host multiple sites, either add a host column in your own subclass/mapping or scope redirects per site ID.

Gotchas and Tips

  • Do not open PRs or issues here. It is a [READ-ONLY] subtree split. Contribute to the Opifer CMS monorepo (which itself is effectively dormant) or fork.
  • 0.1.4 is not a revival. A single patch bump after years of silence, containing one internal matcher swap, does not change the dependency calculus. Treat the version number as noise and the archive status as the fact.
  • Upgrading to 0.1.4 removes matcher-based redirects. If your router config referenced RedirectableUrlMatcher (the bundle's or a subclass), that class is gone — expect a hard class not found or a silent behavior change where redirects stop firing before the controller. Move to an event listener, or pin the previous tag and accept the old constraints.
  • Trailing-slash tolerance is no longer free. Symfony's RedirectableUrlMatcher threw its own redirect when a route matched only after adding/removing a trailing slash; a plain UrlMatcher does not. If you previously got /foo/ → /foo for free, you must normalize explicitly now.
  • Installation will likely fail on modern stacks. Expect old Symfony constraints, XML/YAML service definitions, annotation or XML Doctrine mapping, and PHP version ceilings around 5.x/7.0. Budget for composer require --ignore-platform-reqs plus manual fixes, or copy the entity + listener into your app.
  • No autowiring. Services are explicitly defined; if you extend the listener, you must register it yourself with the right tags and arguments.
  • Listener priority matters. If your redirect listener runs after the router or after the security firewall, authenticated-URL redirects behave differently than anonymous ones. Set an explicit priority and test both cases.
  • 301s are cached by browsers indefinitely. While iterating, return 302 or test in a private window — otherwise you will chase "the fix didn't work" for an hour.
  • Query strings are usually dropped. Decide whether ?utm_source=... should be preserved on the target and append it yourself; most bundles of this vintage do not.
  • Normalize before matching. Trailing slash, case, URL-encoded characters, and double slashes all produce misses that look like bugs. Normalize once, in one place — doubly so now that the matcher no longer helps.
  • Loop protection is your job. A redirect to a path that itself redirects (or 404s and re-enters the exception listener) produces infinite loops or 500s. Validate targets on save and cap redirect depth at request time.
  • Open-redirect risk. If admins can enter arbitrary absolute URLs, restrict allowed hosts; otherwise you have shipped an open redirector on your domain.
  • Uninstall plan. Because the package is archived and unmaintained, design for removal: keep the Redirect entity and lookup logic behind your own interface so swapping in a maintained alternative (or a handful of nginx rules) is a one-file change rather than a refactor.
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.
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
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console