LinkGenerator – Call to a member function link() on null

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

Ahoj,

právě pracuji na projektu pro cli mod nette a mám dotaz.

Potřebuji generovat odkaz v latte šabloně mailu pomocí LinkGeneratoru, postupoval jsem dle https://phpfashion.com/…-a-nette-2-3

Ovšem se mi vypisuje chyba: Call to a member function link() on null

Zkoušel jsem přidat service generator do config.neon, ovšem nepomohlo…

Nevíte prosím co by to mohlo být za chybu?

Felix
Nette Core | 1190
+
0
-

Určitě si nasetoval?

$tpl->_control = $tpl->_presenter = $linkGenerator;

N-makra totiž potřebuji proměnou $_presenter.

Editoval Felix (8. 4. 2015 20:06)

rasovsky
Člen | 3
+
0
-

Ahoj,

přidáno:

$template->_presenter = $this->linkGenerator;

Ovšem chyba přetrvává

Pro úplnost:

  • Konstruktor presenteru ze kterého se action volá:
/** @var \Nette\Application\LinkGenerator */
private $linkGenerator;

function construct(\Nette\Application\LinkGenerator $generator)
{
    $this->linkGenerator = $generator;
}

Pak jsem jen do šablony přidal:

$template->_control = $this->linkGenerator;
$template->_presenter = $this->linkGenerator;

V latte je použito makro link:

