/** * Run the controller */ public function run() { global $objPage; $pageId = $this->getPageIdFromUrl(); $objRootPage = null; // Load a website root page object if there is no page ID if ($pageId === null) { $objRootPage = $this->getRootPageFromUrl(); $objHandler = new $GLOBALS['TL_PTY']['root'](); $pageId = $objHandler->generate($objRootPage->id, true); } elseif ($pageId === false) { $this->User->authenticate(); $objHandler = new $GLOBALS['TL_PTY']['error_404'](); $objHandler->generate($pageId); } elseif (Config::get('rewriteURL') && strncmp(Environment::get('request'), 'index.php/', 10) === 0) { $this->User->authenticate(); $objHandler = new $GLOBALS['TL_PTY']['error_404'](); $objHandler->generate($pageId); } // Get the current page object(s) $objPage = PageModel::findPublishedByIdOrAlias($pageId); // Check the URL and language of each page if there are multiple results if ($objPage !== null && $objPage->count() > 1) { $objNewPage = null; $arrPages = array(); // Order by domain and language while ($objPage->next()) { $objCurrentPage = $objPage->current()->loadDetails(); $domain = $objCurrentPage->domain ?: '*'; $arrPages[$domain][$objCurrentPage->rootLanguage] = $objCurrentPage; // Also store the fallback language if ($objCurrentPage->rootIsFallback) { $arrPages[$domain]['*'] = $objCurrentPage; } } $strHost = Environment::get('host'); // Look for a root page whose domain name matches the host name if (isset($arrPages[$strHost])) { $arrLangs = $arrPages[$strHost]; } else { $arrLangs = $arrPages['*'] ?: array(); // empty domain } // Use the first result (see #4872) if (!Config::get('addLanguageToUrl')) { $objNewPage = current($arrLangs); } elseif (($lang = Input::get('language')) != '' && isset($arrLangs[$lang])) { $objNewPage = $arrLangs[$lang]; } // Store the page object if (is_object($objNewPage)) { $objPage = $objNewPage; } } // Throw a 404 error if the page could not be found or the result is still ambiguous if ($objPage === null || $objPage instanceof Model\Collection && $objPage->count() != 1) { $this->User->authenticate(); $objHandler = new $GLOBALS['TL_PTY']['error_404'](); $objHandler->generate($pageId); } // Make sure $objPage is a Model if ($objPage instanceof Model\Collection) { $objPage = $objPage->current(); } // Load a website root page object (will redirect to the first active regular page) if ($objPage->type == 'root') { $objHandler = new $GLOBALS['TL_PTY']['root'](); $objHandler->generate($objPage->id); } // Inherit the settings from the parent pages if it has not been done yet if (!is_bool($objPage->protected)) { $objPage->loadDetails(); } // Set the admin e-mail address if ($objPage->adminEmail != '') { list($GLOBALS['TL_ADMIN_NAME'], $GLOBALS['TL_ADMIN_EMAIL']) = String::splitFriendlyEmail($objPage->adminEmail); } else { list($GLOBALS['TL_ADMIN_NAME'], $GLOBALS['TL_ADMIN_EMAIL']) = String::splitFriendlyEmail(Config::get('adminEmail')); } // Exit if the root page has not been published (see #2425) // Do not try to load the 404 page, it can cause an infinite loop! if (!BE_USER_LOGGED_IN && !$objPage->rootIsPublic) { header('HTTP/1.1 404 Not Found'); die_nicely('be_no_page', 'Page not found'); } // Check wether the language matches the root page language if (Config::get('addLanguageToUrl') && Input::get('language') != $objPage->rootLanguage) { $this->User->authenticate(); $objHandler = new $GLOBALS['TL_PTY']['error_404'](); $objHandler->generate($pageId); } // Check whether there are domain name restrictions if ($objPage->domain != '') { // Load an error 404 page object if ($objPage->domain != Environment::get('host')) { $this->User->authenticate(); $objHandler = new $GLOBALS['TL_PTY']['error_404'](); $objHandler->generate($objPage->id, $objPage->domain, Environment::get('host')); } } // Authenticate the user if (!$this->User->authenticate() && $objPage->protected && !BE_USER_LOGGED_IN) { $objHandler = new $GLOBALS['TL_PTY']['error_403'](); $objHandler->generate($pageId, $objRootPage); } // Check the user groups if the page is protected if ($objPage->protected && !BE_USER_LOGGED_IN) { $arrGroups = $objPage->groups; // required for empty() if (!is_array($arrGroups) || empty($arrGroups) || !count(array_intersect($arrGroups, $this->User->groups))) { $this->log('Page "' . $pageId . '" can only be accessed by groups "' . implode(', ', (array) $objPage->groups) . '" (current user groups: ' . implode(', ', $this->User->groups) . ')', __METHOD__, TL_ERROR); $objHandler = new $GLOBALS['TL_PTY']['error_403'](); $objHandler->generate($pageId, $objRootPage); } } // Load the page object depending on its type $objHandler = new $GLOBALS['TL_PTY'][$objPage->type](); try { // Generate the page switch ($objPage->type) { case 'root': case 'error_404': $objHandler->generate($pageId); break; case 'error_403': $objHandler->generate($pageId, $objRootPage); break; default: $objHandler->generate($objPage, true); break; } } catch (UnusedArgumentsException $e) { // Render the error page (see #5570) $objHandler = new $GLOBALS['TL_PTY']['error_404'](); $objHandler->generate($pageId, null, null, true); } // Stop the script (see #4565) exit; }
/** * Recursively validate an input variable * * @param mixed $varInput The user input * * @return mixed The original or modified user input */ protected function validator($varInput) { if (is_array($varInput)) { foreach ($varInput as $k => $v) { $varInput[$k] = $this->validator($v); } return $varInput; } if (!$this->doNotTrim) { $varInput = trim($varInput); } if ($varInput == '') { if (!$this->mandatory) { return ''; } else { if ($this->strLabel == '') { $this->addError($GLOBALS['TL_LANG']['ERR']['mdtryNoLabel']); } else { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['mandatory'], $this->strLabel)); } } } if ($this->minlength && $varInput != '' && utf8_strlen($varInput) < $this->minlength) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['minlength'], $this->strLabel, $this->minlength)); } if ($this->maxlength && $varInput != '' && utf8_strlen($varInput) > $this->maxlength) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['maxlength'], $this->strLabel, $this->maxlength)); } if ($this->minval && is_numeric($varInput) && $varInput < $this->minval) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['minval'], $this->strLabel, $this->minval)); } if ($this->maxval && is_numeric($varInput) && $varInput > $this->maxval) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['maxval'], $this->strLabel, $this->maxval)); } if ($this->rgxp != '') { switch ($this->rgxp) { // Special validation rule for style sheets case strncmp($this->rgxp, 'digit_', 6) === 0: $textual = explode('_', $this->rgxp); array_shift($textual); if (in_array($varInput, $textual) || strncmp($varInput, '$', 1) === 0) { break; } // DO NOT ADD A break; STATEMENT HERE // Numeric characters (including full stop [.] and minus [-]) // DO NOT ADD A break; STATEMENT HERE // Numeric characters (including full stop [.] and minus [-]) case 'digit': // Support decimal commas and convert them automatically (see #3488) if (substr_count($varInput, ',') == 1 && strpos($varInput, '.') === false) { $varInput = str_replace(',', '.', $varInput); } if (!\Validator::isNumeric($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['digit'], $this->strLabel)); } break; // Natural numbers (positive integers) // Natural numbers (positive integers) case 'natural': if (!\Validator::isNatural($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['natural'], $this->strLabel)); } break; // Alphabetic characters (including full stop [.] minus [-] and space [ ]) // Alphabetic characters (including full stop [.] minus [-] and space [ ]) case 'alpha': if (!\Validator::isAlphabetic($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['alpha'], $this->strLabel)); } break; // Alphanumeric characters (including full stop [.] minus [-], underscore [_] and space [ ]) // Alphanumeric characters (including full stop [.] minus [-], underscore [_] and space [ ]) case 'alnum': if (!\Validator::isAlphanumeric($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['alnum'], $this->strLabel)); } break; // Do not allow any characters that are usually encoded by class Input [=<>()#/]) // Do not allow any characters that are usually encoded by class Input [=<>()#/]) case 'extnd': if (!\Validator::isExtendedAlphanumeric(html_entity_decode($varInput))) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['extnd'], $this->strLabel)); } break; // Check whether the current value is a valid date format // Check whether the current value is a valid date format case 'date': if (!\Validator::isDate($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['date'], \Date::getInputFormat(\Date::getNumericDateFormat()))); } else { // Validate the date (see #5086) try { new \Date($varInput, \Date::getNumericDateFormat()); } catch (\OutOfBoundsException $e) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varInput)); } } break; // Check whether the current value is a valid time format // Check whether the current value is a valid time format case 'time': if (!\Validator::isTime($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['time'], \Date::getInputFormat(\Date::getNumericTimeFormat()))); } break; // Check whether the current value is a valid date and time format // Check whether the current value is a valid date and time format case 'datim': if (!\Validator::isDatim($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['dateTime'], \Date::getInputFormat(\Date::getNumericDatimFormat()))); } else { // Validate the date (see #5086) try { new \Date($varInput, \Date::getNumericDatimFormat()); } catch (\OutOfBoundsException $e) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidDate'], $varInput)); } } break; // Check whether the current value is a valid friendly name e-mail address // Check whether the current value is a valid friendly name e-mail address case 'friendly': list($strName, $varInput) = \String::splitFriendlyEmail($varInput); // no break; // Check whether the current value is a valid e-mail address // no break; // Check whether the current value is a valid e-mail address case 'email': if (!\Validator::isEmail($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['email'], $this->strLabel)); } if ($this->rgxp == 'friendly' && $strName != '') { $varInput = $strName . ' [' . $varInput . ']'; } break; // Check whether the current value is list of valid e-mail addresses // Check whether the current value is list of valid e-mail addresses case 'emails': $arrEmails = trimsplit(',', $varInput); foreach ($arrEmails as $strEmail) { $strEmail = \Idna::encodeEmail($strEmail); if (!\Validator::isEmail($strEmail)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['emails'], $this->strLabel)); break; } } break; // Check whether the current value is a valid URL // Check whether the current value is a valid URL case 'url': if (!\Validator::isUrl($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['url'], $this->strLabel)); } break; // Check whether the current value is a valid alias // Check whether the current value is a valid alias case 'alias': if (!\Validator::isAlias($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['alias'], $this->strLabel)); } break; // Check whether the current value is a valid folder URL alias // Check whether the current value is a valid folder URL alias case 'folderalias': if (!\Validator::isFolderAlias($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['folderalias'], $this->strLabel)); } break; // Phone numbers (numeric characters, space [ ], plus [+], minus [-], parentheses [()] and slash [/]) // Phone numbers (numeric characters, space [ ], plus [+], minus [-], parentheses [()] and slash [/]) case 'phone': if (!\Validator::isPhone(html_entity_decode($varInput))) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['phone'], $this->strLabel)); } break; // Check whether the current value is a percent value // Check whether the current value is a percent value case 'prcnt': if (!\Validator::isPercent($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['prcnt'], $this->strLabel)); } break; // Check whether the current value is a locale // Check whether the current value is a locale case 'locale': if (!\Validator::isLocale($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['locale'], $this->strLabel)); } break; // Check whether the current value is a language code // Check whether the current value is a language code case 'language': if (!\Validator::isLanguage($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['language'], $this->strLabel)); } break; // Check whether the current value is a Google+ ID or vanity name // Check whether the current value is a Google+ ID or vanity name case 'google+': if (!\Validator::isGooglePlusId($varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['invalidGoogleId'], $this->strLabel)); } break; // HOOK: pass unknown tags to callback functions // HOOK: pass unknown tags to callback functions default: if (isset($GLOBALS['TL_HOOKS']['addCustomRegexp']) && is_array($GLOBALS['TL_HOOKS']['addCustomRegexp'])) { foreach ($GLOBALS['TL_HOOKS']['addCustomRegexp'] as $callback) { $this->import($callback[0]); $break = $this->{$callback}[0]->{$callback}[1]($this->rgxp, $varInput, $this); // Stop the loop if a callback returned true if ($break === true) { break; } } } break; } } if ($this->isHexColor && $varInput != '' && strncmp($varInput, '$', 1) !== 0) { $varInput = preg_replace('/[^a-f0-9]+/i', '', $varInput); } if ($this->nospace && preg_match('/[\\t ]+/', $varInput)) { $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['noSpace'], $this->strLabel)); } if ($this->spaceToUnderscore) { $varInput = preg_replace('/\\s+/', '_', trim($varInput)); } if (is_bool($this->trailingSlash) && $varInput != '') { $varInput = preg_replace('/\\/+$/', '', $varInput) . ($this->trailingSlash ? '/' : ''); } return $varInput; }
/** * Extract the e-mail addresses from the func_get_args() arguments * * @param array $arrRecipients The recipients array * * @return array An array of e-mail addresses */ protected function compileRecipients($arrRecipients) { $arrReturn = array(); foreach ($arrRecipients as $varRecipients) { if (!is_array($varRecipients)) { $varRecipients = \String::splitCsv($varRecipients); } // Support friendly name addresses and internationalized domain names foreach ($varRecipients as $v) { list($strName, $strEmail) = \String::splitFriendlyEmail($v); $strName = trim($strName, ' "'); $strEmail = \Idna::encodeEmail($strEmail); if ($strName != '') { $arrReturn[$strEmail] = $strName; } else { $arrReturn[] = $strEmail; } } } return $arrReturn; }
/** * Renturn a form to choose an existing style sheet and import it * * @param \DataContainer $dc * * @return string */ public function send(\DataContainer $dc) { $objNewsletter = $this->Database->prepare("SELECT n.*, c.useSMTP, c.smtpHost, c.smtpPort, c.smtpUser, c.smtpPass FROM tl_newsletter n LEFT JOIN tl_newsletter_channel c ON n.pid=c.id WHERE n.id=?")->limit(1)->execute($dc->id); // Return if there is no newsletter if ($objNewsletter->numRows < 1) { return ''; } // Overwrite the SMTP configuration if ($objNewsletter->useSMTP) { \Config::set('useSMTP', true); \Config::set('smtpHost', $objNewsletter->smtpHost); \Config::set('smtpUser', $objNewsletter->smtpUser); \Config::set('smtpPass', $objNewsletter->smtpPass); \Config::set('smtpEnc', $objNewsletter->smtpEnc); \Config::set('smtpPort', $objNewsletter->smtpPort); } // Add default sender address if ($objNewsletter->sender == '') { list($objNewsletter->senderName, $objNewsletter->sender) = \String::splitFriendlyEmail(\Config::get('adminEmail')); } $arrAttachments = array(); $blnAttachmentsFormatError = false; // Add attachments if ($objNewsletter->addFile) { $files = deserialize($objNewsletter->files); if (!empty($files) && is_array($files)) { $objFiles = \FilesModel::findMultipleByUuids($files); if ($objFiles === null) { if (!\Validator::isUuid($files[0])) { $blnAttachmentsFormatError = true; \Message::addError($GLOBALS['TL_LANG']['ERR']['version2format']); } } else { while ($objFiles->next()) { if (is_file(TL_ROOT . '/' . $objFiles->path)) { $arrAttachments[] = $objFiles->path; } } } } } // Replace insert tags $html = $this->replaceInsertTags($objNewsletter->content, false); $text = $this->replaceInsertTags($objNewsletter->text, false); // Convert relative URLs if ($objNewsletter->externalImages) { $html = $this->convertRelativeUrls($html); } // Send newsletter if (!$blnAttachmentsFormatError && \Input::get('token') != '' && \Input::get('token') == $this->Session->get('tl_newsletter_send')) { $referer = preg_replace('/&(amp;)?(start|mpc|token|recipient|preview)=[^&]*/', '', \Environment::get('request')); // Preview if (isset($_GET['preview'])) { // Check the e-mail address if (!\Validator::isEmail(\Input::get('recipient', true))) { $_SESSION['TL_PREVIEW_MAIL_ERROR'] = true; $this->redirect($referer); } $arrRecipient['email'] = urldecode(\Input::get('recipient', true)); // Send $objEmail = $this->generateEmailObject($objNewsletter, $arrAttachments); $this->sendNewsletter($objEmail, $objNewsletter, $arrRecipient, $text, $html); // Redirect \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_newsletter']['confirm'], 1)); $this->redirect($referer); } // Get the total number of recipients $objTotal = $this->Database->prepare("SELECT COUNT(DISTINCT email) AS count FROM tl_newsletter_recipients WHERE pid=? AND active=1")->execute($objNewsletter->pid); // Return if there are no recipients if ($objTotal->count < 1) { $this->Session->set('tl_newsletter_send', null); \Message::addError($GLOBALS['TL_LANG']['tl_newsletter']['error']); $this->redirect($referer); } $intTotal = $objTotal->count; // Get page and timeout $intTimeout = \Input::get('timeout') > 0 ? \Input::get('timeout') : 1; $intStart = \Input::get('start') ? \Input::get('start') : 0; $intPages = \Input::get('mpc') ? \Input::get('mpc') : 10; // Get recipients $objRecipients = $this->Database->prepare("SELECT *, r.email FROM tl_newsletter_recipients r LEFT JOIN tl_member m ON(r.email=m.email) WHERE r.pid=? AND r.active=1 GROUP BY r.email ORDER BY r.email")->limit($intPages, $intStart)->execute($objNewsletter->pid); echo '<div style="font-family:Verdana,sans-serif;font-size:11px;line-height:16px;margin-bottom:12px">'; // Send newsletter if ($objRecipients->numRows > 0) { // Update status if ($intStart == 0) { $this->Database->prepare("UPDATE tl_newsletter SET sent=1, date=? WHERE id=?")->execute(time(), $objNewsletter->id); $_SESSION['REJECTED_RECIPIENTS'] = array(); } while ($objRecipients->next()) { $objEmail = $this->generateEmailObject($objNewsletter, $arrAttachments); $this->sendNewsletter($objEmail, $objNewsletter, $objRecipients->row(), $text, $html); echo 'Sending newsletter to <strong>' . $objRecipients->email . '</strong><br>'; } } echo '<div style="margin-top:12px">'; // Redirect back home if ($objRecipients->numRows < 1 || $intStart + $intPages >= $intTotal) { $this->Session->set('tl_newsletter_send', null); // Deactivate rejected addresses if (!empty($_SESSION['REJECTED_RECIPIENTS'])) { $intRejected = count($_SESSION['REJECTED_RECIPIENTS']); \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_newsletter']['rejected'], $intRejected)); $intTotal -= $intRejected; foreach ($_SESSION['REJECTED_RECIPIENTS'] as $strRecipient) { $this->Database->prepare("UPDATE tl_newsletter_recipients SET active='' WHERE email=?")->execute($strRecipient); $this->log('Recipient address "' . $strRecipient . '" was rejected and has been deactivated', __METHOD__, TL_ERROR); } } \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_newsletter']['confirm'], $intTotal)); echo '<script>setTimeout(\'window.location="' . \Environment::get('base') . $referer . '"\',1000)</script>'; echo '<a href="' . \Environment::get('base') . $referer . '">Please click here to proceed if you are not using JavaScript</a>'; } else { $url = preg_replace('/&(amp;)?(start|mpc|recipient)=[^&]*/', '', \Environment::get('request')) . '&start=' . ($intStart + $intPages) . '&mpc=' . $intPages; echo '<script>setTimeout(\'window.location="' . \Environment::get('base') . $url . '"\',' . $intTimeout * 1000 . ')</script>'; echo '<a href="' . \Environment::get('base') . $url . '">Please click here to proceed if you are not using JavaScript</a>'; } echo '</div></div>'; exit; } $strToken = md5(uniqid(mt_rand(), true)); $this->Session->set('tl_newsletter_send', $strToken); $sprintf = $objNewsletter->senderName != '' ? $objNewsletter->senderName . ' <%s>' : '%s'; $this->import('BackendUser', 'User'); // Preview newsletter $return = ' <div id="tl_buttons"> <a href="' . $this->getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> ' . \Message::generate() . ' <form action="' . TL_SCRIPT . '" id="tl_newsletter_send" class="tl_form" method="get"> <div class="tl_formbody_edit tl_newsletter_send"> <input type="hidden" name="do" value="' . \Input::get('do') . '"> <input type="hidden" name="table" value="' . \Input::get('table') . '"> <input type="hidden" name="key" value="' . \Input::get('key') . '"> <input type="hidden" name="id" value="' . \Input::get('id') . '"> <input type="hidden" name="token" value="' . $strToken . '"> <table class="prev_header"> <tr class="row_0"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['from'] . '</td> <td class="col_1">' . sprintf($sprintf, $objNewsletter->sender) . '</td> </tr> <tr class="row_1"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['subject'][0] . '</td> <td class="col_1">' . $objNewsletter->subject . '</td> </tr> <tr class="row_2"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['template'][0] . '</td> <td class="col_1">' . $objNewsletter->template . '</td> </tr>' . (!empty($arrAttachments) && is_array($arrAttachments) ? ' <tr class="row_3"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['attachments'] . '</td> <td class="col_1">' . implode(', ', $arrAttachments) . '</td> </tr>' : '') . ' </table>' . (!$objNewsletter->sendText ? ' <div class="preview_html"> ' . $html . ' </div>' : '') . ' <div class="preview_text"> <pre style="white-space:pre-wrap">' . $text . '</pre> </div> <div class="tl_tbox"> <div class="w50"> <h3><label for="ctrl_mpc">' . $GLOBALS['TL_LANG']['tl_newsletter']['mailsPerCycle'][0] . '</label></h3> <input type="text" name="mpc" id="ctrl_mpc" value="10" class="tl_text" onfocus="Backend.getScrollOffset()">' . ($GLOBALS['TL_LANG']['tl_newsletter']['mailsPerCycle'][1] && \Config::get('showHelp') ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['mailsPerCycle'][1] . '</p>' : '') . ' </div> <div class="w50"> <h3><label for="ctrl_timeout">' . $GLOBALS['TL_LANG']['tl_newsletter']['timeout'][0] . '</label></h3> <input type="text" name="timeout" id="ctrl_timeout" value="1" class="tl_text" onfocus="Backend.getScrollOffset()">' . ($GLOBALS['TL_LANG']['tl_newsletter']['timeout'][1] && \Config::get('showHelp') ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['timeout'][1] . '</p>' : '') . ' </div> <div class="w50"> <h3><label for="ctrl_start">' . $GLOBALS['TL_LANG']['tl_newsletter']['start'][0] . '</label></h3> <input type="text" name="start" id="ctrl_start" value="0" class="tl_text" onfocus="Backend.getScrollOffset()">' . ($GLOBALS['TL_LANG']['tl_newsletter']['start'][1] && \Config::get('showHelp') ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['start'][1] . '</p>' : '') . ' </div> <div class="w50"> <h3><label for="ctrl_recipient">' . $GLOBALS['TL_LANG']['tl_newsletter']['sendPreviewTo'][0] . '</label></h3> <input type="text" name="recipient" id="ctrl_recipient" value="' . $this->User->email . '" class="tl_text" onfocus="Backend.getScrollOffset()">' . (isset($_SESSION['TL_PREVIEW_MAIL_ERROR']) ? ' <div class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['email'] . '</div>' : ($GLOBALS['TL_LANG']['tl_newsletter']['sendPreviewTo'][1] && \Config::get('showHelp') ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['sendPreviewTo'][1] . '</p>' : '')) . ' </div> <div class="clear"></div> </div> </div>'; // Do not send the newsletter if there is an attachment format error if (!$blnAttachmentsFormatError) { $return .= ' <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="preview" class="tl_submit" accesskey="p" value="' . specialchars($GLOBALS['TL_LANG']['tl_newsletter']['preview']) . '"> <input type="submit" id="send" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_newsletter']['send'][0]) . '" onclick="return confirm(\'' . str_replace("'", "\\'", $GLOBALS['TL_LANG']['tl_newsletter']['sendConfirm']) . '\')"> </div> </div>'; } $return .= ' </form>'; unset($_SESSION['TL_PREVIEW_MAIL_ERROR']); return $return; }
/** * Split a friendly-name e-address and return name and e-mail as array * * @param string $strEmail A friendly-name e-mail address * * @return array An array with name and e-mail address * * @deprecated Use String::splitFriendlyEmail() instead */ public static function splitFriendlyName($strEmail) { return \String::splitFriendlyEmail($strEmail); }
/** * Renturn a form to choose an existing style sheet and import it * @param \DataContainer * @return string */ public function send(\DataContainer $objDc) { if (TL_MODE == 'BE') { $GLOBALS['TL_CSS'][] = 'system/modules/newsletter_content/assets/css/style.css'; if ($this->isFlexible) { $GLOBALS['TL_CSS'][] = 'system/modules/newsletter_content/assets/css/style-flexible.css'; } } $objNewsletter = $this->Database->prepare("SELECT n.*, c.useSMTP, c.smtpHost, c.smtpPort, c.smtpUser, c.smtpPass FROM tl_newsletter n LEFT JOIN tl_newsletter_channel c ON n.pid=c.id WHERE n.id=?")->limit(1)->execute($objDc->id); // Return if there is no newsletter if ($objNewsletter->numRows < 1) { return ''; } // Overwrite the SMTP configuration if ($objNewsletter->useSMTP) { $GLOBALS['TL_CONFIG']['useSMTP'] = true; $GLOBALS['TL_CONFIG']['smtpHost'] = $objNewsletter->smtpHost; $GLOBALS['TL_CONFIG']['smtpUser'] = $objNewsletter->smtpUser; $GLOBALS['TL_CONFIG']['smtpPass'] = $objNewsletter->smtpPass; $GLOBALS['TL_CONFIG']['smtpEnc'] = $objNewsletter->smtpEnc; $GLOBALS['TL_CONFIG']['smtpPort'] = $objNewsletter->smtpPort; } // Add default sender address if ($objNewsletter->sender == '') { list($objNewsletter->senderName, $objNewsletter->sender) = \String::splitFriendlyEmail($GLOBALS['TL_CONFIG']['adminEmail']); } $arrAttachments = array(); $blnAttachmentsFormatError = false; // Add attachments if ($objNewsletter->addFile) { $files = deserialize($objNewsletter->files); if (!empty($files) && is_array($files)) { $objFiles = \FilesModel::findMultipleByUuids($files); if ($objFiles === null) { if (!\Validator::isUuid($files[0])) { $blnAttachmentsFormatError = true; \Message::addError($GLOBALS['TL_LANG']['ERR']['version2format']); } } else { while ($objFiles->next()) { if (is_file(TL_ROOT . '/' . $objFiles->path)) { $arrAttachments[] = $objFiles->path; } } } } } // Get content $html = ''; $objContentElements = \ContentModel::findPublishedByPidAndTable($objNewsletter->id, 'tl_newsletter'); if ($objContentElements !== null) { if (!defined('NEWSLETTER_CONTENT_PREVIEW')) { define('NEWSLETTER_CONTENT_PREVIEW', true); } while ($objContentElements->next()) { $html .= $this->getContentElement($objContentElements->id); } } // Replace insert tags $text = $this->replaceInsertTags($objNewsletter->text); $html = $this->replaceInsertTags($html); // Convert relative URLs $html = $this->convertRelativeUrls($html); // Set back to object $objNewsletter->content = $html; // Send newsletter if (!$blnAttachmentsFormatError && \Input::get('token') != '' && \Input::get('token') == $this->Session->get('tl_newsletter_send')) { $referer = preg_replace('/&(amp;)?(start|mpc|token|recipient|preview)=[^&]*/', '', \Environment::get('request')); // Preview if (isset($_GET['preview'])) { // Check the e-mail address if (!\Validator::isEmail(\Input::get('recipient', true))) { $_SESSION['TL_PREVIEW_MAIL_ERROR'] = true; $this->redirect($referer); } // get preview recipient $arrRecipient = array(); $strEmail = urldecode(\Input::get('recipient', true)); $objRecipient = $this->Database->prepare("SELECT * FROM tl_member m WHERE email=? ORDER BY email")->limit(1)->execute($strEmail); if ($objRecipient->num_rows < 1) { $arrRecipient['email'] = $strEmail; } else { $arrRecipient = $objRecipient->row(); } $arrRecipient = array_merge($arrRecipient, array('extra' => '&preview=1', 'tracker_png' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $strEmail . '&preview=1&t=png', 'tracker_gif' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $strEmail . '&preview=1&t=gif', 'tracker_css' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $strEmail . '&preview=1&t=css', 'tracker_js' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $strEmail . '&preview=1&t=js')); // Send $objEmail = $this->generateEmailObject($objNewsletter, $arrAttachments); $objNewsletter->email = $strEmail; $this->sendNewsletter($objEmail, $objNewsletter, $arrRecipient, $text, $html); // Redirect \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_newsletter']['confirm'], 1)); $this->redirect($referer); } // Get the total number of recipients $objTotal = $this->Database->prepare("SELECT COUNT(DISTINCT email) AS count FROM tl_newsletter_recipients WHERE pid=? AND active=1")->execute($objNewsletter->pid); // Return if there are no recipients if ($objTotal->count < 1) { $this->Session->set('tl_newsletter_send', null); \Message::addError($GLOBALS['TL_LANG']['tl_newsletter']['error']); $this->redirect($referer); } $intTotal = $objTotal->count; // Get page and timeout $intTimeout = \Input::get('timeout') > 0 ? \Input::get('timeout') : 1; $intStart = \Input::get('start') ? \Input::get('start') : 0; $intPages = \Input::get('mpc') ? \Input::get('mpc') : 10; // Get recipients $objRecipients = $this->Database->prepare("SELECT *, r.email FROM tl_newsletter_recipients r LEFT JOIN tl_member m ON(r.email=m.email) WHERE r.pid=? AND r.active=1 GROUP BY r.email ORDER BY r.email")->limit($intPages, $intStart)->execute($objNewsletter->pid); echo '<div style="font-family:Verdana,sans-serif;font-size:11px;line-height:16px;margin-bottom:12px">'; // Send newsletter if ($objRecipients->numRows > 0) { // Update status if ($intStart == 0) { $this->Database->prepare("UPDATE tl_newsletter SET sent=1, date=? WHERE id=?")->execute(time(), $objNewsletter->id); $_SESSION['REJECTED_RECIPIENTS'] = array(); } while ($objRecipients->next()) { $objEmail = $this->generateEmailObject($objNewsletter, $arrAttachments); $objNewsletter->email = $objRecipients->email; $arrRecipient = array_merge($objRecipients->row(), array('tracker_png' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $objRecipients->email . '&t=png', 'tracker_gif' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $objRecipients->email . '&t=gif', 'tracker_css' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $objRecipients->email . '&t=css', 'tracker_js' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $objRecipients->email . '&t=js')); $this->sendNewsletter($objEmail, $objNewsletter, $arrRecipient, $text, $html); echo 'Sending newsletter to <strong>' . $objRecipients->email . '</strong><br>'; } } echo '<div style="margin-top:12px">'; // Redirect back home if ($objRecipients->numRows < 1 || $intStart + $intPages >= $intTotal) { $this->Session->set('tl_newsletter_send', null); // Deactivate rejected addresses if (!empty($_SESSION['REJECTED_RECIPIENTS'])) { $intRejected = count($_SESSION['REJECTED_RECIPIENTS']); \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_newsletter']['rejected'], $intRejected)); $intTotal -= $intRejected; foreach ($_SESSION['REJECTED_RECIPIENTS'] as $strRecipient) { $this->Database->prepare("UPDATE tl_newsletter_recipients SET active='' WHERE email=?")->execute($strRecipient); $this->log('Recipient address "' . $strRecipient . '" was rejected and has been deactivated', __METHOD__, TL_ERROR); } } $this->Database->prepare("UPDATE tl_newsletter SET recipients=?, rejected=? WHERE id=?")->execute($intTotal, $intRejected, $objNewsletter->id); \Message::addConfirmation(sprintf($GLOBALS['TL_LANG']['tl_newsletter']['confirm'], $intTotal)); echo '<script>setTimeout(\'window.location="' . \Environment::get('base') . $referer . '"\',1000)</script>'; echo '<a href="' . \Environment::get('base') . $referer . '">Please click here to proceed if you are not using JavaScript</a>'; } else { $url = preg_replace('/&(amp;)?(start|mpc|recipient)=[^&]*/', '', \Environment::get('request')) . '&start=' . ($intStart + $intPages) . '&mpc=' . $intPages; echo '<script>setTimeout(\'window.location="' . \Environment::get('base') . $url . '"\',' . $intTimeout * 1000 . ')</script>'; echo '<a href="' . \Environment::get('base') . $url . '">Please click here to proceed if you are not using JavaScript</a>'; } echo '</div></div>'; exit; } $strToken = md5(uniqid(mt_rand(), true)); $this->Session->set('tl_newsletter_send', $strToken); $sprintf = $objNewsletter->senderName != '' ? $objNewsletter->senderName . ' <%s>' : '%s'; $this->import('BackendUser', 'User'); // prepare preview $preview = $text; if (!$objNewsletter->sendText) { // Default template if ($objNewsletter->template == '') { $objNewsletter->template = 'mail_default'; } // Load the mail template $objTemplate = new \BackendTemplate($objNewsletter->template); $objTemplate->setData($objNewsletter->row()); $objTemplate->title = $objNewsletter->subject; $objTemplate->body = $html; $objTemplate->charset = $GLOBALS['TL_CONFIG']['characterSet']; $objTemplate->css = $css; // Backwards compatibility // Parse template $preview = $objTemplate->parse(); } // Replace inserttags $arrName = explode(' ', $this->User->name); $preview = $this->replaceInsertTags($preview); $preview = $this->prepareLinkTracking($preview, $objNewsletter->id, $this->User->email, '&preview=1'); $preview = $this->parseSimpleTokens($preview, array('firstname' => $arrName[0], 'lastname' => $arrName[sizeof($arrName) - 1], 'street' => 'Königsbrücker Str. 9', 'postal' => '01099', 'city' => 'Dresden', 'phone' => '0351 30966184', 'email' => $this->User->email, 'tracker_png' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $this->User->email . '&preview=1&t=png', 'tracker_gif' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $this->User->email . '&preview=1&t=gif', 'tracker_css' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $this->User->email . '&preview=1&t=css', 'tracker_js' => \Environment::get('base') . 'tracking/?n=' . $objNewsletter->id . '&e=' . $this->User->email . '&preview=1&t=js')); // Create cache folder if (!file_exists(TL_ROOT . '/system/cache/newsletter')) { mkdir(TL_ROOT . '/system/cache/newsletter'); file_put_contents(TL_ROOT . '/system/cache/newsletter/.htaccess', '<IfModule !mod_authz_core.c> Order allow,deny Allow from all </IfModule> <IfModule mod_authz_core.c> Require all granted </IfModule>'); } // Cache preview file_put_contents(TL_ROOT . '/system/cache/newsletter/' . $objNewsletter->alias . '.html', preg_replace('/^\\s+|\\n|\\r|\\s+$/m', '', $preview)); // Preview newsletter $return = ' <div id="tl_buttons"> <a href="' . $this->getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> <h2 class="sub_headline">' . sprintf($GLOBALS['TL_LANG']['tl_newsletter']['send'][1], $objNewsletter->id) . '</h2> ' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('script'), true) . '" id="tl_newsletter_send" class="tl_form" method="get"> <div class="tl_formbody_edit tl_newsletter_send"> <input type="hidden" name="do" value="' . \Input::get('do') . '"> <input type="hidden" name="table" value="' . \Input::get('table') . '"> <input type="hidden" name="key" value="' . \Input::get('key') . '"> <input type="hidden" name="id" value="' . \Input::get('id') . '"> <input type="hidden" name="token" value="' . $strToken . '"> <table class="prev_header"> <tr class="row_0"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['from'] . '</td> <td class="col_1">' . sprintf($sprintf, $objNewsletter->sender) . '</td> </tr> <tr class="row_1"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['subject'][0] . '</td> <td class="col_1">' . $objNewsletter->subject . '</td> </tr> <tr class="row_2"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['template'][0] . '</td> <td class="col_1">' . $objNewsletter->template . '</td> </tr>' . (!empty($arrAttachments) && is_array($arrAttachments) ? ' <tr class="row_3"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_newsletter']['attachments'] . '</td> <td class="col_1">' . implode(', ', $arrAttachments) . '</td> </tr>' : '') . ' </table>' . (!$objNewsletter->sendText ? ' <iframe class="preview_html" id="preview_html" seamless border="0" width="703px" height="503px" style="padding:0" src="system/cache/newsletter/' . $objNewsletter->alias . '.html"></iframe> ' : '') . ' <div class="preview_text"> ' . nl2br_html5($text) . ' </div> <div class="tl_tbox"> <div class="w50"> <h3><label for="ctrl_mpc">' . $GLOBALS['TL_LANG']['tl_newsletter']['mailsPerCycle'][0] . '</label></h3> <input type="text" name="mpc" id="ctrl_mpc" value="10" class="tl_text" onfocus="Backend.getScrollOffset()">' . ($GLOBALS['TL_LANG']['tl_newsletter']['mailsPerCycle'][1] && $GLOBALS['TL_CONFIG']['showHelp'] ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['mailsPerCycle'][1] . '</p>' : '') . ' </div> <div class="w50"> <h3><label for="ctrl_timeout">' . $GLOBALS['TL_LANG']['tl_newsletter']['timeout'][0] . '</label></h3> <input type="text" name="timeout" id="ctrl_timeout" value="1" class="tl_text" onfocus="Backend.getScrollOffset()">' . ($GLOBALS['TL_LANG']['tl_newsletter']['timeout'][1] && $GLOBALS['TL_CONFIG']['showHelp'] ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['timeout'][1] . '</p>' : '') . ' </div> <div class="w50"> <h3><label for="ctrl_start">' . $GLOBALS['TL_LANG']['tl_newsletter']['start'][0] . '</label></h3> <input type="text" name="start" id="ctrl_start" value="0" class="tl_text" onfocus="Backend.getScrollOffset()">' . ($GLOBALS['TL_LANG']['tl_newsletter']['start'][1] && $GLOBALS['TL_CONFIG']['showHelp'] ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['start'][1] . '</p>' : '') . ' </div> <div class="w50"> <h3><label for="ctrl_recipient">' . $GLOBALS['TL_LANG']['tl_newsletter']['sendPreviewTo'][0] . '</label></h3> <input type="text" name="recipient" id="ctrl_recipient" value="' . $this->User->email . '" class="tl_text" onfocus="Backend.getScrollOffset()">' . (isset($_SESSION['TL_PREVIEW_MAIL_ERROR']) ? ' <div class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['email'] . '</div>' : ($GLOBALS['TL_LANG']['tl_newsletter']['sendPreviewTo'][1] && $GLOBALS['TL_CONFIG']['showHelp'] ? ' <p class="tl_help tl_tip">' . $GLOBALS['TL_LANG']['tl_newsletter']['sendPreviewTo'][1] . '</p>' : '')) . ' </div> <div class="clear"></div> </div> </div>'; // Do not send the newsletter if there is an attachment format error if (!$blnAttachmentsFormatError) { $return .= ' <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="preview" class="tl_submit" accesskey="p" value="' . specialchars($GLOBALS['TL_LANG']['tl_newsletter']['preview']) . '"> <input type="submit" id="send" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_newsletter']['send'][0]) . '" onclick="return confirm(\'' . str_replace("'", "\\'", $GLOBALS['TL_LANG']['tl_newsletter']['sendConfirm']) . '\')"> </div> </div>'; } $return .= ' </form>'; unset($_SESSION['TL_PREVIEW_MAIL_ERROR']); return $return; }
/** * Process submitted form data * Send mail, store data in backend * @param array $arrSubmitted Submitted data * @param array|bool $arrForm Form configuration * @param array|bool $arrFiles Files uploaded * @param array|bool $arrLabels Form field labels * @return void */ public function processSubmittedData($arrSubmitted, $arrForm = false, $arrFiles = false, $arrLabels = false) { // Form config if (!$arrForm) { return; } $arrFormFields = array(); $this->import('FrontendUser', 'Member'); $this->import('Formdata'); $this->strFdDcaKey = 'fd_' . (!empty($arrForm['alias']) ? $arrForm['alias'] : str_replace('-', '_', standardize($arrForm['title']))); $this->Formdata->FdDcaKey = $this->strFdDcaKey; // Get params of related listing formdata $intListingId = intval($_SESSION['EFP']['LISTING_MOD']['id']); if ($intListingId > 0) { $objListing = \Database::getInstance()->prepare("SELECT * FROM tl_module WHERE id=?")->execute($intListingId); if ($objListing->numRows) { $arrListing = $objListing->fetchAssoc(); // Mail delivery defined in frontend listing module $arrForm['sendConfirmationMailOnFrontendEditing'] = $arrListing['efg_fe_no_confirmation_mail'] ? false : true; $arrForm['sendFormattedMailOnFrontendEditing'] = $arrListing['efg_fe_no_formatted_mail'] ? false : true; } } if (!empty($arrListing['efg_DetailsKey'])) { $this->strFormdataDetailsKey = $arrListing['efg_DetailsKey']; } $blnFEedit = false; $intOldId = 0; $strRedirectTo = ''; $strUrl = preg_replace('/\\?.*$/', '', \Environment::get('request')); $strUrlParams = ''; $blnQuery = false; foreach (preg_split('/&(amp;)?/', $_SERVER['QUERY_STRING']) as $fragment) { if (strlen($fragment)) { if (strncasecmp($fragment, $this->strFormdataDetailsKey, strlen($this->strFormdataDetailsKey)) !== 0 && strncasecmp($fragment, 'act', 3) !== 0) { $strUrlParams .= (!$blnQuery ? '' : '&') . $fragment; $blnQuery = true; } } } if (in_array($arrListing['efg_fe_edit_access'], array('public', 'groupmembers', 'member'))) { if (\Input::get('act') == 'edit') { $blnFEedit = true; $objCheck = \Database::getInstance()->prepare("SELECT id FROM tl_formdata WHERE id=? OR alias=?")->execute(\Input::get($this->strFormdataDetailsKey), \Input::get($this->strFormdataDetailsKey)); if ($objCheck->numRows == 1) { $intOldId = intval($objCheck->id); } else { $this->log('Could not identify record by ID "' . \Input::get($this->strFormdataDetailsKey) . '"', __METHOD__, TL_GENERAL); } } } // Types of form fields with storable data $arrFFstorable = $this->Formdata->arrFFstorable; if (($arrForm['storeFormdata'] || $arrForm['sendConfirmationMail'] || $arrForm['sendFormattedMail']) && !empty($arrSubmitted)) { $timeNow = time(); $this->loadDataContainer($this->strFdDcaKey); $this->loadDataContainer('tl_formdata_details'); $this->loadDataContainer('tl_files'); $arrFormFields = $this->Formdata->getFormfieldsAsArray($arrForm['id']); $arrBaseFields = array(); $arrDetailFields = array(); if (!empty($GLOBALS['TL_DCA']['tl_formdata']['tl_formdata']['baseFields'])) { $arrBaseFields = $GLOBALS['TL_DCA']['tl_formdata']['tl_formdata']['baseFields']; } if (!empty($GLOBALS['TL_DCA']['tl_formdata']['tl_formdata']['detailFields'])) { $arrDetailFields = $GLOBALS['TL_DCA']['tl_formdata']['tl_formdata']['detailFields']; } $arrHookFields = array_merge($arrBaseFields, $arrDetailFields); $arrToSave = array(); foreach ($arrSubmitted as $k => $varVal) { if (in_array($k, array('id'))) { continue; } elseif (in_array($k, $arrHookFields) || in_array($k, array_keys($arrFormFields)) || in_array($k, array('FORM_SUBMIT', 'MAX_FILE_SIZE'))) { $arrToSave[$k] = $varVal; } } // HOOK: process efg form data callback if (array_key_exists('processEfgFormData', $GLOBALS['TL_HOOKS']) && is_array($GLOBALS['TL_HOOKS']['processEfgFormData'])) { foreach ($GLOBALS['TL_HOOKS']['processEfgFormData'] as $key => $callback) { $this->import($callback[0]); $arrResult = $this->{$callback}[0]->{$callback}[1]($arrToSave, $arrFiles, $intOldId, $arrForm, $arrLabels); if (!empty($arrResult)) { $arrSubmitted = $arrResult; $arrToSave = $arrSubmitted; } } } } // Formdata storage if ($arrForm['storeFormdata'] && !empty($arrSubmitted)) { $blnStoreOptionsValue = $arrForm['efgStoreValues'] ? true : false; // Get old record on frontend editing if ($intOldId > 0) { $arrOldData = $this->Formdata->getFormdataAsArray($intOldId); $arrOldFormdata = $arrOldData['fd_base']; $arrOldFormdataDetails = $arrOldData['fd_details']; } // Prepare record tl_formdata $arrSet = array('form' => $arrForm['title'], 'tstamp' => $timeNow, 'date' => $timeNow, 'ip' => \System::anonymizeIp(\Environment::get('ip')), 'published' => $GLOBALS['TL_DCA']['tl_formdata']['fields']['published']['default'] ? '1' : '', 'fd_member' => intval($this->Member->id), 'fd_member_group' => intval($this->Member->groups[0]), 'fd_user' => intval($this->User->id), 'fd_user_group' => intval($this->User->groups[0])); // Keep some values from existing record on frontend editing if ($intOldId > 0) { $arrSet['form'] = $arrOldFormdata['form']; $arrSet['be_notes'] = $arrOldFormdata['be_notes']; $arrSet['fd_member'] = $arrOldFormdata['fd_member']; $arrSet['fd_member_group'] = $arrOldFormdata['fd_member_group']; if (intval($this->Member->id) > 0) { $arrSet['fd_member'] = intval($this->Member->id); if (count($this->Member->groups) == 1 && intval($this->Member->groups[0]) > 0) { $arrSet['fd_member_group'] = intval($this->Member->groups[0]); } } else { $arrSet['fd_member'] = 0; } $arrSet['fd_user'] = $arrOldFormdata['fd_user']; $arrSet['fd_user_group'] = $arrOldFormdata['fd_user_group']; // Set published to value of old record, if no default value is defined if (!isset($GLOBALS['TL_DCA']['tl_formdata']['fields']['published']['default'])) { $arrSet['published'] = $arrOldFormdata['published']; } } // Store formdata: Update or insert and delete if ($blnFEedit && strlen($arrListing['efg_fe_keep_id'])) { $intNewId = $intOldId; \Database::getInstance()->prepare("UPDATE tl_formdata %s WHERE id=?")->set($arrSet)->execute($intOldId); \Database::getInstance()->prepare("DELETE FROM tl_formdata_details WHERE pid=?")->execute($intOldId); } else { $objNewFormdata = \Database::getInstance()->prepare("INSERT INTO tl_formdata %s")->set($arrSet)->execute(); $intNewId = $objNewFormdata->insertId; // Update related comments if (in_array('comments', \ModuleLoader::getActive())) { \Database::getInstance()->prepare("UPDATE tl_comments %s WHERE `source` = 'tl_formdata' AND parent=?")->set(array('parent' => $intNewId))->execute($intOldId); } } // Store details data foreach ($arrFormFields as $k => $arrField) { $strType = $arrField['formfieldType']; $strVal = ''; if (in_array($strType, $arrFFstorable)) { if ($blnStoreOptionsValue) { $arrField['eval']['efgStoreValues'] = true; } else { $arrField['eval']['efgStoreValues'] = false; } // Set rgxp 'date' for field type 'calendar' if not set if ($strType == 'calendar') { if (!isset($arrField['rgxp'])) { $arrField['rgxp'] = 'date'; } } elseif ($strType == 'xdependentcalendarfields') { $arrField['rgxp'] = 'date'; $arrField['dateFormat'] = $arrField['xdateformat']; } $strVal = $this->Formdata->preparePostValueForDatabase($arrSubmitted[$k], $arrField, $arrFiles[$k]); // Special treatment for type upload // Keep old file on frontend editing, if no new file has been uploaded if ($strType == 'upload') { if ($intOldId) { if (!$arrFiles[$k]['name']) { if (strlen($arrOldFormdataDetails[$k]['value'])) { $strVal = $arrOldFormdataDetails[$k]['value']; } } } } if (isset($arrSubmitted[$k]) || $strType == 'upload' && strlen($strVal)) { // Prepare data $arrFieldSet = array('pid' => $intNewId, 'sorting' => $arrField['sorting'], 'tstamp' => $timeNow, 'ff_id' => $arrField['id'], 'ff_name' => $arrField['name'], 'value' => $strVal); $objNewFormdataDetails = \Database::getInstance()->prepare("INSERT INTO tl_formdata_details %s")->set($arrFieldSet)->execute(); } } } // Delete old record after frontend editing if ($blnFEedit) { if (!isset($arrListing['efg_fe_keep_id']) || $arrListing['efg_fe_keep_id'] != "1") { if ($intNewId > 0 && intval($intOldId) > 0 && intval($intNewId) != intval($intOldId)) { \Database::getInstance()->prepare("DELETE FROM tl_formdata_details WHERE pid=?")->execute($intOldId); \Database::getInstance()->prepare("DELETE FROM tl_formdata WHERE id=?")->execute($intOldId); } } $strRedirectTo = preg_replace('/\\?.*$/', '', \Environment::get('request')); } // Auto-generate alias $strAlias = $this->Formdata->generateAlias($arrOldFormdata['alias'], $arrForm['title'], $intNewId); if (strlen($strAlias)) { $arrUpd = array('alias' => $strAlias); \Database::getInstance()->prepare("UPDATE tl_formdata %s WHERE id=?")->set($arrUpd)->execute($intNewId); } } // Store data in the session to display on confirmation page unset($_SESSION['EFP']['FORMDATA']); $blnSkipEmptyFields = $arrForm['confirmationMailSkipEmpty'] ? true : false; foreach ($arrFormFields as $k => $arrField) { $strType = $arrField['formfieldType']; $strVal = ''; if (in_array($strType, $arrFFstorable)) { $strVal = $this->Formdata->preparePostValueForMail($arrSubmitted[$k], $arrField, $arrFiles[$k], $blnSkipEmptyFields); } $_SESSION['EFP']['FORMDATA'][$k] = $strVal; } $_SESSION['EFP']['FORMDATA']['_formId_'] = $arrForm['id']; // Confirmation Mail if ($blnFEedit && !$arrForm['sendConfirmationMailOnFrontendEditing']) { $arrForm['sendConfirmationMail'] = false; } if ($arrForm['sendConfirmationMail']) { $objMailProperties = new \stdClass(); $objMailProperties->subject = ''; $objMailProperties->sender = ''; $objMailProperties->senderName = ''; $objMailProperties->replyTo = ''; $objMailProperties->recipients = array(); $objMailProperties->messageText = ''; $objMailProperties->messageHtmlTmpl = ''; $objMailProperties->messageHtml = ''; $objMailProperties->attachments = array(); $objMailProperties->skipEmptyFields = false; $objMailProperties->skipEmptyFields = $arrForm['confirmationMailSkipEmpty'] ? true : false; // Set the sender as given in form configuration list($senderName, $sender) = \String::splitFriendlyEmail($arrForm['confirmationMailSender']); $objMailProperties->sender = $sender; $objMailProperties->senderName = $senderName; // Set the 'reply to' address, if given in form configuration if (!empty($arrForm['confirmationMailReplyto'])) { list($replyToName, $replyTo) = \String::splitFriendlyEmail($arrForm['confirmationMailReplyto']); $objMailProperties->replyTo = strlen($replyToName) ? $replyToName . ' <' . $replyTo . '>' : $replyTo; } // Set recipient(s) $recipientFieldName = $arrForm['confirmationMailRecipientField']; $varRecipient = $arrSubmitted[$recipientFieldName]; if (is_array($varRecipient)) { $arrRecipient = $varRecipient; } else { $arrRecipient = trimsplit(',', $varRecipient); } if (!empty($arrForm['confirmationMailRecipient'])) { $varRecipient = $arrForm['confirmationMailRecipient']; $arrRecipient = array_merge($arrRecipient, trimsplit(',', $varRecipient)); } $arrRecipient = array_filter(array_unique($arrRecipient)); if (!empty($arrRecipient)) { foreach ($arrRecipient as $kR => $recipient) { list($recipientName, $recipient) = \String::splitFriendlyEmail($this->replaceInsertTags($recipient, false)); $arrRecipient[$kR] = strlen($recipientName) ? $recipientName . ' <' . $recipient . '>' : $recipient; } } $objMailProperties->recipients = $arrRecipient; // Check if we want custom attachments... (Thanks to Torben Schwellnus) if ($arrForm['addConfirmationMailAttachments']) { if ($arrForm['confirmationMailAttachments']) { $arrCustomAttachments = deserialize($arrForm['confirmationMailAttachments'], true); if (!empty($arrCustomAttachments)) { foreach ($arrCustomAttachments as $varFile) { $objFileModel = \FilesModel::findById($varFile); if ($objFileModel !== null) { $objFile = new \File($objFileModel->path); if ($objFile->size) { $objMailProperties->attachments[TL_ROOT . '/' . $objFile->path] = array('file' => TL_ROOT . '/' . $objFile->path, 'name' => $objFile->basename, 'mime' => $objFile->mime); } } } } } } $objMailProperties->subject = \String::decodeEntities($arrForm['confirmationMailSubject']); $objMailProperties->messageText = \String::decodeEntities($arrForm['confirmationMailText']); $objMailProperties->messageHtmlTmpl = $arrForm['confirmationMailTemplate']; // Replace Insert tags and conditional tags $objMailProperties = $this->Formdata->prepareMailData($objMailProperties, $arrSubmitted, $arrFiles, $arrForm, $arrFormFields); // Send Mail $blnConfirmationSent = false; if (!empty($objMailProperties->recipients)) { $objMail = new \Email(); $objMail->from = $objMailProperties->sender; if (!empty($objMailProperties->senderName)) { $objMail->fromName = $objMailProperties->senderName; } if (!empty($objMailProperties->replyTo)) { $objMail->replyTo($objMailProperties->replyTo); } $objMail->subject = $objMailProperties->subject; if (!empty($objMailProperties->attachments)) { foreach ($objMailProperties->attachments as $strFile => $varParams) { $strContent = file_get_contents($varParams['file'], false); $objMail->attachFileFromString($strContent, $varParams['name'], $varParams['mime']); } } if (!empty($objMailProperties->messageText)) { $objMail->text = $objMailProperties->messageText; } if (!empty($objMailProperties->messageHtml)) { $objMail->html = $objMailProperties->messageHtml; } foreach ($objMailProperties->recipients as $recipient) { $objMail->sendTo($recipient); $blnConfirmationSent = true; } } if ($blnConfirmationSent && isset($intNewId) && intval($intNewId) > 0) { $arrUpd = array('confirmationSent' => '1', 'confirmationDate' => $timeNow); $res = \Database::getInstance()->prepare("UPDATE tl_formdata %s WHERE id=?")->set($arrUpd)->execute($intNewId); } } // Information (formatted) Mail if ($blnFEedit && !$arrForm['sendFormattedMailOnFrontendEditing']) { $arrForm['sendFormattedMail'] = false; } if ($arrForm['sendFormattedMail']) { $objMailProperties = new \stdClass(); $objMailProperties->subject = ''; $objMailProperties->sender = ''; $objMailProperties->senderName = ''; $objMailProperties->replyTo = ''; $objMailProperties->recipients = array(); $objMailProperties->messageText = ''; $objMailProperties->messageHtmlTmpl = ''; $objMailProperties->messageHtml = ''; $objMailProperties->attachments = array(); $objMailProperties->skipEmptyFields = false; $objMailProperties->skipEmptyFields = $arrForm['formattedMailSkipEmpty'] ? true : false; // Set the admin e-mail as "from" address $objMailProperties->sender = $GLOBALS['TL_ADMIN_EMAIL']; $objMailProperties->senderName = $GLOBALS['TL_ADMIN_NAME']; // Get 'reply to' address, if form contains field named 'email' if (isset($arrSubmitted['email']) && !empty($arrSubmitted['email']) && !is_bool(strpos($arrSubmitted['email'], '@'))) { $replyTo = $arrSubmitted['email']; // add name if (isset($arrSubmitted['name']) && !empty($arrSubmitted['name'])) { $replyTo = '"' . $arrSubmitted['name'] . '" <' . $arrSubmitted['email'] . '>'; } $objMailProperties->replyTo = $replyTo; } // Set recipient(s) $varRecipient = $arrForm['formattedMailRecipient']; if (is_array($varRecipient)) { $arrRecipient = $varRecipient; } else { $arrRecipient = trimsplit(',', $varRecipient); } $arrRecipient = array_filter(array_unique($arrRecipient)); if (!empty($arrRecipient)) { foreach ($arrRecipient as $kR => $recipient) { list($recipientName, $recipient) = \String::splitFriendlyEmail($this->replaceInsertTags($recipient, false)); $arrRecipient[$kR] = strlen($recipientName) ? $recipientName . ' <' . $recipient . '>' : $recipient; } } $objMailProperties->recipients = $arrRecipient; // Check if we want custom attachments... (Thanks to Torben Schwellnus) if ($arrForm['addFormattedMailAttachments']) { if ($arrForm['formattedMailAttachments']) { $arrCustomAttachments = deserialize($arrForm['formattedMailAttachments'], true); if (is_array($arrCustomAttachments)) { foreach ($arrCustomAttachments as $varFile) { $objFileModel = \FilesModel::findById($varFile); if ($objFileModel !== null) { $objFile = new \File($objFileModel->path); if ($objFile->size) { $objMailProperties->attachments[TL_ROOT . '/' . $objFile->path] = array('file' => TL_ROOT . '/' . $objFile->path, 'name' => $objFile->basename, 'mime' => $objFile->mime); } } } } } } $objMailProperties->subject = \String::decodeEntities($arrForm['formattedMailSubject']); $objMailProperties->messageText = \String::decodeEntities($arrForm['formattedMailText']); $objMailProperties->messageHtmlTmpl = $arrForm['formattedMailTemplate']; // Replace Insert tags and conditional tags $objMailProperties = $this->Formdata->prepareMailData($objMailProperties, $arrSubmitted, $arrFiles, $arrForm, $arrFormFields); // Send Mail $blnInformationSent = false; if (!empty($objMailProperties->recipients)) { $objMail = new \Email(); $objMail->from = $objMailProperties->sender; if (!empty($objMailProperties->senderName)) { $objMail->fromName = $objMailProperties->senderName; } if (!empty($objMailProperties->replyTo)) { $objMail->replyTo($objMailProperties->replyTo); } $objMail->subject = $objMailProperties->subject; if (!empty($objMailProperties->attachments)) { foreach ($objMailProperties->attachments as $strFile => $varParams) { $strContent = file_get_contents($varParams['file'], false); $objMail->attachFileFromString($strContent, $varParams['name'], $varParams['mime']); } } if (!empty($objMailProperties->messageText)) { $objMail->text = $objMailProperties->messageText; } if (!empty($objMailProperties->messageHtml)) { $objMail->html = $objMailProperties->messageHtml; } foreach ($objMailProperties->recipients as $recipient) { $objMail->sendTo($recipient); $blnInformationSent = true; } } } // Redirect after frontend editing if ($blnFEedit) { if (!empty($strRedirectTo)) { $strRed = preg_replace(array('/\\/' . $this->strFormdataDetailsKey . '\\/' . \Input::get($this->strFormdataDetailsKey) . '/i', '/' . $this->strFormdataDetailsKey . '=' . \Input::get($this->strFormdataDetailsKey) . '/i', '/act=edit/i'), array('', '', ''), $strUrl) . (!empty($strUrlParams) ? '?' . $strUrlParams : ''); \Controller::redirect($strRed); } } }
protected function createConfirmationEmail($arrSubmissionData) { $arrRecipient = deserialize($arrSubmissionData[$this->confirmationMailRecipientField]['value'], true); $objEmail = new \Email(); $objEmail->from = $GLOBALS['TL_ADMIN_EMAIL']; $objEmail->fromName = $GLOBALS['TL_ADMIN_NAME']; $objEmail->subject = \String::parseSimpleTokens($this->replaceInsertTags(FormHelper::replaceFormDataTags($this->confirmationMailSubject, $arrSubmissionData), false), $arrSubmissionData); if ($hasText = strlen($this->confirmationMailText) > 0) { $objEmail->text = \String::parseSimpleTokens($this->replaceInsertTags(FormHelper::replaceFormDataTags($this->confirmationMailText, $arrSubmissionData), false), $arrSubmissionData); // convert <br> to new line and strip tags, except links $objEmail->text = strip_tags(preg_replace('/<br(\\s+)?\\/?>/i', "\n", $objEmail->text), '<a>'); } if ($this->confirmationMailTemplate != '') { $objModel = \FilesModel::findByUuid($this->confirmationMailTemplate); if ($objModel !== null && is_file(TL_ROOT . '/' . $objModel->path)) { $objFile = new \File($objModel->path, true); $objEmail->html = \String::parseSimpleTokens($this->replaceInsertTags(FormHelper::replaceFormDataTags($objFile->getContent(), $arrSubmissionData), false), $arrSubmissionData); // if no text is set, convert html to text if (!$hasText) { $objHtml2Text = new \Html2Text\Html2Text($objEmail->html); $objEmail->text = $objHtml2Text->getText(); } } } // overwrite default from and if (!empty($this->confirmationMailSender)) { list($senderName, $sender) = \String::splitFriendlyEmail($this->confirmationMailSender); $objEmail->from = $this->replaceInsertTags(FormHelper::replaceFormDataTags($sender, $arrSubmissionData), false); $objEmail->fromName = $this->replaceInsertTags(FormHelper::replaceFormDataTags($senderName, $arrSubmissionData), false); } if ($this->confirmationMailAttachment != '') { $this->addAttachmentToEmail($objEmail, deserialize($this->confirmationMailAttachment)); } if ($this->sendConfirmationEmail($objEmail, $arrRecipient, $arrSubmissionData)) { if (is_array($arrRecipient)) { $arrRecipient = array_filter(array_unique($arrRecipient)); try { $objEmail->sendTo($arrRecipient); } catch (Exception $e) { log_message('Error sending submission email for entity ' . $this->strTable . ':' . $this->intId . ' to : ' . implode(',', $arrRecipient) . ' (' . $e . ')', $this->strLogFile); } } } }
/** * Generate CC or BCC recipients from comma separated string * @param string */ public static function compileRecipients($strRecipients, $arrTokens) { // Replaces tokens first so that tokens can contain a list of recipients. $strRecipients = static::recursiveReplaceTokensAndTags($strRecipients, $arrTokens, static::NO_TAGS | static::NO_BREAKS); $arrRecipients = array(); foreach ((array) trimsplit(',', $strRecipients) as $strAddress) { if ($strAddress != '') { $strAddress = static::recursiveReplaceTokensAndTags($strAddress, $arrTokens, static::NO_TAGS | static::NO_BREAKS); list($strName, $strEmail) = \String::splitFriendlyEmail($strAddress); // Address could become empty through invalid insert tag if ($strAddress == '' || !\Validator::isEmail($strEmail)) { continue; } $arrRecipients[] = $strAddress; } } return $arrRecipients; }
/** * Send confirmation mail * @param integer $intID ID of record * @return string */ public function mail($intID = false) { $blnSend = false; if (strlen(\Input::get('token')) && \Input::get('token') == $this->Session->get('fd_mail_send')) { $blnSend = true; } $strFormFilter = $this->strTable == 'tl_formdata' && strlen($this->strFormKey) ? $this->sqlFormFilter : ''; $table_alias = $this->strTable == 'tl_formdata' ? ' f' : ''; if ($intID) { $this->intId = $intID; } $return = ''; $this->values[] = $this->intId; $this->procedure[] = 'id=?'; $this->blnCreateNewVersion = false; // Get current record $sqlQuery = "SELECT * " . (!empty($this->arrSqlDetails) ? ', ' . implode(',', array_values($this->arrSqlDetails)) : '') . " FROM " . $this->strTable . $table_alias; $sqlWhere = " WHERE id=?"; if ($sqlWhere != '') { $sqlQuery .= $sqlWhere; } $objRow = \Database::getInstance()->prepare($sqlQuery)->limit(1)->execute($this->intId); // Redirect if there is no record with the given ID if ($objRow->numRows < 1) { $this->log('Could not load record "' . $this->strTable . '.id=' . $this->intId . '"', __METHOD__, TL_ERROR); \Controller::redirect('contao/main.php?act=error'); } $arrSubmitted = $objRow->fetchAssoc(); $arrFiles = array(); // Form $objForm = null; $intFormId = 0; if (!empty($GLOBALS['TL_DCA'][$this->strTable]['tl_formdata']['detailFields'])) { // Try to get the form foreach ($GLOBALS['TL_DCA'][$this->strTable]['tl_formdata']['detailFields'] as $strField) { if ($objForm !== null) { break; } if (!empty($GLOBALS['TL_DCA'][$this->strTable]['fields'][$strField]['f_id'])) { $intFormId = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$strField]['f_id']; $objForm = \FormModel::findByPk($intFormId); } } } if ($objForm == null) { $objForm = \FormModel::findOneBy('title', $arrSubmitted['form']); } if ($objForm == null) { $this->log('Could not load record "tl_form.id=' . $intFormId . '" / "tl_form.title=' . $arrSubmitted['form'] . '"', __METHOD__, TL_ERROR); \Controller::redirect('contao/main.php?act=error'); } $arrForm = $objForm->row(); $arrFormFields = $this->Formdata->getFormfieldsAsArray($arrForm['id']); if (empty($arrForm['confirmationMailSubject']) || empty($arrForm['confirmationMailText']) && empty($arrForm['confirmationMailTemplate'])) { return '<p class="tl_error">Can not send this form data record.<br>Missing "Subject", "Text of confirmation mail" or "HTML-template for confirmation mail"<br>Please check configuration of form in form generator.</p>'; } $this->loadDataContainer('tl_files'); $objMailProperties = new \stdClass(); $objMailProperties->subject = ''; $objMailProperties->sender = ''; $objMailProperties->senderName = ''; $objMailProperties->replyTo = ''; $objMailProperties->recipients = array(); $objMailProperties->messageText = ''; $objMailProperties->messageHtmlTmpl = ''; $objMailProperties->messageHtml = ''; $objMailProperties->attachments = array(); $objMailProperties->skipEmptyFields = false; $objMailProperties->skipEmptyFields = $arrForm['confirmationMailSkipEmpty'] ? true : false; $blnStoreOptionsValues = $arrForm['efgStoreValues'] ? true : false; // Set the sender as given in form configuration list($senderName, $sender) = \String::splitFriendlyEmail($arrForm['confirmationMailSender']); $objMailProperties->sender = $sender; $objMailProperties->senderName = $senderName; // Set the 'reply to' address, if given in form configuration if (!empty($arrForm['confirmationMailReplyto'])) { list($replyToName, $replyTo) = \String::splitFriendlyEmail($arrForm['confirmationMailReplyto']); $objMailProperties->replyTo = strlen($replyToName) ? $replyToName . ' <' . $replyTo . '>' : $replyTo; } // Set recipient(s) $recipientFieldName = $arrForm['confirmationMailRecipientField']; if (!empty($recipientFieldName) && !empty($arrSubmitted[$recipientFieldName])) { $varRecipient = $arrSubmitted[$recipientFieldName]; // handle efg option 'save options of values' for field types radio, select, checkbox if (in_array($arrFormFields[$recipientFieldName]['type'], array('radio', 'select', 'checkbox'))) { if (!$blnStoreOptionsValues) { $arrRecipient = $this->Formdata->prepareDatabaseValueForWidget($varRecipient, $arrFormFields[$recipientFieldName], false); if (!empty($arrRecipient)) { $varRecipient = implode(', ', $arrRecipient); } unset($arrRecipient); } } $strSep = isset($arrFormFields[$recipientFieldName]['eval']['csv']) ? $arrFormFields[$recipientFieldName]['eval']['csv'] : '|'; $varRecipient = str_replace($strSep, ',', $varRecipient); } if (strlen($varRecipient) || strlen($arrForm['confirmationMailRecipient'])) { $arrRecipient = array_merge(trimsplit(',', $varRecipient), trimsplit(',', $arrForm['confirmationMailRecipient'])); } if (\Input::get('recipient')) { $arrRecipient = trimsplit(',', \Input::get('recipient')); } if (is_array($arrRecipient)) { $strRecipient = implode(', ', $arrRecipient); // handle insert tag {{user::email}} in recipient fields if (!is_bool(strpos($strRecipient, "{{user::email}}")) && $arrSubmitted['fd_member'] > 0) { $objUser = \Database::getInstance()->prepare("SELECT `email` FROM `tl_member` WHERE id=?")->limit(1)->execute($arrSubmitted['fd_member']); $arrRecipient = array_map("str_replace", array_fill(0, count($arrRecipient), "{{user::email}}"), array_fill(0, count($arrRecipient), $objUser->email), $arrRecipient); } $arrRecipient = array_filter(array_unique($arrRecipient)); } $objMailProperties->recipients = $arrRecipient; // Check if we want custom attachments... (Thanks to Torben Schwellnus) if ($arrForm['addConfirmationMailAttachments']) { if ($arrForm['confirmationMailAttachments']) { $arrCustomAttachments = deserialize($arrForm['confirmationMailAttachments'], true); if (!empty($arrCustomAttachments)) { foreach ($arrCustomAttachments as $varFile) { $objFileModel = \FilesModel::findById($varFile); if ($objFileModel !== null) { $objFile = new \File($objFileModel->path, true); if ($objFile->size) { $objMailProperties->attachments[TL_ROOT . '/' . $objFile->path] = array('file' => TL_ROOT . '/' . $objFile->path, 'name' => $objFile->basename, 'mime' => $objFile->mime); } } } } } } $objMailProperties->subject = \String::decodeEntities($arrForm['confirmationMailSubject']); $objMailProperties->messageText = \String::decodeEntities($arrForm['confirmationMailText']); $objMailProperties->messageHtmlTmpl = $arrForm['confirmationMailTemplate']; // Replace Insert tags and conditional tags $objMailProperties = $this->Formdata->prepareMailData($objMailProperties, $arrSubmitted, $arrFiles, $arrForm, $arrFormFields); $objEmail = new \Email(); $objEmail->from = $objMailProperties->sender; if (!empty($objMailProperties->senderName)) { $objEmail->fromName = $objMailProperties->senderName; } $objEmail->subject = $objMailProperties->subject; if (!empty($objMailProperties->attachments)) { foreach ($objMailProperties->attachments as $strFile => $varParams) { $strContent = file_get_contents($varParams['file'], false); $objEmail->attachFileFromString($strContent, $varParams['name'], $varParams['mime']); } } if (!empty($objMailProperties->messageText)) { $objEmail->text = $objMailProperties->messageText; } if (!empty($objMailProperties->messageHtml)) { $objEmail->html = $objMailProperties->messageHtml; } // Send Mail if (strlen(\Input::get('token')) && \Input::get('token') == $this->Session->get('fd_mail_send')) { $this->Session->set('fd_mail_send', null); $blnSend = true; $blnConfirmationSent = false; if ($blnSend) { // Send e-mail if (!empty($objMailProperties->recipients)) { foreach ($objMailProperties->recipients as $recipient) { if (strlen($recipient)) { $recipient = str_replace(array('[', ']'), array('<', '>'), $recipient); $recipientName = ''; if (strpos($recipient, '<') > 0) { preg_match('/(.*)?<(\\S*)>/si', $recipient, $parts); $recipientName = trim($parts[1]); $recipient = strlen($recipientName) ? $recipientName . ' <' . $parts[2] . '>' : $parts[2]; } } $objEmail->sendTo($recipient); $blnConfirmationSent = true; \Message::addInfo(sprintf($GLOBALS['TL_LANG']['tl_formdata']['mail_sent'], str_replace(array('<', '>'), array('[', ']'), $recipient))); } } if ($blnConfirmationSent && isset($this->intId) && intval($this->intId) > 0) { $arrUpd = array('confirmationSent' => '1', 'confirmationDate' => time()); $res = \Database::getInstance()->prepare("UPDATE tl_formdata %s WHERE id=?")->set($arrUpd)->execute($this->intId); } } } $strToken = md5(uniqid('', true)); $this->Session->set('fd_mail_send', $strToken); $strHint = ''; if (strlen($objRow->confirmationSent)) { if (!$blnSend) { if (strlen($objRow->confirmationDate)) { $dateConfirmation = new \Date($objRow->confirmationDate); $strHint .= '<div class="tl_message"><p class="tl_info">' . sprintf($GLOBALS['TL_LANG']['tl_formdata']['confirmation_sent'], $dateConfirmation->date, $dateConfirmation->time) . '</p></div>'; } else { $strHint .= '<div class="tl_message"><p class="tl_info">' . sprintf($GLOBALS['TL_LANG']['tl_formdata']['confirmation_sent'], '-n/a-', '-n/a-') . '</p></div>'; } } } // Preview Mail $return = ' <div id="tl_buttons"> <a href="' . $this->getReferer(ENCODE_AMPERSANDS) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> <h2 class="sub_headline">' . $GLOBALS['TL_LANG']['tl_formdata']['mail'][0] . '</h2>' . \Message::generate() . $strHint . ' <form action="' . ampersand(\Environment::get('script'), ENCODE_AMPERSANDS) . '" id="tl_formdata_send" class="tl_form" method="get"> <div class="tl_formbody_edit fd_mail_send"> <input type="hidden" name="do" value="' . \Input::get('do') . '"> <input type="hidden" name="table" value="' . \Input::get('table') . '"> <input type="hidden" name="act" value="' . \Input::get('act') . '"> <input type="hidden" name="id" value="' . \Input::get('id') . '"> <input type="hidden" name="rt" value="' . REQUEST_TOKEN . '"> <input type="hidden" name="token" value="' . $strToken . '"> <table cellpadding="0" cellspacing="0" class="prev_header" summary=""> <tr class="row_0"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_formdata']['mail_sender'][0] . '</td> <td class="col_1">' . $objMailProperties->sender . '</td> </tr> <tr class="row_1"> <td class="col_0"><label for="ctrl_formdata_recipient">' . $GLOBALS['TL_LANG']['tl_formdata']['mail_recipient'][0] . '</label></td> <td class="col_1"><input name="recipient" type="ctrl_recipient" class="tl_text" value="' . implode(',', $objMailProperties->recipients) . '" ' . ($blnSend ? 'disabled="disabled"' : '') . '></td> </tr> <tr class="row_2"> <td class="col_0">' . $GLOBALS['TL_LANG']['tl_formdata']['mail_subject'][0] . '</td> <td class="col_1">' . $objMailProperties->subject . '</td> </tr>'; if (!empty($objMailProperties->attachments)) { $attachments = array(); foreach ($objMailProperties->attachments as $strFile => $arr) { $attachments[] = str_replace(TL_ROOT . '/', '', $strFile); } $return .= ' <tr class="row_3"> <td class="col_0" style="vertical-align:top">' . $GLOBALS['TL_LANG']['tl_formdata']['attachments'] . '</td> <td class="col_1">' . implode(',<br> ', $attachments) . '</td> </tr>'; } $return .= ' </table> <h3>' . $GLOBALS['TL_LANG']['tl_formdata']['mail_body_plaintext'][0] . '</h3> <div class="preview_plaintext"> ' . nl2br($objMailProperties->messageText) . ' </div>'; if (!empty($objMailProperties->messageHtml)) { $return .= ' <h3>' . $GLOBALS['TL_LANG']['tl_formdata']['mail_body_html'][0] . '</h3> <div class="preview_html"> ' . preg_replace(array('/.*?<body.*?>/si', '/<\\/body>.*$/si'), array('', ''), $objMailProperties->messageHtml) . ' </div>'; } $return .= ' </div>'; if (!$blnSend) { $return .= ' <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" id="send" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_formdata']['mail'][0]) . '"> </div> </div>'; } $return .= ' </form>'; return $return; }