File manager - Edit - /home/ferretapmx/public_html/Mail.tar
Back
MailerFactory.php 0000644 00000006335 15231065022 0010021 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Mail; use Joomla\CMS\Log\Log; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Default factory for creating mailer objects. * * @since 4.4.0 */ class MailerFactory implements MailerFactoryInterface { /** * The default configuration. * * @var Registry * @since 4.4.0 */ private $defaultConfiguration; /** * The MailerFactory constructor. * * @param Registry $defaultConfiguration The default configuration */ public function __construct(Registry $defaultConfiguration) { $this->defaultConfiguration = $defaultConfiguration; } /** * Method to get an instance of a mailer. If the passed settings are null, * then the mailer does use the internal configuration. * * @param ?Registry $settings The configuration * * @return MailerInterface * * @since 4.4.0 */ public function createMailer(?Registry $settings = null): MailerInterface { $configuration = new Registry($this->defaultConfiguration); if ($settings) { $configuration->merge($settings); } $mailer = new Mail((bool) $configuration->get('throw_exceptions', true)); $smtpauth = $configuration->get('smtpauth') == 0 ? null : 1; $smtpuser = $configuration->get('smtpuser'); $smtppass = $configuration->get('smtppass'); $smtphost = $configuration->get('smtphost'); $smtpsecure = $configuration->get('smtpsecure'); $smtpport = $configuration->get('smtpport'); $mailfrom = $configuration->get('mailfrom'); $fromname = $configuration->get('fromname'); $mailType = $configuration->get('mailer'); // Clean the email address $mailfrom = MailHelper::cleanLine($mailfrom); // Set default sender without Reply-to if the mailfrom is a valid address if (MailHelper::isEmailAddress($mailfrom)) { // Wrap in try/catch to catch Exception if it is throwing them try { // Check for a false return value if exception throwing is disabled if ($mailer->setFrom($mailfrom, MailHelper::cleanLine($fromname), false) === false) { Log::add(__METHOD__ . '() could not set the sender data.', Log::WARNING, 'mail'); } } catch (\Exception) { Log::add(__METHOD__ . '() could not set the sender data.', Log::WARNING, 'mail'); } } // Default mailer is to use PHP's mail function switch ($mailType) { case 'smtp': $mailer->useSmtp($smtpauth, $smtphost, $smtpuser, $smtppass, $smtpsecure, $smtpport); break; case 'sendmail': $mailer->isSendmail(); break; default: $mailer->isMail(); break; } return $mailer; } } MailerFactoryAwareInterface.php 0000644 00000001414 15231065022 0012613 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Mail; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Interface to be implemented by classes depending on a mailer factory. * * @since 4.4.0 */ interface MailerFactoryAwareInterface { /** * Set the mailer factory to use. * * @param ?MailerFactoryInterface $mailerFactory The mailer factory to use. * * @return void * * @since 4.4.0 */ public function setMailerFactory(?MailerFactoryInterface $mailerFactory = null): void; } MailTemplate.php 0000644 00000054002 15231065022 0007630 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2019 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Mail; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Event\Mail\BeforeRenderingMailTemplateEvent; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\LanguageFactoryInterface; use Joomla\CMS\Layout\FileLayout; use Joomla\CMS\Mail\Exception\MailDisabledException; use Joomla\Component\Mails\Administrator\Helper\MailsHelper; use Joomla\Database\ParameterType; use Joomla\Filesystem\File; use Joomla\Filesystem\Path; use Joomla\Registry\Registry; use PHPMailer\PHPMailer\Exception as phpmailerException; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Email Templating Class * * @since 4.0.0 */ class MailTemplate { /** * Mailer object to send the actual mail. * * @var \Joomla\CMS\Mail\Mail * @since 4.0.0 */ protected $mailer; /** * Identifier of the mail template. * * @var string * @since 4.0.0 */ protected $template_id; /** * Language of the mail template. * * @var string */ protected $language; /** * * @var string[] * @since 4.0.0 */ protected $data = []; /** * * @var string[] * @since 5.1.0 */ protected $plain_data = []; /** * * @var string[] * @since 5.1.3 */ protected $unsafe_tags = []; /** * * @var \stdClass[] * @since 4.0.0 */ protected $attachments = []; /** * List of recipients of the email * * @var \stdClass[] * @since 4.0.0 */ protected $recipients = []; /** * Reply To of the email * * @var \stdClass * @since 4.0.0 */ protected $replyto; /** * Layout mailtemplate options of the email * * @var string[] * @since 5.2.0 */ protected $layoutTemplateData = []; /** * The language factory * * @var LanguageFactoryInterface * @since 5.4.7 */ protected LanguageFactoryInterface $languageFactory; /** * Constructor for the mail templating class * * @param string $templateId Id of the mail template. * @param string $language Language of the template to use. * @param ?Mail $mailer Mail object to send the mail with. * * @since 4.0.0 */ public function __construct($templateId, $language, ?Mail $mailer = null, ?LanguageFactoryInterface $languageFactory = null) { $this->template_id = $templateId; $this->language = $language; if ($mailer) { $this->mailer = $mailer; } else { $this->mailer = Factory::getMailer(); } if ($languageFactory) { $this->languageFactory = $languageFactory; } else { $this->languageFactory = Factory::getContainer()->get(LanguageFactoryInterface::class); } } /** * Add an attachment to the mail * * @param string $name Filename of the attachment * @param string $file Either a filepath or filecontent * * @return void * * @since 4.0.0 */ public function addAttachment($name, $file) { $attachment = new \stdClass(); $attachment->name = $name; $attachment->file = $file; $this->attachments[] = $attachment; } /** * Adds recipients for this mail * * @param string $mail Mail address of the recipient * @param string $name Name of the recipient * @param string $type How should the recipient receive the mail? ('to', 'cc', 'bcc') * * @return void * * @since 4.0.0 */ public function addRecipient($mail, $name = null, $type = 'to') { $recipient = new \stdClass(); $recipient->mail = $mail; $recipient->name = $name ?? $mail; $recipient->type = $type; $this->recipients[] = $recipient; } /** * Set reply to for this mail * * @param string $mail Mail address to reply to * @param string $name Name * * @return void * * @since 4.0.0 */ public function setReplyTo($mail, $name = '') { $reply = new \stdClass(); $reply->mail = $mail; $reply->name = $name; $this->replyto = $reply; } /** * Add data to the html layout template * * @param array $data Associative array of strings for the layout * * @return void * * @since 5.2.0 */ public function addLayoutTemplateData($data) { $this->layoutTemplateData = array_merge($this->layoutTemplateData, $data); } /** * Add data to replace in the template * * @param array $data Associative array of strings to replace * @param bool $plain Only use the data for plain-text emails. * * @return void * * @since 4.0.0 */ public function addTemplateData($data, $plain = false) { if (!$plain) { $this->data = array_merge($this->data, $data); } else { $this->plain_data = array_merge($this->plain_data, $data); } } /** * Mark tags as unsafe to ensure escaping in HTML mails * * @param array $tags Tag names * * @return void * * @since 5.1.3 */ public function addUnsafeTags($tags) { $this->unsafe_tags = array_merge($this->unsafe_tags, array_map('strtoupper', $tags)); } /** * Render and send the mail * * @return boolean True on success * * @since 4.0.0 * @throws \Exception * @throws MailDisabledException * @throws phpmailerException */ public function send() { $config = ComponentHelper::getParams('com_mails'); $mail = static::getTemplate($this->template_id, $this->language); // If the Mail Template was not found in the db, we cannot send an email. if ($mail === null) { return false; } /** @var Registry $params */ $params = $mail->params; $app = Factory::getApplication(); $replyTo = $app->get('replyto', ''); $replyToName = $app->get('replytoname', ''); $language = $app->getLanguage(); if ($this->language && $this->language !== $language->getTag()) { $language = $this->languageFactory->createLanguage($this->language, $app->get('debug_lang')); MailsHelper::loadTranslationFiles($mail->extension, $language); } if ((int) $config->get('alternative_mailconfig', 0) === 1 && (int) $params->get('alternative_mailconfig', 0) === 1) { if ($this->mailer->Mailer === 'smtp' || $params->get('mailer') === 'smtp') { $smtpauth = ($params->get('smtpauth', $app->get('smtpauth')) == 0) ? null : 1; $smtpuser = $params->get('smtpuser', $app->get('smtpuser')); $smtppass = $params->get('smtppass', $app->get('smtppass')); $smtphost = $params->get('smtphost', $app->get('smtphost')); $smtpsecure = $params->get('smtpsecure', $app->get('smtpsecure')); $smtpport = $params->get('smtpport', $app->get('smtpport')); $this->mailer->useSmtp($smtpauth, $smtphost, $smtpuser, $smtppass, $smtpsecure, $smtpport); } if ($params->get('mailer') === 'sendmail') { $this->mailer->isSendmail(); } $mailfrom = $params->get('mailfrom', $app->get('mailfrom')); $fromname = $params->get('fromname', $app->get('fromname')); if (MailHelper::isEmailAddress($mailfrom)) { $this->mailer->setFrom(MailHelper::cleanLine($mailfrom), MailHelper::cleanLine($fromname), false); } $replyTo = $params->get('replyto', $replyTo); $replyToName = $params->get('replytoname', $replyToName); } $useLayout = $config->get('disable_htmllayout', '1'); if ((int) $config->get('alternative_mailconfig', 0) === 1) { $useLayout = $params->get('disable_htmllayout', $useLayout); } $app->getDispatcher()->dispatch('onMailBeforeRendering', new BeforeRenderingMailTemplateEvent( 'onMailBeforeRendering', ['templateId' => $this->template_id, 'subject' => $this] )); $subject = $this->replaceTags($language->_($mail->subject), $this->data); $this->mailer->setSubject($subject); $mailStyle = $config->get('mail_style', 'plaintext'); // Use the plain-text replacement data, if specified. $plainData = $this->plain_data ?: $this->data; $plainBody = $this->replaceTags($language->_($mail->body), $plainData); $htmlBody = $useLayout ? $language->_($mail->htmlbody) : $this->replaceTags($language->_($mail->htmlbody), $this->data, true); if ($mailStyle === 'plaintext' || $mailStyle === 'both') { // If the Plain template is empty try to convert the HTML template to a Plain text if (!$plainBody) { $plainBody = strip_tags(str_replace(['<br>', '<br />', '<br/>'], "\n", $this->replaceTags($htmlBody, $plainData))); } $this->mailer->setBody($plainBody); // Set alt body, use $mailer->Body directly because it was filtered by $mailer->setBody() if ($mailStyle === 'both') { $this->mailer->AltBody = $this->mailer->Body; } } if ($mailStyle === 'html' || $mailStyle === 'both') { $this->mailer->isHtml(true); // If HTML body is empty try to convert the Plain template to html if (!$htmlBody) { $htmlBody = nl2br($this->replaceTags($language->_($mail->body), $plainData, true), false); } if ($useLayout) { // Add additional data to the layout template $this->addLayoutTemplateData([ 'siteName' => $app->get('sitename'), 'lang' => substr($this->language, 0, 2), 'mail' => $mail, ]); $layout = $config->get('mail_htmllayout', 'mailtemplate'); $logo = (string) $config->get('mail_logofile', ''); // Check alternative mailconfig if ((int) $config->get('alternative_mailconfig', 0) === 1) { $layout = $params->get('htmllayout', $layout); $logo = $params->get('disable_logofile', 1) ? $logo : '' ; } // Add the logo to the mail as inline attachment if ($logo) { $logo = Path::check(JPATH_ROOT . '/' . HTMLHelper::_('cleanImageURL', $logo)->url); if (is_file(urldecode($logo))) { # Attach the logo as inline attachment $this->mailer->addAttachment($logo, 'site-logo', 'base64', mime_content_type($logo), 'inline'); // We need only the cid for attached logo file $this->addLayoutTemplateData(['logo' => 'site-logo']); } } // Check if layout is a template override $layoutParts = explode(':', $layout); if (\count($layoutParts) === 2) { $layout = $layoutParts[1]; } // Wrap the default Joomla mail template around the HTML body $layoutFile = new FileLayout('joomla.mail.' . $layout, null, ['client' => 'site']); // Set the template layout path if needed if (\count($layoutParts) === 2) { $layoutFile->addIncludePaths([ JPATH_SITE . '/templates/' . $layoutParts[0] . '/html/layouts', JPATH_SITE . '/templates/' . $layoutParts[0] . '/html/layouts/com_mails', ]); } $htmlBody = $layoutFile->render(['mail' => $htmlBody, 'extra' => $this->layoutTemplateData], null); $htmlBody = $this->replaceTags($language->_($htmlBody), $this->data); } $htmlBody = MailHelper::convertRelativeToAbsoluteUrls($htmlBody); $this->mailer->setBody($htmlBody); } if ($config->get('copy_mails') && $params->get('copyto')) { $this->mailer->addBcc($params->get('copyto')); } foreach ($this->recipients as $recipient) { switch ($recipient->type) { case 'cc': $this->mailer->addCc($recipient->mail, $recipient->name); break; case 'bcc': $this->mailer->addBcc($recipient->mail, $recipient->name); break; case 'to': default: $this->mailer->addAddress($recipient->mail, $recipient->name); } } if ($this->replyto) { $this->mailer->addReplyTo($this->replyto->mail, $this->replyto->name); } elseif ($replyTo) { $this->mailer->addReplyTo($replyTo, $replyToName); } if (trim($config->get('attachment_folder', ''))) { $folderPath = rtrim(Path::check(JPATH_ROOT . '/' . $config->get('attachment_folder')), \DIRECTORY_SEPARATOR); if ($folderPath && $folderPath !== Path::clean(JPATH_ROOT) && is_dir($folderPath)) { foreach ((array) json_decode($mail->attachments) as $attachment) { $filePath = Path::check($folderPath . '/' . $attachment->file); if (is_file($filePath)) { $this->mailer->addAttachment($filePath, $this->getAttachmentName($filePath, $attachment->name)); } } } } foreach ($this->attachments as $attachment) { if (is_file($attachment->file)) { $this->mailer->addAttachment($attachment->file, $this->getAttachmentName($attachment->file, $attachment->name)); } else { $this->mailer->addStringAttachment($attachment->file, $attachment->name); } } return $this->mailer->Send(); } /** * Replace tags with their values recursively * * @param string $text The template to process * @param array $tags An associative array to replace in the template * @param bool $isHtml Is the text an HTML text and requires escaping * * @return string Rendered mail template * * @since 4.0.0 */ protected function replaceTags($text, $tags, $isHtml = false) { foreach ($tags as $key => $value) { // If the value is NULL, replace with an empty string. NULL itself throws notices if (\is_null($value)) { $value = ''; } if (\is_array($value)) { $matches = []; $pregKey = preg_quote(strtoupper($key), '/'); if (preg_match_all('/{' . $pregKey . '}(.*?){\/' . $pregKey . '}/s', $text, $matches)) { foreach ($matches[0] as $i => $match) { $replacement = ''; foreach ($value as $name => $subvalue) { if (\is_array($subvalue) && $name == $matches[1][$i]) { $subvalue = implode("\n", $subvalue); // Escape if necessary if ($isHtml && \in_array(strtoupper($key), $this->unsafe_tags, true)) { $subvalue = htmlspecialchars($subvalue, ENT_QUOTES, 'UTF-8'); } $replacement .= implode("\n", $subvalue); } elseif (\is_array($subvalue)) { $replacement .= $this->replaceTags($matches[1][$i], $subvalue, $isHtml); } elseif (\is_string($subvalue) && $name == $matches[1][$i]) { // Escape if necessary if ($isHtml && \in_array(strtoupper($key), $this->unsafe_tags, true)) { $subvalue = htmlspecialchars($subvalue, ENT_QUOTES, 'UTF-8'); } $replacement .= $subvalue; } } $text = str_replace($match, $replacement, $text); } } } else { // Escape if necessary if ($isHtml && \in_array(strtoupper($key), $this->unsafe_tags, true)) { $value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); } $text = str_replace('{' . strtoupper($key) . '}', $value, $text); } } return $text; } /** * Get a specific mail template * * @param string $key Template identifier * @param string $language Language code of the template * * @return object|null An object with the data of the mail, or null if the template not found in the db. * * @since 4.0.0 */ public static function getTemplate($key, $language) { $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select('*') ->from($db->quoteName('#__mail_templates')) ->where($db->quoteName('template_id') . ' = :key') ->whereIn($db->quoteName('language'), ['', $language], ParameterType::STRING) ->order($db->quoteName('language') . ' DESC') ->bind(':key', $key); $db->setQuery($query); $mail = $db->loadObject(); if ($mail) { $mail->params = new Registry($mail->params); } return $mail; } /** * Insert a new mail template into the system * * @param string $key Mail template key * @param string $subject A default subject (normally a translatable string) * @param string $body A default body (normally a translatable string) * @param array $tags Associative array of tags to replace * @param string $htmlbody A default htmlbody (normally a translatable string) * * @return boolean True on success, false on failure * * @since 4.0.0 */ public static function createTemplate($key, $subject, $body, $tags, $htmlbody = '') { $db = Factory::getDbo(); $template = new \stdClass(); $template->template_id = $key; $template->language = ''; $template->subject = $subject; $template->body = $body; $template->htmlbody = $htmlbody; $template->extension = explode('.', $key, 2)[0] ?? ''; $template->attachments = ''; $params = new \stdClass(); $params->tags = (array) $tags; $template->params = json_encode($params); return $db->insertObject('#__mail_templates', $template); } /** * Update an existing mail template * * @param string $key Mail template key * @param string $subject A default subject (normally a translatable string) * @param string $body A default body (normally a translatable string) * @param array $tags Associative array of tags to replace * @param string $htmlbody A default htmlbody (normally a translatable string) * * @return boolean True on success, false on failure * * @since 4.0.0 */ public static function updateTemplate($key, $subject, $body, $tags, $htmlbody = '') { $db = Factory::getDbo(); $template = new \stdClass(); $template->template_id = $key; $template->language = ''; $template->subject = $subject; $template->body = $body; $template->htmlbody = $htmlbody; $params = new \stdClass(); $params->tags = (array) $tags; $template->params = json_encode($params); return $db->updateObject('#__mail_templates', $template, ['template_id', 'language']); } /** * Method to delete a mail template * * @param string $key The key of the mail template * * @return boolean True on success, false on failure * * @since 4.0.0 */ public static function deleteTemplate($key) { $db = Factory::getDbo(); $query = $db->getQuery(true); $query->delete($db->quoteName('#__mail_templates')) ->where($db->quoteName('template_id') . ' = :key') ->bind(':key', $key); $db->setQuery($query); return $db->execute(); } /** * Check and if necessary fix the file name of an attachment so that the attached file * has the same extension as the source file, and not a different file extension * * @param string $file Path to the file to be attached * @param string $name The file name to be used for the attachment * * @return string The corrected file name for the attachment * * @since 4.0.0 */ protected function getAttachmentName(string $file, string $name): string { // If no name is given, do not process it further if (!trim($name)) { return ''; } // Replace any placeholders. $name = $this->replaceTags($name, $this->data); // Get the file extension. $ext = File::getExt($file); // Strip off extension from $name and append extension of $file, if any return File::stripExt($name) . ($ext ? '.' . $ext : ''); } } MailerFactoryInterface.php 0000644 00000001546 15231065022 0011641 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Mail; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Interface defining a factory which can create mailer objects. * * @since 4.4.0 */ interface MailerFactoryInterface { /** * Method to get an instance of a mailer. If the passed settings are null, * then the mailer does use the internal configuration. * * @param ?Registry $settings The configuration * * @return MailerInterface * * @since 4.4.0 */ public function createMailer(?Registry $settings = null): MailerInterface; } MailerFactoryAwareTrait.php 0000644 00000002637 15231065022 0012006 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Mail; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Defines the trait for a MailerFactoryInterface aware class. * * @since 4.4.0 */ trait MailerFactoryAwareTrait { /** * MailerFactoryInterface * * @var MailerFactoryInterface * @since 4.4.0 */ private $mailerFactory; /** * Get the MailerFactoryInterface. * * @return MailerFactoryInterface * * @since 4.4.0 * @throws \UnexpectedValueException May be thrown if the MailerFactory has not been set. */ protected function getMailerFactory(): MailerFactoryInterface { if ($this->mailerFactory) { return $this->mailerFactory; } throw new \UnexpectedValueException('MailerFactory not set in ' . __CLASS__); } /** * Set the mailer factory to use. * * @param ?MailerFactoryInterface $mailerFactory The mailer factory to use. * * @return void * * @since 4.4.0 */ public function setMailerFactory(?MailerFactoryInterface $mailerFactory = null): void { $this->mailerFactory = $mailerFactory; } } MailerInterface.php 0000644 00000007137 15231065022 0010313 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Mail; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Provides a common interface to send emails with. * * @since 4.4.0 */ interface MailerInterface { /** * Send the mail. Throws an exception when something goes wrong. * * @return void * * @since 4.4.0 * * @throws \RuntimeException */ public function send(); /** * Set the email sender. * * @param string $fromEmail The Email address of the sender * @param string $name The name of the sender * * @return void * * @since 4.4.0 * * @throws \UnexpectedValueException if the sender is not a valid address */ public function setSender(string $fromEmail, string $name = ''); /** * Set the email subject. * * @param string $subject Subject of the email * * @return void * * @since 4.4.0 */ public function setSubject(string $subject); /** * Set the email body. * * @param string $content Body of the email * * @return void * * @since 4.4.0 */ public function setBody(string $content); /** * Add a recipient to the email. * * @param string $recipientEmail The email of the recipient * @param string $name The name of the recipient * * @return void * * @since 4.4.0 * * @throws \UnexpectedValueException if the recipient is not a valid address */ public function addRecipient(string $recipientEmail, string $name = ''); /** * Add a carbon copy recipient to the email. * * @param string $ccEmail The email of the CC recipient * @param string $name The name of the CC recipient * * @return void * * @since 4.4.0 * * @throws \UnexpectedValueException if the CC is not a valid address */ public function addCc(string $ccEmail, string $name = ''); /** * Add a blind carbon copy recipient to the email. * * @param string $bccEmail The email of the BCC recipient * @param string $name The name of the BCC recipient * * @return void * * @since 4.4.0 * * @throws \UnexpectedValueException if the BCC is not a valid address */ public function addBcc(string $bccEmail, string $name = ''); /** * Add file attachment to the email. * * @param string $data The data of the attachment * @param string $name The name of the attachment * @param string $encoding The encoding of the attachment * @param string $type The mime type of the attachment * * @return void * * @since 4.4.0 */ public function addAttachment(string $data, string $name = '', string $encoding = 'base64', string $type = 'application/octet-stream'); /** * Add Reply to email address to the email * * @param string $replyToEmail The email of the reply address * @param string $name The name of the reply address * * @return void * * @since 4.4.0 * * @throws \UnexpectedValueException if the replay to is not a valid address */ public function addReplyTo(string $replyToEmail, string $name = ''); } Exception/MailDisabledException.php 0000644 00000003436 15231065022 0013406 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Mail\Exception; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Exception class defining an error for disabled mail functionality. * * @since 4.0.0 */ final class MailDisabledException extends \RuntimeException { /** * Send Mail option is disabled by the user. * * @var string * @since 4.0.0 */ public const REASON_USER_DISABLED = 'user_disabled'; /** * Mail() function is not available on the system. * * @var string * @since 4.0.0 */ public const REASON_MAIL_FUNCTION_NOT_AVAILABLE = 'mail_function_not_available'; /** * Reason mail is disabled. * * @var string * @since 4.0.0 */ private $reason; /** * Constructor. * * @param string $reason The reason why mail is disabled. * @param string $message The Exception message to throw. * @param integer $code The Exception code. * @param ?\Throwable $previous The previous exception used for the exception chaining. * * @since 4.0.0 */ public function __construct(string $reason, string $message = '', int $code = 0, ?\Throwable $previous = null) { parent::__construct($message, $code, $previous); $this->reason = $reason; } /** * Method to return the reason why mail is disabled. * * @return string * * @since 4.0.0 */ public function getReason(): string { return $this->reason; } } Exception/.htaccess 0000555 00000000355 15231065022 0010300 0 ustar 00 <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>