{link //Mail:Unsubscribe:unsubscribeTooLongNotLoggedIn, $userId, $unsubscribeHash}

Ovšem hlásí…
Call to a member function link() on null

David Kudera
Člen | 455
+
0
-

Tak minimálně by jsi měl určitě úplně vždy volat parent::__construct(); když přepisuješ konstruktor

David Matějka
Moderator | 6445
+
0
-

@rasovsky ukaz cely kod – jak tu sablonu vytvaris, vykreslujes atd.

rasovsky
Člen | 3
+
0
-

Ahoj,

takže jsem se s tím po delší odmlce snažil bojovat a všiml jsem si, že mi se vůbec nevolal konstruktor, takže jsem jej přepsal:

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

public function __construct(\Fabian\Linkedin\Linkedin $linkedin, \Nette\Application\LinkGenerator $generator)
{
    parent::__construct($linkedin);
    $this->linkGenerator = $generator;
}

Dále jsem do configu přidal service generator:

		generator: Nette\Application\LinkGenerator(@url)

latte šablona ve které se link generuje:

{extends "../MailWithoutSuggestedJobs/mailWithoutSuggestedJobs.latte"}

{block unsubscribe}
	{ifset $unsubscribeHash}
	    {capture $unsubscribeUrl}{link //:Mail:Unsubscribe:unsubscribeTrialEnded, $userId, $unsubscribeHash}{/capture}
		{!_"T_MAIL_TEXT_TO_UNSUBSTRIBE_FROM_LIST_GENERAL", $unsubscribeUrl}
	{/ifset}
{/block}

Původní chyba zmizela, ovšem objevila se nová…

Recoverable Error

Argument 2 passed to CronModule\MailPresenter::__construct() must be an instance of Nette\Application\LinkGenerator, none given, called in C:\xampp\htdocs\JoboteDEV\temp\cache\Nette.Configurator\Container_535fa75d2d.php on line 1834 and defined


Dále pro Davida Matějku kompletní kód presenteru, kde se má vytvořit šablona a odeslat mailem:

<?php

namespace CronModule;
use Nette\Utils\Validators;

class MailPresenter extends \CronModule\CronBasePresenter
{

	const MAIL_TYPE_HR_WAITING = 'hr_waiting_status_warning';

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

    public function __construct(\Fabian\Linkedin\Linkedin $linkedin, \Nette\Application\LinkGenerator $generator)
    {
        parent::__construct($linkedin);
        $this->linkGenerator = $generator;
    }

    public function actionTrialEnded(){
        $db = $this->model->dbConnection;

        $this->model->emails->addRowsForUsersNotHavingEmailType(\Jobote\EmailsSubmodel::EMAIL_TYPE_TRIAL_ENDED, 0);

        $managerIds = $db->query("
				SELECT U.id
				FROM company C
				LEFT JOIN user U
				ON U.id = C.manager
				LEFT JOIN email_notification_settings ES
				ON U.id = ES.user
				WHERE
				      ES.email_type = ?
			", \Jobote\EmailsSubmodel::EMAIL_TYPE_TRIAL_ENDED)->fetchAll();

        $htmlText =
            $this->translator->translate("T_MAIL_TEXT_NOT_SHARED_HELLO") . "<br><br>" .
            $this->translator->translate("T_MAIL_TEXT_TRIAL_ENDED_YOUR_TRIAL_EXPIRED") . "<br><br>" .
            $this->translator->translate("T_MAIL_TEXT_TRIAL_ENDED_IF_YOU_ARE_INTERESETED") . "<br><br>".
            $this->translator->translate("T_MAIL_TEXT_TRIAL_ENDED_JUST_EMAIL_US") . "<br><br>".
            $this->translator->translate("T_MAIL_SIGNATURE_TOMAS") . "<br>".
            $this->translator->translate("T_MAIL_SIGNATURE_TOMAS_PHONE") . "<br>".
            $this->translator->translate("T_MAIL_SIGNATURE_TOMAS_EMAIL") . "<br>"
        ;

        $rawText =
            $this->translator->translate("T_MAIL_TEXT_NOT_SHARED_HELLO") . "\n\n" .
            $this->translator->translate("T_MAIL_TEXT_TRIAL_ENDED_YOUR_TRIAL_EXPIRED") . "\n\n" .
            $this->translator->translate("T_MAIL_TEXT_TRIAL_ENDED_IF_YOU_ARE_INTERESETED") . "\n\n" .
            $this->translator->translate("T_MAIL_TEXT_TRIAL_ENDED_JUST_EMAIL_US") . "\n\n".
            $this->translator->translate("T_MAIL_SIGNATURE_TOMAS") . "\n".
            $this->translator->translate("T_MAIL_SIGNATURE_TOMAS_PHONE") . "\n".
            $this->translator->translate("T_MAIL_SIGNATURE_TOMAS_EMAIL") . "\n"
        ;

        foreach($managerIds as $creator) {
            $user = $this->model->users->getUserById($creator['id']);
            $this->model->emails->updateLastSendForUserAndEmailType($user, \Jobote\EmailsSubmodel::EMAIL_TYPE_TRIAL_ENDED );
            $pathToTemplate = "TrialEnded/trialEnded.latte";
            //Add unsubscribe
            $this->translator->setLang($user->language); // Set language according to user settings

            /** -------- zde se vytvari sablona --------  **/
            $template = $this->createEmailTemplateWithoutSuggestedJobs(
                $this->translator->translate("T_MAIL_SUBJECT_TRIAL_ENDED"), $htmlText,
                $user->name, $pathToTemplate);
            $template->setTranslator($this->translator);

            $unsubscribeHash = md5($user->email . \MailModule\UnsubscribePresenter::UNSUBSCRIBE_EMAIL_TYPE_TRIAL_ENDED);
            $template->unsubscribeHash = $unsubscribeHash;

            /** -------- zde vklada linkGenerator do sablony --------  **/
            $template->_control = $this->linkGenerator;
            $template->_presenter = $this->linkGenerator;
            $email = new \Nette\Mail\Message;
            $email->addTo($user->email)
                ->setFrom('test@test.cz', 'test mail')
                ->setSubject($this->translator->translate("T_MAIL_SUBJECT_TRIAL_ENDED"))
                ->setHtmlBody($template)
                ->setBody($rawText);
            $mailer = new \Jobote\MandrillMailer($this->context->parameters['mandrill']['apiKey']);
            $mailer->send($email);
            die();
        }

        $this->terminate();
    }

}

pro úplnost metoda createEmailTemplateWithoutSuggestedJobs:

	/**
	 * Create template for email without suggested jobs included.
	 *
	 * @param string $title
	 * @param string $emailBody is raw format body of the email
	 * @param string $nameInHello is the name to write in heading of email
	 * @param string $pathToTemplate is the path to the template from /MailModule/templates/
	 *
	 * @return template $template
	 */
	public function createEmailTemplateWithoutSuggestedJobs($title, $emailBody, $nameInHello, $pathToTemplate)
	{
		$template = $this->createTemplate();
		$absolutePath = $this->context->parameters['appDir'];
		$template->setFile($absolutePath . "/MailModule/templates/" . $pathToTemplate);
		//$template->registerFilter(new \Nette\Latte\Engine);
		$template->staticsUrl = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://') . $this->context->parameters['urls']['statics'];
		$template->title = $title;
		$template->content = $emailBody;
		$template->nameInHello = $nameInHello;

		return $template;
	}

Editoval rasovsky (14. 4. 2015 15:30)