File manager - Edit - /home/jardides/www/Jardi-design/j37/plugins/fabrik_form/email/email.php
Back
<?php /** * @package Joomla.Plugin * @subpackage Fabrik.form.email * @copyright Copyright (C) 2005-2016 Media A-Team, Inc. - All rights reserved. * @license GNU/GPL http://www.gnu.org/copyleft/gpl.html */ // No direct access defined('_JEXEC') or die('Restricted access'); // Require the abstract plugin class require_once COM_FABRIK_FRONTEND . '/models/plugin-form.php'; require_once COM_FABRIK_FRONTEND . '/helpers/pdf.php'; /** * Send email upon form submission * * @package Joomla.Plugin * @subpackage Fabrik.form.email * @since 3.0 */ class PlgFabrik_FormEmail extends PlgFabrik_Form { /** * Attachment files * * @var array */ protected $attachments = array(); /** * Attachment files to delete after use * * @var array */ protected $deleteAttachments = array(); /** * Posted form keys that we don't want to include in the message * This is basically the fileupload elements * * @var array */ protected $dontEmailKeys = null; /** * MOVED TO PLUGIN.PHP SHOULDPROCESS() * determines if a condition has been set and decides if condition is matched * * @param object $params * @return bool true if you should send the email, false stops sending of email */ /*function shouldSend(&$params) { }*/ /** * Run right at the end of the form processing * form needs to be set to record in database for this to hook to be called * * @return bool */ public function onAfterProcess() { $profiler = JProfiler::getInstance('Application'); JDEBUG ? $profiler->mark("email: start: onAfterProcess") : null; $params = $this->getParams(); $input = $this->app->input; jimport('joomla.mail.helper'); $w = new FabrikWorker; /** @var \FabrikFEModelForm $formModel */ $formModel = $this->getModel(); $emailTemplate = JPath::clean(JPATH_SITE . '/plugins/fabrik_form/email/tmpl/' . $params->get('email_template', '')); $this->data = $this->getProcessData(); /* $$$ hugh - moved this to here from above the previous line, 'cos it needs $this->data * check if condition exists and is met */ if ($this->alreadySent() || !$this->shouldProcess('email_conditon', null, $params)) { return true; } /** * Added option to run content plugins on message text. Note that rather than run it one time at the * end of the following code, after we have assembled all the various options in to a single $message, * it needs to be run separately on each type of content. This is because we do placeholder replacement * in various places, which will strip all {text} which doesn't match element names. */ $runContentPlugins = $params->get('email_run_content_plugins', '0') === '1'; $contentTemplate = $params->get('email_template_content'); $content = $contentTemplate != '' ? FabrikHelperHTML::getContentTemplate($contentTemplate, 'both', $runContentPlugins) : ''; // Always send as html as even text email can contain html from wysiwyg editors $htmlEmail = true; $messageTemplate = ''; if (JFile::exists($emailTemplate)) { $messageTemplate = JFile::getExt($emailTemplate) == 'php' ? $this->_getPHPTemplateEmail($emailTemplate) : $this ->_getTemplateEmail($emailTemplate); // $$$ hugh - added ability for PHP template to return false to abort, same as if 'condition' was was false if ($messageTemplate === false) { return true; } if ($runContentPlugins === true) { FabrikHelperHTML::runContentPlugins($messageTemplate, false); } $messageTemplate = str_replace('{content}', $content, $messageTemplate); } $messageText = $params->get('email_message_text', ''); if (!empty($messageText)) { if ($runContentPlugins === true) { FabrikHelperHTML::runContentPlugins($messageText, false); } $messageText = str_replace('{content}', $content, $messageText); $messageText = str_replace('{template}', $messageTemplate, $messageText); $messageText = $w->parseMessageForPlaceholder($messageText, $this->data, false); } if (!empty($messageText)) { $message = $messageText; } elseif (!empty($messageTemplate)) { $message = $messageTemplate; } elseif (!empty($content)) { $message = $content; } else { $message = $this->_getTextEmail(); } $this->addAttachments(); $cc = null; $bcc = null; // $$$ hugh - test stripslashes(), should be safe enough. $message = stripslashes($message); $editURL = COM_FABRIK_LIVESITE . 'index.php?option=com_' . $this->package . '&view=form&fabrik=' . $formModel->get('id') . '&rowid=' . $input->get('rowid', '', 'string'); $viewURL = COM_FABRIK_LIVESITE . 'index.php?option=com_' . $this->package . '&view=details&fabrik=' . $formModel->get('id') . '&rowid=' . $input->get('rowid', '', 'string'); $editLink = '<a href="' . $editURL . '">' . FText::_('EDIT') . '</a>'; $viewLink = '<a href="' . $viewURL . '">' . FText::_('VIEW') . '</a>'; $message = str_replace('{fabrik_editlink}', $editLink, $message); $message = str_replace('{fabrik_viewlink}', $viewLink, $message); $message = str_replace('{fabrik_editurl}', $editURL, $message); $message = str_replace('{fabrik_viewurl}', $viewURL, $message); FabrikPDFHelper::fullPaths($message); // $$$ rob if email_to is not a valid email address check the raw value to see if that is $emailTo = explode(',', $params->get('email_to')); foreach ($emailTo as &$emailKey) { $emailKey = $w->parseMessageForPlaceholder($emailKey, $this->data, false); // Can be in repeat group in which case returns "email1,email2" $emailKey = explode(',', $emailKey); foreach ($emailKey as &$key) { // $$$ rob added strstr test as no point trying to add raw suffix if not placeholder in $emailKey if (!FabrikWorker::isEmail($key) && trim($key) !== '' && strstr($key, '}')) { $key = explode('}', $key); if (substr($key[0], -4) !== '_raw') { $key = $key[0] . '_raw}'; } else { $key = $key[0] . '}'; } $key = $w->parseMessageForPlaceholder($key, $this->data, false); } } } // Reduce back down to single dimension array foreach ($emailTo as $i => $a) { foreach ($a as $v) { $emailTo[] = $v; } unset($emailTo[$i]); } $emailToEval = $params->get('email_to_eval', ''); if (!empty($emailToEval)) { $emailToEval = $w->parseMessageForPlaceholder($emailToEval, $this->data, false); $emailToEval = @eval($emailToEval); FabrikWorker::logEval($emailToEval, 'Caught exception on eval in email emailto : %s'); $emailToEval = explode(',', $emailToEval); $emailTo = array_merge($emailTo, $emailToEval); } @list($emailFrom, $emailFromName) = explode(":", $w->parseMessageForPlaceholder($params->get('email_from'), $this->data, false), 2); if (empty($emailFrom)) { $emailFrom = $this->config->get('mailfrom'); } if (empty($emailFromName)) { $emailFromName = $this->config->get('fromname', $emailFrom); } // Changes by JFQ @list($returnPath, $returnPathName) = explode(":", $w->parseMessageForPlaceholder($params->get('return_path'), $this->data, false), 2); if (empty($returnPath)) { $returnPath = null; } if (empty($returnPathName)) { $returnPathName = null; } // End changes $subject = $params->get('email_subject'); if ($subject == '') { $subject = $this->config->get('sitename') . " :: Email"; } $subject = preg_replace_callback('/&#([0-9a-fx]+);/mi', array($this, 'replace_num_entity'), $subject); $attachType = $params->get('email_attach_type', ''); $attachFileName = $this->config->get('tmp_path') . '/' . uniqid() . '.' . $attachType; $query = $this->_db->getQuery(true); $emailTo = array_map('trim', $emailTo); // Add any assigned groups to the to list $sendTo = (array) $params->get('to_group'); $groupEmails = (array) $this->getUsersInGroups($sendTo, $field = 'email'); $emailTo = array_merge($emailTo, $groupEmails); $emailTo = array_unique($emailTo); // Remove blank email addresses $emailTo = array_filter($emailTo); $dbEmailTo = array_map(array($this->_db, 'quote'), $emailTo); // Get an array of user ids from the email to array if (!empty($dbEmailTo)) { $query->select('id, email')->from('#__users')->where('email IN (' . implode(',', $dbEmailTo) . ')'); $this->_db->setQuery($query); $userIds = $this->_db->loadObjectList('email'); } else { $userIds = array(); } $customHeadersEval = $params->get('email_headers_eval', ''); $customHeaders = array(); if (!empty($customHeadersEval)) { $customHeadersEval = $w->parseMessageForPlaceholder($customHeadersEval, $this->data, false); $customHeaders = @eval($customHeadersEval); FabrikWorker::logEval($customHeadersEval, 'Caught exception on eval in email custom headers : %s'); } // Send email foreach ($emailTo as $email) { $email = strip_tags($email); if (FabrikWorker::isEmail($email)) { $thisAttachments = $this->attachments; $this->data['emailto'] = $email; $userId = array_key_exists($email, $userIds) ? $userIds[$email]->id : 0; $thisUser = JFactory::getUser($userId); $thisMessage = $w->parseMessageForPlaceholder($message, $this->data, true, false, $thisUser); $thisSubject = strip_tags($w->parseMessageForPlaceholder($subject, $this->data, true, false, $thisUser)); if (!empty($attachType)) { if (JFile::write($attachFileName, $thisMessage)) { $thisAttachments[] = $attachFileName; } else { $attachFileName = ''; } } $this->pdfAttachment($thisAttachments); /* * Sanity check for attachment files existing. Could have base folder paths for things * like file upload elements with no file. As of J! 3.5.1, the J! mailer tosses an exception * if files don't exist. We catch that in the sendMail helper, but remove non-files here anyway */ foreach ($thisAttachments as $aKey => $attachFile) { if (!JFile::exists($attachFile)) { unset($thisAttachments[$aKey]); } } JDEBUG ? $profiler->mark("email: sendMail start: " . $email) : null; $res = FabrikWorker::sendMail( $emailFrom, $emailFromName, $email, $thisSubject, $thisMessage, $htmlEmail, $cc, $bcc, $thisAttachments, $returnPath, $returnPathName, $customHeaders ); JDEBUG ? $profiler->mark("email: sendMail end: " . $email) : null; /* * $$$ hugh - added some error reporting, but not sure if 'invalid address' is the appropriate message, * may need to add a generic "there was an error sending the email" message */ if ($res !== true) { $this->app->enqueueMessage(JText::sprintf('PLG_FORM_EMAIL_DID_NOT_SEND_EMAIL', $email), 'notice'); } if (JFile::exists($attachFileName)) { JFile::delete($attachFileName); } } else { $this->app->enqueueMessage(JText::sprintf('PLG_FORM_EMAIL_DID_NOT_SEND_EMAIL_INVALID_ADDRESS', $email), 'notice'); } } foreach($this->deleteAttachments as $attachment) { if (JFile::exists($attachment)) { JFile::delete($attachment); } } $this->updateRow(); JDEBUG ? $profiler->mark("email: end: onAfterProcess") : null; return true; } /** * Check to see if there is an "update field" specified, and if it is already non-zero * * @return bool */ protected function alreadySent() { $params = $this->getParams(); $updateField = $params->get('email_update_field'); if (!empty($updateField)) { $updateField .= '_raw'; $updateEl = FabrikString::safeColNameToArrayKey($updateField); $updateVal = FArrayHelper::getValue($this->data, $updateEl, ''); $updateVal = is_array($updateVal) ? $updateVal[0] : $updateVal; return !empty($updateVal); } return false; } /** * Attach the details view as a PDF to the email * * @param array &$thisAttachments Attachments * * @throws RuntimeException * * @return void */ protected function pdfAttachment(&$thisAttachments) { $params = $this->getParams(); if ($params->get('attach_pdf', 0) == 0) { return; } /** @var FabrikFEModelForm $model */ $model = $this->getModel(); $model->setRowId($this->data['rowid']); $document = JFactory::getDocument(); $docType = $document->getType(); $document->setType('pdf'); $input = $this->app->input; $orig['details'] = $input->get('view'); $orig['format'] = $input->get('format'); $input->set('view', 'details'); $input->set('format', 'pdf'); // set editable false so things like getFormCss() pick up the detail, not form, CSS $model->setEditable(false); // Ensure the package is set to fabrik $prevUserState = $this->app->getUserState('com_fabrik.package'); $this->app->setUserState('com_fabrik.package', 'fabrik'); try { $model->getFormCss(); foreach ($document->_styleSheets as $url => $ss) { if (!strstr($url, COM_FABRIK_LIVESITE)) { $url = COM_FABRIK_LIVESITE . $url; } $url = htmlspecialchars_decode($url); $formCss[] = file_get_contents($url); } // Require files and set up DOM pdf require_once JPATH_SITE . '/components/com_fabrik/helpers/pdf.php'; require_once JPATH_SITE . '/components/com_fabrik/controllers/details.php'; FabrikPDFHelper::iniDomPdf(); $domPdf = new DOMPDF; $size = strtoupper($params->get('pdf_size', 'A4')); $orientation = $params->get('pdf_orientation', 'portrait'); $domPdf->set_paper($size, $orientation); $controller = new FabrikControllerDetails; /** * $$$ hugh - stuff our model in there, with already formatted data, so it doesn't get rendered * all over again by the view, with unformatted data. Should probably use a setModel() method * here instead of poking in to the _model, but I don't think there is a setModel for controllers? */ $controller->_model = $model; /** * Unfortunately, we need to reload the data, so it's in the right format. Can't use the * submitted data. "One of these days" we need to have a serious look at normalizing the data formats, * so submitted data is in the same format (once processed) as data read from the database. */ $controller->_model->data = $this->model->getData(); // Store in output buffer ob_start(); $controller->display(); $html = ob_get_contents(); ob_end_clean(); if (!empty($formCss)) { $html = "<style>\n" . implode("\n", $formCss) . "</style>\n" . $html; } // Load the HTML into DOMPdf and render it. // $$$trob: convert as in libraries\joomla\document\pdf\pdf.php $html = mb_convert_encoding($html,'HTML-ENTITIES','UTF-8'); $domPdf->load_html($html); $domPdf->render(); // Store the file in the tmp folder so it can be attached $layout = FabrikHelperHTML::getLayout('form.fabrik-pdf-title'); $displayData = new stdClass; $displayData->doc = $document; $displayData->model = $model; $fileName = $layout->render($displayData); $file = $this->config->get('tmp_path') . '/' . JStringNormalise::toDashSeparated($fileName) . '.pdf'; $pdf = $domPdf->output(); if (JFile::write($file, $pdf)) { $thisAttachments[] = $file; } else { throw new RuntimeException('Could not write PDF file to tmp folder'); } } catch (Exception $e) { $this->app->enqueueMessage($e->getMessage(), 'error'); } // set back to editable $model->setEditable(true); // Set the package back to what it was before rendering the module $this->app->setUserState('com_fabrik.package', $prevUserState); // Reset input foreach ($orig as $key => $val) { $input->set($key, $val); } // Reset document type $document->setType($docType); } /** * Use a php template for advanced email templates, particularly for forms with repeat group data * * @param string $tmpl Path to template * * @return string email message */ protected function _getPHPTemplateEmail($tmpl) { $emailData = $this->data; $formModel = $this->getModel(); // Start capturing output into a buffer ob_start(); $result = require $tmpl; $message = ob_get_contents(); ob_end_clean(); if ($result === false) { return false; } return $message; } /** * Add attachments to the email * * @return void */ protected function addAttachments() { $params = $this->getParams(); $data = $this->getProcessData(); /** @var FabrikFEModelForm $formModel */ $formModel = $this->getModel(); $groups = $formModel->getGroupsHiarachy(); foreach ($groups as $groupModel) { $elementModels = $groupModel->getPublishedElements(); foreach ($elementModels as $elementModel) { $elName = $elementModel->getFullName(true, false); if (array_key_exists($elName, $this->data)) { if (method_exists($elementModel, 'addEmailAttachement')) { if (array_key_exists($elName . '_raw', $data)) { $val = $data[$elName . '_raw']; } else { $val = $data[$elName]; } if (is_array($val)) { if (is_array(current($val))) { // Can't implode multi dimensional arrays $val = json_encode($val); $val = FabrikWorker::JSONtoData($val, true); } } else { $val = array($val); } foreach ($val as $v) { $file = $elementModel->addEmailAttachement($v); if ($file !== false) { $this->attachments[] = $file; if ($elementModel->shouldDeleteEmailAttachment($v)) { $this->deleteAttachments[] = $file; } } } } } } } // $$$ hugh - added an optional eval for adding attachments. // Eval'd code should just return an array of file paths which we merge with $this->attachments[] $w = new FabrikWorker; $emailAttachEval = $w->parseMessageForPlaceholder($params->get('email_attach_eval', ''), $this->data, false); if (!empty($emailAttachEval)) { $email_attach_array = @eval($emailAttachEval); FabrikWorker::logEval($email_attach_array, 'Caught exception on eval in email email_attach_eval : %s'); if (!empty($email_attach_array)) { $this->attachments = array_merge($this->attachments, $email_attach_array); } } } /** * Get an array of keys we don't want to email to the user * * @return array */ protected function getDontEmailKeys() { if (is_null($this->dontEmailKeys)) { $this->dontEmailKeys = array(); foreach ($_FILES as $key => $file) { $this->dontEmailKeys[] = $key; } } return $this->dontEmailKeys; } /** * Template email handling routine, called if email template specified * * @param string $emailTemplate path to template * * @return string email message */ protected function _getTemplateEmail($emailTemplate) { return file_get_contents($emailTemplate); } /** * Get content item template * DEPRECATED use FabrikHelperHTML::getContentTemplate() instead * * @param int $contentTemplate Joomla article ID to load * * @return string content item html (translated with Joomfish if installed) */ protected function _getContentTemplate($contentTemplate) { if ($this->app->isAdmin()) { $query = $this->_db->getQuery(true); $query->select('introtext, ' . $this->_db->qn('fulltext'))->from('#__content')->where('id = ' . (int) $contentTemplate); $this->_db->setQuery($query); $res = $this->_db->loadObject(); } else { JModelLegacy::addIncludePath(COM_FABRIK_BASE . 'components/com_content/models'); $articleModel = JModelLegacy::getInstance('Article', 'ContentModel'); $res = $articleModel->getItem($contentTemplate); } return $res->introtext . ' ' . $res->fulltext; } /** * Default email handling routine, called if no email template specified * * @return string email message */ protected function _getTextEmail() { $data = $this->getProcessData(); $ignore = $this->getDontEmailKeys(); $message = ''; /** @var FabrikFEModelForm $formModel */ $formModel = $this->getModel(); $groupModels = $formModel->getGroupsHiarachy(); foreach ($groupModels as &$groupModel) { $elementModels = $groupModel->getPublishedElements(); foreach ($elementModels as &$elementModel) { $element = $elementModel->getElement(); // @TODO - how about adding a 'renderEmail()' method to element model, so specific element types can render themselves? $key = (!array_key_exists($element->name, $data)) ? $elementModel->getFullName(true, false) : $element->name; if (!in_array($key, $ignore)) { $val = ''; if (is_array(FArrayHelper::getValue($data, $key))) { // Repeat group data foreach ($data[$key] as $k => $v) { if (is_array($v)) { $val = implode(", ", $v); } $val .= count($data[$key]) == 1 ? ": $v<br />" : ($k++) . ": $v<br />"; } } else { $val = FArrayHelper::getValue($data, $key); } $val = FabrikString::rtrimword($val, "<br />"); $val = stripslashes($val); // Set $val to default value if empty if ($val == '') { $val = " - "; } // Don't add a second ":" $label = trim(strip_tags($element->label)); $message .= $label; if (strlen($label) != 0 && JString::strpos($label, ':', JString::strlen($label) - 1) === false) { $message .= ':'; } $message .= "<br />" . $val . "<br /><br />"; } } } $message = FText::_('Email from') . ' ' . $this->config->get('sitename') . '<br />' . FText::_('Message') . ':' . "<br />===================================<br />" . "<br />" . stripslashes($message); return $message; } /** * Update row */ private function updateRow() { $params = $this->getParams(); $updateField = $params->get('email_update_field'); $rowid = $this->data['rowid']; if (!empty($updateField) && !empty($rowid)) { $this->getModel()->getListModel()->updateRow($rowid, $updateField, '1'); } } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0 |
proxy
|
phpinfo
|
Settings