Beispiel #1
0
 /**
  * Fix relative URL to absolute URL
  */
 private function infoRelativeToAbsolute()
 {
     // Find out the absolute domain. If specified in HTML source, use it as is.
     if (preg_match('|<base[^>]*href="([^"]*)"[^>]*/>|i', $this->content, $match)) {
         $absoluteDomain = $match[1];
     } else {
         $absoluteDomain = $this->newsletter->getBaseUrl() . '/';
     }
     $urlPatterns = ['hyperlinks' => '/<a [^>]*href="(.*)"/Ui', 'stylesheets' => '/<link [^>]*href="(.*)"/Ui', 'images' => '/ src="(.*)"/Ui', 'background images' => '/ background="(.*)"/Ui'];
     foreach ($urlPatterns as $type => $urlPattern) {
         preg_match_all($urlPattern, $this->content, $urls);
         $replacementCount = 0;
         foreach ($urls[1] as $i => $url) {
             // If this is already an absolute link, dont replace it
             $decodedUrl = html_entity_decode($url);
             if (!Uri::isAbsolute($decodedUrl)) {
                 $replace_url = str_replace($decodedUrl, $absoluteDomain . ltrim($decodedUrl, '/'), $urls[0][$i]);
                 $this->content = str_replace($urls[0][$i], $replace_url, $this->content);
                 ++$replacementCount;
             }
         }
         if ($replacementCount) {
             $this->infos[] = sprintf($this->lang->getLL('validation_mail_converted_relative_url'), $type);
         }
     }
 }
Beispiel #2
0
 /**
  * Sets the newsletter
  *
  * @param Newsletter $newsletter
  * @param string $language
  * @throws \Exception
  */
 public function setNewsletter(Newsletter $newsletter, $language = null)
 {
     // When sending newsletter via scheduler (so via CLI mode) realurl cannot guess
     // the domain name by himself, so we help him by filling HTTP_HOST variable
     $_SERVER['HTTP_HOST'] = $newsletter->getDomain();
     $_SERVER['SCRIPT_NAME'] = '/index.php';
     $this->siteUrl = $newsletter->getBaseUrl() . '/';
     $this->linksCache = [];
     $this->newsletter = $newsletter;
     $this->homeUrl = $this->siteUrl . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath('newsletter');
     $this->senderName = $newsletter->getSenderName();
     $this->senderEmail = $newsletter->getSenderEmail();
     $this->replytoName = $newsletter->getReplytoName();
     $this->replytoEmail = $newsletter->getReplytoEmail();
     $bounceAccount = $newsletter->getBounceAccount();
     $this->bounceAddress = $bounceAccount ? $bounceAccount->getEmail() : null;
     // Build html
     $validatedContent = $newsletter->getValidatedContent($language);
     if (count($validatedContent['errors'])) {
         throw new \Exception('The newsletter HTML content does not validate. The sending is aborted. See errors: ' . serialize($validatedContent['errors']));
     }
     $this->setHtml($validatedContent['content']);
     // Build title from HTML source (we cannot use $newsletter->getTitle(), because it is NOT localized)
     $this->setTitle($validatedContent['content']);
     // Attaching files
     $files = $newsletter->getAttachments();
     foreach ($files as $file) {
         if (trim($file) != '') {
             $filename = PATH_site . "uploads/tx_newsletter/{$file}";
             $this->attachments[] = Swift_Attachment::fromPath($filename);
         }
     }
 }
