Srv Bebeboutik 340bc7c146 push site
2016-01-04 12:48:08 +01:00

260 lines
7.5 KiB
PHP
Executable File

<?php
/**
* Swift Mailer Message Decorating Plugin.
* Please read the LICENSE file
* @author Chris Corbyn <chris@w3style.co.uk>
* @package Swift_Plugin
* @subpackage Decorator
* @license GNU Lesser General Public License
*/
require_once dirname(__FILE__) . "/../ClassLoader.php";
Swift_ClassLoader::load("Swift_Events_BeforeSendListener");
Swift_ClassLoader::load("Swift_Plugin_Decorator_Replacements");
/**
* Swift Decorator Plugin.
* Allows messages to be slightly different for each recipient.
* @package Swift_Plugin
* @subpackage Decorator
* @author Chris Corbyn <chris@w3style.co.uk>
*/
class Swift_Plugin_Decorator implements Swift_Events_BeforeSendListener
{
/**
* The replacements object.
* @var Swift_Plugin_Decorator_Replacements
*/
protected $replacements;
/**
* Temporary storage so we can restore changes we make.
* @var array
*/
protected $store;
/**
* A list of allowed mime types to replace bodies for.
* @var array
*/
protected $permittedTypes = array("text/plain" => 1, "text/html" => 1);
/**
* True if values in the headers can be replaced
* @var boolean
*/
protected $permittedInHeaders = true;
/**
* Ctor.
* @param mixed Replacements as a 2-d array or Swift_Plugin_Decorator_Replacements instance.
*/
public function __construct($replacements=null)
{
$this->setReplacements($replacements);
}
/**
* Enable of disable the ability to replace values in the headers
* @param boolean
*/
public function setPermittedInHeaders($bool)
{
$this->permittedInHeaders = (bool) $bool;
}
/**
* Check if replacements in headers are allowed.
* @return boolean
*/
public function getPermittedInHeaders()
{
return $this->permittedInHeaders;
}
/**
* Add a mime type to the list of permitted type to replace values in the body.
* @param string The mime type (e.g. text/plain)
*/
public function addPermittedType($type)
{
$type = strtolower($type);
$this->permittedTypes[$type] = 1;
}
/**
* Remove the ability to replace values in the body of the given mime type
* @param string The mime type
*/
public function removePermittedType($type)
{
unset($this->permittedTypes[$type]);
}
/**
* Get the list of mime types for which the body can be changed.
* @return array
*/
public function getPermittedTypes()
{
return array_keys($this->permittedTypes);
}
/**
* Check if the body can be replaced in the given mime type.
* @param string The mime type
* @return boolean
*/
public function isPermittedType($type)
{
return array_key_exists(strtolower($type), $this->permittedTypes);
}
/**
* Called just before Swift sends a message.
* We perform operations on the message here.
* @param Swift_Events_SendEvent The event object for sending a message
*/
public function beforeSendPerformed(Swift_Events_SendEvent $e)
{
$message = $e->getMessage();
$this->recursiveRestore($message, $this->store); //3.3.3 bugfix
$recipients = $e->getRecipients();
$to = array_keys($recipients->getTo());
if (count($to) > 0) $to = $to[0];
else return;
$replacements = (array)$this->replacements->getReplacementsFor($to);
$this->store = array(
"headers" => array(),
"body" => false,
"children" => array()
);
$this->recursiveReplace($message, $replacements, $this->store);
}
/**
* Replace strings in the message searching through all the allowed sub-parts.
* @param Swift_Message_Mime The message (or part)
* @param array The list of replacements
* @param array The array to cache original values into where needed
*/
protected function recursiveReplace(Swift_Message_Mime $mime, $replacements, &$store)
{
//Check headers
if ($this->getPermittedInHeaders())
{
foreach ($mime->headers->getList() as $name => $value)
{
if (is_string($value) && ($replaced = $this->replace($replacements, $value)) != $value)
{
$mime->headers->set($name, $replaced);
$store["headers"][$name] = array();
$store["headers"][$name]["value"] = $value;
$store["headers"][$name]["attributes"] = array();
}
foreach ($mime->headers->listAttributes($name) as $att_name => $att_value)
{
if (is_string($att_value)
&& ($att_replaced = $this->replace($replacements, $att_value)) != $att_value)
{
if (!isset($store["headers"][$name]))
{
$store["headers"][$name] = array("value" => false, "attributes" => array());
}
$mime->headers->setAttribute($name, $att_name, $att_replaced);
$store["headers"][$name]["attributes"][$att_name] = $att_value;
}
}
}
}
//Check body
$body = $mime->getData();
if ($this->isPermittedType($mime->getContentType())
&& is_string($body) && ($replaced = $this->replace($replacements, $body)) != $body)
{
$mime->setData($replaced);
$store["body"] = $body;
}
//Check sub-parts
foreach ($mime->listChildren() as $id)
{
$store["children"][$id] = array(
"headers" => array(),
"body" => false,
"children" => array()
);
$child = $mime->getChild($id);
$this->recursiveReplace($child, $replacements, $store["children"][$id]);
}
}
/**
* Perform a str_replace() over the given value.
* @param array The list of replacements as (search => replacement)
* @param string The string to replace
* @return string
*/
protected function replace($replacements, $value)
{
return str_replace(array_keys($replacements), array_values($replacements), $value);
}
/**
* Put the original values back in the message after it was modified before sending.
* @param Swift_Message_Mime The message (or part)
* @param array The location of the stored values
*/
protected function recursiveRestore(Swift_Message_Mime $mime, &$store)
{
if (empty($store)) //3.3.3 bugfix
{
return;
}
//Restore headers
foreach ($store["headers"] as $name => $array)
{
if ($array["value"] !== false) $mime->headers->set($name, $array["value"]);
foreach ($array["attributes"] as $att_name => $att_value)
{
$mime->headers->setAttribute($name, $att_name, $att_value);
}
}
//Restore body
if ($store["body"] !== false)
{
$mime->setData($store["body"]);
}
//Restore children
foreach ($store["children"] as $id => $child_store)
{
$child = $mime->getChild($id);
$this->recursiveRestore($child, $child_store);
}
}
/**
* Set the replacements as a 2-d array or an instance of Swift_Plugin_Decorator_Replacements.
* @param mixed Array or Swift_Plugin_Decorator_Replacements
*/
public function setReplacements($replacements)
{
if ($replacements === null)
{
$r = array();
$this->replacements = new Swift_Plugin_Decorator_Replacements($r);
}
elseif (is_array($replacements))
{
$this->replacements = new Swift_Plugin_Decorator_Replacements($replacements);
}
elseif ($replacements instanceof Swift_Plugin_Decorator_Replacements)
{
$this->replacements = $replacements;
}
else
{
throw new Exception(
"Decorator replacements must be array or instance of Swift_Plugin_Decorator_Replacements.");
}
}
/**
* Get the replacements object.
* @return Swift_Plugin_Decorator_Replacements
*/
public function getReplacements()
{
return $this->replacements;
}
}