Last active
March 16, 2017 14:55
-
-
Save benjaminpick/b0c8c4d9a0e9c219413b4c022db6ddcf to your computer and use it in GitHub Desktop.
Powermail Extension: Embed images from template into the HTML email (e.g. for images in the email footer)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */ | |
$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\SignalSlot\Dispatcher'); | |
// Needs powermail >= 3.3.0 | |
$signalSlotDispatcher->connect( | |
'In2code\Powermail\Domain\Service\SendMailService', | |
'sendTemplateEmailBeforeSend', | |
'In2code\Powermailextended\Domain\Service\SendMailService', | |
'manipulateMail', | |
FALSE | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace In2code\Powermailextended\Domain\Service; | |
use In2code\Powermail\Domain\Model\Mail; | |
use TYPO3\CMS\Core\Mail\MailMessage; | |
use TYPO3\CMS\Core\Utility\GeneralUtility; | |
use In2code\Powermail\Domain\Service\SendMailService as SendMailServicePowermail; | |
/** | |
* SendMailService | |
* (used for embedding the signature images) | |
* | |
* SignalSlot is declared in ext_localconf | |
* | |
*/ | |
class SendMailService { | |
const TAG_START = '<img src="'; | |
const TAG_END = '"'; | |
const PATH = 'EXT:powermail_optigem/Resources/Public/Images/Signature/'; | |
const ALLOWED_PATH = 'EXT:powermail_optigem/Resources/Public/'; | |
/** | |
* Manipulate message object short before powermail send the mail | |
* | |
* @param MailMessage $message | |
* @param array $email | |
* @param SendMailServicePowermail $sendMailService | |
*/ | |
public function manipulateMail($message, &$email, SendMailServicePowermail $sendMailService) { | |
$body = $message->getBody(); | |
$path = self::PATH; | |
$len_tag_start = mb_strlen(self::TAG_START); | |
$len_tag_end = mb_strlen(self::TAG_END); | |
$start = mb_stripos($body, self::TAG_START); | |
while ($start !== false) { | |
$end = mb_strpos($body, self::TAG_END, $start + $len_tag_start + 1); | |
$filename = mb_substr($body, $start + $len_tag_start, $end - $start - $len_tag_start - $len_tag_end + 1); | |
if (!$this->str_starts_with($filename, 'cid:')) { | |
if ($this->str_starts_with($filename, 'http://') || $this->str_starts_with($filename, 'https://')) | |
{ | |
if (GeneralUtility::isOnCurrentHost($filename)) { | |
$host = GeneralUtility::getIndpEnv('TYPO3_REQUEST_HOST'); | |
$site_path = dirname(GeneralUtility::getIndpEnv('SCRIPT_FILENAME')); | |
$fileAbs = $site_path . mb_substr($filename, mb_strlen($host)); | |
} | |
} | |
else | |
{ | |
$fileAbs = GeneralUtility::getFileAbsFileName($path . $filename); | |
} | |
if ($this->validateFilename($fileAbs)) { | |
$embedId = $message->embed(\Swift_Image::fromPath($fileAbs)); | |
if ($embedId) { | |
$search = self::TAG_START . $filename . self::TAG_END; | |
$replace = self::TAG_START . $embedId . self::TAG_END; | |
$body = str_replace($search, $replace, $body); | |
} | |
} | |
} | |
$start = mb_stripos($body, self::TAG_START, $start + 1); | |
} | |
$message->setBody($body, 'text/html'); | |
} | |
protected function str_starts_with($haystack, $needle) { | |
$length = mb_strlen($needle); | |
return mb_substr($haystack, 0, $length) === $needle; | |
} | |
protected function validateFilename($filename) { | |
if (!file_exists($filename)) | |
return false; | |
// Security: only images may be attached | |
$allowedExtensions = array( | |
'png', | |
'jpg', | |
'jpeg', | |
'gif', | |
); | |
$ext = pathinfo($filename, PATHINFO_EXTENSION); | |
if (!in_array(strtolower($ext), $allowedExtensions)) | |
return false; | |
// Security: Check if path is within ALLOWED_PATH | |
$allowed = @realpath(GeneralUtility::getFileAbsFileName(self::ALLOWED_PATH)); | |
if (!$allowed) | |
return false; | |
$r1 = @realpath($filename); | |
if (!$this->str_starts_with($r1, $allowed)) | |
return false; | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment