pmochine / Laravel-Tongue

🎉 Finally a subdomain localization that works how you want it to work. 🌐
MIT License
40 stars 7 forks source link

tongue()->detect() with Laravel Octane #54

Open Legoraccio opened 1 year ago

Legoraccio commented 1 year ago

Hi, I'm trying to use Laravel-Tongue with Laravel Octane. All works as expected, except for the automatic language detection by client settings.

So, if I access the application with a language (IT in my case) that is different from the default (EN), the tongue()->detect(); do not detect the correct language.

I run the tongue()->detect() fun from a custom middleware, because the boot() function in Octane run only at server startup.

Laravel version: 10.15.0 Tongue version: 5.0.0

This is the middleware:

class Localize
{
    public function handle(Request $request, Closure $next): Response
    {
        tongue()->detect();
        Carbon::setLocale(tongue()->current());

        Log::debug("Localize: ".tongue()->current());

        return $next($request);
    }
}

And my localization.php

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Domain name
    |--------------------------------------------------------------------------
    |
    | Here you may change the name of the domain used in your application.
    | By default, the domain is read from the .env file.
    | Example: APP_DOMAIN=185ad73e.eu.ngrok.io (only because of this we know what your real domain is)
    |
    */
    'domain' => env('APP_DOMAIN'),

    /*
    |--------------------------------------------------------------------------
    | Beautify url
    |--------------------------------------------------------------------------
    |
    | Use to set fallback language to mydomain.com and not to en.mydomain.com
    | Other languages are getting e.g. fr.mydomain.com
    |
    */
    'beautify_url' => false,
    /*
    |--------------------------------------------------------------------------
    | subdomains that are whitelisted
    |--------------------------------------------------------------------------
    |
    | If you don't want to be redirected, when you have special subdomains
    | for example 'admin', 'archontas', 'nova' etc.
    |
    */
    'subdomains' => [
        'api'
    ],
    /*
    |--------------------------------------------------------------------------
    | custom locale subdomains via aliases
    |--------------------------------------------------------------------------
    |
    | Let's say you don't want to use locale as a subdomain.
    | You can add your custom subdomains here. Example:
    | gewinnen.domain.com --> "de"
    | gagner.domain.com --> "fr",
    |
    */
    'aliases' => [
        'zhs' => 'zh', //important: it has to match with an active locale from the supportedLocales list
        'zht' => 'zh-Hant',
        'ph'  => 'fil',
        'grc' => 'el'
    ],
    /*
    |--------------------------------------------------------------------------
    | https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language
    |--------------------------------------------------------------------------
    |
    |  Negotiate for the user locale using the Accept-Language header if it's not defined in the URL
    |  If false, system will take app.php fallback locale attribute
    |
    */
    'acceptLanguage' => true,
    /*
    |--------------------------------------------------------------------------
    | Cookie localization
    |--------------------------------------------------------------------------
    |
    | Use this option to enable or disable the use of cookies
    | in locale detection.
    |
    */
    'cookie_localization' => true,
    /*
    |--------------------------------------------------------------------------
    | Cookie Serialization
    |--------------------------------------------------------------------------
    |
    | If you have not changed anything in your middleware "EncryptCookies", you
    | don't need to change anything here as well.
    | For information visit:
    | https://laravel.com/docs/5.6/upgrade#upgrade-5.6.30
    */
    'cookie_serialize' => false,
    /*
    |--------------------------------------------------------------------------
    | Prevent redirect
    |--------------------------------------------------------------------------
    |
    | Sometimes in testing you don't want to use redirection.
    | If you set the value to true, the middleware TongueSpeaksLocale
    | will not redirect anymore.
    |
    */
    'prevent_redirect' => env('PREVENT_REDIRECT', false),

    // Uncomment the languages that your site supports - or add new ones.
    // These are sorted by the native name, which is the order you might show them in a language selector.
    // Regional languages are sorted by their base language, so "British English" sorts as "English, British"
    'supportedLocales' => [
        'de'          => ['name' => 'German',                 'script' => 'Latn', 'native' => 'Deutsch', 'regional' => 'de_DE'],
        'en'          => ['name' => 'English',                'script' => 'Latn', 'native' => 'English', 'regional' => 'en_GB'],
        'es'          => ['name' => 'Spanish',                'script' => 'Latn', 'native' => 'español', 'regional' => 'es_ES'],
        'fil'         => ['name' => 'Filipino',               'script' => 'Latn', 'native' => 'Filipino', 'regional' => 'fil_PH'],
        'fr'          => ['name' => 'French',                 'script' => 'Latn', 'native' => 'français', 'regional' => 'fr_FR'],
        'it'          => ['name' => 'Italian',                'script' => 'Latn', 'native' => 'italiano', 'regional' => 'it_IT'],
        'hu'          => ['name' => 'Hungarian',              'script' => 'Latn', 'native' => 'magyar', 'regional' => 'hu_HU'],
        'pt'          => ['name' => 'Portuguese',             'script' => 'Latn', 'native' => 'português', 'regional' => 'pt_PT'],
        'el'          => ['name' => 'Greek',                  'script' => 'Grek', 'native' => 'Ελληνικά', 'regional' => 'el_GR'],
        'ru'          => ['name' => 'Russian',                'script' => 'Cyrl', 'native' => 'русский', 'regional' => 'ru_RU'],
        'he'          => ['name' => 'Hebrew',                 'script' => 'Hebr', 'native' => 'עברית', 'regional' => 'he_IL'],
        'ar'          => ['name' => 'Arabic',                 'script' => 'Arab', 'native' => 'العربية', 'regional' => 'ar_AE'],
        'sa'          => ['name' => 'Sanskrit',               'script' => 'Deva', 'native' => 'संस्कृतम्', 'regional' => 'sa_IN'],
        'ja'          => ['name' => 'Japanese',               'script' => 'Jpan', 'native' => '日本語', 'regional' => 'ja_JP'],
        'zh'          => ['name' => 'Chinese (Simplified)',   'script' => 'Hans', 'native' => '简体中文', 'regional' => 'zh_CN'],
        'zh-Hant'     => ['name' => 'Chinese (Traditional)',  'script' => 'Hant', 'native' => '繁體中文', 'regional' => 'zh_CN'],
        'ko'          => ['name' => 'Korean',                 'script' => 'Hang', 'native' => '한국어', 'regional' => 'ko_KR'],
    ],
];

