Added feature #15998: Create a new API to send mails based on SwiftMailer to replace...
[Packages/TYPO3.CMS.git] / typo3 / contrib / swiftmailer / classes / Swift / Plugins / DecoratorPlugin.php
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 */
23 class 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 }