Ako zabezpecit aby SendMail posielal maily v inej lokalizacii, ako je aktualny jazyk aplikacie?

steelbull
Člen | 240
+
0
-

Ako zabezpecit aby SendMail posielal maily v inej lokalizacii, ako je aktualny jazyk aplikacie? Problemom je trieda Mails, kde potrebujem iba v tejto triede zmenit lokalizaciu na ‚en‘.

Translator mam nakonfigurovany takto:

extensions:
    translation: Kdyby\Translation\DI\TranslationExtension
    - WebChemistry\Forms\Controls\DI\MultiplierExtension

translation:
    default: sk
    whitelist: [sk, en, pl]
    fallback: [sk_SK, sk]
    resolvers:
        session: on
        request: off
        header: off

Mam nasledujuci formular:

class ProjectForm extends UI\Control
{
    /** @var Context */
    private $context;

    /** @var Translator */
    private $translator;

    /** @var User */
    private $user;

    /** @var int */
    private $id;

    /** @var mixed */
    private $values;

    /** @var \Nette\Database\Table\ActiveRow */
    private $leader;

    /** @var \Nette\Database\Table\Selection */
    private $members;

    /** @var mixed */
    private $tools;

    /** @var Model\ProjectsModel */
    private $modelProjects;

    /** @var Model\TeamProjectModel */
    private $modelTeamProject;

    /** @var Model\TeamsModel */
    private $modelTeams;

    /** @var Model\BaseListModel */
    private $modelBaseList;

    /** @var bool */
    private $is_P4G = false;

    /** @var ProjectFilesUploader @inject */
    private $uploader;

    /** @var UI\ITemplateFactory */
    private $templateFactory;

    /** @var \Nette\Application\LinkGenerator */
    private $linkGenerator;

    /** @var Mails\Mail */
    private $mails;

    /** @var Nette\Database\ResultSet */
    private $users;

    /** @var array */
    private $percentages;

    /**
     * Constructor ProjectForm
     * @param Context $context
     * @param Translator $t
     * @param User $u
     * @param IProjectFilesUloaderFactory $uploader
     * @param UI\ITemplateFactory $tpl
     * @param LinkGenerator $link
     * @param Mails\IMailFactory $mailFactory
     */
    public function __construct(Context $context, Translator $t, User $u, IProjectFilesUloaderFactory $uploader, UI\ITemplateFactory $tpl, LinkGenerator $link, Mails\IMailFactory $mailFactory)
    {
        parent::__construct();

        $this->context = $context;
        $this->translator = $t;
        $this->user = $u;
        $this->uploader = $uploader;
        $this->templateFactory = $tpl;
        $this->linkGenerator = $link;
        $this->modelProjects = new Model\ProjectsModel($this->context, $this->user);
        $this->modelTeamProject = new Model\TeamProjectModel($this->context, $this->user);
        $this->modelTeams = new Model\TeamsModel($this->context, $this->user);
        $this->modelBaseList = new Model\BaseListModel($this->context, $this->user);
        $this->mails = $mailFactory->create();

        for ($i = 0; $i <= 100; $i = $i + 5) {
            $this->percentages[$i] = $i . '%';
        }
    }
...

Do presentera je injectnuty pomocou DI.

V BasePresenter mam nastaveny jazyk:

/** @var \Kdyby\Translation\LocaleResolver\SessionResolver @inject */
public $translatorSession;


	...


	$this->translatorSession->setLocale('sk');

Ale maily chcem posielat v EN a preto som v Mails\IMailFactory nastavil jazyk na EN a toto je problem, lebo ked to urobim, prestavim jazkyk vlastne vsade:

class Mail
{
    use Nette\SmartObject;

    /** @var Nette\Mail\IMailer */
    protected $mailer;

    /** @var Context */
    private $context;

    /** @var User */
    private $user;

    /** @var Translator */
    private $translator;

    /** @var Nette\Application\LinkGenerator */
    private $linkGenerator;

    /** @var ITemplateFactory */
    private $templateFactory;

