Пакет PHP Symfony 2.8 Swiftmailer 2.5, создание сообщения с вложением PDF из кода

Я пытаюсь создать сообщение SwiftMailer с помощью Symfony 2.8 и SwiftMailer Bundle 2.5, где я отправляю PDF-файл с простым HTML-сообщением по адресу. Я могу отправлять электронные письма, однако во всем примере кода используются такие методы, как addPart () и attach (), которых нет в списке методов, предоставленном Swift_Message, и я не могу найти ни одного примера, который использует что-либо еще.

Я создаю PDF-файл из визуализированного шаблона Twig, а затем создаю сообщение, чтобы прикрепить его к

$pdf = $this->get('knp_snappy.pdf')->getOutputFromHtml($response);

$message = \Swift_Message::newInstance()
                ->setSubject('Hello Email')
                ->setFrom('[email protected]')
                ->setTo('[email protected]')
                ->setBody(
                    $this->renderView(
                    // app/Resources/views/Emails/registration.html.twig
                        'Emails/registration.html.twig',
                        array('name' => "test")
                    ),
                    'text/html'
                );

Приложение: $attachment = \Swift_Attachment::newInstance($pdf, $pdf_name, 'application/pdf');

Оба

$message->addPart($attachment, $contentType = "application/pdf", $charset = null);

а также

$message->attach(\Swift_Attachment::fromPath('/path/to/image.jpg')->setFilename('myfilename.jpg'));

методов просто не существует.

Как ни странно, в выделенном сообщении говорится

Method 'attach' not found in class \Swift_Mime_MimePart less...
Referenced method is not found in subject class.

Но мне не удалось выяснить, откуда это происходит и как я могу правильно вызвать класс сообщения, учитывая, что класс Swift_Mime_MimePart находится на несколько уровней выше в иерархии классов и никогда не вызывается или не упоминается непосредственно в коде.


person G_V    schedule 15.04.2017    source источник
comment
Я чувствую, что здесь отсутствует какой-то код, который показывает проблему. Можете ли вы включить весь код с момента создания переменной $message до момента, когда вы пытаетесь запустить метод attach()?   -  person Augwa    schedule 15.04.2017
comment
@Augwa - он практически полностью скопирован из самих документов Swiftmailer swiftmailer.org/docs/messages.html вот почему я так запутался. Я создаю сообщение и сразу же пытаюсь attach() . Должен ли быть промежуточный код?   -  person G_V    schedule 15.04.2017
comment
Я также попытался полностью переустановить комплект. Я мог бы попробовать откатиться к более старой версии, чтобы увидеть, исправит ли это это, но от этого зависит множество других пакетов, таких как FOSUserBundle, поэтому я полагаю, что это само по себе приведет к ряду проблем.   -  person G_V    schedule 15.04.2017
comment
Я не думаю, что это проблема. Вы сказали, что сказали, что это pretty much straight, что не совсем так. Я на 99,9% уверен, что если вы разместите весь запрашиваемый код, ошибка обнаружится сама собой.   -  person Augwa    schedule 15.04.2017
comment
Я изменил $this->renderView( // app/Resources/views/Emails/registration.html.twig 'Emails/registration.html.twig', array('name' => "test") ),, чтобы на самом деле имел шаблон для тестирования, и переместил присоединяемую часть кода за пределы создания сообщения, поскольку он не работал, как показано в примерах ниже. В остальном это точно так же, как в примере с точки зрения количества кода. Нет пропущенных шагов.   -  person G_V    schedule 15.04.2017
comment
Если вы просто сделаете $message = \Swift_Message::newInstance()->attach(...);, это будет ошибка или нет?   -  person Augwa    schedule 15.04.2017
comment
@Augwa - Странно, если я помещаю все компоненты цепочки в примере в отдельные строки, я не получаю ошибку «метод не найден», где он ссылается на родительский класс вместо подкласса. Похоже, что вызов методов ::newInstance вместо результирующего объекта заставляет интерпретатор искать эти методы в родительском классе, где вызывается parent::_construct()? Теперь код вроде работает.   -  person G_V    schedule 15.04.2017


Ответы (1)


Если посмотреть на все вызываемые отдельные методы, то все они оканчиваются на return $this, который возвращает экземпляр объекта как универсальный тип, в котором метод находится на нижнем уровне иерархии.

Поскольку в PHP нет загрузки универсального типа, setBody возвращает Swift_Mime_MimePart, в то время как другие методы возвращают Swift_Mime_SimpleMessage вместо ? extends Swift_Mime_MimePart или ? extends Swift_Mime_SimpleMessage. Поскольку в примере сообщение задается в той же цепочке, а setBody является последним вызванным методом, $message теперь Swift_Mime_MimePart вместо Swift_Message, где расположены attach() метод и другие.

Поэтому решение довольно простое; поместите вызовы в отдельные строки, чтобы $ message оставалось Swift_Message

$message = \Swift_Message::newInstance();
$message->setSubject('Hello Email')
$message->setFrom('[email protected]')
$message->setTo('[email protected]')
$message->setBody(
                    $this->renderView(
                    // app/Resources/views/Emails/registration.html.twig
                        'Emails/registration.html.twig',
                        array('name' => "test")
                    ),
                    'text/html'
                );
$attachment = \Swift_Attachment::newInstance($pdf, $pdf_name, 'application/pdf');
$message->attach($attachment);
person G_V    schedule 21.04.2017