Email Localization → presenter + template

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Joacim
Člen | 229
+
0
-

Mám webové stránky s kontaktním formulářem, který se odesílá vyplněný po odeslání na server pomocí AJAXU (Nette AJAX), stránky jsou též lokalizované do cz|en pomocí:
config.neon

extensions:
    translation: Kdyby\Translation\DI\TranslationExtension

ContactPresenter

<?php

namespace App\Presenters;

use Nette;
use App\Model;

/**
 * Description of ContactPresenter
 *
 * @author
 */
class ContactPresenter extends BasePresenter {

    /** @var Nette\Database\Context */
    private $database;

    public function __construct(Nette\Database\Context $database) {
        $this->database = $database;
    }

    public function renderDefault() {
        $this->template->p_name = $this->p_name;
    }

    public function handleRenderContactSendMail($name, $addFrom, $subject, $message) {

        $to = $this->database->query('SELECT value FROM settings WHERE name = \'EMAIL_TO\'')->fetchField();
        $from = $this->database->query('SELECT value FROM settings WHERE name = \'EMAIL_FROM\'')->fetchField();

        // Přijemce zpravy
        $owner_email_param = array(
            'addTo' => $to,
            'addFrom' => $from, // Odesilame vždy z emailu daného serveru
            'name' => $name,
            'subject' => $subject,
            'email_template' => 'contactFormOwner',
            'body' => array(
                'addFrom' => $addFrom,
                'name' => $name,
                'subject' => $subject,
                'message' => $message
            ),
        );

        // Kopie pro odesilatele zpravy
        $sender_email_param = array(
            'addTo' => $addFrom,
            'addFrom' => $from, // Odesilame vždy z emailu daného serveru
            'name' => $name,
            'subject' => $subject,
            'email_template' => 'contactFormSender',
            'body' => array(
                'addFrom' => $addFrom,
                'name' => $name,
                'subject' => 'KOPIE zprávy ze serveru www.test.cz - ' . $subject,
                'message' => $message
            ),
        );

        try {
            if ($_SERVER['SERVER_NAME'] != 'localhost') {
                $mail_owner = new \App\Model\EmailNotification($owner_email_param);
                $mail_sender = new \App\Model\EmailNotification($sender_email_param);
                $this->flashMessage('Email byl úspěšně odeslán.', 'success');
            } else {
                $this->flashMessage('Email nelze odeslat z localhostu.', 'danger');
            }
        } catch (\Nette\Mail\SmtpException $exc) {
            echo 'fail';
            $this->flashMessage('Email se nepodařilo odeslat, kvůli špatnému nastavení SMTP.', 'danger');
        }
        exit();
    }

}

Model EmailNotification

namespace App\Model;

use Nette\Mail\Message,
    Nette\Mail\SmtpMailer,
    Nette\Mail\SendmailMailer,
    Latte\Engine;

class EmailNotification {

    private $message;
    private $sender;

    public function __construct($param) {
        $this->message = new \Nette\Mail\Message();
        $this->sender = new \Nette\Mail\SendmailMailer();

        $this->setFrom($param['addFrom'], $param['name']);
        $this->setEmail($param['addTo']);
        $this->setSubject($param['subject']);
        $this->setBody($param['email_template'], $param['body']);
        $this->sendEmail();
    }

    /* nastaveni od koho je */

    private function setFrom($from, $name) {
        $this->message->setFrom($from);
    }

    /**
     * nastaveni prijemcu
     * @param mixed $emails (string nebo array)
     */
    private function setEmail($emails) {
        if (is_array($emails)) {
            foreach ($emails as $email) {
                $this->message->addTo($email);
            }
        } else
            $this->message->addTo($emails);
    }

    private function setSubject($subject) {
        $this->message->setSubject($subject);
    }

    /**
     * nastaveni body
     * @param string $template nastaveni ktera sablona.latte bude v emailu
     * @param array $content seznam promennych v sablone
     */
    private function setBody($template, $content) {
        $latte = new Engine();
        $this->message->setHtmlBody($latte->renderToString('../app/presenters/templates/Emails/' . $template . '.latte', $content));
    }

    private function sendEmail() {
        if (strpos($_SERVER['SERVER_NAME'], 'localhost') === false) {
            $this->sender->send($this->message);
        }
    }

}

EmailTemplate – contactFormOwner

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <p><strong>Tento email vám zaslal: </strong><a href="mailto:{$addFrom}">{$name}</a></p>
        </br>
        <p><strong>{$subject}</strong></p>
        <p>
            {$message}
        </p>

        <p style="text-align: left; font-size: 0.7em;">Tento email byl automaticky odeslán ze serveru <a href=""></a> přes kontaktní formulář.</p>
    </body>
</html>

Potřebuji přeložit podle URL stránky:
Defaultní je CS verze: www.test.cz/contact/
EN verze: www.test.cz/en/contact/

$router[] = new Route('[<locale=cs cs|en>/]<presenter>/<action>/[<id>]', "Home:default");

Pokud je uživatel na EN verzi formuláře chci odeslat email s EN popisky jak v template tak presenteru(poli pro model mít přeloženo např: KOPIE zprávy ze serveru test – (viz pole presenteru))