If I change manually the language with https://it.foo.bar, all works.

Any idea? Thanks!

Legoraccio commented 1 year ago

I solve setting the 'cookie_localization' => false in config. It stills a bug?

guestpectacular commented 1 year ago

Stills, but you can workaround this issue creating a middleware and moving "tongue()->detect()" inside.

BugHunterLooper commented 5 months ago

is there any solution for this problem?

BugHunterLooper commented 5 months ago

solved :

1. Create the Listener Class:

// app/Listeners/DetectLanguageListener.php

namespace App\Listeners;

use Laravel\Octane\Events\RequestReceived;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;

class DetectLanguageListener
{
    /**
     * Handle the event.
     *
     * @param  RequestReceived  $event
     * @return void
     */
    public function handle(RequestReceived $event)
    {
        // Extract the request object from the event
        $request = $event->request;

        // Detect the user's locale and set it
        tongue()->detect();

        // Set the locale for Carbon dates
        Carbon::setLocale(tongue()->current());

        // Log the current locale for debugging purposes
        Log::debug("Localize: " . tongue()->current());
    }
}

2. Updated octane.php:

// config/octane.php

use Laravel\Octane\Events\RequestReceived;
use App\Listeners\DetectLanguageListener;

return [

    /*
    |--------------------------------------------------------------------------
    | Octane Listeners
    |--------------------------------------------------------------------------
    |
    | All of the event listeners for Octane's events are defined below. These
    | listeners are responsible for resetting your application's state for
    | the next request. You may even add your own listeners to the list.
    |
    */

    'listeners' => [
        WorkerStarting::class => [
            EnsureUploadedFilesAreValid::class,
            EnsureUploadedFilesCanBeMoved::class,
        ],

        RequestReceived::class => [
            ...Octane::prepareApplicationForNextOperation(),
            ...Octane::prepareApplicationForNextRequest(),
            DetectLanguageListener::class, // Add this line
        ],