为Joomla com_mailto定期发送PHP邮件

时间:2014-02-16 10:05:39

标签: php email joomla joomla1.5

我有以下脚本,据我所知发送电子邮件无限制,但我想限制它发送400封电子邮件然后等待30分钟,是否有这样的可能性?这是我主人的限制。

 <?php
    /**
     * @version     $Id: controller.php 21078 2011-04-04 20:52:23Z dextercowley $
     * @package     Joomla
     * @subpackage  MailTo
     * @copyright   Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
     * @license     GNU/GPL, see LICENSE.php
     * Joomla! is free software. This version may have been modified pursuant to the
     * GNU General Public License, and as distributed it includes or is derivative
     * of works licensed under the GNU General Public License or other free or open
     * source software licenses. See COPYRIGHT.php for copyright notices and
     * details.
     */

    // Check to ensure this file is included in Joomla!
    defined('_JEXEC') or die( 'Restricted access' );

    jimport('joomla.application.component.controller');

    define('MAILTO_TIMEOUT', 20);

    /**
     * @package     Joomla
     * @subpackage  MailTo
     */
    class MailtoController extends JController
    {

        /**
         * Show the form so that the user can send the link to someone
         *
         * @access public
         * @since 1.5
         */
        function mailto()
        {
            $session =& JFactory::getSession();
            $session->set('com_mailto.formtime', time());
            JRequest::setVar( 'view', 'mailto' );
            $this->display();
        }

        /**
         * Send the message and display a notice
         *
         * @access public
         * @since 1.5
         */
        function send()
        {
            global $mainframe;

            // Check for request forgeries
            JRequest::checkToken() or jexit( 'Invalid Token' );
            $session =& JFactory::getSession();
            $db =& JFactory::getDBO();

            // we return time() instead of 0 (as it previously was), so that the session variable has to be set in order to send the mail
            $timeout = $session->get('com_mailto.formtime', time());
    //      if($timeout == 0 || time() - $timeout < MAILTO_TIMEOUT) {
    //          JError::raiseNotice( 500, JText:: _ ('EMAIL_NOT_SENT' ));
    //          return $this->mailto();
    //      }
            // here we unset the counter right away so that you have to wait again, and you have to visit mailto() first
            $session->set('com_mailto.formtime', null);

            jimport( 'joomla.mail.helper' );

            $SiteName   = $mainframe->getCfg('sitename');
            $MailFrom   = $mainframe->getCfg('mailfrom');
            $FromName   = $mainframe->getCfg('fromname');

                    $link           = MailtoHelper::validateHash(JRequest::getString('link', '', 'post'));

            // Verify that this is a local link
    //      if((!$link) || (!JURI::isInternal($link))) {
    //          //Non-local url...  
    //          JError::raiseNotice( 500, JText:: _ ('EMAIL_NOT_SENT' ));
    //          return $this->mailto();
    //      }

            // An array of e-mail headers we do not want to allow as input
            $headers = array (  'Content-Type:',
                                'MIME-Version:',
                                'Content-Transfer-Encoding:',
                                'bcc:',
                                'cc:');

            // An array of the input fields to scan for injected headers
            $fields = array ('mailto',
                             'sender',
                             'from',
                             'subject',
                             );

            /*
             * Here is the meat and potatoes of the header injection test.  We
             * iterate over the array of form input and check for header strings.
             * If we find one, send an unauthorized header and die.
             */

            foreach ($fields as $field)
            {
                foreach ($headers as $header)
                {
                    if (strpos($_POST[$field], $header) !== false)
                    {
                        JError::raiseError(403, '');
                    }
                }
            }

            /*
             * Free up memory
             */
            unset ($headers, $fields);

            $email              = JRequest::getString('mailto', '', 'post');
            $sender             = JRequest::getString('sender', '', 'post');
            $from               = JRequest::getString('from', '', 'post');
            $body               = JRequest::getString('body', '', 'post');
            $vacancy            = JRequest::getString('vacancy', '', 'post');

            $subject            = 'A message of interest sent by '.$email;
    //      $subject            = JRequest::getString('subject', $subject_default, 'post');

            // Check for a valid to address
            $error  = false;
            if ( ! $email  || ! JMailHelper::isEmailAddress($email) )
            {
                $error  = JText::sprintf('EMAIL_INVALID', $email);
                JError::raiseWarning(0, $error );
            }

            // Check for a valid from address
            if ( ! $from || ! JMailHelper::isEmailAddress($from) )
            {
                $error  = JText::sprintf('EMAIL_INVALID', $from);
                JError::raiseWarning(0, $error );
            }

            if ( $error )
            {
                return $this->mailto();
            }

            // Build the message to send
            if($vacancy) {
                $query = 'SELECT DISTINCT i.*, (i.plus / (i.plus + i.minus) ) * 100 AS votes, cy.title AS country, emp.comp_name AS employer,' .
                ' CASE WHEN CHAR_LENGTH(i.alias) THEN CONCAT_WS(\':\', i.id, i.alias) ELSE i.id END as slug' .
                ' FROM jos_career_items AS i' .
                ' LEFT JOIN jos_career_cats_item_relations AS rel ON rel.itemid = i.id' .
                ' LEFT JOIN jos_career_country AS cy ON cy.id = i.id_country' .
                ' LEFT JOIN jos_career_employer AS emp ON emp.id = i.employer_id' .
                ' WHERE i.id = ' . $vacancy;
                $db->setQuery($query);
                $itemData = $db->loadObjectList();
                $vacancyData = $itemData[0];
                $body   = '<div style="margin: 10px auto; width:100%;font-size:13px;">
                        <div><img src="http://search4staff.com/newsite/images/logo.png" alt=""/></div>
                        <div style="padding: 10px;">'.$sender.' saw the job below advertised on www.search4staff.com and thought it might be of interest to you</div>
                        <div style="clear:both; border-bottom: 1px dotted #cccccc;"></div>
                        <div style="font-size:16px;font-weight:bold;padding: 5px;">'.$vacancyData->title.'</div>
                        <div>'.$vacancyData->text1.'</div>
                        <div>'.$vacancyData->text2.'</div>
                        <div style="clear:both; border-bottom: 1px dotted #cccccc;"></div>
                        <div style="padding:10px;">Click here to view the job ad: '.$link.'</div>
                        <div style="clear:both; border-bottom: 1px dotted #cccccc;"></div>
                        <div style="padding:10px;">'.$sender.' message: '.$body.'</div>
                        <div style="clear:both; border-bottom: 1px dotted #cccccc;"></div>
                        <div style="padding:10px;">HR-Consulting, Professional Search Consultants<br/>www.search4staff.com<br/>phone: +373 22 20 91 33<br/>
                      </div>
                      ';
            } else {
                $msg    = JText :: _('EMAIL_MSG');
                $body   = sprintf( $msg, $SiteName, $sender, $from, $link);    
            }

            // Clean the email data
            $subject = JMailHelper::cleanSubject($subject);
            $body    = JMailHelper::cleanBody($body);
            $sender  = JMailHelper::cleanAddress($sender);

            // Send the email
            if ( JUtility::sendMail($from, $sender, $email, $subject, $body, true) !== true )
            {
                JError::raiseNotice( 500, JText:: _ ('EMAIL_NOT_SENT' ));
                return $this->mailto();
            }

            JRequest::setVar( 'view', 'sent' );
            $this->display();
        }


        function upload_cv() {
            global $mainframe;

            $postData = JRequest::get('post');

            if(file_exists(JPATH_BASE."/CV"))
            {
                if(!file_exists(JPATH_BASE."/CV/".$postData['item_id'])) {
                    mkdir(JPATH_BASE."/CV/".$postData['item_id']);
                }
                chmod(JPATH_BASE."/CV/".$postData['item_id'], 0777);
            }

            $file =  JPATH_BASE."/CV/".$postData['item_id'].'/'.$postData['item_code'].'_'.basename($_FILES['uploadfile']['name']);

            move_uploaded_file($_FILES['uploadfile']['tmp_name'], $file);

            $mailfrom       = $mainframe->getCfg( 'mailfrom' );
            $fromname       = $mainframe->getCfg( 'fromname' );

            $subject = $postData['item_code'].' UPLOAD CV - '.$_FILES['uploadfile']['name'];
            $message = $postData['body'];
            $message .= '<br /><br />Please check attachment!';
            $attachment = $file;

            JUtility::sendMail($mailfrom, 'New CV for '.$postData['item_code'].' from '.$postData['from'], $postData['item_mail'], $subject , $message, true, null, null, $attachment);//$postData['item_mail']
        JRequest::setVar( 'view', 'cvsend' );
        $this->display();
        }
    }

