Support the ongoing development of Laravel.io →
posted 8 years ago
Requests
Last updated 1 year ago.

besfort liked this thread

1
Solution

Ok. I found the solution after almost loosing my mind. I had to dig beyond Laravel and all the way into the Symfony2 classes, that are used, to solve the issue. Basically to make this work, we have to create a new request within our routing and then re-run the routing with the new request. The solution:

Route::get('{path_alias}', function(\App\PathAlias $path_alias){
    return Route::dispatchToRoute(\Illuminate\Http\Request::create($path_alias->source));
});

Dispatch a route using a new request created with the SymfonyRequest create method and give it the source of your slug as the parameter.

If you have a route you can now access it from the slug.

0

After spending 2 hours, digging through google and Laravel source, I came up with this solution, which I think works the best and looks the cleanest. No need for redirects and multiple inner requests.

You add this route at the very bottom of routes files. If no other routes are matched, this is executed. In the closure, you decide which controller and action to execute. The best part is - all route parameters are passed to action, and method injection still works. The ControllerDispatcer line is from Laravel Route(r?) class.

My example would handle 2 cases - first checks if user exists by that name, then checks if an article can be found by the slug.

    Route::get('{slug}/{slug2?}', function ($slug) {
        $class = false;
        $action = false;

        $user = UserModel::where('slug', $slug)->first();
        if ($user) {
            $class = UserController::class;
            $action = 'userProfile';
        }

        if (!$class) {
            $article = ArticleModel::where('slug', $slug)->first();
            if ($article) {
                $class = ArticleController::class;
                $action = 'index';
            }
        }

        if ($class) {
            $route = app(\Illuminate\Routing\Route::class);
            $request = app(\Illuminate\Http\Request::class);
            $router = app(\Illuminate\Routing\Router::class);
            $container = app(\Illuminate\Container\Container::class);
            return (new ControllerDispatcher($router, $container))->dispatch($route, $request, $class, $action);
        }
        
        // Some fallback to 404
        throw new NotFoundHttpException;
    });

Hope this helps!

besfort liked this reply

1

Sign in to participate in this thread!

Eventy

Your banner here too?

KHIT93 khit93 Joined 4 Aug 2015

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.