ProShell v2.0
Dashboard
Server Info
Server: 158.106.128.192
PHP: 8.2.33
home
planet5
public_html
bansibaba.com
2026-09-16 22:19:08
Editing: Mail.php
Cancel
Save Changes
<?php /** * E-Mail sending class for aMember. Changes: * - type of message urgency - to queue handling * @package Am_Mail */ class Am_Mail extends Zend_Mail { const REGULAR = 10; const ADMIN_REQUESTED = 20; const USER_REQUESTED = 30; protected $periodic = self::REGULAR; const PRIORITY_HIGH = 9; const PRIORITY_MEDIUM = 5; const PRIORITY_LOW = 0; protected $priority = null; const LINK_USER = 1; protected $addUnsubscribeLink = false; const UNSUBSCRIBE_HTML = ' <br /> <font color="gray">To unsubscribe from our periodic e-mail messages, please click the following <a href="%link%">link</a></font> <br /> '; const UNSUBSCRIBE_TXT = ' ------------------------------------------------------------------- To unsubscribe from our periodic e-mail messages, please click the following link: %link% ------------------------------------------------------------------- '; public function __construct($charset = 'utf-8') { parent::__construct($charset); } public function setPeriodic($periodic){ $this->periodic = $periodic ; return $this; } public function getPeriodic($periodic){ return $this->periodic; } /** Should the e-mail be sent immediately, or it can be put to queue ? */ public function isInstant(){ return $this->periodic == self::USER_REQUESTED; } /** @return int calculate from periodic+priority, bigger will stay higher in the queue and will be set faster */ public function getPriority(){ return (int)$this->priority + (int)$this->periodic;} /** Set mail order in the queue, by default it will be set based on "periodic" */ public function setPriority($priority){ $this->priority = $priority; return $this; } /** * Add unsubscibe link of given type (see class constants) * This must be called before adding e-mail body * @param int $type */ public function addUnsubscribeLink($type = self::LINK_USER){ if ($this->_bodyText || $this->_bodyHtml) throw new Am_Exception_InternalError("Body is already added, could not do " . __METHOD__); $this->addUnsubscribeLink = $type; } public function clearUnsubscribeLink(){ if ($this->_bodyText || $this->_bodyHtml) throw new Am_Exception_InternalError("Body is already added, could not do " . __METHOD__); $this->addUnsubscribeLink = false; } /** * @param string $content - will be modified * @param bool $isHtml * @return null */ protected function _addUnsubscribeLink(& $content, $isHtml){ if (!$this->addUnsubscribeLink) return ; if (Am_Di::getInstance()->config->get('disable_unsubscribe_link')) return; //disabled at all $e = @$this->_to[0]; if ($e=="") { trigger_error("E-Mail address is empty in " . __METHOD__.", did you call addUnsubscribeLink before adding receipients?", E_USER_WARNING); return; // no email address } $link = Am_Mail::getUnsubscribeLink($e, $this->addUnsubscribeLink); if ($isHtml) $out = Am_Di::getInstance()->config->get('unsubscribe_html', Am_Mail::UNSUBSCRIBE_HTML); else $out = Am_Di::getInstance()->config->get('unsubscribe_txt', Am_Mail::UNSUBSCRIBE_TXT); $out = "\r\n" . str_replace('%link%', $isHtml ? Am_Controller::escape($link) : $link, $out); if (!$isHtml) { $content .= "\r\n" . $out; } else { $content = str_ireplace('</body>', $out . '</body>', $content, $replaced); if (!$replaced) $content .= $out; } } static function getUnsubscribeLink($email, $type = self::LINK_USER) { $link = ROOT_SURL; $sign = Am_Di::getInstance()->app->hash(Am_Di::getInstance()->app->getSiteKey() . $email . 'MAIL-USER', 10); $link .= sprintf('/unsubscribe?e=%s&s=%s', urlencode($email), $sign); return $link; } static function validateUnsubscribeLink($email, $sign, $type = self::LINK_USER) { return $sign === Am_Di::getInstance()->app->hash(Am_Di::getInstance()->app->getSiteKey() . $email . 'MAIL-USER', 10); } public function setBodyHtml($html, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE) { $this->_addUnsubscribeLink($html, true); parent::setBodyHtml($html, $charset, $encoding); } public function setBodyText($txt, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE) { $this->_addUnsubscribeLink($txt, false); parent::setBodyText($txt, $charset, $encoding); } public function send($transport = null) { return parent::send($transport); } /** * Store itself into a string for later quick loading * Attachments (aka parts) must be handled separately * @param array parts are Am_Mime_Part objects to be saved separately * @return string */ public function serialize(array & $parts){ $parts = $this->_parts; foreach ($parts as $p) { if ($p instanceof Am_Mime_Part) { } } $ret = serialize($this); $this->_parts = $parts; } public function serialzeAttachments(){ $ret = array(); foreach ($this->_parts as $part) { $part = new Zend_Mime_Part(); } } /** * Restore an Am_Mail object from a string * Attachments must be restored separately */ public static function unserialize($string){ return unserialize($string); } static function initDefaults() { self::setDefaultFrom( Am_Di::getInstance()->config->get('admin_email_from', Am_Di::getInstance()->config->get('admin_email')), Am_Di::getInstance()->config->get('admin_email_name', Am_Di::getInstance()->config->get('site_title'))); self::setDefaultTransport(Am_Mail_Queue::getInstance()); } public function createAttachment($body, $mimeType = Zend_Mime::TYPE_OCTETSTREAM, $disposition = Zend_Mime::DISPOSITION_ATTACHMENT, $encoding = Zend_Mime::ENCODING_BASE64, $filename = null) { $mp = new Am_Mime_Part($body); // it was only the change $mp->encoding = $encoding; $mp->type = $mimeType; $mp->disposition = $disposition; $mp->filename = $filename; $this->addAttachment($mp); return $mp; } /** * Set message To: admin * @return Am_Mail */ public function toAdmin(){ $this->clearRecipients(); $this->addTo(Am_Di::getInstance()->config->get('admin_email'), Am_Di::getInstance()->config->get('site_title') . ' Admin'); if (Am_Di::getInstance()->config->get('copy_admin_email')) foreach (preg_split("/[,;]/",Am_Di::getInstance()->config->get('copy_admin_email')) as $email) if ($email) $this->addBcc($email); return $this; } } /** * Just to satisfy Zend_Mail_Transport_Abstract needs * @internal * @package Am_Mail */ class Am_Mail_Saved { public $from; public $subject; public $recipients; function getFrom(){ return $this->from; } function getSubject(){ return $this->subject; } function getRecipients(){ return $this->recipients; } function getReturnPath(){ return $this->from; } } /** * @package Am_Mail * @todo put into a separate file for lazy-loading */ class Am_Mail_Transport_Smtp extends Zend_Mail_Transport_Smtp { function sendFromSaved($from, $recipients, $body, array $headers, $subject){ $this->_mail = new Am_Mail_Saved; $this->_mail->from = $from; $this->_mail->subject = $subject; $this->_mail->recipients = split(',', $recipients); $this->recipients = $recipients; $this->body = $body; $this->_prepareHeaders($headers); $this->_sendMail(); } } /** * @package Am_Mail * @todo put into a separate file for lazy-loading */ class Am_Mail_Transport_Sendmail extends Zend_Mail_Transport_Sendmail { function sendFromSaved($from, $recipients, $body, array $headers, $subject){ $this->_mail = new Am_Mail_Saved; $this->_mail->from = $from; $this->_mail->subject = $subject; $this->recipients = $recipients; $this->body = $body; $this->_prepareHeaders($headers); $this->_sendMail(); } } /** * Do not send any e-mails * @package Am_Mail */ class Am_Mail_Transport_Null extends Zend_Mail_Transport_Abstract { protected function _sendMail() { // do nothing } function sendFromSaved($from, $recipients, $body, array $headers, $subject) { // do nothing } } /** * This is a proxy e-mail transport, it does the following: * - initializes real transport when necessary using Am_Di::getInstance()->config->get() values * - saves e-mail messages to log when enabled * - puts not regular messages to queue instead of sending when enabled * @package Am_Mail */ class Am_Mail_Queue extends Zend_Mail_Transport_Abstract { const QUEUE_DISABLED = -1; const QUEUE_OK = 1; const QUEUE_ONLY_INSTANT = 2; const QUEUE_FULL = 3; /** @var Zend_Mail_Transport_Abstract */ protected $transport; protected $queueEnabled = false; /** @var int seconds */ protected $queuePeriod; /** @var int limit of emails in $queuePeriod minutes */ protected $queueLimit; /** @var int limit of periodical e-mails per hour * (automatically set to 80% @see $queueLimit) * to keep window for urgent emails like password * requests */ protected $queuePeriodicLimit; /** @var int days to store sent messages * even if that is null, aMember can anyway * store messages for queuing, it will then * be deleted automatically after 14 days if not delivered */ protected $logDays; /** * How many messages can we send in this period? This is set * by @see getQueueStatus * @var int */ protected $leftMessagesToSend = null; static protected $instance; /** * Singleton * @return Am_Mail_Queue */ static public function getInstance(){ if (self::$instance == null) self::$instance = new self(); return self::$instance; } public function __construct() { $this->_readConfig(); $di = Am_Di::getInstance(); if (APPLICATION_ENV == 'demo' || ($di->config->get('email_method') == 'disabled')) { $this->setTransport(new Am_Mail_Transport_Null); } elseif ($di->config->get('email_method') == 'smtp') { $host = $di->config->get('smtp_host'); $config = array( 'port' => $di->config->get('smtp_port', 25), 'ssl' => $di->config->get('smtp_security'), ); if ($di->config->get('smtp_user') && $di->config->get('smtp_pass')){ $config['username'] = $di->config->get('smtp_user'); $config['password'] = $di->config->get('smtp_pass'); $config['auth'] = 'login'; $config['ssl'] = $di->config->get('smtp_security'); } $this->setTransport(new Am_Mail_Transport_Smtp($host, $config)); } elseif ($di->config->get('email_method') == 'ses') { $config = array( 'accessKey' => $di->config->get('ses_id', 25), 'privateKey' => $di->config->get('ses_key'), ); $this->setTransport(new Am_Mail_Transport_Ses($config)); } else { $this->setTransport(new Am_Mail_Transport_Sendmail); } } function setTransport(Zend_Mail_Transport_Abstract $transport){ $this->transport = $transport; } function _readConfig(){ if (Am_Di::getInstance()->config->get('email_queue_enabled')) { $this->queueEnabled = true; $this->queuePeriod = Am_Di::getInstance()->config->get('email_queue_period', 3600); if ($this->queuePeriod <= 600){ throw new Am_Exception_InternalError("email_queue_period set to invalid value [{$this->queuePeriod}]"); } $this->queueLimit = Am_Di::getInstance()->config->get('email_queue_limit', 100); $this->queuePeriodicLimit = (int)$this->queueLimit * 80 / 100; } if (Am_Di::getInstance()->config->get('email_log_days') > 0) $this->setLogDays(Am_Di::getInstance()->config->get('email_log_days', 7)); } public function logEnabled(){ return $this->logDays > 0; } public function setLogDays($days){ $this->logDays = $days > 0 ? (int)$days : 0; } /** * Send message or put it queue if necessary */ public function send(Zend_Mail $mail) { if (!$mail instanceof Am_Mail) { trigger_error(__METHOD__ . ' should get Am_Mail, not Zend_Mail', E_USER_NOTICE); $isInstant = true; } else { $isInstant = $mail->isInstant(); } $status = $this->getQueueStatus(); $sent = null; $exception = null; if (in_array($status, array(self::QUEUE_DISABLED, self::QUEUE_OK)) || (($status==self::QUEUE_ONLY_INSTANT) && $isInstant)) { try { $this->transport->send($mail); $sent = Am_Di::getInstance()->time; // workaround for memory overusage if ($this->transport instanceof Zend_Mail_Transport_Smtp) $this->transport->getConnection()->resetLog(); // end of workaround } catch (Zend_Mail_Exception $e) { $exception = $e; } } if ($status != self::QUEUE_DISABLED || $this->logEnabled()) $this->addToQueue($mail, $sent); if ($exception) throw $exception; // re-raise } /** * Put message to queue instead of sending it */ protected function _sendMail() { if (defined('AM_FB_ENABLED')){ fb(array('header'=>$this->header, 'body'=>$this->body), 'E-Mail'); } } /** * Just save headers as it passed to * @param mixed $headers */ protected function _prepareHeaders($headers) { $this->headers = $headers; } /** * Save e-mail to mail_queue table * @param Am_Mail $mail * @param int $sent timestamp * @return int inserted record id */ public function addToQueue(Am_Mail $mail, $sent = null) { parent::send($mail); $vals = array( 'from' => $mail->getFrom(), 'recipients' => implode(',',$mail->getRecipients()), 'count_recipients' => count($mail->getRecipients()), 'subject' => $mail->getSubject(), 'priority' => $mail->getPriority(), 'body' => $this->body, 'headers' => serialize($this->headers), 'added' => Am_Di::getInstance()->time, 'sent' => $sent ? $sent : null, ); Am_Di::getInstance()->db->query("INSERT INTO ?_mail_queue SET ?a", $vals); return Am_Di::getInstance()->db->selectCell("SELECT LAST_INSERT_ID()"); } /** * Send message to transport from queue * @param array $row as retreived from database */ public function _sendSavedMessage(array & $row) { try { $ret = $this->transport->sendFromSaved($row['from'], $row['recipients'], $row['body'], unserialize($row['headers']), $row['subject']); $row['sent'] = Am_Di::getInstance()->time; Am_Di::getInstance()->db->query("UPDATE ?_mail_queue SET sent=?d WHERE queue_id=?d", $row['sent'], $row['queue_id']); } catch (Zend_Mail_Exception $e) { Am_Di::getInstance()->errorLogTable->logException($e); $row['failures']++; if ($row['failures'] >= 3) { //// deleting message on 3-rd failure Am_Di::getInstance()->db->query("DELETE FROM ?_mail_queue WHERE queue_id=?d", $row['queue_id']); } else { // save failure Am_Di::getInstance()->db->query("UPDATE ?_mail_queue SET failures=failures+1, last_error=? WHERE queue_id=?d", $e->getMessage(), $row['queue_id']); } } } /** * Check if there are messages in queue, and sending is allowed, * then send */ public function sendFromQueue(){ if (!$this->queueEnabled) return; if ($this->getQueueStatus() != self::QUEUE_OK) return; // do{ $sent = 0; $q = Am_Di::getInstance()->db->queryResultOnly( "SELECT * FROM ?_mail_queue WHERE sent IS NULL ORDER BY priority DESC, added, rand() limit 10" ); while ($row = Am_Di::getInstance()->db->fetchRow($q)) { if (!in_array($this->getQueueStatus(), array(self::QUEUE_OK, self::QUEUE_DISABLED))) return; $this->_sendSavedMessage($row); $sent++; } } while ($sent); } public function getQueueStatus(){ if (!$this->queueEnabled) return self::QUEUE_DISABLED; $sentLastPeriod = Am_Di::getInstance()->db->selectCell("SELECT SUM(count_recipients) FROM ?_mail_queue WHERE sent >= ?d", Am_Di::getInstance()->time - $this->queuePeriod); $this->leftMessagesToSend = max(0, $this->queuePeriodicLimit - $sentLastPeriod); if ($sentLastPeriod < $this->queuePeriodicLimit) return self::QUEUE_OK; elseif ($sentLastPeriod < $this->queueLimit) return self::QUEUE_ONLY_INSTANT; else return self::QUEUE_FULL; } /** * Remove old e-mail messages from the queue */ function cleanUp() { $days = (int)Am_Di::getInstance()->config->get('email_log_days', 0); if (!$days) return; Am_Di::getInstance()->db->query("DELETE FROM ?_mail_queue WHERE added <= ?d", Am_Di::getInstance()->time - 3600*24*$days); } } /** * @package Am_Mail * @internal */ class Am_Mime_Part extends Zend_Mime_Part { protected $_streamPath = null; // get this info for serialization function serialize(){ } function unserialize(){ } } /** * Amazon Simple Email Service mail transport * * Integration between Zend Framework and Amazon Simple Email Service * * @package Am_Mail * @license http://framework.zend.com/license/new-bsd New BSD License * @author Alex Scott <alex@cgi-central.net> * * Class is based on Chistopher Valles work Christopher Valles <info@christophervalles.com> * https://github.com/christophervalles/Amazon-SES-Zend-Mail-Transport * main change is usage of Am_HttpClient instead of Zend_Http_Client */ class Am_Mail_Transport_Ses extends Zend_Mail_Transport_Abstract { /** * Template of the webservice body request * * @var string */ protected $_bodyRequestTemplate = 'Action=SendRawEmail&Source=%s&%s&RawMessage.Data=%s'; /** * Remote smtp hostname or i.p. * * @var string */ protected $_host; /** * Amazon Access Key * * @var string|null */ protected $_accessKey; /** * Amazon private key * * @var string|null */ protected $_privateKey; /** * Constructor. * * @param string $endpoint (Default: https://email.us-east-1.amazonaws.com) * @param array|null $config (Default: null) * @return void * @throws Zend_Mail_Transport_Exception if accessKey is not present in the config * @throws Zend_Mail_Transport_Exception if privateKey is not present in the config */ public function __construct(Array $config = array(), $host = 'https://email.us-east-1.amazonaws.com') { if (!array_key_exists('accessKey', $config)) { throw new Zend_Mail_Transport_Exception('This transport requires the Amazon access key'); } if (!array_key_exists('privateKey', $config)) { throw new Zend_Mail_Transport_Exception('This transport requires the Amazon private key'); } $this->_accessKey = $config['accessKey']; $this->_privateKey = $config['privateKey']; $this->_host = $host; } /** * Send an email using the amazon webservice api * * @return void */ public function _sendMail() { $date = gmdate('D, d M Y H:i:s O'); //Send the request $client = new Am_HttpRequest($this->_host, Am_HttpRequest::METHOD_POST); $client->setHeader(array( 'Date' => $date, 'X-Amzn-Authorization' => $this->_buildAuthKey($date) )); //Build the parameters $params = array( 'Action' => 'SendRawEmail', 'Source' => $this->_mail->getFrom(), 'RawMessage.Data' => base64_encode(sprintf("%s\n%s\n", $this->header, $this->body)) ); $recipients = explode(',', $this->recipients); while (list($index, $recipient) = each($recipients)) { $params[sprintf('Destination.ToAddresses.member.%d', $index + 1)] = $recipient; } $client->addPostParameter($params); $response = $client->send(); if ($response->getStatus() != 200) { throw new Zend_Mail_Transport_Exception("Amazon SES: unexpected response: " . $response->getBody()); } } /** * Format and fix headers * * Some SMTP servers do not strip BCC headers. Most clients do it themselves as do we. * * @access protected * @param array $headers * @return void * @throws Zend_Transport_Exception */ protected function _prepareHeaders($headers) { if (!$this->_mail) { //require_once 'Zend/Mail/Transport/Exception.php'; throw new Zend_Mail_Transport_Exception('_prepareHeaders requires a registered Zend_Mail object'); } unset($headers['Bcc']); // Prepare headers parent::_prepareHeaders($headers); } /** * Returns header string containing encoded authentication key * * @param date $date * @return string */ private function _buildAuthKey($date) { return sprintf('AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=HmacSHA256,Signature=%s', $this->_accessKey, base64_encode(hash_hmac('sha256', $date, $this->_privateKey, TRUE))); } function sendFromSaved($from, $recipients, $body, array $headers, $subject){ $this->_mail = new Am_Mail_Saved; $this->_mail->from = $from; $this->_mail->subject = $subject; $this->recipients = $recipients; $this->body = $body; $this->_prepareHeaders($headers); $this->_sendMail(); } } Am_Mail::initDefaults(); /** * I believe using Zend_Validator_Hostname adds unacceptable overhead to Zend_Mail_Protocol * class, so it is disabled in this project * @internal * @package Am_Mail */ class Am_Util_Dummy_Zend_Validate { function addValidator(){} function isValid(){ return 1;} }
Upload Files
Cancel
Upload
Create New
Cancel
Create
Change Permissions
Cancel
Save
Change Date
Cancel
Save
Rename Item
Cancel
Save
Confirm Delete
Are you sure you want to delete the selected items?
Cancel
Delete