laravel-localization icon indicating copy to clipboard operation
laravel-localization copied to clipboard

Wrong behaviour for LaravelLocalization::extractAttributes() => redirects to 404

Open Nuranto opened this issue 3 years ago • 2 comments

Redirection from non-localized URLs to localized URLs does not work sometimes, because of LaravelLocalization::extractAttributes() behaviour : it does not match domain restrictions. (More generally, getLocalizedURL does not work because of that.)

For instance :

Route::domain('www.toto.com')->group(function() {
     Route::get('tutu/{slug}', 'TotoController@toto')->name('toto');
});
Route::domain('www.tata.com')->group(function() {
     Route::get('tutu/titi', 'TataController@tata')->name('tata');
});

If you try to load https://www.tata.com/tutu/titiit will match toto route instead of tata route, and will redirect to : https://www.tata.com/en/tutu/{slug} instead of https://www.tata.com/en/tutu/titi !

Isn't it possible to get the route directly from laravel methods ? That way, we would be sure the route found is the correct one, even for futures Laravel updates on routing..?

Maybe like this ?

protected function extractAttributes($url = false, $locale = '')
    {
        if (!empty($url)) {
             $route = collect(\Route::getRoutes())->first(function($route) use($url){
                  return $route->matches(request()->create($url));
             });
            /* generate $attributes from found $route */
[...]

where $url is the absolute url.

(credits : I found that solution here => https://stackoverflow.com/questions/24582922/laravel-get-route-name-from-given-url)

Nuranto avatar Jul 28 '20 15:07 Nuranto

Here is the full solution, but it gets slow..

protected function extractAttributesNew($url = false, $locale = '')
    {
        $route = false;
        if (!empty($url)) {
            $route = collect(\Route::getRoutes())->first(function($route) use($url){
                  return $route->matches(request()->create($url));
             });
            if($route) {
                $attributes = $this->normalizeAttributes((new \Illuminate\Routing\RouteParameterBinder($route))
                        ->parameters(request()));
            }
        } else {
            $route = $this->router->current();
            $attributes = $this->normalizeAttributes($route->parameters());
        }
        if (!$route) {
            return [];
        }

        
        $response = event('routes.translation', [$locale, $attributes]);

        if (!empty($response)) {
            $response = array_shift($response);
        }

        if (\is_array($response)) {
            $attributes = array_merge($attributes, $response);
        }

        return $attributes;
    }

Nuranto avatar Aug 18 '20 09:08 Nuranto

@mcamara I PR a mixed version between the one above, and yours... You'll tell me.

Nuranto avatar Aug 18 '20 10:08 Nuranto