Merge pull request #22682 from agileware/CIVICRM-1922
[civicrm-core.git] / CRM / Utils / Mail / FilteredPearMailer.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 * The filtered-mailer is a utility to wrap an existing PEAR Mail class
14 * and apply extra filters. It is primarily intended for resolving
15 * quirks in the standard implementations.
16 *
17 * This wrapper acts a bit like a chameleon, passing-through properties
18 * from the underlying object. Consequently, internal properties are
19 * prefixed with `_` to avoid conflict.
20 *
21 * @package CRM
22 * @copyright CiviCRM LLC https://civicrm.org/licensing
23 */
24 class CRM_Utils_Mail_FilteredPearMailer extends Mail {
25
26 /**
27 * @var string
28 * Ex: 'smtp' or 'sendmail'
29 */
30 protected $_driver;
31
32 /**
33 * @var array
34 */
35 protected $_params;
36
37 /**
38 * @var Mail
39 */
40 protected $_delegate;
41
42 /**
43 * @var callable[]
44 */
45 protected $_filters = [];
46
47 /**
48 * CRM_Utils_Mail_FilteredPearMailer constructor.
49 * @param string $driver
50 * @param array $params
51 * @param Mail $mailer
52 */
53 public function __construct($driver, $params, $mailer) {
54 $this->_driver = $driver;
55 $this->_params = $params;
56 $this->_delegate = $mailer;
57 }
58
59 public function __destruct() {
60 try {
61 unset($this->_delegate);
62 }
63 catch (Exception $e) {
64 Civi::log()->error($e->getMessage());
65 }
66 }
67
68 public function send($recipients, $headers, $body) {
69 $filterArgs = [$this, &$recipients, &$headers, &$body];
70 foreach ($this->_filters as $filter) {
71 $result = call_user_func_array($filter, $filterArgs);
72 if ($result !== NULL) {
73 return $result;
74 }
75 }
76
77 return $this->_delegate->send($recipients, $headers, $body);
78 }
79
80 /**
81 * @param string $id
82 * Unique ID for this filter. Filters are sorted by ID.
83 * Suggestion: '{nnnn}_{name}', where '{nnnn}' is a number.
84 * Filters are sorted and executed in order.
85 * @param callable $func
86 * function(FilteredPearMailer $mailer, mixed $recipients, array $headers, string $body).
87 * The return value should generally be null/void. However, if you wish to
88 * short-circuit execution of the filters, then return a concrete value.
89 * @return static
90 */
91 public function addFilter($id, $func) {
92 $this->_filters[$id] = $func;
93 ksort($this->_filters);
94 return $this;
95 }
96
97 /**
98 * @return string
99 * Ex: 'smtp', 'sendmail', 'mail'.
100 */
101 public function getDriver() {
102 return $this->_driver;
103 }
104
105 public function &__get($name) {
106 return $this->_delegate->{$name};
107 }
108
109 public function __set($name, $value) {
110 return $this->_delegate->{$name} = $value;
111 }
112
113 public function __isset($name) {
114 return isset($this->_delegate->{$name});
115 }
116
117 public function __unset($name) {
118 unset($this->_delegate->{$name});
119 }
120
121 public function disconnect() {
122 if (is_callable([$this->_delegate, 'disconnect'])) {
123 return $this->_delegate->disconnect();
124 }
125 return TRUE;
126 }
127
128 }