某人有人出汗了

               // Send the email
  if ( JUtility::sendMail($from, $sender, $email, $subject, $body) !== true )
  {
                                      sleep(108000); //30 minutes
                          if ( JUtility::sendMail($from, $sender, $email, $subject, $body) !== true )
                         {
                   JError::raiseNotice( 500, JText:: _ ('EMAIL_NOT_SENT' ));
                   return $this->mailto();
                                                }
  }

如果失败,它会等待再试一次。不确定你是否在其他地方超时,例如最长执行时间。

我应该将bigegr值设置为define('MAILTO_TIMEOUT', 20);吗?

3 个答案:

答案 0 :(得分:1)

由于脚本出现在控制器中,我假设有多个实例 可以立即调用脚本。这使得超时的所有用途都没有用。

即。如果你将30分钟/ 400 = 4.5秒分开,并在发送邮件前等待4.5秒,你会认为你很尊重这个限制。但你不是!如果500个用户同时点击,您将等待4.5秒,然后同时发送500封电子邮件。

您需要设置

  • 可能存储在数据库中的列表,其中包含您要发送的电子邮件的详细信息。上面的代码将自己限制为填充列表。
  • 一个计划任务,它迭代列表并发送电子邮件,一旦发送邮件就向上面的列表项添加时间戳。对过去30分钟内所有邮件的快速查询将显示是否已发送过多邮件。

