/** * @test */ public function getUrlReturnsInitialValueForString() { if (!$this->canRunLynx()) { $this->markTestSkipped('The command "' . Tools::confParam('path_to_lynx') . '" is not available.'); } $html = file_get_contents(__DIR__ . '/input.html'); $expected = file_get_contents(__DIR__ . '/lynx.txt'); $actual = $this->subject->getPlainText($html, 'http://my-domain.com'); $this->assertSame($expected, $actual); }
public function getPlainText($content, $baseUrl) { $tmpFile = tempnam(sys_get_temp_dir(), 'newsletter_'); $contentWithBase = $this->injectBaseUrl($content, $baseUrl); file_put_contents($tmpFile, $contentWithBase); $cmd = escapeshellcmd(Tools::confParam('path_to_lynx')) . ' -force_html -dump ' . escapeshellarg($tmpFile); exec($cmd, $output); unlink($tmpFile); $plainText = implode("\n", $output); return $plainText; }
/** * This method is designed to return some additional information about the task, * that may help to set it apart from other tasks from the same class * This additional information is used - for example - in the Scheduler's BE module * This method should be implemented in most task classes * * @return string Information to display */ public function getAdditionalInformation() { $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class); $newsletterRepository = $objectManager->get(\Ecodev\Newsletter\Domain\Repository\NewsletterRepository::class); $newslettersToSend = $newsletterRepository->findAllReadyToSend(); $newslettersBeingSent = $newsletterRepository->findAllBeingSent(); $newslettersToSendCount = count($newslettersToSend); $newslettersBeingSentCount = count($newslettersBeingSent); $emailNotSentCount = 0; foreach ($newslettersToSend as $newsletter) { $emailNotSentCount += $newsletter->getEmailNotSentCount(); } foreach ($newslettersBeingSent as $newsletter) { $emailNotSentCount += $newsletter->getEmailNotSentCount(); } $emailsPerRound = Tools::confParam('mails_per_round'); return \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('task_send_emails_additional_information', 'newsletter', [$emailsPerRound, $emailNotSentCount, $newslettersToSendCount, $newslettersBeingSentCount]); }
/** * Fetch all email from Bounce Accounts and pipe each of them to cli/bounce.php */ public static function fetchBouncedEmails() { // Check that th configured fetchmail is actually available $fetchmail = Tools::confParam('path_to_fetchmail'); $foo = $exitStatus = null; exec("{$fetchmail} --version 2>&1", $foo, $exitStatus); if ($exitStatus) { throw new Exception("fetchmail is not available with path configured via Extension Manager '{$fetchmail}'. Install fetchmail or update configuration and try again."); } // Find all bounce accounts we need to check $content = ''; $servers = array(); $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); $bounceAccountRepository = $objectManager->get('Ecodev\\Newsletter\\Domain\\Repository\\BounceAccountRepository'); foreach ($bounceAccountRepository->findAll() as $bounceAccount) { $server = $bounceAccount->getServer(); $protocol = $bounceAccount->getProtocol(); $username = $bounceAccount->getUsername(); $password = $bounceAccount->getPassword(); $content .= "poll {$server} proto {$protocol} username \"{$username}\" password \"{$password}\"\n"; $servers[] = $server; } // Write a new fetchmailrc based on bounce accounts found $fetchmailhome = PATH_site . 'uploads/tx_newsletter'; $fetchmailfile = "{$fetchmailhome}/fetchmailrc"; file_put_contents($fetchmailfile, $content); chmod($fetchmailfile, 0600); putenv("FETCHMAILHOME={$fetchmailhome}"); // Keep messages on server $keep = Tools::confParam('keep_messages') ? '--keep ' : ''; // Execute fetchtmail and ask him to pipe emails to our cli/bounce.php $cli_dispatcher = PATH_typo3 . 'cli_dispatch.phpsh'; // This needs to be the absolute path of /typo3/cli_dispatch.phpsh foreach ($servers as $server) { $cmd = "{$fetchmail} -s {$keep} -m \"{$cli_dispatcher} newsletter_bounce\" {$server}"; exec($cmd); } unlink($fetchmailfile); }
/** * Fetch all email from Bounce Accounts and pipe each of them to cli/bounce.php */ public static function fetchBouncedEmails() { // Check that th configured fetchmail is actually available $fetchmail = Tools::confParam('path_to_fetchmail'); $foo = $exitStatus = null; exec("{$fetchmail} --version 2>&1", $foo, $exitStatus); if ($exitStatus) { throw new \Exception("fetchmail is not available with path configured via Extension Manager '{$fetchmail}'. Install fetchmail or update configuration and try again."); } // Find all bounce accounts we need to check $fetchmailConfiguration = ''; $servers = []; $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class); $bounceAccountRepository = $objectManager->get(\Ecodev\Newsletter\Domain\Repository\BounceAccountRepository::class); foreach ($bounceAccountRepository->findAll() as $bounceAccount) { $fetchmailConfiguration .= $bounceAccount->getSubstitutedConfig() . "\n"; $servers[] = $bounceAccount->getServer(); } // Write a new fetchmailrc based on bounce accounts found $fetchmailHome = PATH_site . 'uploads/tx_newsletter'; $fetchmailFile = "{$fetchmailHome}/fetchmailrc"; file_put_contents($fetchmailFile, $fetchmailConfiguration); $fetchmailConfiguration = null; // Dont leave unencrypted values in memory around for too long. chmod($fetchmailFile, 0600); putenv("FETCHMAILHOME={$fetchmailHome}"); // Keep messages on server $keep = Tools::confParam('keep_messages') ? '--keep ' : ''; // Execute fetchtmail and ask him to pipe emails to our cli/bounce.php $cli_dispatcher = PATH_typo3 . 'cli_dispatch.phpsh'; // This needs to be the absolute path of /typo3/cli_dispatch.phpsh foreach ($servers as $server) { $cmd = "{$fetchmail} -s {$keep} -m \"{$cli_dispatcher} newsletter_bounce\" {$server}"; exec($cmd); } unlink($fetchmailFile); }
/** * Returns the URL of the content of this newsletter * @return string */ public function getContentUrl($language = null) { $append_url = Tools::confParam('append_url'); $baseUrl = $this->getBaseUrl(); if (!is_null($language)) { $language = '&L=' . $language; } return $baseUrl . '/index.php?id=' . $this->getPid() . $language . $append_url; }
/** * Find all pairs of newsletter-email UIDs that are should be sent * * @global \TYPO3\CMS\Core\Database\DatabaseConnection $TYPO3_DB * @param Newsletter $newsletter * @return array [[newsletter => 12, email => 5], ...] */ public static function findAllNewsletterAndEmailUidToSend(Newsletter $newsletter = null) { global $TYPO3_DB; // Apply limit of emails per round $mails_per_round = (int) \Ecodev\Newsletter\Tools::confParam('mails_per_round'); if ($mails_per_round) { $limit = ' LIMIT ' . $mails_per_round; } else { $limit = ''; } // Apply newsletter restriction if any if ($newsletter) { $newsletterUid = 'AND tx_newsletter_domain_model_newsletter.uid = ' . $newsletter->getUid(); } else { $newsletterUid = ''; } // Find the uid of emails and newsletters that need to be sent $rs = $TYPO3_DB->sql_query('SELECT tx_newsletter_domain_model_newsletter.uid AS newsletter, tx_newsletter_domain_model_email.uid AS email FROM tx_newsletter_domain_model_email INNER JOIN tx_newsletter_domain_model_newsletter ON (tx_newsletter_domain_model_email.newsletter = tx_newsletter_domain_model_newsletter.uid) WHERE tx_newsletter_domain_model_email.begin_time = 0 ' . $newsletterUid . ' ORDER BY tx_newsletter_domain_model_email.newsletter ' . $limit); $result = array(); while ($record = $TYPO3_DB->sql_fetch_assoc($rs)) { $result[] = $record; } return $result; }
/** * Replace all links in the mail to make spy links. * * @param \Ecodev\Newsletter\Domain\Model\Email $email The email to prepare the newsletter for * @param bool $isPreview whether we are preparing a preview version (if true links will not be stored in database thus no statistics will be available) */ private function injectLinksSpy(Email $email, $isPreview) { /* Exchange all http:// links html */ preg_match_all('|<a [^>]*href="(https?://[^"]*)"|Ui', $this->html, $urls); // No-Track Marker $notrackMarker = Tools::confParam('no-track'); foreach ($urls[1] as $i => $url) { // Check for a no-track marker if (!empty($notrackMarker) && stripos($url, $notrackMarker) != false) { continue; } $newUrl = $this->getLinkAuthCode($email, $url, $isPreview); /* Two step replace to be as precise as possible */ $link = str_replace($url, $newUrl, $urls[0][$i]); $this->html = str_replace($urls[0][$i], $link, $this->html); } }
/** * 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 * @return void */ 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\n\t\t\tFROM be_users\n\t\t\tLEFT JOIN pages ON be_users.uid = pages.perms_userid\n\t\t\tWHERE pages.uid = " . $newsletter->getPid()); list($notificationEmail) = $GLOBALS['TYPO3_DB']->sql_fetch_row($rs); } // If cannot find valid email, don't send any notification if (!\TYPO3\CMS\Core\Utility\GeneralUtility::validEmail($notificationEmail)) { return; } // Build email texts $baseUrl = 'http://' . $newsletter->getDomain(); $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', array($email->getRecipientAddress(), $urlRecipient, $recipientList->getTitle(), $urlRecipientList, $newsletter->getTitle(), $urlNewsletter)); // Actually sends email $message = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Mail\\MailMessage'); $message->setTo($notificationEmail)->setFrom(array($newsletter->getSenderEmail() => $newsletter->getSenderName()))->setSubject($subject)->setBody($body, 'text/html'); $message->send(); }
/** * Returns the URL of the content of this newsletter * @return string */ public function getContentUrl($language = null) { $append_url = Tools::confParam('append_url'); $domain = $this->getDomain(); if (!is_null($language)) { $language = '&L=' . $language; } $protocol = Tools::confParam('protocol'); //stefano: protocol is now set through "basic.protocol" parameter return "{$protocol}{$domain}/index.php?id=" . $this->getPid() . $language . $append_url; }
/** * Returns the URL of the content of this newsletter * @return string */ public function getContentUrl($language = null) { $append_url = Tools::confParam('append_url'); $domain = $this->getDomain(); if (!is_null($language)) { $language = '&L=' . $language; } return "http://{$domain}/index.php?id=" . $this->getPid() . $language . $append_url; }