Laravel-Lang / publisher

Publisher provides functionality for working with application localization
https://laravel-lang.com/packages-publisher.html
MIT License
212 stars 25 forks source link

Is the facade meant for use in code or for CI/CD? #297

Closed ronaldwanink closed 2 years ago

ronaldwanink commented 2 years ago

Question: When I use the facade in my middleware to set request based locales, I am forced to pull all three packages in production i.s.o. dev in my composer.json.

Is this how it should be, or am I not using the facade as designed?

andrey-helldar commented 2 years ago

No. Ideally, none of the Laravel Lang packages should be in production.

There can be two exceptions:

  1. If you need to get a list of available localizations in production, then it is allowed to install a publisher.
  2. If the direct installation of localizations is done on the fly (yes, this also occurs).

In general, it is enough to store localization packages in dev dependencies (require-dev block in the composer.json file).

Since the publisher changes the files, it is recommended that the developers do this directly, when changing, you will need to create a commit and push to the repository. Of course, you can use CI/CD for this, but...

andrey-helldar commented 2 years ago

To activate localization in the middleware of the application, you need to contact not the publisher, but the framework.

For example:

namespace App\Http\Middleware;

use Carbon\Carbon;
use Closure;
use Illuminate\Http\Request;

class SetLocalizationMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        $locale = $this->getLocale($request);

        $this->setLocale($locale);

        return $next($request);
    }

    protected function setLocale(string $locale): void
    {
        app()->setLocale($locale);

        Carbon::setLocale($locale);
    }

    protected function getLocale(Request $request): string
    {
        return $request->header('X-Locale', $this->getFallback());
    }

    protected function getFallback(): string
    {
        return config('app.fallback_locale');
    }
}
ronaldwanink commented 2 years ago

Thanks for a quick response, indeed I will use my own facade to the framework iso the publisher.

I wrote my middleware alike this

    $lang = $request->lang; 
    if (Locales::isAvailable($lang)) {
        App::setLocale($lang);
    } else {
        $lang = Locales::getFallback();
        App::setLocale($lang);
    }

but I understand that is not the proper way of doing it.

Keep up the good work!

ronaldwanink commented 2 years ago

For other devs reading this: note the 'Carbon::setLocale()' in the answer @andrey-helldar gave. It is easy to forget, and must indeed be set separately.

andrey-helldar commented 2 years ago

In general, it is not necessary to install it. Laravel has a wrapper for it:

use Illuminate\Support\Carbon;

return Carbon::now();

In this case, the Carbon locale is automatically set when app()->setLocale() is called.

But in the case of a direct call to Carbon\Carbon, I encountered a problem when the localization was not passed, so I explicitly call its installation in my applications.

andrey-helldar commented 2 years ago

if (Locales::isAvailable($lang)) {

This design does not make sense because if localization is not detected in the application, then fallback will be used.

This is a feature of the framework itself.

ronaldwanink commented 2 years ago

Thanks for the very useful feedback.

Btw, I used the Accept-Language http header, and use locale_accept_from_http($accept-language-header) to resolve it to a locale. Is there a reason you switched to X-Locale ?

andrey-helldar commented 2 years ago

@ronaldwanink, yes, I have.

locale_accept_from_http is a PHP mechanism, and the locale must be set in the framework itself to avoid pitfalls.