Complex classes like Mailer often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Mailer, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
22 | class Mailer { |
||
23 | |||
24 | protected $headers = array(); |
||
25 | protected $attach = array(); |
||
26 | protected $html = ''; |
||
27 | protected $text = ''; |
||
28 | |||
29 | protected $boundary = ''; |
||
30 | protected $partid = ''; |
||
31 | protected $sendparam = null; |
||
32 | |||
33 | protected $allowhtml = true; |
||
34 | |||
35 | protected $replacements = array('text'=> array(), 'html' => array()); |
||
36 | |||
37 | /** |
||
38 | * Constructor |
||
39 | * |
||
40 | * Initializes the boundary strings, part counters and token replacements |
||
41 | */ |
||
42 | public function __construct() { |
||
72 | |||
73 | /** |
||
74 | * Attach a file |
||
75 | * |
||
76 | * @param string $path Path to the file to attach |
||
77 | * @param string $mime Mimetype of the attached file |
||
78 | * @param string $name The filename to use |
||
79 | * @param string $embed Unique key to reference this file from the HTML part |
||
80 | */ |
||
81 | public function attachFile($path, $mime, $name = '', $embed = '') { |
||
93 | |||
94 | /** |
||
95 | * Attach a file |
||
96 | * |
||
97 | * @param string $data The file contents to attach |
||
98 | * @param string $mime Mimetype of the attached file |
||
99 | * @param string $name The filename to use |
||
100 | * @param string $embed Unique key to reference this file from the HTML part |
||
101 | */ |
||
102 | public function attachContent($data, $mime, $name = '', $embed = '') { |
||
115 | |||
116 | /** |
||
117 | * Callback function to automatically embed images referenced in HTML templates |
||
118 | * |
||
119 | * @param array $matches |
||
120 | * @return string placeholder |
||
121 | */ |
||
122 | protected function autoEmbedCallBack($matches) { |
||
123 | static $embeds = 0; |
||
124 | $embeds++; |
||
125 | |||
126 | // get file and mime type |
||
127 | $media = cleanID($matches[1]); |
||
128 | list(, $mime) = mimetype($media); |
||
129 | $file = mediaFN($media); |
||
130 | if(!file_exists($file)) return $matches[0]; //bad reference, keep as is |
||
131 | |||
132 | // attach it and set placeholder |
||
133 | $this->attachFile($file, $mime, '', 'autoembed'.$embeds); |
||
134 | return '%%autoembed'.$embeds.'%%'; |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * Add an arbitrary header to the mail |
||
139 | * |
||
140 | * If an empy value is passed, the header is removed |
||
141 | * |
||
142 | * @param string $header the header name (no trailing colon!) |
||
143 | * @param string|string[] $value the value of the header |
||
144 | * @param bool $clean remove all non-ASCII chars and line feeds? |
||
145 | */ |
||
146 | public function setHeader($header, $value, $clean = true) { |
||
167 | |||
168 | /** |
||
169 | * Set additional parameters to be passed to sendmail |
||
170 | * |
||
171 | * Whatever is set here is directly passed to PHP's mail() command as last |
||
172 | * parameter. Depending on the PHP setup this might break mailing alltogether |
||
173 | * |
||
174 | * @param string $param |
||
175 | */ |
||
176 | public function setParameters($param) { |
||
179 | |||
180 | /** |
||
181 | * Set the text and HTML body and apply replacements |
||
182 | * |
||
183 | * This function applies a whole bunch of default replacements in addition |
||
184 | * to the ones specified as parameters |
||
185 | * |
||
186 | * If you pass the HTML part or HTML replacements yourself you have to make |
||
187 | * sure you encode all HTML special chars correctly |
||
188 | * |
||
189 | * @param string $text plain text body |
||
190 | * @param array $textrep replacements to apply on the text part |
||
191 | * @param array $htmlrep replacements to apply on the HTML part, null to use $textrep (urls wrapped in <a> tags) |
||
192 | * @param string $html the HTML body, leave null to create it from $text |
||
193 | * @param bool $wrap wrap the HTML in the default header/Footer |
||
194 | */ |
||
195 | public function setBody($text, $textrep = null, $htmlrep = null, $html = null, $wrap = true) { |
||
249 | |||
250 | /** |
||
251 | * Set the HTML part of the mail |
||
252 | * |
||
253 | * Placeholders can be used to reference embedded attachments |
||
254 | * |
||
255 | * You probably want to use setBody() instead |
||
256 | * |
||
257 | * @param string $html |
||
258 | */ |
||
259 | public function setHTML($html) { |
||
262 | |||
263 | /** |
||
264 | * Set the plain text part of the mail |
||
265 | * |
||
266 | * You probably want to use setBody() instead |
||
267 | * |
||
268 | * @param string $text |
||
269 | */ |
||
270 | public function setText($text) { |
||
273 | |||
274 | /** |
||
275 | * Add the To: recipients |
||
276 | * |
||
277 | * @see cleanAddress |
||
278 | * @param string|string[] $address Multiple adresses separated by commas or as array |
||
279 | */ |
||
280 | public function to($address) { |
||
283 | |||
284 | /** |
||
285 | * Add the Cc: recipients |
||
286 | * |
||
287 | * @see cleanAddress |
||
288 | * @param string|string[] $address Multiple adresses separated by commas or as array |
||
289 | */ |
||
290 | public function cc($address) { |
||
293 | |||
294 | /** |
||
295 | * Add the Bcc: recipients |
||
296 | * |
||
297 | * @see cleanAddress |
||
298 | * @param string|string[] $address Multiple adresses separated by commas or as array |
||
299 | */ |
||
300 | public function bcc($address) { |
||
303 | |||
304 | /** |
||
305 | * Add the From: address |
||
306 | * |
||
307 | * This is set to $conf['mailfrom'] when not specified so you shouldn't need |
||
308 | * to call this function |
||
309 | * |
||
310 | * @see cleanAddress |
||
311 | * @param string $address from address |
||
312 | */ |
||
313 | public function from($address) { |
||
316 | |||
317 | /** |
||
318 | * Add the mail's Subject: header |
||
319 | * |
||
320 | * @param string $subject the mail subject |
||
321 | */ |
||
322 | public function subject($subject) { |
||
325 | |||
326 | /** |
||
327 | * Return a clean name which can be safely used in mail address |
||
328 | * fields. That means the name will be enclosed in '"' if it includes |
||
329 | * a '"' or a ','. Also a '"' will be escaped as '\"'. |
||
330 | * |
||
331 | * @param string $name the name to clean-up |
||
332 | * @see cleanAddress |
||
333 | */ |
||
334 | public function getCleanName($name) { |
||
342 | |||
343 | /** |
||
344 | * Sets an email address header with correct encoding |
||
345 | * |
||
346 | * Unicode characters will be deaccented and encoded base64 |
||
347 | * for headers. Addresses may not contain Non-ASCII data! |
||
348 | * |
||
349 | * If @$addresses is a string then it will be split into multiple |
||
350 | * addresses. Addresses must be separated by a comma. If the display |
||
351 | * name includes a comma then it MUST be properly enclosed by '"' to |
||
352 | * prevent spliting at the wrong point. |
||
353 | * |
||
354 | * Example: |
||
355 | * cc("föö <[email protected]>, [email protected]","TBcc"); |
||
356 | * to("foo, Dr." <[email protected]>, [email protected]"); |
||
357 | * |
||
358 | * @param string|string[] $addresses Multiple adresses separated by commas or as array |
||
359 | * @return false|string the prepared header (can contain multiple lines) |
||
360 | */ |
||
361 | public function cleanAddress($addresses) { |
||
430 | |||
431 | |||
432 | /** |
||
433 | * Prepare the mime multiparts for all attachments |
||
434 | * |
||
435 | * Replaces placeholders in the HTML with the correct CIDs |
||
436 | * |
||
437 | * @return string mime multiparts |
||
438 | */ |
||
439 | protected function prepareAttachments() { |
||
470 | |||
471 | /** |
||
472 | * Build the body and handles multi part mails |
||
473 | * |
||
474 | * Needs to be called before prepareHeaders! |
||
475 | * |
||
476 | * @return string the prepared mail body, false on errors |
||
477 | */ |
||
478 | protected function prepareBody() { |
||
538 | |||
539 | /** |
||
540 | * Cleanup and encode the headers array |
||
541 | */ |
||
542 | protected function cleanHeaders() { |
||
581 | |||
582 | /** |
||
583 | * Returns a complete, EOL terminated header line, wraps it if necessary |
||
584 | * |
||
585 | * @param string $key |
||
586 | * @param string $val |
||
587 | * @return string line |
||
588 | */ |
||
589 | protected function wrappedHeaderLine($key, $val){ |
||
592 | |||
593 | /** |
||
594 | * Create a string from the headers array |
||
595 | * |
||
596 | * @returns string the headers |
||
597 | */ |
||
598 | protected function prepareHeaders() { |
||
606 | |||
607 | /** |
||
608 | * return a full email with all headers |
||
609 | * |
||
610 | * This is mainly intended for debugging and testing but could also be |
||
611 | * used for MHT exports |
||
612 | * |
||
613 | * @return string the mail, false on errors |
||
614 | */ |
||
615 | public function dump() { |
||
623 | |||
624 | /** |
||
625 | * Prepare default token replacement strings |
||
626 | * |
||
627 | * Populates the '$replacements' property. |
||
628 | * Should be called by the class constructor |
||
629 | */ |
||
630 | protected function prepareTokenReplacements() { |
||
689 | |||
690 | /** |
||
691 | * Send the mail |
||
692 | * |
||
693 | * Call this after all data was set |
||
694 | * |
||
695 | * @triggers MAIL_MESSAGE_SEND |
||
696 | * @return bool true if the mail was successfully passed to the MTA |
||
697 | */ |
||
698 | public function send() { |
||
777 | } |
||
778 |
This check looks for type mismatches where the missing type is
false
. This is usually indicative of an error condtion.Consider the follow example
This function either returns a new
DateTime
object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returnedfalse
before passing on the value to another function or method that may not be able to handle afalse
.