Weave Code
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

Easy Redirect Bundle Laravel Package

agence-adeliom/easy-redirect-bundle

Symfony bundle to manage URL redirects and log 404 errors. Intercepts 404s, looks up matching redirects, performs redirects, and updates hit count/last accessed. Stores 404 path/URL/timestamp/referer for stats and clears matching 404s when redirects change.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require agence-adeliom/easy-redirect-bundle
    

    Ensure your composer.json includes the GitHub recipes endpoint for Flex compatibility.

  2. Configure Database Run migrations:

    php bin/console doctrine:migration:diff
    php bin/console doctrine:migration:migrate
    

    Or force schema update (if not using migrations):

    php bin/console doctrine:schema:update --force
    
  3. Integrate with EasyAdmin Add EasyRedirectTrait to your DashboardController and include the redirect menu item:

    use Adeliom\EasyRedirectBundle\Admin\EasyRedirectTrait;
    
    class DashboardController extends AbstractDashboardController {
        use EasyRedirectTrait;
    
        public function configureMenuItems(): iterable {
            yield from $this->configRedirectEntry();
            // ... other menu items
        }
    }
    
  4. Basic Configuration Update config/packages/easy_redirect.yaml:

    easy_redirect:
        redirect_class: App\Entity\Redirect  # Replace with your custom entity
        not_found_class: App\Entity\NotFound  # Replace with your custom entity
        remove_not_founds: true  # Auto-clean 404s when redirects are updated
    

