diff --git a/modules/symfony_mailer_bc/src/Plugin/EmailBuilder/WebformEmailBuilder.php b/modules/symfony_mailer_bc/src/Plugin/EmailBuilder/WebformEmailBuilder.php new file mode 100644 index 0000000..d924ba9 --- /dev/null +++ b/modules/symfony_mailer_bc/src/Plugin/EmailBuilder/WebformEmailBuilder.php @@ -0,0 +1,27 @@ +setParam('attachments', $legacy_message['params']['attachments']); + } + } + +} diff --git a/src/Email.php b/src/Email.php index 42d2ad0..eb3a4fb 100644 --- a/src/Email.php +++ b/src/Email.php @@ -600,4 +600,12 @@ class Email implements InternalEmailInterface { } } + /** + * {@inheritdoc} + */ + public function attach(string $content, string $name = NULL, string $mimeType = NULL) { + $this->inner->attach($content, $name, $mimeType); + return $this; + } + } diff --git a/src/EmailInterface.php b/src/EmailInterface.php index 6ebb5dd..205bbea 100644 --- a/src/EmailInterface.php +++ b/src/EmailInterface.php @@ -373,4 +373,18 @@ interface EmailInterface extends BaseEmailInterface { */ public function getTransportDsn(); + /** + * Adds an attachment by content. + * + * @param string $content + * The content of the file. + * @param string|null $name + * (optional) The file name. Defaults to the base name of the path. + * @param string|null $mimeType + * (optional) The mime type. If omitted, the type will be guessed. + * + * @return $this + */ + public function attach(string $content, ?string $name = NULL, ?string $mimeType = NULL); + } diff --git a/src/LegacyMailerHelper.php b/src/LegacyMailerHelper.php index c953027..64149d0 100644 --- a/src/LegacyMailerHelper.php +++ b/src/LegacyMailerHelper.php @@ -86,7 +86,12 @@ class LegacyMailerHelper implements LegacyMailerHelperInterface { // Attachments. $attachments = $message['params']['attachments'] ?? []; foreach ($attachments as $attachment) { - $email->attachFromPath($attachment['filepath'], $attachment['filename'] ?? NULL, $attachment['filemime'] ?? NULL); + if (!empty($attachment['filecontent'])) { + $email->attach($attachment["filecontent"], $attachment['filename'] ?? NULL, $attachment['filemime'] ?? NULL); + } + else { + $email->attachFromPath($attachment['filepath'], $attachment['filename'] ?? NULL, $attachment['filemime'] ?? NULL); + } } // Address headers. diff --git a/src/Plugin/EmailAdjuster/AttachmentEmailAdjuster.php b/src/Plugin/EmailAdjuster/AttachmentEmailAdjuster.php new file mode 100644 index 0000000..0adc2f3 --- /dev/null +++ b/src/Plugin/EmailAdjuster/AttachmentEmailAdjuster.php @@ -0,0 +1,198 @@ +configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $configuration); + $this->fileSystem = $file_system; + $this->logger = $logger; + + $this->allowedPaths = []; + + if ($this->configuration['public_files']) { + $this->allowedPaths['public'] = $this->fileSystem->realpath('public://'); + } + + if ($this->configuration['private_files']) { + $this->allowedPaths['private'] = $this->fileSystem->realpath('private://'); + } + + if ($this->configuration['temporary_files']) { + $this->allowedPaths['temporary'] = $this->fileSystem->realpath('temporary://'); + } + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('file_system'), + $container->get('logger.factory')->get('symfony_mailer') + ); + } + + /** + * {@inheritdoc} + */ + public function preRender(EmailInterface $email) { + try { + if ($attachments = $email->getParam('attachments')) { + foreach ($attachments as $attachment) { + if (!isset($attachment['filepath'])) { + continue; + } + + if ($file_path = $this->fileSystem->realpath($attachment['filepath'])) { + foreach ($this->allowedPaths as $scheme => $allowed_path) { + if (\strpos($file_path, $allowed_path) === 0) { + $email->attachFromPath( + $file_path, + $attachment['filename'] ?? null, + $attachment['filemime'] ?? null + ); + break; + } + } + } + elseif ($this->urlAllowed() && $this->configuration['url_files'] && \filter_var($attachment['filepath'], FILTER_VALIDATE_URL)) { + $email->attachFromPath( + $attachment['filepath'] + ); + } + else { + $this->logger->warning($this->t('Attachment %file not attached to email %subject for %recepient', [ + '%file' => $attachment['filepath'], + '%subject' => (string) $email->getSubject(), + '%recepient' => \reset($email->getTo())->getEmail() + ])); + } + } + } + } catch (\Exception $e) { + watchdog_exception('symfony_mailer', $e); + } + } + + /** + * Gets default configuration for this plugin. + * + * @return array + * An associative array with the default configuration. + */ + public function defaultConfiguration() { + return [ + 'public_files' => TRUE, + 'private_files' => FALSE, + 'temporary_files' => TRUE, + 'url_files' => FALSE, + ]; + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $form['public_files'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Public files'), + '#description' => $this->t('Allow attachments to be files within public files.'), + '#default_value' => $this->configuration['public_files'], + ]; + + $form['private_files'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Private files'), + '#description' => $this->t('Allow attachments to be files within private files.'), + '#default_value' => $this->configuration['private_files'], + ]; + + $form['temporary_files'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Temporary files'), + '#description' => $this->t('Allow attachments to be files within temporary files.'), + '#default_value' => $this->configuration['temporary_files'], + ]; + + $form['url_files'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Files by URL'), + '#description' => $this->t('Allow attachments to be remote files accessed by URL.'), + '#default_value' => $this->urlAllowed() + ? $this->configuration['url_files'] + : FALSE, + ]; + + if (!$this->urlAllowed()) { + $form['url_files']['#attributes']['disabled'] = 'disabled'; + } + + return $form; + } + + /** + * Check if system is set up to handle url with fopen. + */ + protected function urlAllowed() { + return \ini_get('allow_url_fopen'); + } +}