TYPO3 API  SVNRelease
DecoratorPlugin.php
Go to the documentation of this file.
00001 <?php
00002 
00003 /*
00004  * This file is part of SwiftMailer.
00005  * (c) 2004-2009 Chris Corbyn
00006  *
00007  * For the full copyright and license information, please view the LICENSE
00008  * file that was distributed with this source code.
00009  */
00010 
00011 //@require 'Swift/Events/SendListener.php';
00012 //@require 'Swift/Events/SendEvent.php';
00013 //@require 'Swift/Plugins/Decorator/Replacements.php';
00014 
00015 /**
00016  * Allows customization of Messages on-the-fly.
00017  *
00018  * @package Swift
00019  * @subpackage Plugins
00020  *
00021  * @author Chris Corbyn
00022  */
00023 class Swift_Plugins_DecoratorPlugin
00024   implements Swift_Events_SendListener, Swift_Plugins_Decorator_Replacements
00025 {
00026 
00027   /** The replacement map */
00028   private $_replacements;
00029 
00030   /** The body as it was before replacements */
00031   private $_orginalBody;
00032 
00033   /** The original subject of the message, before replacements */
00034   private $_originalSubject;
00035 
00036   /** Bodies of children before they are replaced */
00037   private $_originalChildBodies = array();
00038 
00039   /** The Message that was last replaced */
00040   private $_lastMessage;
00041 
00042   /**
00043    * Create a new DecoratorPlugin with $replacements.
00044    *
00045    * The $replacements can either be an associative array, or an implementation
00046    * of {@link Swift_Plugins_Decorator_Replacements}.
00047    *
00048    * When using an array, it should be of the form:
00049    * <code>
00050    * $replacements = array(
00051    *  "address1@domain.tld" => array("{a}" => "b", "{c}" => "d"),
00052    *  "address2@domain.tld" => array("{a}" => "x", "{c}" => "y")
00053    * )
00054    * </code>
00055    *
00056    * When using an instance of {@link Swift_Plugins_Decorator_Replacements},
00057    * the object should return just the array of replacements for the address
00058    * given to {@link Swift_Plugins_Decorator_Replacements::getReplacementsFor()}.
00059    *
00060    * @param mixed $replacements
00061    */
00062   public function __construct($replacements)
00063   {
00064     if (!($replacements instanceof Swift_Plugins_Decorator_Replacements))
00065     {
00066       $this->_replacements = (array) $replacements;
00067     }
00068     else
00069     {
00070       $this->_replacements = $replacements;
00071     }
00072   }
00073 
00074   /**
00075    * Invoked immediately before the Message is sent.
00076    *
00077    * @param Swift_Events_SendEvent $evt
00078    */
00079   public function beforeSendPerformed(Swift_Events_SendEvent $evt)
00080   {
00081     $message = $evt->getMessage();
00082     $this->_restoreMessage($message);
00083     $to = array_keys($message->getTo());
00084     $address = array_shift($to);
00085     if ($replacements = $this->getReplacementsFor($address))
00086     {
00087       $body = $message->getBody();
00088       $search = array_keys($replacements);
00089       $replace = array_values($replacements);
00090       $bodyReplaced = str_replace(
00091         $search, $replace, $body
00092         );
00093       if ($body != $bodyReplaced)
00094       {
00095         $this->_originalBody = $body;
00096         $message->setBody($bodyReplaced);
00097       }
00098       $subject = $message->getSubject();
00099       $subjectReplaced = str_replace(
00100         $search, $replace, $subject
00101         );
00102       if ($subject != $subjectReplaced)
00103       {
00104         $this->_originalSubject = $subject;
00105         $message->setSubject($subjectReplaced);
00106       }
00107       $children = (array) $message->getChildren();
00108       foreach ($children as $child)
00109       {
00110         list($type, ) = sscanf($child->getContentType(), '%[^/]/%s');
00111         if ('text' == $type)
00112         {
00113           $body = $child->getBody();
00114           $bodyReplaced = str_replace(
00115             $search, $replace, $body
00116             );
00117           if ($body != $bodyReplaced)
00118           {
00119             $child->setBody($bodyReplaced);
00120             $this->_originalChildBodies[$child->getId()] = $body;
00121           }
00122         }
00123       }
00124       $this->_lastMessage = $message;
00125     }
00126   }
00127 
00128   /**
00129    * Find a map of replacements for the address.
00130    *
00131    * If this plugin was provided with a delegate instance of
00132    * {@link Swift_Plugins_Decorator_Replacements} then the call will be
00133    * delegated to it.  Otherwise, it will attempt to find the replacements
00134    * from the array provided in the constructor.
00135    *
00136    * If no replacements can be found, an empty value (NULL) is returned.
00137    *
00138    * @param string $address
00139    *
00140    * @return array
00141    */
00142   public function getReplacementsFor($address)
00143   {
00144     if ($this->_replacements instanceof Swift_Plugins_Decorator_Replacements)
00145     {
00146       return $this->_replacements->getReplacementsFor($address);
00147     }
00148     else
00149     {
00150       return isset($this->_replacements[$address])
00151         ? $this->_replacements[$address]
00152         : null
00153         ;
00154     }
00155   }
00156 
00157   /**
00158    * Invoked immediately after the Message is sent.
00159    *
00160    * @param Swift_Events_SendEvent $evt
00161    */
00162   public function sendPerformed(Swift_Events_SendEvent $evt)
00163   {
00164     $this->_restoreMessage($evt->getMessage());
00165   }
00166 
00167   // -- Private methods
00168 
00169   /** Restore a changed message back to its original state */
00170   private function _restoreMessage(Swift_Mime_Message $message)
00171   {
00172     if ($this->_lastMessage === $message)
00173     {
00174       if (isset($this->_originalBody))
00175       {
00176         $message->setBody($this->_originalBody);
00177         $this->_originalBody = null;
00178       }
00179       if (isset($this->_originalSubject))
00180       {
00181         $message->setSubject($this->_originalSubject);
00182         $this->_originalSubject = null;
00183       }
00184       if (!empty($this->_originalChildBodies))
00185       {
00186         $children = (array) $message->getChildren();
00187         foreach ($children as $child)
00188         {
00189           $id = $child->getId();
00190           if (array_key_exists($id, $this->_originalChildBodies))
00191           {
00192             $child->setBody($this->_originalChildBodies[$id]);
00193           }
00194         }
00195         $this->_originalChildBodies = array();
00196       }
00197       $this->_lastMessage = null;
00198     }
00199   }
00200 
00201 }