1<?php 2 3/* 4 * This file is part of SwiftMailer. 5 * (c) 2009 Fabien Potencier 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/** 12 * Redirects all email to a single recipient. 13 * 14 * @author Fabien Potencier 15 */ 16class Swift_Plugins_RedirectingPlugin implements Swift_Events_SendListener 17{ 18 /** 19 * The recipient who will receive all messages. 20 * 21 * @var mixed 22 */ 23 private $recipient; 24 25 /** 26 * List of regular expression for recipient whitelisting. 27 * 28 * @var array 29 */ 30 private $whitelist = array(); 31 32 /** 33 * Create a new RedirectingPlugin. 34 * 35 * @param mixed $recipient 36 * @param array $whitelist 37 */ 38 public function __construct($recipient, array $whitelist = array()) 39 { 40 $this->recipient = $recipient; 41 $this->whitelist = $whitelist; 42 } 43 44 /** 45 * Set the recipient of all messages. 46 * 47 * @param mixed $recipient 48 */ 49 public function setRecipient($recipient) 50 { 51 $this->recipient = $recipient; 52 } 53 54 /** 55 * Get the recipient of all messages. 56 * 57 * @return mixed 58 */ 59 public function getRecipient() 60 { 61 return $this->recipient; 62 } 63 64 /** 65 * Set a list of regular expressions to whitelist certain recipients. 66 * 67 * @param array $whitelist 68 */ 69 public function setWhitelist(array $whitelist) 70 { 71 $this->whitelist = $whitelist; 72 } 73 74 /** 75 * Get the whitelist. 76 * 77 * @return array 78 */ 79 public function getWhitelist() 80 { 81 return $this->whitelist; 82 } 83 84 /** 85 * Invoked immediately before the Message is sent. 86 * 87 * @param Swift_Events_SendEvent $evt 88 */ 89 public function beforeSendPerformed(Swift_Events_SendEvent $evt) 90 { 91 $message = $evt->getMessage(); 92 $headers = $message->getHeaders(); 93 94 // conditionally save current recipients 95 96 if ($headers->has('to')) { 97 $headers->addMailboxHeader('X-Swift-To', $message->getTo()); 98 } 99 100 if ($headers->has('cc')) { 101 $headers->addMailboxHeader('X-Swift-Cc', $message->getCc()); 102 } 103 104 if ($headers->has('bcc')) { 105 $headers->addMailboxHeader('X-Swift-Bcc', $message->getBcc()); 106 } 107 108 // Filter remaining headers against whitelist 109 $this->filterHeaderSet($headers, 'To'); 110 $this->filterHeaderSet($headers, 'Cc'); 111 $this->filterHeaderSet($headers, 'Bcc'); 112 113 // Add each hard coded recipient 114 $to = $message->getTo(); 115 if (null === $to) { 116 $to = array(); 117 } 118 119 foreach ((array) $this->recipient as $recipient) { 120 if (!array_key_exists($recipient, $to)) { 121 $message->addTo($recipient); 122 } 123 } 124 } 125 126 /** 127 * Filter header set against a whitelist of regular expressions. 128 * 129 * @param Swift_Mime_SimpleHeaderSet $headerSet 130 * @param string $type 131 */ 132 private function filterHeaderSet(Swift_Mime_SimpleHeaderSet $headerSet, $type) 133 { 134 foreach ($headerSet->getAll($type) as $headers) { 135 $headers->setNameAddresses($this->filterNameAddresses($headers->getNameAddresses())); 136 } 137 } 138 139 /** 140 * Filtered list of addresses => name pairs. 141 * 142 * @param array $recipients 143 * 144 * @return array 145 */ 146 private function filterNameAddresses(array $recipients) 147 { 148 $filtered = array(); 149 150 foreach ($recipients as $address => $name) { 151 if ($this->isWhitelisted($address)) { 152 $filtered[$address] = $name; 153 } 154 } 155 156 return $filtered; 157 } 158 159 /** 160 * Matches address against whitelist of regular expressions. 161 * 162 * @param $recipient 163 * 164 * @return bool 165 */ 166 protected function isWhitelisted($recipient) 167 { 168 if (in_array($recipient, (array) $this->recipient)) { 169 return true; 170 } 171 172 foreach ($this->whitelist as $pattern) { 173 if (preg_match($pattern, $recipient)) { 174 return true; 175 } 176 } 177 178 return false; 179 } 180 181 /** 182 * Invoked immediately after the Message is sent. 183 * 184 * @param Swift_Events_SendEvent $evt 185 */ 186 public function sendPerformed(Swift_Events_SendEvent $evt) 187 { 188 $this->restoreMessage($evt->getMessage()); 189 } 190 191 private function restoreMessage(Swift_Mime_SimpleMessage $message) 192 { 193 // restore original headers 194 $headers = $message->getHeaders(); 195 196 if ($headers->has('X-Swift-To')) { 197 $message->setTo($headers->get('X-Swift-To')->getNameAddresses()); 198 $headers->removeAll('X-Swift-To'); 199 } else { 200 $message->setTo(null); 201 } 202 203 if ($headers->has('X-Swift-Cc')) { 204 $message->setCc($headers->get('X-Swift-Cc')->getNameAddresses()); 205 $headers->removeAll('X-Swift-Cc'); 206 } 207 208 if ($headers->has('X-Swift-Bcc')) { 209 $message->setBcc($headers->get('X-Swift-Bcc')->getNameAddresses()); 210 $headers->removeAll('X-Swift-Bcc'); 211 } 212 } 213} 214