Skip to content

Commit

Permalink
Merge pull request #60 from AbdullahFaqeir/v2
Browse files Browse the repository at this point in the history
Localised Redirections #49
  • Loading branch information
chinleung authored Oct 22, 2021
2 parents 843382f + 2c821bc commit 2d8e149
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 65 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
strategy:
fail-fast: true
matrix:
php: ['7.2', '7.3', '7.4', '8.0']
php: ['7.4', '8.0']
stability: [prefer-lowest, prefer-stable]

steps:
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@ Route::multilingual('test')->data(['name' => 'Taylor']);
Route::multilingual('test')->view('welcome', ['name' => 'Taylor']);
```

### Redirect localized route

```php
Route::multilingual('support');
Route::multilingual('contact')->redirect('support');
```

## Upgrading from 1.x to 2.x

To update from 1.x to 2.x, you simply have to rename the namespace occurrences in your application from `LaravelMultilingualRoutes` to `MultilingualRoutes`. The most common use case would be the `DetectRequestLocale` middleware.
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
}
],
"require": {
"php": "^7.2|^8.0",
"php": "^7.4|^8.0",
"chinleung/laravel-locales": "^1.2",
"illuminate/support": "~5.8.0|^6.0|^7.0|^8.0"
},
Expand Down
2 changes: 1 addition & 1 deletion src/Controllers/ViewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ViewController
* @param array $headers
* @return \Illuminate\Http\Response
*/
public function __invoke(string $view, array $data = [], int $status = 200, array $headers = [])
public function __invoke(string $view, array $data = [], int $status = 200, array $headers = []): \Illuminate\Http\Response
{
return Response::view($view, $data, $status, $headers);
}
Expand Down
5 changes: 3 additions & 2 deletions src/DetectRequestLocale.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace ChinLeung\MultilingualRoutes;

use Closure;
use Symfony\Component\HttpFoundation\Request;

class DetectRequestLocale
{
Expand All @@ -13,11 +14,11 @@ class DetectRequestLocale
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
public function handle(Request $request, Closure $next)
{
$segment = $request->locale ?: $request->segment(1);

if (in_array($segment, locales())) {
if (in_array($segment, locales(), false)) {
app()->setLocale($segment);
}

Expand Down
4 changes: 1 addition & 3 deletions src/Macros/RequestMacros.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ class RequestMacros
public function localizedRouteIs(): Closure
{
return function (...$patterns) {
return $this->routeIs(array_map(function ($pattern) {
return locale().".{$pattern}";
}, $patterns));
return $this->routeIs(array_map(static fn ($pattern) => locale().".{$pattern}", $patterns));
};
}
}
2 changes: 1 addition & 1 deletion src/Macros/RouterMacros.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function multilingual(): Closure
$this->container && $this->container->bound(MultilingualRegistrar::class)
? $this->container->make(MultilingualRegistrar::class)
: new MultilingualRegistrar($this),
$key == '/' ? $key : ltrim($key, '/'),
$key === '/' ? $key : ltrim($key, '/'),
$handle,
$locales ?: locales()
);
Expand Down
181 changes: 145 additions & 36 deletions src/MultilingualRegistrar.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class MultilingualRegistrar
*
* @var \Illuminate\Routing\Router
*/
protected $router;
protected Router $router;

/**
* Constructor of the class.
Expand Down Expand Up @@ -52,40 +52,90 @@ public function register(string $key, $handle, array $locales, array $options):
}

/**
* Register a single route.
* Register the redirect routes.
*
* @param string $key
* @param mixed $handle
* @param string $destination
* @param int $status
* @param array $locales
* @param array $options
* @return \Illuminate\Routing\RouteCollection
*/
public function redirect(string $key, string $destination, int $status, array $locales, array $options): RouteCollection
{
foreach ($locales as $locale) {
$route = $this->registerRedirectRoute($key, $destination, $status, $locale, $options);

if (isset($options['defaults']) && is_array($options['defaults'])) {
foreach ($options['defaults'] as $paramKey => $paramValue) {
$route->defaults($paramKey, $paramValue);
}
}
}

return tap($this->router->getRoutes())->refreshNameLookups();
}

/**
* Register a single redirect route.
*
* @param string $key
* @param string $destination
* @param int $status
* @param string $locale
* @param array $options
* @return \Illuminate\Routing\Route
*/
protected function registerRoute(string $key, $handle, string $locale, array $options): Route
protected function registerRedirectRoute(string $key, string $destination, int $status, string $locale, array $options): Route
{
$route = $this->generateRoute($key, $handle, $locale, $options);
$route = $this->generateRedirectRoute($key, $destination, $status, $locale, $options);

$this->applyConstraints($route, $locale, $options);
return $this->finalizeRoute($route, $key, $locale, $options);
}

if ($prefix = $this->generatePrefixForLocale($key, $locale)) {
$route->setUri("{$prefix}/{$route->uri}");
}
/**
* Generate a redirect route.
*
* @param string $key
* @param string $destination
* @param int $status
* @param string $locale
* @param array $options
* @return \Illuminate\Routing\Route
*/
protected function generateRedirectRoute(string $key, string $destination, int $status, string $locale, array $options): Route
{
$route = $this->router->any(
$this->applyUniqueRegistrationKey(
$this->generateUriFromKey($key, $locale),
$locale
),
'\Illuminate\Routing\RedirectController'
);

if ($middleware = Arr::get($options, 'middleware')) {
$route->middleware($middleware);
}
$route->defaults('destination', $this->cleanUri($this->applyUniqueRegistrationKey(
$this->generateUriFromKey($destination, $locale),
$locale
), $locale));
$route->defaults('status', $status);

data_set($route, 'action.as', (
$this->generateNameForLocaleFromOptions(
$locale,
$key,
array_merge(
['as' => data_get($route, 'action.as')],
$options
)
)
));
return $route;
}

return $this->cleanUniqueRegistrationKey($route, $locale);
/**
* Register a single route.
*
* @param string $key
* @param mixed $handle
* @param string $locale
* @param array $options
* @return \Illuminate\Routing\Route
*/
protected function registerRoute(string $key, $handle, string $locale, array $options): Route
{
$route = $this->generateRoute($key, $handle, $locale, $options);

return $this->finalizeRoute($route, $key, $locale, $options);
}

/**
Expand Down Expand Up @@ -119,6 +169,41 @@ protected function generateRoute(string $key, $handle, string $locale, array $op
return $route;
}

/**
* Finalize route registration.
*
* @param \Illuminate\Routing\Route $route
* @param string $key
* @param string $locale
* @param array $options
* @return \Illuminate\Routing\Route
*/
protected function finalizeRoute(Route $route, string $key, string $locale, array $options): Route
{
$this->applyConstraints($route, $locale, $options);

if ($prefix = $this->generatePrefixForLocale($key, $locale)) {
$route->setUri("{$prefix}/{$route->uri}");
}

if ($middleware = Arr::get($options, 'middleware')) {
$route->middleware($middleware);
}

data_set($route, 'action.as', (
$this->generateNameForLocaleFromOptions(
$locale,
$key,
array_merge(
['as' => data_get($route, 'action.as')],
$options
)
)
));

return $this->cleanUniqueRegistrationKey($route, $locale);
}

/**
* Retrieve the request method from the options.
*
Expand All @@ -129,7 +214,7 @@ protected function getRequestMethodFromOptions(array $options): array
{
$method = $options['method'] ?? 'get';

if ($method == 'get') {
if ($method === 'get') {
return ['GET', 'HEAD'];
}

Expand All @@ -150,8 +235,8 @@ protected function generateNameForLocaleFromOptions(string $locale, string $key,

if ($prefix = Arr::get($options, 'as')) {
return config('laravel-multilingual-routes.name_prefix_before_locale')
? "{$prefix}{$locale}.{$name}"
: "{$locale}.{$prefix}{$name}";
? "{$prefix}{$locale}.$name"
: "$locale.{$prefix}{$name}";
}

return "{$locale}.{$name}";
Expand All @@ -166,7 +251,7 @@ protected function generateNameForLocaleFromOptions(string $locale, string $key,
*/
protected function generatePrefixForLocale(string $key, string $locale): ?string
{
if ($key == '/' || $this->shouldNotPrefixLocale($locale)) {
if ($key === '/' || $this->shouldNotPrefixLocale($locale)) {
return null;
}

Expand All @@ -182,12 +267,12 @@ protected function generatePrefixForLocale(string $key, string $locale): ?string
*/
protected function generateUriFromKey(string $key, string $locale): string
{
if ($key == '/') {
return $this->shouldNotPrefixHome($locale) ? '/' : "/{$locale}";
if ($key === '/') {
return $this->shouldNotPrefixHome($locale) ? '/' : "/$locale";
}

return Lang::has("routes.{$key}", $locale)
? trans("routes.{$key}", [], $locale)
return Lang::has("routes.$key", $locale)
? trans("routes.$key", [], $locale)
: $key;
}

Expand All @@ -213,7 +298,31 @@ protected function applyUniqueRegistrationKey(string $uri, string $locale): stri
*/
protected function cleanUniqueRegistrationKey(Route $route, string $locale): Route
{
return $route->setUri(rtrim(str_replace("__{$locale}__", '', $route->uri), '/'));
return $route->setUri($this->cleanRoute($route, $locale));
}

/**
* Clean route uri from locale.
*
* @param \Illuminate\Routing\Route $route
* @param string $locale
* @return string
*/
protected function cleanRoute(Route $route, string $locale): string
{
return $this->cleanUri($route->uri, $locale);
}

/**
* Clean uri from locale.
*
* @param string $uri
* @param string $locale
* @return string
*/
protected function cleanUri(string $uri, string $locale): string
{
return rtrim(str_replace("__{$locale}__", '', $uri), '/');
}

/**
Expand All @@ -224,7 +333,7 @@ protected function cleanUniqueRegistrationKey(Route $route, string $locale): Rou
*/
protected function shouldNotPrefixLocale(string $locale): bool
{
return $locale == config('laravel-multilingual-routes.default')
return $locale === config('laravel-multilingual-routes.default')
&& ! config('laravel-multilingual-routes.prefix_default');
}

Expand All @@ -248,7 +357,7 @@ protected function shouldNotPrefixHome(string $locale): bool
*/
protected function shouldNotPrefixDefaultHome(string $locale): bool
{
return $locale == config('laravel-multilingual-routes.default')
return $locale === config('laravel-multilingual-routes.default')
&& ! config('laravel-multilingual-routes.prefix_default_home');
}

Expand All @@ -260,11 +369,11 @@ protected function shouldNotPrefixDefaultHome(string $locale): bool
* @param array $options
* @return void
*/
protected function applyConstraints(Route $route, string $locale, $options): void
protected function applyConstraints(Route $route, string $locale, array $options): void
{
$constraints = array_merge(
Arr::get($options, 'constraints', []),
Arr::get($options, "constraints-{$locale}", [])
Arr::get($options, "constraints-$locale", [])
);

foreach ($constraints as $name => $expression) {
Expand Down
Loading

0 comments on commit 2d8e149

Please sign in to comment.