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 / Container / mdb.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  19.9 KB  |  516 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PEAR :: Mail :: Queue :: MDB Container                               |
  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. // | Author: Lorenzo Alberton <l.alberton at quipo.it>                    |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: mdb.php,v 1.20 2007/10/22 21:41:51 quipo Exp $
  20.  
  21. /**
  22.  * Storage driver for fetching mail queue data from a PEAR::MDB database
  23.  *
  24.  * This storage driver can use all databases which are supported
  25.  * by the PEAR MDB abstraction layer.
  26.  *
  27.  * @author   Lorenzo Alberton <l.alberton at quipo.it>
  28.  * @version  $Id: mdb.php,v 1.20 2007/10/22 21:41:51 quipo Exp $
  29.  * @package  Mail_Queue
  30.  */
  31. require_once 'MDB.php';
  32. require_once 'Mail/Queue/Container.php';
  33.  
  34. /**
  35. * PEAR/MDB Mail_Queue Container.
  36. *
  37. * NB: The field 'changed' has no meaning for the Cache itself. It's just there
  38. * because it's a good idea to have an automatically updated timestamp
  39. * field for debugging in all of your tables.
  40. *
  41. * A XML MDB-compliant schema example for the table needed is provided.
  42. * Look at the file "mdb_mail_queue_schema.xml" for that.
  43. *
  44. * -------------------------------------------------------------------------
  45. * A basic usage example:
  46. * -------------------------------------------------------------------------
  47. *
  48. * $container_options = array(
  49. *   'type'        => 'mdb',
  50. *   'database'    => 'dbname',
  51. *   'phptype'     => 'mysql',
  52. *   'username'    => 'root',
  53. *   'password'    => '',
  54. *   'mail_table'  => 'mail_queue'
  55. * );
  56. *   //optionally, a 'dns' string can be provided instead of db parameters.
  57. *   //look at MDB::connect() method or at MDB docs for details.
  58. *
  59. * $mail_options = array(
  60. *   'driver'   => 'smtp',
  61. *   'host'     => 'your_smtp_server.com',
  62. *   'port'     => 25,
  63. *   'auth'     => false,
  64. *   'username' => '',
  65. *   'password' => ''
  66. * );
  67. *
  68. * $mail_queue =& new Mail_Queue($container_options, $mail_options);
  69. * *****************************************************************
  70. * // Here the code differentiates wrt you want to add an email to the queue
  71. * // or you want to send the emails that already are in the queue.
  72. * *****************************************************************
  73. * // TO ADD AN EMAIL TO THE QUEUE
  74. * *****************************************************************
  75. * $from             = 'user@server.com';
  76. * $from_name        = 'admin';
  77. * $recipient        = 'recipient@other_server.com';
  78. * $recipient_name   = 'recipient';
  79. * $message          = 'Test message';
  80. * $from_params      = empty($from_name) ? '"'.$from_name.'" <'.$from.'>' : '<'.$from.'>';
  81. * $recipient_params = empty($recipient_name) ? '"'.$recipient_name.'" <'.$recipient.'>' : '<'.$recipient.'>';
  82. * $hdrs = array( 'From'    => $from_params,
  83. *                'To'      => $recipient_params,
  84. *                'Subject' => "test message body"  );
  85. * $mime =& new Mail_mime();
  86. * $mime->setTXTBody($message);
  87. * $body = $mime->get();
  88. * $hdrs = $mime->headers($hdrs);
  89. *
  90. * // Put message to queue
  91. * $mail_queue->put( $from, $recipient, $hdrs, $body );
  92. * //Also you could put this msg in more advanced mode [look at Mail_Queue docs for details]
  93. * $seconds_to_send = 3600;
  94. * $delete_after_send = false;
  95. * $id_user = 7;
  96. * $mail_queue->put( $from, $recipient, $hdrs, $body, $seconds_to_send, $delete_after_send, $id_user );
  97. *
  98. * *****************************************************************
  99. * // TO SEND EMAILS IN THE QUEUE
  100. * *****************************************************************
  101. * // How many mails could we send each time
  102. * $max_ammount_mails = 50;
  103. * $mail_queue =& new Mail_Queue($container_options, $mail_options);
  104. * $mail_queue->sendMailsInQueue($max_ammount_mails);
  105. * *****************************************************************
  106. * // end usage example
  107. * -------------------------------------------------------------------------
  108. *
  109. * //You can also send the emails one by one:
  110. *
  111. * //set the internal buffer size according your
  112. * //memory resources (the number indicates how
  113. * //many emails can stay in the buffer at any
  114. * //given time
  115. * $mail_queue->setBufferSize(20);
  116. *
  117. * //set the queue size (i.e. the number of mails to send)
  118. * $limit = 50;
  119. * $mail_queue->setOption($limit);
  120. *
  121. * //loop through the stored emails and send them
  122. * while ($mail = $mail_queue->get()) {
  123. *     $result = $mail_queue->sendMail($mail);
  124. * }
  125. */
  126.  
  127. /**
  128.  * Mail_Queue_Container_mdb
  129.  */
  130. class Mail_Queue_Container_mdb extends Mail_Queue_Container
  131. {
  132.     // {{{ class vars
  133.  
  134.     /**
  135.      * Reference to the current database connection.
  136.      * @var object PEAR::MDB instance
  137.      */
  138.     var $db;
  139.  
  140.     /**
  141.      * Table for sql database
  142.      * @var  string
  143.      */
  144.     var $mail_table = 'mail_queue';
  145.  
  146.     /**
  147.      * @var string  the name of the sequence for this table
  148.      */
  149.     var $sequence = null;
  150.  
  151.     // }}}
  152.     // {{{ Mail_Queue_Container_mdb()
  153.  
  154.     /**
  155.      * Contructor
  156.      *
  157.      * Mail_Queue_Container_mdb:: Mail_Queue_Container_mdb()
  158.      *
  159.      * @param mixed $options    An associative array of option names and
  160.      *                          their values. See MDB_common::setOption
  161.      *                          for more information about connection options.
  162.      *
  163.      * @access public
  164.      */
  165.     function Mail_Queue_Container_mdb($options)
  166.     {
  167.         if (!is_array($options)) {
  168.             return new Mail_Queue_Error(MAILQUEUE_ERROR_NO_OPTIONS,
  169.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  170.                 'No options specified!');
  171.         }
  172.         if (isset($options['mail_table'])) {
  173.             $this->mail_table = $options['mail_table'];
  174.             unset($options['mail_table']);
  175.         }
  176.         if (isset($options['sequence'])) {
  177.             $this->sequence = $options['sequence'];
  178.             unset($options['sequence']);
  179.         } else {
  180.             $this->sequence = $this->mail_table;
  181.         }
  182.         if (!empty($options['pearErrorMode'])) {
  183.             $this->pearErrorMode = $options['pearErrorMode'];
  184.         }
  185.         if (isset($options['dsn'])) {
  186.             $dsn = $options['dsn'];
  187.         } else {
  188.             $dsn = $options;
  189.         }
  190.         $this->db = &MDB::Connect($dsn);
  191.         if (PEAR::isError($this->db)) {
  192.             return new Mail_Queue_Error(MAILQUEUE_ERROR_CANNOT_CONNECT,
  193.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  194.                 'MDB::connect failed: '. $this->db->getMessage());
  195.         } else {
  196.             $this->db->setFetchMode(MDB_FETCHMODE_ASSOC);
  197.         }
  198.         $this->setOption();
  199.     }
  200.  
  201.     // }}}
  202.     // {{{ _preload()
  203.  
  204.     /**
  205.      * Preload mail to queue.
  206.      *
  207.      * @return mixed   True on success else Mail_Queue_Error object.
  208.      * @access private
  209.      */
  210.     function _preload()
  211.     {
  212.         if (!is_object($this->db) || !is_a($this->db, 'MDB_Common')) {
  213.             $msg = 'MDB::connect failed';
  214.             if (PEAR::isError($this->db)) {
  215.                 $msg .= ': '.$this->db->getMessage();
  216.             }
  217.             return new Mail_Queue_Error(MAILQUEUE_ERROR_CANNOT_CONNECT,
  218.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__, $msg);
  219.         }
  220.         $query = 'SELECT id FROM ' . $this->mail_table
  221.                 .' WHERE sent_time IS NULL AND try_sent < '. $this->try
  222.                 .' AND time_to_send <= '.$this->db->getTimestampValue(date("Y-m-d H:i:s"))
  223.                 .' ORDER BY time_to_send';
  224.         $res = $this->db->limitQuery($query, null, $this->offset, $this->limit);
  225.  
  226.         if (PEAR::isError($res)) {
  227.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  228.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  229.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  230.         }
  231.  
  232.         $this->_last_item = 0;
  233.         $this->queue_data = array(); //reset buffer
  234.         while ($row = $this->db->fetchInto($res, MDB_FETCHMODE_ASSOC)) {
  235.             $this->queue_data[$this->_last_item] = $this->getMailById($row['id']);
  236.             if (PEAR::isError($this->queue_data[$this->_last_item])) {
  237.                 return $this->queue_data[$this->_last_item];
  238.             }
  239.             $this->_last_item++;
  240.         }
  241.         @$this->db->freeResult($res);
  242.         return true;
  243.     }
  244.  
  245.     // }}}
  246.     // {{{ put()
  247.  
  248.     /**
  249.      * Put new mail in queue and save in database.
  250.      *
  251.      * Mail_Queue_Container::put()
  252.      *
  253.      * @param string  $time_to_send  When mail have to be send
  254.      * @param integer $id_user  Sender id
  255.      * @param string  $ip  Sender ip
  256.      * @param string  $from  Sender e-mail
  257.      * @param string  $to  Recipient e-mail
  258.      * @param string  $hdrs  Mail headers (in RFC)
  259.      * @param string  $body  Mail body (in RFC)
  260.      * @param bool    $delete_after_send  Delete or not mail from db after send
  261.      * @return mixed  ID of the record where this mail has been put
  262.      *                or Mail_Queue_Error on error
  263.      * @access public
  264.      */
  265.     function put($time_to_send, $id_user, $ip, $sender,
  266.                 $recipient, $headers, $body, $delete_after_send=true)
  267.     {
  268.         if (!is_object($this->db) || !is_a($this->db, 'MDB_Common')) {
  269.             $msg = 'MDB::connect failed';
  270.             if (PEAR::isError($this->db)) {
  271.                 $msg .= ': '.$this->db->getMessage();
  272.             }
  273.             return new Mail_Queue_Error(MAILQUEUE_ERROR_CANNOT_CONNECT,
  274.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__, $msg);
  275.         }
  276.         $id = $this->db->nextId($this->sequence);
  277.         if (empty($id)) {
  278.             return new Mail_Queue_Error(MAILQUEUE_ERROR,
  279.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  280.                 'Cannot create id in: '.$this->sequence);
  281.         }
  282.         $query = 'INSERT INTO '. $this->mail_table
  283.                 .' (id, create_time, time_to_send, id_user, ip'
  284.                 .', sender, recipient, delete_after_send) VALUES ('
  285.                 .       $this->db->getIntegerValue($id)
  286.                 .', ' . $this->db->getTimestampValue(date("Y-m-d H:i:s"))
  287.                 .', ' . $this->db->getTimestampValue($time_to_send)
  288.                 .', ' . $this->db->getIntegerValue($id_user)
  289.                 .', ' . $this->db->getTextValue($ip)
  290.                 .', ' . $this->db->getTextValue($sender)
  291.                 .', ' . $this->db->getTextValue($recipient)
  292.                 .', ' . ($delete_after_send ? 1 : 0)
  293.                 .')';
  294.         $res = $this->db->query($query);
  295.         if (PEAR::isError($res)) {
  296.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  297.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  298.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  299.         }
  300.         foreach (array('headers', 'body') as $field) {
  301.             $query = 'UPDATE ' . $this->mail_table .' SET ' .$field. '=?'
  302.                     .' WHERE id=' . $this->db->getIntegerValue($id);
  303.             if ($prepared_query = $this->db->prepareQuery($query)) {
  304.                 $char_lob = array('Error' => '',
  305.                                   'Type'  => 'data',
  306.                                   'Data'  => $$field);
  307.                 if (PEAR::isError($clob = $this->db->createLob($char_lob))) {
  308.                     return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  309.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  310.                         'MDB: query failed - "'.$query.'" - '.$clob->getMessage());
  311.                 }
  312.                 $this->db->setParamClob($prepared_query,1,$clob,$field);
  313.                 if (PEAR::isError($error = $this->db->executeQuery($prepared_query))) {
  314.                     return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  315.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  316.                         'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  317.                 }
  318.                 $this->db->destroyLob($clob);
  319.                 $this->db->freePreparedQuery($prepared_query);
  320.             } else {
  321.                 //prepared query failed
  322.                 return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  323.                         $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  324.                         'MDB: query failed - "'.$query.'" - '.$clob->getMessage());
  325.             }
  326.  
  327.         }
  328.         return $id;
  329.     }
  330.  
  331.     // }}}
  332.     // {{{ countSend()
  333.  
  334.     /**
  335.      * Check how many times mail was sent.
  336.      *
  337.      * @param object  Mail_Queue_Body
  338.      * @return mixed  Integer or Mail_Queue_Error class if error.
  339.      * @access public
  340.      */
  341.     function countSend($mail)
  342.     {
  343.         if (!is_object($mail) || !is_a($mail, 'mail_queue_body')) {
  344.             return new Mail_Queue_Error(MAILQUEUE_ERROR_UNEXPECTED,
  345.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  346.                 'Expected: Mail_Queue_Body class');
  347.         }
  348.         $count = $mail->_try();
  349.         $query = 'UPDATE ' . $this->mail_table
  350.                 .' SET try_sent = ' . $this->db->getIntegerValue($count)
  351.                 .' WHERE id = '     . $this->db->getIntegerValue($mail->getId());
  352.         $res = $this->db->query($query);
  353.  
  354.         if (PEAR::isError($res)) {
  355.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  356.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  357.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  358.         }
  359.         return $count;
  360.     }
  361.  
  362.     // }}}
  363.     // {{{ setAsSent()
  364.  
  365.     /**
  366.      * Set mail as already sent.
  367.      *
  368.      * @param object Mail_Queue_Body object
  369.      * @return bool
  370.      * @access public
  371.      */
  372.     function setAsSent($mail)
  373.     {
  374.         if (!is_object($mail) || !is_a($mail, 'mail_queue_body')) {
  375.             return new Mail_Queue_Error(MAILQUEUE_ERROR_UNEXPECTED,
  376.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  377.                 'Expected: Mail_Queue_Body class');
  378.         }
  379.         $query = 'UPDATE ' . $this->mail_table
  380.                 .' SET sent_time = '.$this->db->getTimestampValue(date("Y-m-d H:i:s"))
  381.                 .' WHERE id = '. $this->db->getIntegerValue($mail->getId());
  382.  
  383.         $res = $this->db->query($query);
  384.  
  385.         if (PEAR::isError($res)) {
  386.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  387.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  388.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  389.         }
  390.  
  391.         return true;
  392.     }
  393.  
  394.     // }}}
  395.     // {{{ getMailById()
  396.  
  397.     /**
  398.      * Return mail by id $id (bypass mail_queue)
  399.      *
  400.      * @param integer $id  Mail ID
  401.      * @return mixed  Mail object or false on error.
  402.      * @access public
  403.      */
  404.     function getMailById($id)
  405.     {
  406.         $query = 'SELECT * FROM ' . $this->mail_table
  407.                 .' WHERE id = '   . (int)$id;
  408.         $res = $this->db->query($query);
  409.         if (PEAR::isError($res)) {
  410.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  411.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  412.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  413.         }
  414.         $row = $this->db->fetchRow($res, MDB_FETCHMODE_ASSOC);
  415.         if (!is_array($row)) {
  416.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  417.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  418.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  419.         }
  420. /*
  421. //DISABLED (using a standard query, without LOBs special management:
  422. //it does not work with pgsql (there's probably a problem in the MDB pgsql driver)
  423.         $query = 'SELECT id, create_time, time_to_send, sent_time'
  424.                 .', id_user, ip, sender, recipient, delete_after_send'
  425.                 .', try_sent FROM ' . $this->mail_table
  426.                 .' WHERE id = '     . $this->db->getTextValue($id);
  427.         $res = $this->db->query($query);
  428.         if (MDB::isError($res)) {
  429.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  430.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  431.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  432.         }
  433.         $row = $this->db->fetchRow($res, MDB_FETCHMODE_ASSOC);
  434.         if (!is_array($row)) {
  435.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  436.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  437.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  438.         }
  439.         //now fetch lobs...
  440.         foreach (array('headers','body') as $field) {
  441.             $query = 'SELECT '.$field.' FROM ' . $this->mail_table
  442.                     .' WHERE id=' . $this->db->getIntegerValue($id);
  443.             $res = $this->db->query($query);
  444.             if (MDB::isError($res)) {
  445.                 //return new Mail_Queue_Error('MDB::query failed: '
  446.                 //          . $result->getMessage(), __FILE__, __LINE__);
  447.                 $row[$field] = ''; //Not sure if this is better than raising the error...
  448.             } else {
  449.                 if ($this->db->endOfResult($res)) {
  450.                     //no rows returned
  451.                     $row[$field] = '';
  452.                 } else {
  453.                     $clob = $this->db->fetchClob($res, 0, $field);
  454.                     if (MDB::isError($clob)) {
  455.                         return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  456.                             $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  457.                             'MDB: query failed - "'.$query.'" - '.$clob->getMessage());
  458.                     }
  459.  
  460.                     $row[$field] = '';
  461.                     while (!$this->db->endOfLOB($clob)) {
  462.                         if (MDB::isError($error =
  463.                                         $this->db->readLob($clob, $data, 8192) < 0)) {
  464.                             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  465.                                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  466.                                 'MDB: query failed - "'.$query.'" - '.$error->getMessage());
  467.                         }
  468.                         $row[$field] .= $data;
  469.                         unset($data);
  470.                     }
  471.                     $this->db->destroyLob($clob);
  472.                 }
  473.             }
  474.         }
  475. */
  476.         return new Mail_Queue_Body(
  477.             $row['id'],
  478.             $row['create_time'],
  479.             $row['time_to_send'],
  480.             $row['sent_time'],
  481.             $row['id_user'],
  482.             $row['ip'],
  483.             $row['sender'],
  484.             $this->_isSerialized($row['recipient']) ? unserialize($row['recipient']) : $row['recipient'],
  485.             unserialize($row['headers']),
  486.             unserialize($row['body']),
  487.             $row['delete_after_send'],
  488.             $row['try_sent']
  489.         );
  490.     }
  491.  
  492.     // }}}
  493.     // {{{ deleteMail()
  494.  
  495.     /**
  496.      * Remove from queue mail with $id identifier.
  497.      *
  498.      * @param integer $id  Mail ID
  499.      * @return bool  True on success else Mail_Queue_Error class
  500.      * @access public
  501.      */
  502.     function deleteMail($id) {
  503.         $query = 'DELETE FROM ' . $this->mail_table
  504.                 .' WHERE id = ' . $this->db->getTextValue($id);
  505.         $res = $this->db->query($query);
  506.         if (PEAR::isError($res)) {
  507.             return new Mail_Queue_Error(MAILQUEUE_ERROR_QUERY_FAILED,
  508.                 $this->pearErrorMode, E_USER_ERROR, __FILE__, __LINE__,
  509.                 'MDB: query failed - "'.$query.'" - '.$res->getMessage());
  510.         }
  511.         return true;
  512.     }
  513.  
  514.     // }}}
  515. }
  516. ?>