Beispiel #3
0
 /**
  * Returns the content of the newsletter with validation messages. The content
  * is also "fixed" automatically when possible.
  * @param Newsletter $newsletter
  * @param string $language language of the content of the newsletter (the 'L' parameter in TYPO3 URL)
  * @return array ('content' => $content, 'errors' => $errors, 'warnings' => $warnings, 'infos' => $infos);
  */
 public function validate(Newsletter $newsletter, $language = null)
 {
     $this->initializeLang();
     // We need to catch the exception if domain was not found/configured properly
     try {
         $url = $newsletter->getContentUrl($language);
     } catch (Exception $e) {
         return array('content' => '', 'errors' => array($e->getMessage()), 'warnings' => array(), 'infos' => array());
     }
     $content = $this->getURL($url);
     $errors = array();
     $warnings = array();
     $infos = array(sprintf($this->lang->getLL('validation_content_url'), '<a target="_blank" href="' . $url . '">' . $url . '</a>'));
     // Content should be more that just a few characters. Apache error propably occured
     if (strlen($content) < 200) {
         $errors[] = $this->lang->getLL('validation_mail_too_short');
     }
     // Content should not contain PHP-Warnings
     if (substr($content, 0, 22) == "<br />\n<b>Warning</b>:") {
         $errors[] = $this->lang->getLL('validation_mail_contains_php_warnings');
     }
     // Content should not contain PHP-Warnings
     if (substr($content, 0, 26) == "<br />\n<b>Fatal error</b>:") {
         $errors[] = $this->lang->getLL('validation_mail_contains_php_errors');
     }
     // If the page contains a "Pages is being generared" text... this is bad too
     if (strpos($content, 'Page is being generated.') && strpos($content, 'If this message does not disappear within')) {
         $errors[] = $this->lang->getLL('validation_mail_being_generated');
     }
     // Find out the absolute domain. If specified in HTML source, use it as is.
     if (preg_match('|<base[^>]*href="([^"]*)"[^>]*/>|i', $content, $match)) {
         $absoluteDomain = $match[1];
     } else {
         $absoluteDomain = $newsletter->getBaseUrl() . '/';
     }
     // Fix relative URL to absolute URL
     $urlPatterns = array('hyperlinks' => '/<a [^>]*href="(.*)"/Ui', 'stylesheets' => '/<link [^>]*href="(.*)"/Ui', 'images' => '/ src="(.*)"/Ui', 'background images' => '/ background="(.*)"/Ui');
     foreach ($urlPatterns as $type => $urlPattern) {
         preg_match_all($urlPattern, $content, $urls);
         $replacementCount = 0;
         foreach ($urls[1] as $i => $url) {
             // If this is already an absolute link, dont replace it
             $decodedUrl = html_entity_decode($url);
             if (!Uri::isAbsolute($decodedUrl)) {
                 $replace_url = str_replace($decodedUrl, $absoluteDomain . ltrim($decodedUrl, '/'), $urls[0][$i]);
                 $content = str_replace($urls[0][$i], $replace_url, $content);
                 ++$replacementCount;
             }
         }
         if ($replacementCount) {
             $infos[] = sprintf($this->lang->getLL('validation_mail_converted_relative_url'), $type);
         }
     }
     // Find linked css and convert into a style-tag
     preg_match_all('|<link rel="stylesheet" type="text/css" href="([^"]+)"[^>]+>|Ui', $content, $urls);
     foreach ($urls[1] as $i => $url) {
         $content = str_replace($urls[0][$i], "<!-- fetched URL: {$url} -->\n<style type=\"text/css\">\n<!--\n" . $this->getURL($url) . "\n-->\n</style>", $content);
     }
     if (count($urls[1])) {
         $infos[] = $this->lang->getLL('validation_mail_contains_linked_styles');
     }
     // We cant very well have attached javascript in a newsmail ... removing
     $content = preg_replace('|<script[^>]*type="text/javascript"[^>]*>[^<]*</script>|i', '', $content, -1, $count);
     if ($count) {
         $warnings[] = $this->lang->getLL('validation_mail_contains_javascript');
     }
     // Images in CSS
     if (preg_match('|background-image: url\\([^\\)]+\\)|', $content) || preg_match('|list-style-image: url\\([^\\)]+\\)|', $content)) {
         $errors[] = $this->lang->getLL('validation_mail_contains_css_images');
     }
     // CSS-classes
     if (preg_match('|<[a-z]+ [^>]*class="[^"]+"[^>]*>|', $content)) {
         $warnings[] = $this->lang->getLL('validation_mail_contains_css_classes');
     }
     // Positioning & element sizes in CSS
     $forbiddenCssProperties = array('width' => '((min|max)+-)?width', 'height' => '((min|max)+-)?height', 'margin' => 'margin(-(bottom|left|right|top)+)?', 'padding' => 'padding(-(bottom|left|right|top)+)?', 'position' => 'position');
     $forbiddenCssPropertiesWarnings = array();
     if (preg_match_all('|<[a-z]+[^>]+style="([^"]*)"|', $content, $matches)) {
         foreach ($matches[1] as $stylepart) {
             foreach ($forbiddenCssProperties as $property => $regex) {
                 if (preg_match('/(^|[^\\w-])' . $regex . '[^\\w-]/', $stylepart)) {
                     $forbiddenCssPropertiesWarnings[$property] = $property;
                 }
             }
         }
         foreach ($forbiddenCssPropertiesWarnings as $property) {
             $warnings[] = sprintf($this->lang->getLL('validation_mail_contains_css_some_property'), $property);
         }
     }
     return array('content' => $content, 'errors' => $errors, 'warnings' => $warnings, 'infos' => $infos);
 }
Beispiel #4
0
    /**
     * Sends an email to the address configured in extension settings when a recipient unsubscribe
     * @param \Ecodev\Newsletter\Domain\Model\Newsletter $newsletter
     * @param \Ecodev\Newsletter\Domain\Model\RecipientList $recipientList
     * @param \Ecodev\Newsletter\Domain\Model\Email $email
     */
    protected function notifyUnsubscribe($newsletter, $recipientList, Email $email)
    {
        $notificationEmail = Tools::confParam('notification_email');
        // Use the page-owner as user
        if ($notificationEmail == 'user') {
            $rs = $GLOBALS['TYPO3_DB']->sql_query('SELECT email
			FROM be_users
			LEFT JOIN pages ON be_users.uid = pages.perms_userid
			WHERE pages.uid = ' . $newsletter->getPid());
            list($notificationEmail) = $GLOBALS['TYPO3_DB']->sql_fetch_row($rs);
        }
        // If cannot find valid email, don't send any notification
        if (!GeneralUtility::validEmail($notificationEmail)) {
            return;
        }
        // Build email texts
        $baseUrl = $newsletter->getBaseUrl();
        $urlRecipient = $baseUrl . '/typo3/alt_doc.php?&edit[tx_newsletter_domain_model_email][' . $email->getUid() . ']=edit';
        $urlRecipientList = $baseUrl . '/typo3/alt_doc.php?&edit[tx_newsletter_domain_model_recipientlist][' . $recipientList->getUid() . ']=edit';
        $urlNewsletter = $baseUrl . '/typo3/alt_doc.php?&edit[tx_newsletter_domain_model_newsletter][' . $newsletter->getUid() . ']=edit';
        $subject = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('unsubscribe_notification_subject', 'newsletter');
        $body = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('unsubscribe_notification_body', 'newsletter', [$email->getRecipientAddress(), $urlRecipient, $recipientList->getTitle(), $urlRecipientList, $newsletter->getTitle(), $urlNewsletter]);
        // Actually sends email
        $message = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
        $message->setTo($notificationEmail)->setFrom([$newsletter->getSenderEmail() => $newsletter->getSenderName()])->setSubject($subject)->setBody($body, 'text/html');
        $message->send();
    }