Používám soubory app / lang / ui.cs_CZ.neon (a en file) formátu:

home: DOMŮ
author: O AUTOROVI
gallery: GALERIE

Použití lokalizace v klasickém template

<h4>{_ ui.author}</h4>

Nevím jak použít lokalizaci pro presenter string a pro latte file emailu (pokud vložím makro pro překlad obdržím Chyba 500 – Internal Server Error)

iguana007
Člen | 970
+
0
-

Joacim napsal(a):
Nevím jak použít lokalizaci pro presenter string a pro latte file emailu (pokud vložím makro pro překlad obdržím Chyba 500 – Internal Server Error)

A co ti spadne do error logu? Chyba 500 je hodně široký pojem …

David Matějka
Moderator | 6445
+
+2
-
  1. Latte Engine nevytvarej rucne, ale pomoci ILatteFactory, pripadne sablonu pomoci ITemplateFactory, viz https://phpfashion.com/…-a-nette-2-3
  2. stejne tak nevytvarej rucne mailer, vyzadej si IMailer jako zavislost.
  3. Z toho vyplyva, ze nejak musis do EmailNotification ty zavislosti dostat. Ta trida je uplne spatne navrzena. V konstruktoru delej vzdy co nejmene veci. Takze: EmailNotification registruj jako sluzbu a uprav zhruba nasledovne:
namespace App\Model;

use Nette\Mail\Message;
use Nette\Mail\IMailer;
use Nette\Bridges\ApplicationLatte\ILatteFactory;


class EmailNotification {

    private $mailer;

    private $latteFactory;

	private $emailDir;

	public function __construct($emailDir, IMailer $mailer, ILatteFactory $latteFactory)
	{
		$this->emailDir = $emailDir;
		$this->mailer = $mailer;
		$this->latteFactory = $latteFactory
	}

    public function send($param) {
        $message = new Message();

        ..... nastaveni from, to, subject...

		$latte = $this->latteFactory->create();


		$message->setHtmlBody($latte->renderToString($this->emailDir . $param['email_template'] . '.latte', $param['body']));


		$this->mailer->send($message);
    }

}

A registrujes

services:
	- App\Model\EmailNotification(%appDir%/presenters/templates/Emails/)

Diky tomu, ze pouzijes LatteFactory, tak se automaticky registruje translator. V presenteru si pak injectnes tuhle sluzbu a budes volat ->send($owner_email_param)

A diky tomu, ze i mailer mame jako zavislost, tak se muzes vykaslat na nejaky kontroly, jestli se to posila na localhostu a pouze vymenit mailer (treba aby jen zapisoval do souboru, nebo jen aby pouzival jiny smtp, ja treba pouzivam mailtrap.io)

Joacim
Člen | 229
+
0
-

iguana007 napsal(a):

Joacim napsal(a):
Nevím jak použít lokalizaci pro presenter string a pro latte file emailu (pokud vložím makro pro překlad obdržím Chyba 500 – Internal Server Error)

A co ti spadne do error logu? Chyba 500 je hodně široký pojem …

Logic exception → filter ‚Translate‘ is not defined

David Matějka
Moderator | 6445
+
+1
-

A jeste par poznamek:

  • jestli chces chytat vyjimku, tak ji nezapomen zalogovat, nejsnadneji pres Tracy\Debugger::log($e, 'exception') a od nette 2.3.4 nechytej SmtpException, ale obecnejsi https://api.nette.org/…ception.html
  • vsechny hodnoty posilej do sql dotazu pres parametry:
$this->database->query('SELECT value FROM settings WHERE name = ?', 'EMAIL_TO')->fetchField();
Joacim
Člen | 229
+
0
-

David Matějka napsal(a):

A jeste par poznamek:

  • jestli chces chytat vyjimku, tak ji nezapomen zalogovat, nejsnadneji pres Tracy\Debugger::log($e, 'exception') a od nette 2.3.4 nechytej SmtpException, ale obecnejsi https://api.nette.org/…ception.html
  • vsechny hodnoty posilej do sql dotazu pres parametry:
$this->database->query('SELECT value FROM settings WHERE name = ?', 'EMAIL_TO')->fetchField();

Díky moc za cenné rady, nepsal jsem to já, ale kolega – jdu to předělat

Lze použít localization i v presenteru ?

Editoval Joacim (29. 9. 2015 20:01)

David Matějka
Moderator | 6445
+
0
-

Musi byt registrovany filtr translate, jako je to tady, takze bud si do toho EmailNotification predej zminovane ILatteFactory (to bude lepsi) a vytvor si ten engine, nebo si tam predej translator a filtr zaregistruj rucne

Joacim
Člen | 229
+
0
-

David Matějka napsal(a):

Musi byt registrovany filtr translate, jako je to tady, takze bud si do toho EmailNotification predej zminovane ILatteFactory (to bude lepsi) a vytvor si ten engine, nebo si tam predej translator a filtr zaregistruj rucne

V presenteru stačilo nakonec použít jen toto (viz. manuál)

$subject_full = $this->translator->translate('ui.contact_email_send_sender_subject') . $subject;