home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Mail / Queue.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  17.7 KB  |  565 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PEAR :: Mail :: Queue                                                |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2008 Radek Maciaszek, Lorenzo Alberton            |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 3.01 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/3_01.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Radek Maciaszek <chief@php.net>                             |
  17. // |          Lorenzo Alberton <l.alberton@quipo.it>                      |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: Queue.php,v 1.26 2008/05/06 20:47:22 till Exp $
  21.  
  22. /**
  23. * Class for handle mail queue managment.
  24. * Wrapper for Pear::Mail and Pear::DB.
  25. * Could load, save and send saved mails in background
  26. * and also backup some mails.
  27. *
  28. * Mail queue class put mails in a temporary
  29. * container waiting to be fed to the MTA (Mail Transport Agent)
  30. * and send them later (eg. every few minutes) by crontab or in other way.
  31. *
  32. * -------------------------------------------------------------------------
  33. * A basic usage example:
  34. * -------------------------------------------------------------------------
  35. *
  36. * $container_options = array(
  37. *   'type'        => 'db',
  38. *   'database'    => 'dbname',
  39. *   'phptype'     => 'mysql',
  40. *   'username'    => 'root',
  41. *   'password'    => '',
  42. *   'mail_table'  => 'mail_queue'
  43. * );
  44. *   //optionally, a 'dns' string can be provided instead of db parameters.
  45. *   //look at DB::connect() method or at DB or MDB docs for details.
  46. *   //you could also use mdb container instead db
  47. *
  48. * $mail_options = array(
  49. *   'driver'   => 'smtp',
  50. *   'host'     => 'your_smtp_server.com',
  51. *   'port'     => 25,
  52. *   'auth'     => false,
  53. *   'username' => '',
  54. *   'password' => ''
  55. * );
  56. *
  57. * $mail_queue =& new Mail_Queue($container_options, $mail_options);
  58. * *****************************************************************
  59. * // Here the code differentiates wrt you want to add an email to the queue
  60. * // or you want to send the emails that already are in the queue.
  61. * *****************************************************************
  62. * // TO ADD AN EMAIL TO THE QUEUE
  63. * *****************************************************************
  64. * $from             = 'user@server.com';
  65. * $from_name        = 'admin';
  66. * $recipient        = 'recipient@other_server.com';
  67. * $recipient_name   = 'recipient';
  68. * $message          = 'Test message';
  69. * $from_params      = empty($from_name) ? '"'.$from_name.'" <'.$from.'>' : '<'.$from.'>';
  70. * $recipient_params = empty($recipient_name) ? '"'.$recipient_name.'" <'.$recipient.'>' : '<'.$recipient.'>';
  71. * $hdrs = array( 'From'    => $from_params,
  72. *                'To'      => $recipient_params,
  73. *                'Subject' => "test message body"  );
  74. * $mime =& new Mail_mime();
  75. * $mime->setTXTBody($message);
  76. * $body = $mime->get();
  77. * $hdrs = $mime->headers($hdrs);
  78. *
  79. * // Put message to queue
  80. * $mail_queue->put( $from, $recipient, $hdrs, $body );
  81. * //Also you could put this msg in more advanced mode [look at Mail_Queue docs for details]
  82. * $seconds_to_send = 3600;
  83. * $delete_after_send = false;
  84. * $id_user = 7;
  85. * $mail_queue->put( $from, $recipient, $hdrs, $body, $seconds_to_send, $delete_after_send, $id_user );
  86. *
  87. * *****************************************************************
  88. * // TO SEND EMAILS IN THE QUEUE
  89. * *****************************************************************
  90. * // How many mails could we send each time
  91. * $max_ammount_mails = 50;
  92. * $mail_queue =& new Mail_Queue($container_options, $mail_options);
  93. * $mail_queue->sendMailsInQueue($max_ammount_mails);
  94. * *****************************************************************
  95. *
  96. * // for more examples look to docs directory
  97. *
  98. * // end usage example
  99. * -------------------------------------------------------------------------
  100. *
  101. * @version $Revision: 1.26 $
  102. * $Id: Queue.php,v 1.26 2008/05/06 20:47:22 till Exp $
  103. * @author Radek Maciaszek <chief@php.net>
  104. */
  105.  
  106. /**
  107.  * This is special constant define start offset for limit sql queries to
  108.  * get mails.
  109.  */
  110. define('MAILQUEUE_START', 0);
  111.  
  112. /**
  113.  * You can specify how many mails will be loaded to
  114.  * queue else object use this constant for load all mails from db.
  115.  */
  116. define('MAILQUEUE_ALL', -1);
  117.  
  118. /**
  119.  * When you put new mail to queue you could specify user id who send e-mail.
  120.  * Else you could use system id: MAILQUEUE_SYSTEM or user unknown id: MAILQUEUE_UNKNOWN
  121.  */
  122. define('MAILQUEUE_SYSTEM',  -1);
  123. define('MAILQUEUE_UNKNOWN', -2);
  124.  
  125. /**
  126.  * This constant tells Mail_Queue how many times should try
  127.  * to send mails again if was any errors before.
  128.  */
  129. define('MAILQUEUE_TRY', 25);
  130.  
  131. /**
  132.  * MAILQUEUE_ERROR constants
  133.  */
  134. define('MAILQUEUE_ERROR',                   -1);
  135. define('MAILQUEUE_ERROR_NO_DRIVER',         -2);
  136. define('MAILQUEUE_ERROR_NO_CONTAINER',      -3);
  137. define('MAILQUEUE_ERROR_CANNOT_INITIALIZE', -4);
  138. define('MAILQUEUE_ERROR_NO_OPTIONS',        -5);
  139. define('MAILQUEUE_ERROR_CANNOT_CONNECT',    -6);
  140. define('MAILQUEUE_ERROR_QUERY_FAILED',      -7);
  141. define('MAILQUEUE_ERROR_UNEXPECTED',        -8);
  142. define('MAILQUEUE_ERROR_CANNOT_SEND_MAIL',  -9);
  143. define('MAILQUEUE_ERROR_NO_RECIPIENT',     -10);
  144.  
  145. require_once 'PEAR.php';
  146. require_once 'Mail.php';
  147. require_once 'Mail/mime.php';
  148.  
  149.  
  150. /**
  151.  * Mail_Queue - base class for mail queue managment.
  152.  *
  153.  * @author   Radek Maciaszek <wodzu@tonet.pl>
  154.  * @version  $Id: Queue.php,v 1.26 2008/05/06 20:47:22 till Exp $
  155.  * @package  Mail_Queue
  156.  * @access   public
  157.  */
  158. class Mail_Queue extends PEAR
  159. {
  160.     // {{{ Class vars
  161.  
  162.     /**
  163.      * Mail options: smtp, mail etc. see Mail::factory
  164.      *
  165.      * @var array
  166.      */
  167.     var $mail_options;
  168.  
  169.     /**
  170.      * Mail_Queue_Container
  171.      *
  172.      * @var object
  173.      */
  174.     var $container;
  175.  
  176.     /**
  177.      * Reference to Pear_Mail object
  178.      *
  179.      * @var object
  180.      */
  181.     var $send_mail;
  182.  
  183.     /**
  184.      * Pear error mode (when raiseError is called)
  185.      * (see PEAR doc)
  186.      *
  187.      * @var int $_pearErrorMode
  188.      * @access private
  189.      */
  190.     var $pearErrorMode = PEAR_ERROR_RETURN;
  191.  
  192.     // }}}
  193.     // {{{ Mail_Queue
  194.  
  195.     /**
  196.      * Mail_Queue constructor
  197.      *
  198.      * @param  array $container_options  Mail_Queue container options
  199.      * @param  array $mail_options  How send mails.
  200.      *
  201.      * @return mixed  True on success else PEAR error class.
  202.      *
  203.      * @access public
  204.      */
  205.     function Mail_Queue($container_options, $mail_options)
  206.     {
  207.         $this->PEAR();
  208.         if (isset($mail_options['pearErrorMode'])) {
  209.             $this->pearErrorMode = $mail_options['pearErrorMode'];
  210.             // ugly hack to propagate 'pearErrorMode'
  211.             $container_options['pearErrorMode'] = $mail_options['pearErrorMode'];
  212.         }
  213.  
  214.         if (!is_array($mail_options) || !isset($mail_options['driver'])) {
  215.             return new Mail_Queue_Error(MAILQUEUE_ERROR_NO_DRIVER,
  216.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__);
  217.         }
  218.         $this->mail_options = $mail_options;
  219.  
  220.         if (!is_array($container_options) || !isset($container_options['type'])) {
  221.             return new Mail_Queue_Error(MAILQUEUE_ERROR_NO_CONTAINER,
  222.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__);
  223.         }
  224.         $container_type = strtolower($container_options['type']);
  225.         $container_class = 'Mail_Queue_Container_' . $container_type;
  226.         $container_classfile = $container_type . '.php';
  227.  
  228.         // Attempt to include a custom version of the named class, but don't treat
  229.         // a failure as fatal.  The caller may have already included their own
  230.         // version of the named class.
  231.         if (!class_exists($container_class)) {
  232.             include_once 'Mail/Queue/Container/' . $container_classfile;
  233.         }
  234.         $this->container = new $container_class($container_options);
  235.         if(PEAR::isError($this->container)) {
  236.             return new Mail_Queue_Error(MAILQUEUE_ERROR_CANNOT_INITIALIZE,
  237.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__);
  238.         }
  239.         return true;
  240.     }
  241.  
  242.     // }}}
  243.     // {{{ _Mail_Queue()
  244.  
  245.     /**
  246.      * Mail_Queue desctructor
  247.      *
  248.      * @return void
  249.      * @access public
  250.      */
  251.     function _Mail_Queue()
  252.     {
  253.         unset($this);
  254.     }
  255.  
  256.     // }}}
  257.     // {{{ factorySendMail()
  258.  
  259.     /**
  260.      * Provides an interface for generating Mail:: objects of various
  261.      * types see Mail::factory()
  262.      *
  263.      * @return void
  264.      *
  265.      * @access public
  266.      */
  267.     function factorySendMail()
  268.     {
  269.         $options = $this->mail_options;
  270.         unset($options['driver']);
  271.         $this->send_mail =& Mail::factory($this->mail_options['driver'], $options);
  272.     }
  273.  
  274.     // }}}
  275.     // {{{ setBufferSize()
  276.  
  277.     /**
  278.      * Keep memory usage under control. You can set the max number
  279.      * of mails that can be in the preload buffer at any given time.
  280.      * It won't limit the number of mails you can send, just the
  281.      * internal buffer size.
  282.      *
  283.      * @param integer $size  Optional - internal preload buffer size
  284.      */
  285.     function setBufferSize($size = 10)
  286.     {
  287.         $this->container->buffer_size = $size;
  288.     }
  289.  
  290.  
  291.     // }}}
  292.     // {{{ sendMailsInQueue()
  293.  
  294.    /**
  295.      * Send mails fom queue.
  296.      *
  297.      * Mail_Queue::sendMailsInQueue()
  298.      *
  299.      * @param integer $limit     Optional - max limit mails send.
  300.      *                           This is the max number of emails send by
  301.      *                           this function.
  302.      * @param integer $offset    Optional - you could load mails from $offset (by id)
  303.      * @param integer $try       Optional - hoh many times mailqueu should try send
  304.      *                           each mail. If mail was sent succesful it will be delete
  305.      *                           from Mail_Queue.
  306.      * @return mixed  True on success else MAILQUEUE_ERROR object.
  307.      */
  308.     function sendMailsInQueue($limit = MAILQUEUE_ALL, $offset = MAILQUEUE_START,
  309.                               $try = MAILQUEUE_TRY)
  310.     {
  311.         $this->container->setOption($limit, $offset, $try);
  312.         while ($mail = $this->get()) {
  313.             $this->container->countSend($mail);
  314.  
  315.             $result = $this->sendMail($mail, true);
  316.             if (PEAR::isError($result)) {
  317.                 //remove the problematic mail from the buffer, but don't delete
  318.                 //it from the db: it might be a temporary issue.
  319.                 $this->container->skip();
  320.                 PEAR::raiseError(
  321.                     'Error in sending mail: '.$result->getMessage(),
  322.                     MAILQUEUE_ERROR_CANNOT_SEND_MAIL, PEAR_ERROR_TRIGGER,
  323.                     E_USER_NOTICE
  324.                 );
  325.             } else if ($mail->isDeleteAfterSend()) {
  326.                 $this->deleteMail($mail->getId());
  327.             }
  328.         }
  329.         if (!empty($this->mail_options['persist']) && is_object($this->send_mail)) {
  330.             $this->send_mail->disconnect();
  331.         }
  332.         return true;
  333.     }
  334.  
  335.     // }}}
  336.     // {{{ sendMailById()
  337.  
  338.     /**
  339.      * Send Mail by $id identifier. (bypass Mail_Queue)
  340.      *
  341.      * @param integer $id  Mail identifier
  342.      * @param  bool   $set_as_sent
  343.      * @return bool   true on success else false
  344.      *
  345.      * @access public
  346.      */
  347.     function sendMailById($id, $set_as_sent=true)
  348.     {
  349.         $mail =& $this->container->getMailById($id);
  350.         if (PEAR::isError($mail)) {
  351.             return $mail;
  352.         }
  353.         return $this->sendMail($mail, $set_as_sent);
  354.     }
  355.  
  356.     // }}}
  357.     // {{{ sendMail()
  358.  
  359.     /**
  360.      * Send mail from MailBody object
  361.      *
  362.      * @param object  MailBody object
  363.      * @return mixed  True on success else pear error class
  364.      * @param  bool   $set_as_sent
  365.      *
  366.      * @access public
  367.      */
  368.     function sendMail($mail, $set_as_sent=true)
  369.     {
  370.         $recipient = $mail->getRecipient();
  371.         if (empty($recipient)) {
  372.             return new Mail_Queue_Error('Recipient cannot be empty.',
  373.                 MAILQUEUE_ERROR_NO_RECIPIENT);
  374.         }
  375.  
  376.         $hdrs = $mail->getHeaders();
  377.         $body = $mail->getBody();
  378.  
  379.         if (empty($this->send_mail)) {
  380.             $this->factorySendMail();
  381.         }
  382.         if (PEAR::isError($this->send_mail)) {
  383.             return $this->send_mail;
  384.         }
  385.         $sent = $this->send_mail->send($recipient, $hdrs, $body);
  386.         if (!PEAR::isError($sent) && $sent && $set_as_sent) {
  387.             $this->container->setAsSent($mail);
  388.         }
  389.         return $sent;
  390.     }
  391.  
  392.     // }}}
  393.     // {{{ get()
  394.  
  395.     /**
  396.      * Get next mail from queue. The emails are preloaded
  397.      * in a buffer for better performances.
  398.      *
  399.      * @return    object Mail_Queue_Container or error object
  400.      * @throw     MAILQUEUE_ERROR
  401.      * @access    public
  402.      */
  403.     function get()
  404.     {
  405.         return $this->container->get();
  406.     }
  407.  
  408.     // }}}
  409.     // {{{ put()
  410.  
  411.     /**
  412.      * Put new mail in queue.
  413.      *
  414.      * @see Mail_Queue_Container::put()
  415.      *
  416.      * @param string  $time_to_send  When mail have to be send
  417.      * @param integer $id_user  Sender id
  418.      * @param string  $ip    Sender ip
  419.      * @param string  $from  Sender e-mail
  420.      * @param string|array  $to    Reciepient(s) e-mail
  421.      * @param string  $hdrs  Mail headers (in RFC)
  422.      * @param string  $body  Mail body (in RFC)
  423.      * @return mixed  ID of the record where this mail has been put
  424.      *                or Mail_Queue_Error on error
  425.      *
  426.      * @access public
  427.      */
  428.     function put($from, $to, $hdrs, $body, $sec_to_send=0, $delete_after_send=true, $id_user=MAILQUEUE_SYSTEM)
  429.     {
  430.         $ip = getenv('REMOTE_ADDR');
  431.         $time_to_send = date("Y-m-d H:i:s", time() + $sec_to_send);
  432.         return $this->container->put(
  433.             $time_to_send,
  434.             $id_user,
  435.             $ip,
  436.             $from,
  437.             serialize($to),
  438.             serialize($hdrs),
  439.             serialize($body),
  440.             $delete_after_send
  441.         );
  442.     }
  443.  
  444.     // }}}
  445.     // {{{ deleteMail()
  446.  
  447.     /**
  448.      * Delete mail from queue database
  449.      *
  450.      * @param integer $id  Maila identifier
  451.      * @return boolean
  452.      *
  453.      * @access private
  454.      */
  455.     function deleteMail($id)
  456.     {
  457.         return $this->container->deleteMail($id);
  458.     }
  459.  
  460.     // }}}
  461.     // {{{ isError()
  462.  
  463.     /**
  464.      * Tell whether a result code from a Mail_Queue method is an error
  465.      *
  466.      * @param   int       $value  result code
  467.      * @return  boolean   whether $value is an MAILQUEUE_ERROR
  468.      * @access public
  469.      */
  470.     function isError($value)
  471.     {
  472.         return (is_object($value) && is_a($value, 'pear_error'));
  473.     }
  474.  
  475.     // }}}
  476.     // {{{ errorMessage()
  477.  
  478.     /**
  479.      * Return a textual error message for a MDB error code
  480.      *
  481.      * @param   int     $value error code
  482.      * @return  string  error message, or false if the error code was
  483.      *                  not recognized
  484.      * @access public
  485.      */
  486.     function errorMessage($value)
  487.     {
  488.         static $errorMessages;
  489.         if (!isset($errorMessages)) {
  490.             $errorMessages = array(
  491.                 MAILQUEUE_ERROR                    => 'unknown error',
  492.                 MAILQUEUE_ERROR_NO_DRIVER          => 'No mail driver specified',
  493.                 MAILQUEUE_ERROR_NO_CONTAINER       => 'No container specified',
  494.                 MAILQUEUE_ERROR_CANNOT_INITIALIZE  => 'Cannot initialize container',
  495.                 MAILQUEUE_ERROR_NO_OPTIONS         => 'No container options specified',
  496.                 MAILQUEUE_ERROR_CANNOT_CONNECT     => 'Cannot connect to database',
  497.                 MAILQUEUE_ERROR_QUERY_FAILED       => 'db query failed',
  498.                 MAILQUEUE_ERROR_UNEXPECTED         => 'Unexpected class',
  499.                 MAILQUEUE_ERROR_CANNOT_SEND_MAIL   => 'Cannot send email',
  500.             );
  501.         }
  502.  
  503.         if (Mail_Queue::isError($value)) {
  504.             $value = $value->getCode();
  505.         }
  506.  
  507.         return isset($errorMessages[$value]) ?
  508.            $errorMessages[$value] : $errorMessages[MAILQUEUE_ERROR];
  509.     }
  510.  
  511.     // }}}
  512. /*
  513.     function raiseError($msg, $code = null, $file = null, $line = null, $mode = null)
  514.     {
  515.         if ($file !== null) {
  516.             $err = PEAR::raiseError(sprintf("%s [%s on line %d].", $msg, $file, $line), $code, $mode);
  517.         } else {
  518.             $err = PEAR::raiseError(sprintf("%s", $msg), $code, $mode);
  519.         }
  520. á á á á return $err;
  521.     }
  522. */
  523. }
  524.  
  525.  
  526.  
  527.  
  528. /**
  529.  * Mail_Queue_Error implements a class for reporting error
  530.  * messages.
  531.  *
  532.  * @package Mail_Queue
  533.  * @category Mail
  534.  */
  535. class Mail_Queue_Error extends PEAR_Error
  536. {
  537.     // {{{ constructor
  538.  
  539.     /**
  540.      * Mail_Queue_Error constructor.
  541.      *
  542.      * @param mixed   $code      Mail_Queue error code, or string with error message.
  543.      * @param integer $mode      what 'error mode' to operate in
  544.      * @param integer $level     what error level to use for
  545.      *                           $mode & PEAR_ERROR_TRIGGER
  546.      * @param string  $debuginfo additional debug info
  547.      */
  548.     function Mail_Queue_Error($code = MAILQUEUE_ERROR, $mode = PEAR_ERROR_RETURN,
  549.               $level = E_USER_NOTICE,  $file=__FILE__, $line=__LINE__, $debuginfo='')
  550.     {
  551.  
  552.         $debuginfo .= (empty($debuginfo) ? '' : ' - '). 'FILE: '.$file.', LINE: '.$line;
  553.         if (is_int($code)) {
  554.             $this->PEAR_Error('Mail Queue Error: ' . Mail_Queue::errorMessage($code),
  555.                               $code, $mode, $level, $debuginfo);
  556.         } else {
  557.             $this->PEAR_Error('Mail Queue Error: ' . $code, MAILQUEUE_ERROR, $mode,
  558.                               $level, $debuginfo);
  559.         }
  560.     }
  561.  
  562.     // }}}
  563. }
  564. ?>
  565.