cancel
Showing results for 
Search instead for 
Did you mean: 

Customer E-mail notifications are hard to hook into.

0 Kudos

Customer E-mail notifications are hard to hook into.

Magento 2.1.3:

 

I've been given the task that when a customer with a certain property registers itself it should get a different e-mail template. What this property is, is not important for the question, but lets say for sake of simplicity I have a Service Contract that can check if the customer qualifies for the different e-mail template or not:

 

$this->customerChecker->hasCertainProperty($customerId); // returns true or false

Now this might seem like an easy task right? Just hook into `Magento\Customer\Model\EmailNotification` with a plugin or something, and modify the part where the correct e-mail template is selected. Right?

 

    public function newAccount(
        CustomerInterface $customer,
        $type = self::NEW_ACCOUNT_EMAIL_REGISTERED,
        $backUrl = '',
        $storeId = 0,
        $sendemailStoreId = null
    ) {
        $types = $this->getTemplateTypes();

        if (!isset($types[$type])) {
            throw new LocalizedException(__('Please correct the transactional account email type.'));
        }

        if (!$storeId) {
            $storeId = $this->getWebsiteStoreId($customer, $sendemailStoreId);
        }

        $store = $this->storeManager->getStore($customer->getStoreId());

        $customerEmailData = $this->getFullCustomerObject($customer);

        $this->sendEmailTemplate(
            $customer,
            $types[$type],
            self::XML_PATH_REGISTER_EMAIL_IDENTITY,
            ['customer' => $customerEmailData, 'back_url' => $backUrl, 'store' => $store],
            $storeId
        );
    }

Right... the e-mail template is sent in this method using sendEmailTemplate(). So we can't use a interceptor for this... Well let's just look at the sendEmailTemplate()-method then:

 

    private function sendEmailTemplate(
        $customer,
        $template,
        $sender,
        $templateParams = [],
        $storeId = null,
        $email = null
    ) {
        $templateId = $this->scopeConfig->getValue($template, 'store', $storeId);
        if ($email === null) {
            $email = $customer->getEmail();
        }

        $transport = $this->transportBuilder->setTemplateIdentifier($templateId)
            ->setTemplateOptions(['area' => 'frontend', 'store' => $storeId])
            ->setTemplateVars($templateParams)
            ->setFrom($this->scopeConfig->getValue($sender, 'store', $storeId))
            ->addTo($email, $this->customerViewHelper->getCustomerName($customer))
            ->getTransport();

        $transport->sendMessage();
    }

Darn! The method is private! So an interceptor will definitely not work here. And we also cannot use a rewrite, since private methods are not inherited. 

 

The only way to manipulate our desired functionality is by rewriting the EmailNotification and copy/paste everything that is private from this class. Which are a lot of methods and properties.

 

---

 

I would suggest that the EmailNotification-class gets some refactoring so it makes it's easier for 3rd party modules to extend it's functionality. Or am I missing something here?