PageRenderTime 16ms CodeModel.GetById 10ms app.highlight 4ms RepoModel.GetById 0ms app.codeStats 0ms

/framework/vendor/swift/lib/classes/Swift/Plugins/DecoratorPlugin.php

http://zoop.googlecode.com/
PHP | 201 lines | 117 code | 15 blank | 69 comment | 16 complexity | 655b6626534c41c770c6478564252e2f MD5 | raw file
  1<?php
  2
  3/*
  4 * This file is part of SwiftMailer.
  5 * (c) 2004-2009 Chris Corbyn
  6 *
  7 * For the full copyright and license information, please view the LICENSE
  8 * file that was distributed with this source code.
  9 */
 10
 11//@require 'Swift/Events/SendListener.php';
 12//@require 'Swift/Events/SendEvent.php';
 13//@require 'Swift/Plugins/Decorator/Replacements.php';
 14
 15/**
 16 * Allows customization of Messages on-the-fly.
 17 * 
 18 * @package Swift
 19 * @subpackage Plugins
 20 * 
 21 * @author Chris Corbyn
 22 */
 23class Swift_Plugins_DecoratorPlugin
 24  implements Swift_Events_SendListener, Swift_Plugins_Decorator_Replacements
 25{
 26
 27  /** The replacement map */
 28  private $_replacements;
 29  
 30  /** The body as it was before replacements */
 31  private $_orginalBody;
 32
 33  /** The original subject of the message, before replacements */
 34  private $_originalSubject;
 35
 36  /** Bodies of children before they are replaced */
 37  private $_originalChildBodies = array();
 38
 39  /** The Message that was last replaced */
 40  private $_lastMessage;
 41
 42  /**
 43   * Create a new DecoratorPlugin with $replacements.
 44   * 
 45   * The $replacements can either be an associative array, or an implementation
 46   * of {@link Swift_Plugins_Decorator_Replacements}.
 47   * 
 48   * When using an array, it should be of the form:
 49   * <code>
 50   * $replacements = array(
 51   *  "address1@domain.tld" => array("{a}" => "b", "{c}" => "d"),
 52   *  "address2@domain.tld" => array("{a}" => "x", "{c}" => "y")
 53   * )
 54   * </code>
 55   * 
 56   * When using an instance of {@link Swift_Plugins_Decorator_Replacements},
 57   * the object should return just the array of replacements for the address
 58   * given to {@link Swift_Plugins_Decorator_Replacements::getReplacementsFor()}.
 59   * 
 60   * @param mixed $replacements
 61   */
 62  public function __construct($replacements)
 63  {
 64    if (!($replacements instanceof Swift_Plugins_Decorator_Replacements))
 65    {
 66      $this->_replacements = (array) $replacements;
 67    }
 68    else
 69    {
 70      $this->_replacements = $replacements;
 71    }
 72  }
 73
 74  /**
 75   * Invoked immediately before the Message is sent.
 76   * 
 77   * @param Swift_Events_SendEvent $evt
 78   */
 79  public function beforeSendPerformed(Swift_Events_SendEvent $evt)
 80  {
 81    $message = $evt->getMessage();
 82    $this->_restoreMessage($message);
 83    $to = array_keys($message->getTo());
 84    $address = array_shift($to);
 85    if ($replacements = $this->getReplacementsFor($address))
 86    {
 87      $body = $message->getBody();
 88      $search = array_keys($replacements);
 89      $replace = array_values($replacements);
 90      $bodyReplaced = str_replace(
 91        $search, $replace, $body
 92        );
 93      if ($body != $bodyReplaced)
 94      {
 95        $this->_originalBody = $body;
 96        $message->setBody($bodyReplaced);
 97      }
 98      $subject = $message->getSubject();
 99      $subjectReplaced = str_replace(
100        $search, $replace, $subject
101        );
102      if ($subject != $subjectReplaced)
103      {
104        $this->_originalSubject = $subject;
105        $message->setSubject($subjectReplaced);
106      }
107      $children = (array) $message->getChildren();
108      foreach ($children as $child)
109      {
110        list($type, ) = sscanf($child->getContentType(), '%[^/]/%s');
111        if ('text' == $type)
112        {
113          $body = $child->getBody();
114          $bodyReplaced = str_replace(
115            $search, $replace, $body
116            );
117          if ($body != $bodyReplaced)
118          {
119            $child->setBody($bodyReplaced);
120            $this->_originalChildBodies[$child->getId()] = $body;
121          }
122        }
123      }
124      $this->_lastMessage = $message;
125    }
126  }
127  
128  /**
129   * Find a map of replacements for the address.
130   * 
131   * If this plugin was provided with a delegate instance of
132   * {@link Swift_Plugins_Decorator_Replacements} then the call will be
133   * delegated to it.  Otherwise, it will attempt to find the replacements
134   * from the array provided in the constructor.
135   * 
136   * If no replacements can be found, an empty value (NULL) is returned.
137   * 
138   * @param string $address
139   * 
140   * @return array
141   */
142  public function getReplacementsFor($address)
143  {
144    if ($this->_replacements instanceof Swift_Plugins_Decorator_Replacements)
145    {
146      return $this->_replacements->getReplacementsFor($address);
147    }
148    else
149    {
150      return isset($this->_replacements[$address])
151        ? $this->_replacements[$address]
152        : null
153        ;
154    }
155  }
156
157  /**
158   * Invoked immediately after the Message is sent.
159   * 
160   * @param Swift_Events_SendEvent $evt
161   */
162  public function sendPerformed(Swift_Events_SendEvent $evt)
163  {
164    $this->_restoreMessage($evt->getMessage());
165  }
166
167  // -- Private methods
168
169  /** Restore a changed message back to its original state */
170  private function _restoreMessage(Swift_Mime_Message $message)
171  {
172    if ($this->_lastMessage === $message)
173    {
174      if (isset($this->_originalBody))
175      {
176        $message->setBody($this->_originalBody);
177        $this->_originalBody = null;
178      }
179      if (isset($this->_originalSubject))
180      {
181        $message->setSubject($this->_originalSubject);
182        $this->_originalSubject = null;
183      }
184      if (!empty($this->_originalChildBodies))
185      {
186        $children = (array) $message->getChildren();
187        foreach ($children as $child)
188        {
189          $id = $child->getId();
190          if (array_key_exists($id, $this->_originalChildBodies))
191          {
192            $child->setBody($this->_originalChildBodies[$id]);
193          }
194        }
195        $this->_originalChildBodies = array();
196      }
197      $this->_lastMessage = null;
198    }
199  }
200
201}