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