PHPonTrax
[ class tree: PHPonTrax ] [ index: PHPonTrax ] [ all elements ]

Source for file action_mailer.php

Documentation is available at action_mailer.php

  1. <?php
  2. /**
  3.  *  File for ActionMailer class
  4.  *
  5.  *  (PHP 5)
  6.  *
  7.  *  @package PHPonTrax
  8.  *  @version $Id: action_mailer.php 217 2006-06-07 02:37:36Z john $
  9.  *  @copyright (c) 2005 John Peterson
  10.  *
  11.  *   Permission is hereby granted, free of charge, to any person obtaining
  12.  *   a copy of this software and associated documentation files (the
  13.  *   "Software"), to deal in the Software without restriction, including
  14.  *   without limitation the rights to use, copy, modify, merge, publish,
  15.  *   distribute, sublicense, and/or sell copies of the Software, and to
  16.  *   permit persons to whom the Software is furnished to do so, subject to
  17.  *   the following conditions:
  18.  *
  19.  *   The above copyright notice and this permission notice shall be
  20.  *   included in all copies or substantial portions of the Software.
  21.  *
  22.  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23.  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24.  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25.  *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  26.  *   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  27.  *   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28.  *   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29.  */
  30.  
  31. /**
  32.  *
  33.  */
  34. include_once"Mail.php" );
  35. include_once"Mail/mime.php" );
  36.  
  37. /**
  38.  *
  39.  *  @package PHPonTrax
  40.  */
  41. class ActionMailer {
  42.  
  43.     
  44. private
  45.         $mail_mime = null,  # Mail_mime object
  46.         $mail = null# Mail object to deliver mail
  47.         $mime_params = array()# params for charset
  48.         $errors = array()# array to hold any errors
  49.     
  50. public
  51.         $smtp_settings = array
  52.             'host'      => 'localhost'# The server to connect.
  53.             'port'      => 25,  # The port to connect.
  54.             'persist'   => false# Indicates whether or not the SMTP connection should persist over multiple sends.
  55.             'auth'      => false# Whether or not to use SMTP authentication.
  56.             'username'  => null# The username to use for SMTP authentication.
  57.             'password'  => null# The password to use for SMTP authentication.            
  58.         ),
  59.         $sendmail_settings = array(
  60.             'path' => '/usr/sbin/sendmail',
  61.             'args' => '-i -t'
  62.         ),
  63.         $delivery_method = "mail"# mail | sendmail | smtp | test
  64.         $perform_deliveries = true# true will attempt to deliver mail | false will not deliver mail
  65.         $default_charset = "utf-8"# default charset for email.
  66.         $head_charset = null# charset for email headers.
  67.         $html_charset = null# charset for html email body.
  68.         $text_charset = null# charset for text email body.
  69.         $template = null# view file to use for body of email.
  70.         $template_root = null# template_root determines the base from which template references will be made.
  71.         $deliveries = array()# if delivery_method is "test" it will not deliver but store emails in this array.
  72.         $recipients = null# to address(es)
  73.         $subject = null# email subject
  74.         $from = null# from email address
  75.         $default_from = null# if no from specified use this as the from.
  76.         $body = array()# array set in child class of values for view template.
  77.         $preparse_body = array()# holder for orginal body array from child class
  78.         $headers = array()# email headers
  79.         $crlf = "\r\n"# linefeed char
  80.         $content_type = "text"# text | html | both
  81.  
  82.     /**
  83.      *  ActionMailer constructor.
  84.      *  @todo Document this API
  85.      */ 
  86.     function __construct({
  87.         $this->mail_mime = new Mail_mime($this->crlf);               
  88.     }
  89.  
  90.     /**
  91.      *  Override call() to do some magic where you can call create_*() and deliver_*().
  92.      *  @todo Document this API
  93.      */     
  94.     function __call($method_name$parameters{
  95.         if(method_exists($this$method_name)) {
  96.             # If the method exists, just call it
  97.             $result call_user_func_array(array($this,$method_name)$parameters);
  98.         else {
  99.             if(preg_match("/^create_([_a-z]\w*)/"$method_name$matches)) {
  100.                 $result $this->create_mail($matches[1]$parameters);
  101.             elseif(preg_match("/^deliver_([_a-z]\w*)/"$method_name$matches)) {              
  102.                 $result $this->create_mail($matches[1]$parameters);
  103.                 if(!$this->deliver($result)) {
  104.                     $result false;    
  105.                 }
  106.             }
  107.         }
  108.         return $result;
  109.     }
  110.  
  111.     /**
  112.      *  Set all the necessary email headers
  113.      *  @todo Document this API
  114.      */     
  115.     private function set_headers({
  116.         if(!is_null($this->recipients)) {
  117.             $recipients $this->format_emails($this->recipients"To");
  118.             $this->set_header_line("To"$recipients);            
  119.         }
  120.         
  121.         if(!is_null($this->cc)) {
  122.             $cc $this->format_emails($this->cc"Cc");
  123.             $this->set_header_line("Cc"$cc);            
  124.         }
  125.  
  126.         if(!is_null($this->bcc)) {
  127.             $bcc $this->format_emails($this->bcc"Bcc");
  128.             $this->set_header_line("Bcc"$bcc);            
  129.         }
  130.  
  131.         if(!is_null($this->reply_to)) {
  132.             $reply_to $this->format_emails($this->reply_to"Reply-To");
  133.             $this->set_header_line("Reply-To"$reply_to);            
  134.         }
  135.         
  136.         if(is_null($this->from|| $this->from == ''{
  137.             $this->from = $this->default_from;            
  138.         
  139.         $from $this->format_emails($this->from"From");
  140.         $this->set_header_line("From"$from);
  141.         
  142.         if(!is_null($this->subject))  {
  143.             $this->set_header_line("Subject"$this->subject);
  144.         else {
  145.             $this->set_header_line("Subject""");
  146.         }
  147.  
  148.         if(!array_key_exists("Date"$this->headers)) {
  149.             $this->set_header_line("Date"date("r"));
  150.         }
  151.         
  152.         if(!array_key_exists("Return-Path"$this->headers&& !is_null($this->from_address)) {
  153.             $this->set_header_line("Return-Path"$this->from_address);
  154.         }  
  155.           
  156.         if(!array_key_exists("Reply-To"$this->headers&& !is_null($this->from_address)) {
  157.             $this->set_header_line("Reply-To"$this->from_address);            
  158.         }
  159.     }
  160.  
  161.     /**
  162.      *  Format an array of emails into a correct string / validate emails.
  163.      *  @todo Document this API
  164.      */    
  165.     private function format_emails($emails$type null{
  166.      
  167.         $email_addresses null;     
  168.         if(!is_null($emails&& is_string($emails)) {
  169.             if(strstr($emails",")) {
  170.                 $emails explode(","$emails);        
  171.             else {
  172.                 $emails array($emails);    
  173.             }    
  174.         }        
  175.         if(is_array($emails)) {
  176.             foreach($emails as $email{
  177.                 if($this->validate_email($email)) {
  178.                     $email_addresses[$email;
  179.                 else {
  180.                     if($type{
  181.                         $type "$type ";    
  182.                     }
  183.                     $this->errors["Invalid ".$type."email address: ".$email;    
  184.                 }
  185.             }
  186.             if(is_array($email_addresses)) {
  187.                 $email_addresses implode(","$email_addresses);
  188.             }                     
  189.         }      
  190.  
  191.         return $email_addresses;           
  192.     }
  193.  
  194.     /**
  195.      *  Set the text body of the email.
  196.      *  @todo Document this API
  197.      */    
  198.     private function set_text_body($text{
  199.         if(strlen($text0{
  200.             $this->mail_mime->setTxtBody($text);
  201.         }
  202.     }
  203.  
  204.     /**
  205.      *  Set the html body of the email.
  206.      *  @todo Document this API
  207.      */
  208.     private function set_html_body($html{
  209.         if(strlen($html0{
  210.             $this->mail_mime->setHTMLBody($html);
  211.         }
  212.     }    
  213.  
  214.     /**
  215.      *  Sets up default class variables for this mailer.  Classes extending
  216.      *  ActionMailer can override these values.
  217.      *  @todo Document this API
  218.      */
  219.     private function initialize_defaults($method_name{       
  220.         $this->template_root = Trax::$views_path;
  221.         $this->template_path "{$this->template_root}/".Inflector::underscore(get_class($this));
  222.         $this->template = $this->template ? $this->template : $method_name;        
  223.         $this->headers = $this->headers ? $this->headers : array();
  224.         $this->body = $this->body ? $this->body : array();
  225.         $this->default_from = "nobody@".$_SERVER['HTTP_HOST'];
  226.         $this->head_charset = $this->head_charset ? $this->head_charset : $this->default_charset;
  227.         $this->html_charset = $this->html_charset ? $this->html_charset : $this->default_charset;
  228.         $this->text_charset = $this->text_charset ? $this->text_charset : $this->default_charset;
  229.         $this->mime_params = array(
  230.             'head_charset' => $this->head_charset
  231.             'html_charset' =>  $this->html_charset,
  232.             'text_charset' =>  $this->
  233.         );         
  234.     }
  235.  
  236.     /**
  237.      *  Sets up and creates the email for deliver().
  238.      *  @todo Document this API
  239.      */
  240.     private function create_mail($method_name, $parameters = array()) {  
  241.         $this->initialize_defaults($method_name);
  242.         if(method_exists($this$method_name)) {
  243.             //echo "calling $method_name<br>";
  244.             call_user_func_array(array($this, $method_name), $parameters);   
  245.         }   
  246.         $this->set_headers();
  247.         $body $this->preparse_body = $this->body;
  248.         if(!is_string($body)) {
  249.             $body = $this->render_message($method_name$body);
  250.         }
  251.         if($this->content_type == "html"{
  252.             $this->set_html_body($body);       
  253.         } elseif($this->content_type == "both"{
  254.             $this->set_html_body($body)
  255.             $this->set_text_body($body);   
  256.         } else {
  257.             $this->set_text_body($body);        
  258.         }
  259.            
  260.         $this->body = $this->mail_mime->get($this->mime_params);      
  261.         $this->headers = $this->mail_mime->headers($this->headers);  
  262.         $this->headers['Subject'ereg_replace("[\n\r]"""$this->headers['Subject'])
  263.  
  264.         if($this->delivery_method == "sendmail"{
  265.             $this->mail =Mail::factory("sendmail"$this->sendmail_settings);
  266.         } elseif($this->delivery_method == "smtp"{
  267.             $this->mail =Mail::factory("smtp"$this->smtp_settings);
  268.         } else {
  269.             $this->mail =Mail::factory("mail");    
  270.         }
  271.  
  272.         return $this;
  273.     }
  274.  
  275.     /**
  276.      *  Load the template view file for the body of the email.
  277.      *  @todo Document this API
  278.      */
  279.     function render_message($method_name, $body = array()) {
  280.         if(strstr($method_name, "/")) {
  281.             $template = "{$this->template_root}/{$method_name}.".Trax::$views_extension;
  282.         } else {
  283.             $template = "{$this->template_path}/{$method_name}.".Trax::$views_extension;
  284.         }
  285.  
  286.         if(file_exists($template)) {
  287.             # start to buffer output
  288.             ob_start(); 
  289.             if(count($body)) {
  290.                 extract($body);  
  291.             }
  292.             include($template);
  293.             $result = ob_get_contents();
  294.             ob_end_clean();
  295.         }
  296.         return $result;        
  297.     }
  298.  
  299.     /**
  300.      *  Uses ActionControllers render_partial method.
  301.      *  @todo Document this API
  302.      */      
  303.     function render_partial($path, $options = array()) {
  304.         $locals = $this->preparse_body;
  305.         if(is_array($options['locals']&& is_array($locals)) {
  306.             $options['locals'] = array_merge($locals, $options['locals']);
  307.         } elseif(is_array($locals)) {
  308.             $options['locals'] = $locals;    
  309.         }
  310.         $ar = new ActionController();
  311.         $ar->views_path $this->template_path;
  312.         $ar->render_partial($path$options);                     
  313.     }
  314.  
  315.     /**
  316.      *  Return a text version of the email currently loaded.
  317.      *  @todo Document this API
  318.      */    
  319.     function encoded($add_pre_tags = false) {                   
  320.         if(!count($this->errors)) {
  321.             list(, $text_headers) = $this->mail->prepareHeaders($this->headers);
  322.             $email $text_headers.$this->crlf.$this->crlf.$this->body;
  323.             if($add_pre_tags{
  324.                 $email = "<pre>".$email."</pre>";    
  325.             }
  326.         } else {
  327.             $email = $this->get_errors_as_string("\n");    
  328.         }
  329.         return $email;
  330.     }
  331.  
  332.     /**
  333.      *  Sends the email loaded into this object via create_mail().
  334.      *  @todo Document this API
  335.      */    
  336.     function deliver($mail = null) {
  337.         if(is_null($mail)) {
  338.             $mail =& $this;               
  339.         } 
  340.         if($this->perform_deliveries{
  341.             if($this->delivery_method == "test"{
  342.                 $this->deliveries[$mail->encoded();
  343.                 return true;    
  344.             }
  345.             if(!count($this->errors)) { 
  346.                 $result = $mail->mail->send(null$mail->headers$mail->body);
  347.                 if(is_object($result)) { 
  348.                     $this->errors[$result->getMessage();
  349.                     return false;
  350.                 } 
  351.             } else {
  352.                 return false;
  353.             }
  354.         }
  355.         return true;
  356.     }
  357.  
  358.     /**
  359.      *  Add an attachment to an email.
  360.      *  @todo Document this API
  361.      */
  362.     function add_attachment($file, $content_type ='application/octet-stream', $file_name = '', $is_file = true, $encoding = 'base64') {
  363.         $this->mail_mime->addAttachment($file$content_type$file_name$is_file$encoding);
  364.     }
  365.  
  366.     /**
  367.      *  Validates a single email address
  368.      *
  369.      *  @param string $email
  370.      *    Validates the input $email is in format:
  371.      *      user@domain.com or "John Smith <user@domain.com>"
  372.      *  @return boolean 
  373.      *    <ul>
  374.      *      <li>true => Valid email, no errors found.
  375.      *      <li>false => Email not valid</li>
  376.      *    </ul>
  377.      */
  378.     function validate_email($email) {
  379.         if(eregi("^[a-zA-Z0-9._-]+@([a-zA-Z0-9._-]+\.)+([a-zA-Z0-9_-]){2,4}$", $email) ||
  380.            eregi("^([ '_a-zA-Z0-9]\w*)+<[a-zA-Z0-9._-]+@([a-zA-Z0-9._-]+\.)+([a-zA-Z0-9_-]){2,4}>$", $email)) {
  381.             return true;
  382.         }
  383.         return false;
  384.     }
  385.  
  386.     /**
  387.      *  Set a single line for the header of an email
  388.      *
  389.      *  @uses $headers
  390.      *  @param string $header_key
  391.      *    key for the header line (To:, From:, Subject:, etc)
  392.      *  @param string $header_value
  393.      *    value for the $header_key 
  394.      */
  395.     function set_header_line($header_key, $header_value) {
  396.         if($header_key && $header_value) {
  397.             $this->headers[$header_key$header_value;
  398.         }
  399.     }
  400.     
  401.     /**
  402.      *  Add or overwrite description of an error to the list of errors
  403.      *  @param string $error Error message text
  404.      *  @param string $key Key to associate with the error (in the
  405.      *    simple case, column name).  If omitted, numeric keys will be
  406.      *    assigned starting with 0.  If specified and the key already
  407.      *    exists in $errors, the old error message will be overwritten
  408.      *    with the value of $error.
  409.      *  @uses $errors
  410.      */
  411.     function add_error($error, $key = null) {
  412.         if(!is_null($key)) { 
  413.             $this->errors[$key$error;
  414.         } else {
  415.             $this->errors[$error;
  416.         }
  417.     }
  418.     
  419.     /**
  420.      *  Return description of non-fatal errors
  421.      *
  422.      *  @uses $errors
  423.      *  @param boolean $return_string
  424.      *    <ul>
  425.      *      <li>true => Concatenate all error descriptions into a string
  426.      *        using $seperator between elements and return the
  427.      *        string</li>
  428.      *      <li>false => Return the error descriptions as an array</li>
  429.      *    </ul>
  430.      *  @param string $seperator  String to concatenate between error
  431.      *    descriptions if $return_string == true
  432.      *  @return mixed Error description(s), if any
  433.      */
  434.     function get_errors($return_string = false, $seperator = "<br>") {
  435.         if($return_string && count($this->errors0{
  436.             return implode($seperator, $this->errors);
  437.         } else {
  438.             return $this->errors;
  439.         }
  440.     }
  441.  
  442.     /**
  443.      *  Return errors as a string.
  444.      *
  445.      *  Concatenate all error descriptions into a stringusing
  446.      *  $seperator between elements and return the string.
  447.      *  @param string $seperator  String to concatenate between error
  448.      *    descriptions
  449.      *  @return string Concatenated error description(s), if any
  450.      */
  451.     function get_errors_as_string($seperator = "<br>") {
  452.         return $this->get_errors(true$seperator);
  453.     }
  454.  
  455. }
  456.  
  457.  

Documentation generated on Mon, 21 May 2007 22:27:52 -0600 by phpDocumentor 1.3.2