Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.7] Mailables can hook into LocaleUpdated #24451

Merged
merged 1 commit into from
Jun 5, 2018

Conversation

derekmd
Copy link
Contributor

@derekmd derekmd commented Jun 5, 2018

This makes send() of translated Mailable (and eventually Notification) objects dispatch the event Illuminate\Foundation\Events\LocaleUpdated to allow for more complete localization. For example:

  • Carbon-formatted timestamps
  • Currency and money output
  • route() country/region URI prefixes

Translatable mailable classes were added in 5.6.5 (#23178) to allow translated email subjects and view bodies, but the above localizable content types are left unchanged for queued items.

Example to localize mailable timestamps

When the default queue worker locale is 'en', calling Mail::to($francophone)->locale('fr')->queue(new Schedule); would show French formatting for Carbon timestamps using this event listener.

\Illuminate\Foundation\Events\LocaleUpdated::class => [
    \App\Listeners\LocalizeApp::class,
],
namespace App\Listeners;

use Illuminate\Support\Carbon;
use Illuminate\Foundation\Events\LocaleUpdated;

class LocalizeApp
{
    public function handle(LocaleUpdated $event)
    {
        // Carbon@formatLocalized() / strftime()
        setlocale(LC_TIME, array_get([
            'en' => 'en_CA.UTF-8',
            'fr' => 'fr_CA.UTF-8',
        ], $event->locale, 'en'));

        // Carbon@diffForHumans()
        Carbon::setLocale($event->locale);
    }
}

Flexibility in implementation

I chose the simplest solution (1. below) but this pull request to can be changed one of the following (or another approach entirely.)

  1. Simplest: Assume by localizing a mailable, the app container instance has getLocale() / setLocale() methods.

    public function withLocale($locale, $callback)
    {
        if (! $locale) {
            return $callback();
        }
    
        $app = Container::getInstance();
    
        // throws exception for custom containers
        // maybe you shouldn't be trying to locale() a mailable
        $original = $app->getLocale();
  2. Hack: Check explicitly for Laravel's concrete Application container.

    public function withLocale($locale, $callback)
    {
        $app = Container::getInstance();
    
        if (! $locale || ! $app instanceof \Illuminate\Foundation\Application) {
            return $callback();
        }
    
        $original = $app->getLocale();
  3. Custom Container-friendly Contract: Make Laravel's app container implement a new interface.

    interface LocalizedApplication
    {
        public function setLocale($locale);
        public function getLocale();
        public function isLocale($locale);
    }
    class Application
        extends Container
        implements ApplicationContract, HttpKernelInterface, LocalizedApplication
    {
    public function withLocale($locale, $callback)
    {
        $app = Container::getInstance();
    
        if (! $locale || ! $app instanceof LocalizedApplication) {
            return $callback();
        }
    
        $original = $app->getLocale();

This changes the method signature of Illuminate\Support\Traits\Localizable@withLocale() so this pull request is proposed for 5.7.

Allow mailables to translate timestamps, money
currency, etc. in Mailable body content by
adding LocaleUpdated event listeners.
@derekmd derekmd force-pushed the mailable-app-setlocale-5.7 branch from d5d6d5a to 5673a19 Compare June 5, 2018 06:49
@taylorotwell taylorotwell merged commit 5673a19 into laravel:master Jun 5, 2018
@derekmd derekmd deleted the mailable-app-setlocale-5.7 branch June 5, 2018 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants