sndsabin / Aragorn-Job-Manager-Magento2

Aragorn Job Manager is Magento 2 job and recruitment extension that empowers you to create a separate job section on your Magento store. It allows you to add jobs and interact directly with job seekers.
GNU General Public License v3.0
8 stars 4 forks source link

Problem with createAttachment method in magento 2.3 #5

Open santibm opened 5 years ago

santibm commented 5 years ago

Magento 2.3 seems to have changed how emails are sent:

Fatal error: Uncaught Error: Call to undefined method Magento\Framework\Mail\Message\Interceptor::createAttachment() in /app/code/Aragorn/JobManager/Mail/Template/TransportBuilder.php:22 Stack trace: #0 /app/code/Aragorn/JobManager/Controller/Index/ApplyPost.php(233): Aragorn\JobManager\Mail\Template\TransportBuilder->addAttachment('%PDF-1.4\n%\xC3\xA4\xC3\xBC\xC3...', 'application/pdf', 'documento1 (1)....') #1 /app/code/Aragorn/JobManager/Controller/Index/ApplyPost.php(341): Aragorn\JobManager\Controller\Index\ApplyPost->sendEmail(Array) #2 /app/code/Aragorn/JobManager/Controller/Index/ApplyPost.php(175): Aragorn\JobManager\Controller\Index\ApplyPost->save(Array) #3 /vendor/magento/framework/App/Action/Action.php(108): Aragorn\JobManager\Controller\Index\ApplyPost->execute() #4 /vendor/magento/framework/Interception/Int in /app/code/Aragorn/JobManager/Mail/Template/TransportBuilder.php on line 22

santibm commented 5 years ago

You can update the TransportBuilder.php class:

/**
 * Created by PhpStorm.
 * User: sndsabin
 * Date: 12/1/17
 * Time: 10:40 AM
 */

namespace Aragorn\JobManager\Mail\Template;

use Magento\Framework\Mail\Template\TransportBuilder as TBuilder;
use Zend_Mime;

/**
 * Class TransportBuilder
 * @package Aragorn\JobManager\Mail\Template
 */
class TransportBuilder extends TBuilder
{

    /**
     * @var array
     */
    private $parts = [];

    /**
     * @param $body
     * @param null $filename
     * @param string $mimeType
     * @param string $disposition
     * @param string $encoding
     * @return $this
     */
    public function addAttachment(
        $body,
        $mimeType    = Zend_Mime::TYPE_OCTETSTREAM,
        $filename    = null,
        $disposition = Zend_Mime::DISPOSITION_ATTACHMENT,
        $encoding    = Zend_Mime::ENCODING_BASE64
    ) {
        if (method_exists($this->message, 'createAttachment')) {
            $this->message->createAttachment(
                $body,
                $mimeType,
                $disposition,
                $encoding,
                $filename
            );
        } else {
            $mp = new \Zend\Mime\Part($body);
            $mp->encoding = $encoding;
            $mp->type = $mimeType;
            $mp->disposition = $disposition;
            $mp->filename = $filename;

            $this->parts[] = $mp;
        }

        return $this;
    }

}
sndsabin commented 5 years ago

Or you could just Override TransportBuilder.php class as

/**
 * Created by PhpStorm.
 * User: sndsabin
 * Date: 12/1/17
 * Time: 10:40 AM
 */

namespace Aragorn\JobManager\Mail\Template;

use Zend\Mime\Message as MimeMessage;
use Zend\Mime\Mime;
use Zend\Mime\Part as MimePart;
use Magento\Framework\Mail\Template\TransportBuilder as TBuilder;

/**
 * Class TransportBuilder
 * @package Aragorn\JobManager\Mail\Template
 */
class TransportBuilder extends TBuilder
{

    /**
     * Add an attachment to the message.
     *
     * @param object $message
     * @param array $attachments
     * @return $this
     */
    public function addAttachment($message, $attachments)
    {

        $body = new MimeMessage();
        $existingEmailBody = $message->getBody();

        //For html emails Magento already creates a MimePart
        //@see \Magento\Framework\Mail\Message::createHtmlMimeFromString()
        if (\is_object($existingEmailBody) && $existingEmailBody instanceof \Zend\Mime\Message) {
            $htmlPart = $existingEmailBody->getParts()[0];
            $htmlPart->type = Mime::TYPE_HTML;
            $body->addPart($htmlPart);
        } else {
            $textPart = new MimePart($existingEmailBody);
            $textPart->type = Mime::TYPE_TEXT;
            $textPart->charset = 'utf-8';
            $textPart->encoding = Mime::ENCODING_QUOTEDPRINTABLE;
            $body->addPart($textPart);
        }

        foreach ($attachments as $attachment) {
            $mimeAttachment = new MimePart($attachment['content']);
            $mimeAttachment->filename = $this->getEncodedFileName($attachment['filename']);
            $mimeAttachment->type = $attachment['type'];
            $mimeAttachment->encoding = Mime::ENCODING_BASE64;
            $mimeAttachment->disposition = Mime::DISPOSITION_ATTACHMENT;

            $body->addPart($mimeAttachment);
        }

        $message->setBodyText($body);
        return $this;

    }

    public function getEncodedFileName($filename)
    {
        return sprintf('=?utf-8?B?%s?=', base64_encode($filename));
    }

}

and overide sendEmail Method in ApplyPost.php as

/**
     * Sends Email
     * @param $data
     */
    public function sendEmail($data)
    {

        $from = array('email' => $this->scopeConfig->getValue(
            'jobmanager_email/email/applicant_admin_sender_email', ScopeInterface::SCOPE_STORE
        ), 'name' => $this->scopeConfig->getValue(
            'jobmanager_email/email/applicant_admin_sender_name', ScopeInterface::SCOPE_STORE
        ));
        $templateOptions = array(
            'area' => Area::AREA_FRONTEND,
            'store' => $this->storeManager->getStore()->getId());

        $this->inlineTranslation->suspend();
        $adminto = $this->scopeConfig->getValue(
            'jobmanager_email/email/applicant_admin_receiver_email', ScopeInterface::SCOPE_STORE
        );

        $attachments = [
            ['content' => $this->reader->fileGetContents($this->destinationFolder . $data['cv']),
                'type'=> $_FILES['cv']['type'],
                'filename' => $_FILES['cv']['name']
            ],
            ['content' => $this->reader->fileGetContents($this->destinationFolder . $data['cover_letter']),
                'type'=> $_FILES['letter']['type'],
                'filename' => $_FILES['letter']['name']
            ],
        ];

        $transport = $this->transportBuilder
            ->setTemplateIdentifier('jobmanager_new_applicant_email')
            ->setTemplateOptions($templateOptions)
            ->setTemplateVars($data)
            ->setFrom($from)
            ->addTo($adminto)
            ->getTransport();

       $this->transportBuilder->addAttachment($transport->getMessage(), $attachments);

        $transport->sendMessage();
        $this->inlineTranslation->resume();
    }

(courtesy: Pradeep Prajapati)

sndsabin commented 5 years ago

Thanks @santibm :)