    /** @var string Sender e-mail address */
    protected $mailFrom = "kaizentracker@whirlpool.com";

    /** @var ConfigService */
    protected $config;

    /**
     * Constructor Mail
     * @param Context $context
     * @param User $user
     * @param Translator $translator
     * @param ITemplateFactory $templateFactory
     * @param LinkGenerator $linkGenerator
     * @param Nette\Mail\IMailer $mailer
     * @param ConfigService $config
     */
    public function __construct(Context $context, User $user, Translator $translator, ITemplateFactory $templateFactory, LinkGenerator $linkGenerator, Nette\Mail\IMailer $mailer, ConfigService $config)
    {
        $this->context = $context;
        $this->user = $user;
        $this->translator = $translator;
        $this->templateFactory = $templateFactory;
        $this->linkGenerator = $linkGenerator;
        $this->mailer = $mailer;
        $this->config = $config;

        //@TODO Ako zmenit translation len v tejto triede? Toto nie je OK, lebo to zmeni jazyk vsade.
        // Set translation to locale defined in neon file
        //$this->translator->setLocale($this->config['mailDefaultLocale']);
    }

Dakujem za pomoc.

David Matějka
Moderator | 6445
+
+1
-

tak muzes bud na zacatku te operace, ktera vyzaduje jine locale jej nastavit a potom jej vratit na puvodni. pripadne by mohlo fungovat clone $translator a nastavit locale na naklonovanem

steelbull
Člen | 240
+
0
-

David Matějka napsal(a):

tak muzes bud na zacatku te operace, ktera vyzaduje jine locale jej nastavit a potom jej vratit na puvodni. pripadne by mohlo fungovat clone $translator a nastavit locale na naklonovanem

S clone som to skusal, ale s tym to nefunguje. Sice to zmeni locale, ale prestane fungovat prekladanie v latte. Asi to bude kvoli metode createTemplate:

<?php

namespace App\Mails;

use App\Helpers\Date;
use App\Model\CardsModel;
use App\Model\ProjectsModel;
use App\Model\TeamProjectModel;
use App\Model\UserGroupsModel;
use App\Model\UsersModel;
use App\Services\ConfigService;
use Nette;
use Nette\Database\Context;
use Nette\Security\User;
use Kdyby\Translation\Translator;
use Nette\Mail\Message;
use Nette\Application\UI\ITemplateFactory;
use Nette\Application\LinkGenerator;
use Tracy\Debugger;

class Mail
{
    use Nette\SmartObject;

    /** @var Nette\Mail\IMailer */
    protected $mailer;

    /** @var Context */
    private $context;

    /** @var User */
    private $user;

    /** @var Translator */
    private $translator;

    /** @var Nette\Application\LinkGenerator */
    private $linkGenerator;

    /** @var ITemplateFactory */
    private $templateFactory;

    /** @var string Sender e-mail address */
    protected $mailFrom = "kaizentracker@whirlpool.com";

    /** @var ConfigService */
    protected $config;

    /**
     * Constructor Mail
     * @param Context $context
     * @param User $user
     * @param Translator $translator
     * @param ITemplateFactory $templateFactory
     * @param LinkGenerator $linkGenerator
     * @param Nette\Mail\IMailer $mailer
     * @param ConfigService $config
     */
    public function __construct(Context $context, User $user, Translator $translator, ITemplateFactory $templateFactory, LinkGenerator $linkGenerator, Nette\Mail\IMailer $mailer, ConfigService $config)
    {
        $this->context = $context;
        $this->user = $user;
        $this->translator = clone $translator;
        $this->templateFactory = $templateFactory;
        $this->linkGenerator = $linkGenerator;
        $this->mailer = $mailer;
        $this->config = $config;

        //@TODO Ako zmenit translation len v tejto triede? Toto nie je OK.
        // Set translation to locale defined in neon file
        $this->translator->setLocale('en');
    }

