/framework/lib/swift/classes/Swift/Plugins/DecoratorPlugin.php
PHP | 212 lines | 121 code | 17 blank | 74 comment | 23 complexity | 28bd8023fa7df9ab85b5758867d59741 MD5 | raw file
- <?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 Array or Swift_Plugins_Decorator_Replacements
- */
- public function __construct($replacements)
- {
- $this->setReplacements($replacements);
- }
- /**
- * Sets replacements.
- *
- * @param mixed $replacements Array or Swift_Plugins_Decorator_Replacements
- *
- * @see __construct()
- */
- public function setReplacements($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;
- }
- }
- }