DatsunBing
DatsunBing

Reputation: 9076

ZF2: How to set the base path for the basePath view helper

I use phtml templates rendered with the phpRenderer as the body of my emails. This was working fine until recently when I started to get an error with the basePath() view helper.

I think the problem started occurring after I upgraded my framework to 2.2.6, but I can't be sure.

Here's how I am configuring the view for the body of my email:

$paths = array(__DIR__ . '/../../../view/std-email/');
$resolver = new \Zend\View\Resolver\TemplatePathStack(array('script_paths' => $paths));

$renderer = new \Zend\View\Renderer\PhpRenderer();
$renderer->setResolver($resolver);

$view = new \Zend\View\Model\ViewModel(array(...));
$view->setTemplate($this->template)->setTerminal(true);
$this->mail->setBody($renderer->render($view));

In the view script I am simply echoing $this->basePath() and that's where the exception is occurring. It indicates that the base path is not set, even if I hard code a base path under the view_manager section of the module config.

When a view is assembled in the normal manner (i.e. by MVC listeners on controllers) the base path helper works correctly. It seems to me that when I manually instantiate a new renderer it is getting it's own instance of the view helper plugin manager, and this instance lacks the default configuration. So, a few questions here:

I could manually set the base path each time I instantiate a renderer, but I think there must be a more elegant way. For example, can I share the existing view helper plugin manager instance?

Upvotes: 1

Views: 4828

Answers (2)

Chukky Nze
Chukky Nze

Reputation: 720

Assuming your emails are being sent in or by a specific module you can set the default basePath in the view_manager key of the specific module.config like so:

module.config.php

return  array
        (
            'controllers'       =>  array(...),
            'router'            =>  array(...),
            'view_manager'      =>  array
                                    (
                                        'base_path'           => 'http://local.yourproject.com',
                                        'template_map'        => array(...),
                                        'template_path_stack' => array(...),
                                    ),
       );

However, given Kim's comments, the issue may be one of what you're passing to the setBody method. You could try passing a MimeMessage object with parts that are MimePart objects. The contents of which would come from templates set in the Module and thus subject to the set base path:

$EmailTemplate      =   new EmailUtility();
$emailContent       =   $EmailTemplate->getEmailTemplate
                        (
                            'identifier-for-your-email-template', 
                            $emailTemplateArrayOptions
                        );

$templateRenderer   =   $this->getServiceLocator()->get('ViewRenderer');
$emailHTMLContent   =   $templateRenderer->render
                        (
                            $emailContent['html'], 
                            $emailContent['templateVariables']
                        );
$emailTextContent   =   $templateRenderer->render
                        (
                            $emailContent['text'], 
                            $emailContent['templateVariables']
                        );

// Create HTML & Text Headers
$emailHTMLHeader        =   new MimePart($emailHTMLContent);
$emailHTMLHeader->type  =   "text/html";

$emailTextHeader        =   new MimePart($emailTextContent);
$emailTextHeader->type  =   "text/plain";

$emailBody              =   new MimeMessage();
$emailBody->setParts(array($emailTextHeader, $emailHTMLHeader,));

// instance mail
$mail   =   new Mail\Message();
$mail->setBody($emailBody);

The contents of EmailUtility->getEmailTemplate(...)

public function getEmailTemplate($emailIdentifier, $emailVariables)
{
    switch($emailIdentifier)
    {
        case 'identifier-for-your-email-template' : 
            // logic for required template vars goes here
            $emailTextLink = 'module/config/specific/mapping/text';
    $emailHTMLLink = 'module/config/specific/mapping/html';
    $emailSubject       =   'Verify Your Email Address';
    $templateVariables  =   array(...);
    break;
    }

    return  array
            (
                'text'              =>  $emailTextLink,
                'html'              =>  $emailHTMLLink,
                'subject'           =>  $emailSubject,
                'templateVariables' =>  $templateVariables
            );
}

and then again in your module.config.php

    return  array
        (
            'controllers'       =>  array(...),
            'router'            =>  array(...),
            'view_manager'      =>  array
                                    (
                                        'base_path'           => 'http://local.yourproject.com',
                                        'template_map'        => array
                                        (
                                            // Email Templates
                                            'module/config/specific/mapping/html'  =>  __DIR__ . '/../view/module/config/specific/template-html.phtml', 
                                            'module/config/specific/mapping/text'  =>  __DIR__ . '/../view/module/config/specific/template-text.phtml',                                                                                               ),
                                        'template_path_stack' => array(...),
                                        ),
       );

Upvotes: 2

Sam
Sam

Reputation: 16455

If you're using the full MVC Stack of Zend Framework 2 the basePath will be set automatically. If you don't however you'll need to set the helper manually like this:

$helper = new BasePath();
$helper->setBasePath('/my/base/path');

echo $helper;

Upvotes: 1

Related Questions