    /**
     * Method sendWelcomeMember
     * @param $project_id
     * @param $user_id
     */
    public function sendWelcomeMember($project_id, $user_id)
    {
        try {
            $projectModel = new ProjectsModel($this->context, $this->user);

            $project = $projectModel->getProject($project_id);
            $member = (new UsersModel($this->context))->getUser($user_id);

            if ($project && $member && $member->email) {
                // Prepare template
                $template = $this->createTemplate();
                $template->project = $project;
                $template->projects = $projectModel->getProjects()
                    ->where(':teams.user_id', $member->id);
                $template->member = $member;
                $template->date = new Date();

                // Prepare message
                $message = new Message();
                $message->setFrom($this->mailFrom);
                $message->setSubject($this->translator->translate("mails.welcome.subject", ['sign' => $project->sign]));

                if ($this->config->mailDebug) {
                    $this->addDebugEmails($message);
                    if ($this->config->mailDebugMode == 2) {
                        $message->addTo($member->email, $member->fullname);
                    }
                } else {
                    $message->addTo($member->email, $member->fullname);
                }

                $message->setHtmlBody($template->renderToString(__DIR__ . "/templates/welcomeMember.latte"));

                // Send message
                $this->mailer->send($message);
            }
        } catch (\Exception $ex) {
            throw new \RuntimeException("Unable to send welcome e-mail to projet member. " . $ex->getMessage());
        }
    }

    /**
     * Method sendWelcomeMembers
     * @param $project_id
     * @throws \Exception
     */
    public function sendWelcomeMembers($project_id)
    {
        $modelTeamProject = new TeamProjectModel($this->context, $this->user);

        try {
            $members = $modelTeamProject->getMembers($project_id);
            foreach ($members as $member) {
                $this->sendWelcomeMember($project_id, $member->user_id);
            }
        } catch (\Exception $ex) {
            throw new \RuntimeException($ex->getMessage());
        }
    }


...


    /**
     * Method addDebugEmails
     * @param Message $message
     */
    protected function addDebugEmails(Message $message)
    {
        $recip = array();
        $mailDebugEmail = $string = str_replace(' ', '', $this->config->mailDebugEmail);
        if (strpos($this->config->mailDebugEmail, ";") !== false) {
            $recip = explode(";", $mailDebugEmail);
        } elseif (strpos($this->config->mailDebugEmail, ",") !== false) {
            $recip = explode(",", $mailDebugEmail);
        } else {
            $recip[] = $mailDebugEmail;
        }

        foreach ($recip as $r) {
            $message->addCc($r);
        }
    }


    /**
     * Method createTemplate
     * @return Nette\Application\UI\ITemplate
     */
    protected function createTemplate()
    {
        /** @var Nette\Application\UI\ITemplate $template */
        $template = $this->templateFactory->createTemplate();
        $template->getLatte()->addProvider('uiControl', $this->linkGenerator);

        return $template;
    }
}

/**
 * Interface IMailFactory
 */
interface IMailFactory
{
    /** @return Mail */
    public function create();
}
ali
Člen | 342
+
+1
-

Ja to delam jednoduse takto

{_text, null, [], null, 'en_US'}
steelbull
Člen | 240
+
0
-

ali napsal(a):

Ja to delam jednoduse takto

{_text, null, [], null, 'en_US'}

V tomto pripade by mi to asi pomohlo, ale neda sa to urobit nejakym elegantnejsim sposobom? S Clone sa mi to paci asi najviac, v komponente to normalne funguje, ale problem je, ked v metode createTemplate vytvorim novy template, tam to uz nejde. Ak clone odstranim, preklad funguje aj v template, takze vychadzam z toho, ze template asi pouziva staru instanciu translatora a komponent klonovanu instanciu.

Ale este jedna vec. Ked konujem template, daju sa dodatocne vypnut/zapnut resolvery v translation?

Diq.

Editoval steelbull (27. 2. 2019 8:03)

CZechBoY
Člen | 3608
+
+2
-

Furt by melo fungovat nastaveni translatoru.

$template->setTranslator($enTranslator);
steelbull
Člen | 240
+
0
-

CZechBoY napsal(a):

Furt by melo fungovat nastaveni translatoru.

$template->setTranslator($enTranslator);

Diiiiq. Presne toto som potreboval : – )