答案 1 :(得分:1)

实际上,使用的扩展程序可以了解有关垃圾邮件的法律规定,以及如何使用限制(例如主机所需)。 Joomla mail_to专为注册确认和密码重置而设计,它不是一个功能齐全的邮件管理类。在这个地方,您可以被主机关闭或犯错误(比如忘记包含指向物理地址的链接或不正确的取消订阅链接),这会给您带来巨额罚款,并且您的电子邮件地址被主机列入黑名单。即使CiviCRM正在转向MailChimp集成,他们也拥有您可以找到的最复杂的邮件列表管理系统之一。

答案 2 :(得分:0)

如果您想要安排电子邮件,最好的办法就是在服务器上使用cron作业。这是专门为允许您设置间隔脚本执行的计划而设计的。构建整个事情需要做一些事情,但你最终得到的是一个数据库表,其中包含所有你的电子邮件ID,然后是一个email-id-to-address-id表,这样你就可以跟踪你的电子邮件用户id和已发送的电子邮件ID。

每次脚本执行时,它都会检查最新的消息ID,然后开始排队并将消息发送给列表中的所有人,并在“已发送”表中记录他们的ID。下次执行时,它会检查发送的表和地址簿表,并查找哪些地址没有收到它,并将它们排队等待发送(然后将它们添加到发送的表中)。

那说我同意艾琳的说法,这种方法很可能会给你带来麻烦,主持人肯定不喜欢它。您最好的选择是使用MailChimp API或使用AcyMailing生成消息。 AcyMailing非常强大,为它生成消息构建一个插件同样简单,并且代码可能比上面的脚本更少。您可以轻松地为不同的组(工作发布类别)提供不同的新闻稿,并且它已经为您完成了大部分已发送/未发送的逻辑。