home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / Mail / Queue.php < prev    next >
Encoding:
PHP Script  |  2005-07-07  |  16.7 KB  |  535 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PEAR :: Mail :: Queue                                                |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 3.0 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_0.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 dot alberton at quipo dot it>           |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: Queue.php,v 1.15 2004/07/27 08:58:03 quipo 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.15 $
  102. * $Id: Queue.php,v 1.15 2004/07/27 08:58:03 quipo 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.  
  144. require_once 'PEAR.php';
  145. require_once 'Mail.php';
  146. require_once 'Mail/mime.php';
  147.  
  148.  
  149. /**
  150.  * Mail_Queue - base class for mail queue managment.
  151.  *
  152.  * @author   Radek Maciaszek <wodzu@tonet.pl>
  153.  * @version  $Id: Queue.php,v 1.15 2004/07/27 08:58:03 quipo Exp $
  154.  * @package  Mail_Queue
  155.  * @access   public
  156.  */
  157. class Mail_Queue extends PEAR
  158. {
  159.     // {{{ Class vars
  160.  
  161.     /**
  162.      * Mail options: smtp, mail etc. see Mail::factory
  163.      *
  164.      * @var array
  165.      */
  166.     var $mail_options;
  167.  
  168.     /**
  169.      * Mail_Queue_Container
  170.      *
  171.      * @var object
  172.      */
  173.     var $container;
  174.  
  175.     /**
  176.      * Reference to Pear_Mail object
  177.      *
  178.      * @var object
  179.      */
  180.     var $send_mail;
  181.  
  182.     /**
  183.      * Pear error mode (when raiseError is called)
  184.      * (see PEAR doc)
  185.      *
  186.      * @var int $_pearErrorMode
  187.      * @access private
  188.      */
  189.     var $pearErrorMode = PEAR_ERROR_RETURN;
  190.  
  191.     // }}}
  192.     // {{{ Mail_Queue
  193.  
  194.     /**
  195.      * Mail_Queue constructor
  196.      *
  197.      * @param  array $container_options  Mail_Queue container options
  198.      * @param  array $mail_options  How send mails.
  199.      *
  200.      * @return mixed  True on success else PEAR error class.
  201.      *
  202.      * @access public
  203.      */
  204.     function Mail_Queue($container_options, $mail_options)
  205.     {
  206.         $this->PEAR();
  207.         if (isset($mail_options['pearErrorMode'])) {
  208.             $this->pearErrorMode = $mail_options['pearErrorMode'];
  209.             // ugly hack to propagate 'pearErrorMode'
  210.             $container_options['pearErrorMode'] = $mail_options['pearErrorMode'];
  211.         }
  212.  
  213.         if (!is_array($mail_options) || !isset($mail_options['driver'])) {
  214.             return new Mail_Queue_Error(MAILQUEUE_ERROR_NO_DRIVER,
  215.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__);
  216.         }
  217.         $this->mail_options = $mail_options;
  218.  
  219.         if (!is_array($container_options) || !isset($container_options['type'])) {
  220.             return new Mail_Queue_Error(MAILQUEUE_ERROR_NO_CONTAINER,
  221.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__);
  222.         }
  223.         $container_type = strtolower($container_options['type']);
  224.         $container_class = 'Mail_Queue_Container_' . $container_type;
  225.         $container_classfile = $container_type . '.php';
  226.  
  227.         include_once 'Mail/Queue/Container/' . $container_classfile;
  228.         $this->container = new $container_class($container_options);
  229.         if(PEAR::isError($this->container)) {
  230.             return new Mail_Queue_Error(MAILQUEUE_ERROR_CANNOT_INITIALIZE,
  231.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__);
  232.         }
  233.         return true;
  234.     }
  235.  
  236.     // }}}
  237.     // {{{ _Mail_Queue()
  238.  
  239.     /**
  240.      * Mail_Queue desctructor
  241.      *
  242.      * @return void
  243.      * @access public
  244.      */
  245.     function _Mail_Queue()
  246.     {
  247.         unset($this);
  248.     }
  249.  
  250.     // }}}
  251.     // {{{ factorySendMail()
  252.  
  253.     /**
  254.      * Provides an interface for generating Mail:: objects of various
  255.      * types see Mail::factory()
  256.      *
  257.      * @return void
  258.      *
  259.      * @access public
  260.      */
  261.     function factorySendMail()
  262.     {
  263.         $options = $this->mail_options;
  264.         unset($options['driver']);
  265.         $this->send_mail =& Mail::factory($this->mail_options['driver'], $options);
  266.     }
  267.  
  268.     // }}}
  269.     // {{{ setBufferSize()
  270.  
  271.     /**
  272.      * Keep memory usage under control. You can set the max number
  273.      * of mails that can be in the preload buffer at any given time.
  274.      * It won't limit the number of mails you can send, just the
  275.      * internal buffer size.
  276.      *
  277.      * @param integer $size  Optional - internal preload buffer size
  278.      **/
  279.     function setBufferSize($size = 10)
  280.     {
  281.         $this->container->buffer_size = $size;
  282.     }
  283.  
  284.  
  285.     // }}}
  286.     // {{{ sendMailsInQueue()
  287.  
  288.    /**
  289.      * Send mails fom queue.
  290.      *
  291.      * Mail_Queue::sendMailsInQueue()
  292.      *
  293.      * @param integer $limit     Optional - max limit mails send.
  294.      *                           This is the max number of emails send by
  295.      *                           this function.
  296.      * @param integer $offset    Optional - you could load mails from $offset (by id)
  297.      * @param integer $try       Optional - hoh many times mailqueu should try send
  298.      *                           each mail. If mail was sent succesful it will be delete
  299.      *                           from Mail_Queue.
  300.      * @return mixed  True on success else MAILQUEUE_ERROR object.
  301.      **/
  302.     function sendMailsInQueue($limit = MAILQUEUE_ALL, $offset = MAILQUEUE_START,
  303.                               $try = MAILQUEUE_TRY)
  304.     {
  305.         $this->container->setOption($limit, $offset, $try);
  306.         while ($mail = $this->get()) {
  307.             $this->container->countSend($mail);
  308.  
  309.             $result = $this->sendMail($mail);
  310.  
  311.             if (!PEAR::isError($result)) {
  312.                 $this->container->setAsSent($mail);
  313.                 if($mail->isDeleteAfterSend()) {
  314.                     $this->deleteMail($mail->getId());
  315.                 }
  316.             } else {
  317.                 PEAR::raiseError(
  318.                     'Error in sending mail: '.$result->getMessage(),
  319.                     MAILQUEUE_ERROR_CANNOT_SEND_MAIL, PEAR_ERROR_TRIGGER,
  320.                     E_USER_NOTICE);
  321.             }
  322.         }
  323.         return true;
  324.     }
  325.  
  326.     // }}}
  327.     // {{{ sendMailById()
  328.  
  329.     /**
  330.      * Send Mail by $id identifier. (bypass Mail_Queue)
  331.      *
  332.      * @param integer $id  Mail identifier
  333.      * @param  bool   $set_as_sent
  334.      * @return bool   true on success else false
  335.      *
  336.      * @access public
  337.      */
  338.     function sendMailById($id, $set_as_sent=true)
  339.     {
  340.         $mail =& $this->container->getMailById($id);
  341.         $sent = $this->sendMail($mail);
  342.         if ($sent and $set_as_sent) {
  343.             $this->container->setAsSent($mail);
  344.         }
  345.         return $sent;
  346.     }
  347.  
  348.     // }}}
  349.     // {{{ sendMail()
  350.  
  351.     /**
  352.      * Send mail from MailBody object
  353.      *
  354.      * @param object  MailBody object
  355.      * @return mixed  True on success else pear error class
  356.      *
  357.      * @access public
  358.      */
  359.     function sendMail($mail)
  360.     {
  361.         $recipient = $mail->getRecipient();
  362.         $hdrs = $mail->getHeaders();
  363.         $body = $mail->getBody();
  364.         if (empty($this->send_mail)) {
  365.             $this->factorySendMail();
  366.         }
  367.         return $this->send_mail->send($recipient, $hdrs, $body);
  368.     }
  369.  
  370.     // }}}
  371.     // {{{ get()
  372.  
  373.     /**
  374.      * Get next mail from queue. The emails are preloaded
  375.      * in a buffer for better performances.
  376.      *
  377.      * @return    object Mail_Queue_Container or error object
  378.      * @throw     MAILQUEUE_ERROR
  379.      * @access    public
  380.      */
  381.     function get()
  382.     {
  383.         return $this->container->get();
  384.     }
  385.  
  386.     // }}}
  387.     // {{{ put()
  388.  
  389.     /**
  390.      * Put new mail in queue.
  391.      *
  392.      * @see Mail_Queue_Container::put()
  393.      *
  394.      * @param string  $time_to_send  When mail have to be send
  395.      * @param integer $id_user  Sender id
  396.      * @param string  $ip    Sender ip
  397.      * @param string  $from  Sender e-mail
  398.      * @param string  $to    Reciepient e-mail
  399.      * @param string  $hdrs  Mail headers (in RFC)
  400.      * @param string  $body  Mail body (in RFC)
  401.      * @return mixed  ID of the record where this mail has been put
  402.      *                or Mail_Queue_Error on error
  403.      *
  404.      * @access public
  405.      **/
  406.     function put($from, $to, $hdrs, $body, $sec_to_send=0, $delete_after_send=true, $id_user=MAILQUEUE_SYSTEM)
  407.     {
  408.         $ip = getenv('REMOTE_ADDR');
  409.         $time_to_send = date("Y-m-d G:i:s", time() + $sec_to_send);
  410.         return $this->container->put( $time_to_send, $id_user,
  411.                             $ip, $from, $to, serialize($hdrs),
  412.                             serialize($body), $delete_after_send );
  413.     }
  414.  
  415.     // }}}
  416.     // {{{ deleteMail()
  417.  
  418.     /**
  419.      * Delete mail from queue database
  420.      *
  421.      * @param integer $id  Maila identifier
  422.      * @return boolean
  423.      *
  424.      * @access private
  425.      */
  426.     function deleteMail($id)
  427.     {
  428.         return $this->container->deleteMail($id);
  429.     }
  430.  
  431.     // }}}
  432.     // {{{ isError()
  433.  
  434.     /**
  435.      * Tell whether a result code from a Mail_Queue method is an error
  436.      *
  437.      * @param   int       $value  result code
  438.      * @return  boolean   whether $value is an MAILQUEUE_ERROR
  439.      * @access public
  440.      */
  441.     function isError($value)
  442.     {
  443.         return (is_object($value) && is_a($value, 'pear_error'));
  444.     }
  445.  
  446.     // }}}
  447.     // {{{ errorMessage()
  448.  
  449.     /**
  450.      * Return a textual error message for a MDB error code
  451.      *
  452.      * @param   int     $value error code
  453.      * @return  string  error message, or false if the error code was
  454.      *                  not recognized
  455.      * @access public
  456.      */
  457.     function errorMessage($value)
  458.     {
  459.         static $errorMessages;
  460.         if (!isset($errorMessages)) {
  461.             $errorMessages = array(
  462.                 MAILQUEUE_ERROR                    => 'unknown error',
  463.                 MAILQUEUE_ERROR_NO_DRIVER          => 'No mail driver specified',
  464.                 MAILQUEUE_ERROR_NO_CONTAINER       => 'No container specified',
  465.                 MAILQUEUE_ERROR_CANNOT_INITIALIZE  => 'Cannot initialize container',
  466.                 MAILQUEUE_ERROR_NO_OPTIONS         => 'No container options specified',
  467.                 MAILQUEUE_ERROR_CANNOT_CONNECT     => 'Cannot connect to database',
  468.                 MAILQUEUE_ERROR_QUERY_FAILED       => 'db query failed',
  469.                 MAILQUEUE_ERROR_UNEXPECTED         => 'Unexpected class',
  470.                 MAILQUEUE_ERROR_CANNOT_SEND_MAIL   => 'Cannot send email',
  471.             );
  472.         }
  473.  
  474.         if (Mail_Queue::isError($value)) {
  475.             $value = $value->getCode();
  476.         }
  477.  
  478.         return(isset($errorMessages[$value]) ?
  479.            $errorMessages[$value] : $errorMessages[MAILQUEUE_ERROR]);
  480.     }
  481.  
  482.     // }}}
  483. /*
  484.     function raiseError($msg, $code = null, $file = null, $line = null, $mode = null)
  485.     {
  486.         if ($file !== null) {
  487.             $err = PEAR::raiseError(sprintf("%s [%s on line %d].", $msg, $file, $line), $code, $mode);
  488.         } else {
  489.             $err = PEAR::raiseError(sprintf("%s", $msg), $code, $mode);
  490.         }
  491. á á á á return $err;
  492.     }
  493. */
  494. }
  495.  
  496.  
  497.  
  498.  
  499. /**
  500.  * Mail_Queue_Error implements a class for reporting error
  501.  * messages.
  502.  *
  503.  * @package Mail_Queue
  504.  * @category Mail
  505.  */
  506. class Mail_Queue_Error extends PEAR_Error
  507. {
  508.     // {{{ constructor
  509.  
  510.     /**
  511.      * Mail_Queue_Error constructor.
  512.      *
  513.      * @param mixed   $code      Mail_Queue error code, or string with error message.
  514.      * @param integer $mode      what 'error mode' to operate in
  515.      * @param integer $level     what error level to use for
  516.      *                           $mode & PEAR_ERROR_TRIGGER
  517.      * @param string  $debuginfo additional debug info
  518.      */
  519.     function Mail_Queue_Error($code = MAILQUEUE_ERROR, $mode = PEAR_ERROR_RETURN,
  520.               $level = E_USER_NOTICE,  $file=__FILE__, $line=__LINE__, $debuginfo='')
  521.     {
  522.  
  523.         $debuginfo .= (empty($debuginfo) ? '' : ' - '). 'FILE: '.$file.', LINE: '.$line;
  524.         if (is_int($code)) {
  525.             $this->PEAR_Error('Mail Queue Error: ' . Mail_Queue::errorMessage($code),
  526.                               $code, $mode, $level, $debuginfo);
  527.         } else {
  528.             $this->PEAR_Error('Mail Queue Error: ' . $code, MAILQUEUE_ERROR, $mode,
  529.                               $level, $debuginfo);
  530.         }
  531.     }
  532.  
  533.     // }}}
  534. }
  535. ?>