juriansluiman / Soflomo-Mail

Module to to ease the use of sending e-mail messages in Zend Framework 2
Other
5 stars 8 forks source link

Soflomo Email issue with SlmQueue(SlmQueueBeanstalkd) #3

Closed dasn82 closed 1 year ago

dasn82 commented 9 years ago

Hi Jurian,

I have been working on integrating Soflomo Mail with SlmQueue(SlmQueueBeanstalkd) and I am getting issue when executing it via the Console using the Worker system (Beanstalkd).

To explain in detail, I have created a ReferralEmailJobFactory which has the following code - $sm = $serviceLocator->getServiceLocator(); $emailService = $sm->get('EmailService'); return new ReferralEmailJob($emailService);

This is the ReferralEmailJob file - protected $emailService;

public function __construct($emailService) { $this->emailService = $emailService; }

public function execute()
{
    $payload = $this->getContent();
    $manager_emails = $payload['manager_emails'];
    $payor = $payload['payor'];
    $patient = $payload['patient'];
    $status = $payload['status'];
    $id = $payload['id']; 
    $mailService = new EmailService($this->emailService);
    $mailService->sendEmail($manager_emails, $payor, $patient, $status, $id);
}

I have attached the EmailService.php file which has its EmailServiceFactory(attached as well) to get the instance of the Soflomo\Mail\Service\MailService to send the email.

When the job is ready in Beanstalkd and I run the worker command to execute the job from the console ( I use Ubuntu) - php public/index.php queue beanstalkd default, I get an error due to the renderer inside Soflomo Mail being ViewRenderer which is not supported in Console Execution.

So I then changed the MailServiceFactory inside Soflomo Mail to have this line - $renderer = $serviceLocator->has('ViewRenderer') ? $serviceLocator->get('Soflomo\Mail\Renderer') : new PhpRenderer(); to see if it works and this time, the execution proceeds ahead but I then get this error - exception 'Zend\View\Exception\RuntimeException' with message 'Zend\View\Renderer\PhpRenderer::render: Unable to render template "referral/new-referral-email"; resolver could not resolve to a file' in /var/www/SeniorCareMarketing/vendor/zendframework/zendframework/library/Zend/View/Renderer/PhpRenderer.php:493

The template file is in the correct location and when I have used Soflomo Mail independently via HTTP request, the mail is sent correctly.

I tried adding a Resolver class to the PHPRenderer inside the renderBody method of the MailService class of Soflomo Mail and this helped in overcoming this issue -

$resolver = new TemplateMapResolver(); $resolver->setMap(array('referral/new-referral-email' => '/var/www/SeniorCareMarketing/module/Application/view/application/referral/new-referral-email.phtml')); $this->getRenderer()->setResolver($resolver); $html = $this->getRenderer()->render($options['template'], $variables);

But I request a proper solution to this integration issue instead of the hack that I have done. Please advise. I have been looking at this issue for the past 3 days,

juriansluiman commented 9 years ago

@dasn82 you are right Soflomo\Mail requires a service "ViewRenderer" by an alias.

The service is registered inside the MVC view manager , but the registration only happens when you are not in a console request. Thus, the "ViewRenderer" service is never registered for CLI requests.

I am not sure how we can resolve this in a clean way, so let me think of a proper solution. For now, you can replace the MailServiceFactory with the following:

class MyMailServiceFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $transport = $serviceLocator->get('Soflomo\Mail\Transport');
        // Note the renderer call has changed
        $renderer  = $serviceLocator->get('HttpViewManager')->getRenderer();
        $message   = $serviceLocator->get('Soflomo\Mail\Message');
        $config = $serviceLocator->get('config');
        $config = $config['soflomo_mail'];
        $layout = (isset($config['layout'])) ? $config['layout'] : null;
        return new MailService($transport, $renderer, $message, $layout);
    }
}

And set this in your config:

return [
    'service_manager' => [
        'factories' => [
            'Soflomo\Mail\Service\MailService' => 'MyModule\Factory\MyMailServiceFactory',
        ],
    ],
];
dasn82 commented 9 years ago

@juriansluiman , thanks very much for your response to the issue.

I will try this solution that you have advised in your response and will let you know later today how it goes.

juriansluiman commented 9 years ago

@dasn82 if the solution works, could you help me with a PR? The idea will be as follows:

  1. Have the alias Soflomo\Mail\Renderer point to a Soflomo\Mail\DefaultRenderer
  2. Have a factory for the Soflomo\Mail\DefaultRenderer called Soflomo\Mail\Factory\DefaultRendererFactory
  3. Fetch the renderer using the ViewManager as showed above
  4. The mail service factory will be kept the same as it's now in master

Let me know, because I haven't a working set up right now. If you could assist in this, it's easier to directly merge the PR and have another release which works for you.

dasn82 commented 9 years ago

@juriansluiman Sure. I will first try the solution and then we can take it forward if this works.

So if this works, you want me to fix and open a PR?

dasn82 commented 9 years ago

@juriansluiman The solution does not work. I get this error when I run from Console -

PHP Fatal error: Call to a member function get() on a non-object in /var/www/SeniorCareMarketing/vendor/zendframework/zendframework/library/Zend/Mvc/View/Http/ViewManager.php on line 141

Fatal error: Call to a member function get() on a non-object in /var/www/SeniorCareMarketing/vendor/zendframework/zendframework/library/Zend/Mvc/View/Http/ViewManager.php on line 141

dasn82 commented 9 years ago

@juriansluiman, Since we are trying to render from a Console Request as part of Slmqueue queue/worker system, I tried this solution to get the Renderer in the factory -

$sapi_type = php_sapi_name(); if($sapi_type == 'cli'){ $renderer = $serviceLocator->get('ConsoleViewManager')->getRenderer(); } else { $renderer = $serviceLocator->get('HttpViewManager')->getRenderer(); }

This seemed to have done the trick and the rendering of the email template happened successfully from the Console Request.

Please advise if this looks right to you.

juriansluiman commented 9 years ago

@dasn82 this is exactly already what happens in the ViewManagerFactory. What if you replace $serviceLocator->get('HttpViewManager')->getRenderer(); with $serviceLocator->get('ViewManager')->getRenderer();?

dasn82 commented 9 years ago

Okie. I will check this out later today and see what happens and let you know. I think as you said, it should work.

dasn82 commented 9 years ago

@juriansluiman The advised solution has worked. Thanks very much.

juriansluiman commented 9 years ago

@dasn82 thanks for all the work and testing! Could you create a pull request based on this solution and these steps I described earlier? Would be a great improvement so others can use Soflomo\Mail within their CLI requests too!

dasn82 commented 9 years ago

@juriansluiman Yes sure. I will create a PR with the above solution that you have described and will let you know when done.

Thanks very much for all your assistance in resolving this issue.

Danielss89 commented 1 year ago

Closing as stale