First Use Case: Redirect Management

  • Access the EasyAdmin dashboardRedirects section (auto-added by the trait).
  • Create a redirect by specifying:
    • Source path (e.g., /old-url).
    • Destination URL (e.g., https://example.com/new-url).
  • Test the redirect by visiting /old-url in your browser. The bundle will:
    • Log the redirect (incrementing count and updating lastAccessedAt).
    • Auto-delete any matching 404 records (if remove_not_founds: true).

Implementation Patterns

Core Workflows

1. Handling Redirects Programmatically

Use the RedirectManager service to create/update redirects without EasyAdmin:

use Adeliom\EasyRedirectBundle\Manager\RedirectManagerInterface;

public function __construct(
    private RedirectManagerInterface $redirectManager
) {}

public function createRedirect(string $sourcePath, string $destinationUrl): void {
    $redirect = $this->redirectManager->create($sourcePath, $destinationUrl);
    $this->redirectManager->save($redirect);
}

2. Logging 404 Errors

The bundle auto-captures 404s via Symfony’s KernelEvents::EXCEPTION listener. To manually log a 404:

use Adeliom\EasyRedirectBundle\Manager\NotFoundManagerInterface;

public function __construct(
    private NotFoundManagerInterface $notFoundManager
) {}

public function logNotFound(string $path, string $referer = null): void {
    $this->notFoundManager->create($path, $referer);
}

3. Customizing Redirect Entities

Extend the default Redirect and NotFound entities:

// src/Entity/Redirect.php
namespace App\Entity;

use Adeliom\EasyRedirectBundle\Entity\Redirect as BaseRedirect;

class Redirect extends BaseRedirect {
    // Add custom fields (e.g., `public ?string $customField = null;`)
}

Update easy_redirect.yaml to reference your entities.


Integration Tips

EasyAdmin CRUD Integration

Override the default CRUD controller for advanced features:

use Adeliom\EasyRedirectBundle\Admin\EasyRedirectCrudController;

class CustomRedirectCrudController extends EasyRedirectCrudController {
    public function configureFields(string $pageName): iterable {
        yield from parent::configureFields($pageName);
        // Add custom fields (e.g., $this->addFieldHelper('customField'));
    }
}

API Endpoints for Redirects

Create a controller to fetch redirects via API:

use Adeliom\EasyRedirectBundle\Repository\RedirectRepositoryInterface;

class RedirectApiController {
    public function __construct(
        private RedirectRepositoryInterface $redirectRepository
    ) {}

    public function listRedirects(): Response {
        $redirects = $this->redirectRepository->findAll();
        return $this->json($redirects);
    }
}

Batch Processing 404s

Use the NotFoundManager to bulk-delete or export 404 logs:

$notFoundManager->deleteOlderThan(new \DateTime('-30 days'));

Gotchas and Tips

Pitfalls

  1. Entity Configuration Mismatch

    • Issue: Forgetting to update redirect_class/not_found_class in easy_redirect.yaml after extending entities.
    • Fix: Clear cache (php bin/console cache:clear) and verify entities exist in the database.
  2. Circular Redirects

    • Issue: Redirecting /a/b and /b/a creates an infinite loop.
    • Fix: Add validation in your custom Redirect entity:
      public function validateDestination(string $destination): void {
          if ($this->sourcePath === $destination) {
              throw new \InvalidArgumentException('Circular redirect detected.');
          }
      }
      
  3. Performance with High 404 Volume

    • Issue: Querying NotFound records with many entries slows down the dashboard.
    • Fix: Add indexes to the path and createdAt fields in your NotFound entity:
      /**
       * @ORM\Index(name="idx_path_created", columns={"path", "createdAt"})
       */
      
  4. EasyAdmin Menu Item Conflicts

    • Issue: configRedirectEntry() clashes with existing menu items.
    • Fix: Manually merge menu items:
      public function configureMenuItems(): iterable {
          yield MenuItem::linkToCrud('Redirects', 'fas fa-exchange-alt', Redirect::class);
          // ... other items
      }
      

Debugging Tips

  1. Check Listener Activation Verify the RedirectListener is registered:

    php bin/console debug:event-dispatcher KernelEvents::EXCEPTION
    

    Should show Adeliom\EasyRedirectBundle\EventListener\RedirectListener.

  2. Log Redirect/404 Events Enable debug mode to see intercepted requests:

    # config/packages/dev/easy_redirect.yaml
    easy_redirect:
        debug: true
    
  3. Database Schema Validation Compare your schema with the bundle’s defaults:

    php bin/console doctrine:schema:validate
    

Extension Points

  1. Custom Redirect Logic Override the RedirectListener to add pre/post-redirect logic:

    use Adeliom\EasyRedirectBundle\EventListener\RedirectListener as BaseListener;
    
    class CustomRedirectListener extends BaseListener {
        public function onKernelException(GetResponseForExceptionEvent $event): void {
            // Custom logic before parent::onKernelException()
            parent::onKernelException($event);
        }
    }
    

    Register it in services.yaml:

    services:
        App\EventListener\CustomRedirectListener:
            tags:
                - { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: -10 }
    
  2. Add Redirect Metadata Extend the Redirect entity to store additional data (e.g., redirectReason):

    class Redirect extends BaseRedirect {
        #[ORM\Column(nullable: true)]
        public ?string $redirectReason = null;
    }
    

    Update the form type (src/Form/RedirectType.php) to include the new field.

  3. Export 404 Reports Create a custom command to export NotFound data to CSV:

    use Adeliom\EasyRedirectBundle\Repository\NotFoundRepositoryInterface;
    
    class ExportNotFoundCommand extends Command {
        protected function execute(InputInterface $input, OutputInterface $output): int {
            $notFounds = $this->notFoundRepository->findAll();
            $csv = new \League\Csv\Writer($output->getOutputStream());
            $csv->insertOne(['Path', 'Referer', 'Created At']);
            foreach ($notFounds as $notFound) {
                $csv->insertOne([
                    $notFound->getPath(),
                    $notFound->getReferer(),
                    $notFound->getCreatedAt()->format('Y-m-d H:i:s'),
                ]);
            }
            return Command::SUCCESS;
        }
    }
    

Configuration Quirks

  1. remove_not_founds Behavior

    • When true, updating a redirect deletes all NotFound records with matching path.
    • Use Case: Disable this if you want to preserve 404 history even after creating redirects.
  2. **Case-S

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.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle