123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- <?php
-
- /*
- * This file is part of SwiftMailer.
- * (c) 2004-2009 Chris Corbyn
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-
- /**
- * Allows customization of Messages on-the-fly.
- *
- * @package Swift
- * @subpackage Plugins
- *
- * @author Chris Corbyn
- * @author Fabien Potencier
- */
- class Swift_Plugins_DecoratorPlugin
- implements Swift_Events_SendListener, Swift_Plugins_Decorator_Replacements
- {
-
- /** The replacement map */
- private $_replacements;
-
- /** The body as it was before replacements */
- private $_originalBody;
-
- /** The original headers of the message, before replacements */
- private $_originalHeaders = array();
-
- /** Bodies of children before they are replaced */
- private $_originalChildBodies = array();
-
- /** The Message that was last replaced */
- private $_lastMessage;
-
- /**
- * Create a new DecoratorPlugin with $replacements.
- *
- * The $replacements can either be an associative array, or an implementation
- * of {@link Swift_Plugins_Decorator_Replacements}.
- *
- * When using an array, it should be of the form:
- * <code>
- * $replacements = array(
- * "address1@domain.tld" => array("{a}" => "b", "{c}" => "d"),
- * "address2@domain.tld" => array("{a}" => "x", "{c}" => "y")
- * )
- * </code>
- *
- * When using an instance of {@link Swift_Plugins_Decorator_Replacements},
- * the object should return just the array of replacements for the address
- * given to {@link Swift_Plugins_Decorator_Replacements::getReplacementsFor()}.
- *
- * @param mixed $replacements
- */
- public function __construct($replacements)
- {
- if (!($replacements instanceof Swift_Plugins_Decorator_Replacements))
- {
- $this->_replacements = (array) $replacements;
- }
- else
- {
- $this->_replacements = $replacements;
- }
- }
-
- /**
- * Invoked immediately before the Message is sent.
- *
- * @param Swift_Events_SendEvent $evt
- */
- public function beforeSendPerformed(Swift_Events_SendEvent $evt)
- {
- $message = $evt->getMessage();
- $this->_restoreMessage($message);
- $to = array_keys($message->getTo());
- $address = array_shift($to);
- if ($replacements = $this->getReplacementsFor($address))
- {
- $body = $message->getBody();
- $search = array_keys($replacements);
- $replace = array_values($replacements);
- $bodyReplaced = str_replace(
- $search, $replace, $body
- );
- if ($body != $bodyReplaced)
- {
- $this->_originalBody = $body;
- $message->setBody($bodyReplaced);
- }
-
- foreach ($message->getHeaders()->getAll() as $header)
- {
- $body = $header->getFieldBodyModel();
- $count = 0;
- if (is_array($body))
- {
- $bodyReplaced = array();
- foreach ($body as $key => $value)
- {
- $count1 = 0;
- $count2 = 0;
- $key = is_string($key) ? str_replace($search, $replace, $key, $count1) : $key;
- $value = is_string($value) ? str_replace($search, $replace, $value, $count2) : $value;
- $bodyReplaced[$key] = $value;
-
- if (!$count && ($count1 || $count2))
- {
- $count = 1;
- }
- }
- }
- else
- {
- $bodyReplaced = str_replace($search, $replace, $body, $count);
- }
-
- if ($count)
- {
- $this->_originalHeaders[$header->getFieldName()] = $body;
- $header->setFieldBodyModel($bodyReplaced);
- }
- }
-
- $children = (array) $message->getChildren();
- foreach ($children as $child)
- {
- list($type, ) = sscanf($child->getContentType(), '%[^/]/%s');
- if ('text' == $type)
- {
- $body = $child->getBody();
- $bodyReplaced = str_replace(
- $search, $replace, $body
- );
- if ($body != $bodyReplaced)
- {
- $child->setBody($bodyReplaced);
- $this->_originalChildBodies[$child->getId()] = $body;
- }
- }
- }
- $this->_lastMessage = $message;
- }
- }
-
- /**
- * Find a map of replacements for the address.
- *
- * If this plugin was provided with a delegate instance of
- * {@link Swift_Plugins_Decorator_Replacements} then the call will be
- * delegated to it. Otherwise, it will attempt to find the replacements
- * from the array provided in the constructor.
- *
- * If no replacements can be found, an empty value (NULL) is returned.
- *
- * @param string $address
- *
- * @return array
- */
- public function getReplacementsFor($address)
- {
- if ($this->_replacements instanceof Swift_Plugins_Decorator_Replacements)
- {
- return $this->_replacements->getReplacementsFor($address);
- }
- else
- {
- return isset($this->_replacements[$address])
- ? $this->_replacements[$address]
- : null
- ;
- }
- }
-
- /**
- * Invoked immediately after the Message is sent.
- *
- * @param Swift_Events_SendEvent $evt
- */
- public function sendPerformed(Swift_Events_SendEvent $evt)
- {
- $this->_restoreMessage($evt->getMessage());
- }
-
- // -- Private methods
-
- /** Restore a changed message back to its original state */
- private function _restoreMessage(Swift_Mime_Message $message)
- {
- if ($this->_lastMessage === $message)
- {
- if (isset($this->_originalBody))
- {
- $message->setBody($this->_originalBody);
- $this->_originalBody = null;
- }
- if (!empty($this->_originalHeaders))
- {
- foreach ($message->getHeaders()->getAll() as $header)
- {
- if (array_key_exists($header->getFieldName(), $this->_originalHeaders))
- {
- $header->setFieldBodyModel($this->_originalHeaders[$header->getFieldName()]);
- }
- }
- $this->_originalHeaders = array();
- }
- if (!empty($this->_originalChildBodies))
- {
- $children = (array) $message->getChildren();
- foreach ($children as $child)
- {
- $id = $child->getId();
- if (array_key_exists($id, $this->_originalChildBodies))
- {
- $child->setBody($this->_originalChildBodies[$id]);
- }
- }
- $this->_originalChildBodies = array();
- }
- $this->_lastMessage = null;
- }
- }
-
- }
|