Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Mail 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 Mail, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
40 | class Mail |
||
41 | { |
||
42 | /** |
||
43 | * Type of the used MUA. Possible values: |
||
44 | * - built-in. |
||
45 | * |
||
46 | * @var string |
||
47 | */ |
||
48 | public $agent; |
||
49 | |||
50 | /** |
||
51 | * Attached filed. |
||
52 | * |
||
53 | * @var mixed |
||
54 | */ |
||
55 | public $attachments; |
||
56 | |||
57 | /** |
||
58 | * Body of the e-mail. |
||
59 | * |
||
60 | * @var string |
||
61 | */ |
||
62 | public $body = ''; |
||
63 | |||
64 | /** |
||
65 | * Boundary. |
||
66 | * |
||
67 | * @var string |
||
68 | */ |
||
69 | public $boundary = '----------'; |
||
70 | |||
71 | /** |
||
72 | * Charset. |
||
73 | * |
||
74 | * @var string |
||
75 | */ |
||
76 | public $charset = 'utf-8'; |
||
77 | |||
78 | /** |
||
79 | * Content disposition. |
||
80 | * |
||
81 | * @var string |
||
82 | */ |
||
83 | public $contentDisposition = 'inline'; |
||
84 | |||
85 | /** |
||
86 | * Content type. |
||
87 | * |
||
88 | * @var string |
||
89 | */ |
||
90 | public $contentType = 'text/plain'; |
||
91 | |||
92 | /** |
||
93 | * Content transfer encoding. |
||
94 | * |
||
95 | * @var string |
||
96 | */ |
||
97 | public $contentTransferEncoding = '8bit'; |
||
98 | |||
99 | /** |
||
100 | * The one and only valid End Of Line sequence as per RFC 2822: |
||
101 | * carriage-return followed by line-feed. |
||
102 | * |
||
103 | * @var string |
||
104 | */ |
||
105 | public $eol = "\r\n"; |
||
106 | |||
107 | /** |
||
108 | * Array of headers of the e-mail |
||
109 | * |
||
110 | * @var array |
||
111 | */ |
||
112 | public $headers; |
||
113 | |||
114 | /** |
||
115 | * Message of the e-mail: HTML text allowed. |
||
116 | * |
||
117 | * @var string |
||
118 | */ |
||
119 | public $message; |
||
120 | |||
121 | /** |
||
122 | * Alternate message of the e-mail: only plain text allowed. |
||
123 | * |
||
124 | * @var string |
||
125 | */ |
||
126 | public $messageAlt; |
||
127 | |||
128 | /** |
||
129 | * Message-ID of the e-mail. |
||
130 | * |
||
131 | * @var string |
||
132 | */ |
||
133 | public $messageId; |
||
134 | |||
135 | /** |
||
136 | * Priorities: 1 (Highest), 2 (High), 3 (Normal), 4 (Low), 5 (Lowest). |
||
137 | * |
||
138 | * @var mixed |
||
139 | */ |
||
140 | public $priorities = [ |
||
141 | 1 => 'Highest', |
||
142 | 2 => 'High', |
||
143 | 3 => 'Normal', |
||
144 | 4 => 'Low', |
||
145 | 5 => 'Lowest' |
||
146 | ]; |
||
147 | |||
148 | /** |
||
149 | * Priority of the e-mail: 1 (Highest), 2 (High), 3 (Normal), 4 (Low), 5 (Lowest). |
||
150 | * |
||
151 | * @var int |
||
152 | * |
||
153 | * @see priorities |
||
154 | */ |
||
155 | public $priority; |
||
156 | |||
157 | /** |
||
158 | * Subject of the e-mail. |
||
159 | * |
||
160 | * @var string |
||
161 | */ |
||
162 | public $subject; |
||
163 | |||
164 | /** |
||
165 | * Recipients of the e-mail as <BCC>. |
||
166 | * |
||
167 | * @var mixed |
||
168 | */ |
||
169 | private $_bcc; |
||
170 | |||
171 | /** |
||
172 | * Recipients of the e-mail as <CC>. |
||
173 | * |
||
174 | * @var mixed |
||
175 | */ |
||
176 | private $_cc; |
||
177 | |||
178 | /** |
||
179 | * Recipients of the e-mail as <From>. |
||
180 | * |
||
181 | * @var mixed |
||
182 | */ |
||
183 | private $_from; |
||
184 | |||
185 | /** |
||
186 | * Mailer string. |
||
187 | * |
||
188 | * @var string |
||
189 | */ |
||
190 | private $_mailer; |
||
191 | |||
192 | /** |
||
193 | * Recipient of the optional notification. |
||
194 | * |
||
195 | * @var mixed |
||
196 | */ |
||
197 | private $_notifyTo; |
||
198 | |||
199 | /** |
||
200 | * Recipient of the e-mail as <Reply-To>. |
||
201 | * |
||
202 | * @var mixed |
||
203 | */ |
||
204 | private $_replyTo; |
||
205 | |||
206 | /** |
||
207 | * Recipient of the e-mail as <Return-Path>. |
||
208 | * |
||
209 | * @var mixed |
||
210 | */ |
||
211 | private $_returnPath; |
||
212 | |||
213 | /** |
||
214 | * Recipient of the e-mail as <Sender>. |
||
215 | * |
||
216 | * @var mixed |
||
217 | */ |
||
218 | private $_sender; |
||
219 | |||
220 | /** |
||
221 | * Recipients of the e-mail as <TO:>. |
||
222 | * |
||
223 | * @var mixed |
||
224 | */ |
||
225 | private $_to; |
||
226 | |||
227 | /** |
||
228 | * @var PMF_Configuration |
||
229 | */ |
||
230 | private $_config; |
||
231 | |||
232 | /* |
||
233 | * Default constructor. |
||
234 | * Note: any email will be sent from the PMF administrator, use unsetFrom |
||
235 | * before using setFrom. |
||
236 | * |
||
237 | * @param Configuration $config |
||
238 | */ |
||
239 | public function __construct(Configuration $config) |
||
268 | |||
269 | /** |
||
270 | * Add an e-mail address to an array. |
||
271 | * |
||
272 | * @param array $target Target array. |
||
273 | * @param string $targetAlias Alias Target alias. |
||
274 | * @param string $address User e-mail address. |
||
275 | * @param string $name User name (optional). |
||
276 | * |
||
277 | * @return bool True if successful, false otherwise. |
||
278 | * |
||
279 | * @todo Enhance error handling using exceptions |
||
280 | */ |
||
281 | private function _addEmailTo(&$target, $targetAlias, $address, $name = null) |
||
326 | |||
327 | /** |
||
328 | * Create the body of the email. |
||
329 | */ |
||
330 | private function _createBody() |
||
411 | |||
412 | /** |
||
413 | * Create the headers of the email. |
||
414 | */ |
||
415 | private function _createHeaders() |
||
510 | |||
511 | /** |
||
512 | * Set just one e-mail address into an array. |
||
513 | * |
||
514 | * @param array $target Target array. |
||
515 | * @param string $targetAlias Alias Target alias. |
||
516 | * @param string $address User e-mail address. |
||
517 | * @param string $name User name (optional). |
||
518 | * |
||
519 | * @return bool True if successful, false otherwise. |
||
520 | */ |
||
521 | private function _setEmailTo(&$target, $targetAlias, $address, $name = null) |
||
536 | |||
537 | /** |
||
538 | * Add an attachment. |
||
539 | * |
||
540 | * @param string $path File path. |
||
541 | * @param string $name File name. Defaults to the basename. |
||
542 | * @param string $mimetype File MIME type. Defaults to 'application/octet-stream'. |
||
543 | * @param string $disposition Attachment disposition. Defaults to 'attachment'. |
||
544 | * @param string $cid Content ID, required when disposition is 'inline'. Defaults to ''. |
||
545 | * |
||
546 | * @return bool True if successful, false otherwise. |
||
547 | */ |
||
548 | public function addAttachment($path, $name = null, $mimetype = 'application/octet-stream', $disposition = 'attachment', $cid = '') |
||
572 | |||
573 | /** |
||
574 | * Add a recipient as <BCC>. |
||
575 | * |
||
576 | * @param string $address User e-mail address. |
||
577 | * @param string $name User name (optional). |
||
578 | * |
||
579 | * @return bool True if successful, false otherwise. |
||
580 | */ |
||
581 | public function addBcc($address, $name = null) |
||
585 | |||
586 | /** |
||
587 | * Add a recipient as <CC>. |
||
588 | * |
||
589 | * @param string $address User e-mail address. |
||
590 | * @param string $name User name (optional). |
||
591 | * |
||
592 | * @return bool True if successful, false otherwise. |
||
593 | */ |
||
594 | public function addCc($address, $name = null) |
||
598 | |||
599 | /** |
||
600 | * Add an address to send a notification to. |
||
601 | * |
||
602 | * @param string $address User e-mail address. |
||
603 | * @param string $name User name (optional). |
||
604 | * |
||
605 | * @return bool True if successful, false otherwise. |
||
606 | */ |
||
607 | public function addNotificationTo($address, $name = null) |
||
611 | |||
612 | /** |
||
613 | * Add a recipient as <TO>. |
||
614 | * |
||
615 | * @param string $address User e-mail address. |
||
616 | * @param string $name User name (optional). |
||
617 | * |
||
618 | * @return bool True if successful, false otherwise. |
||
619 | */ |
||
620 | public function addTo($address, $name = null) |
||
624 | |||
625 | /** |
||
626 | * Create a string to be used as a valid boundary value. |
||
627 | * |
||
628 | * @static |
||
629 | * |
||
630 | * @return string The boundary value. |
||
631 | */ |
||
632 | public static function createBoundary() |
||
636 | |||
637 | /** |
||
638 | * Returns the given text being sure that any CR or LF has been fixed |
||
639 | * according with RFC 2822 EOL setting. |
||
640 | * |
||
641 | * @param string $text Text with a mixed usage of CR, LF, CRLF. |
||
642 | * |
||
643 | * @return string The fixed text. |
||
644 | * |
||
645 | * @see eol |
||
646 | */ |
||
647 | public function fixEOL($text) |
||
664 | |||
665 | /** |
||
666 | * Returns the date according with RFC 2822. |
||
667 | * |
||
668 | * @static |
||
669 | * |
||
670 | * @param string $date Unix timestamp. |
||
671 | * |
||
672 | * @return string The RFC 2822 date if successful, false otherwise. |
||
673 | */ |
||
674 | public static function getDate($date) |
||
680 | |||
681 | /** |
||
682 | * Returns the Unix timestamp with preference to the Page Request time. |
||
683 | * |
||
684 | * @static |
||
685 | * |
||
686 | * @return int Unix timestamp. |
||
687 | */ |
||
688 | public static function getTime() |
||
696 | |||
697 | /** |
||
698 | * Get the instance of the class implementing the MUA for the given type. |
||
699 | * |
||
700 | * @static |
||
701 | * |
||
702 | * @param string $mua Type of the MUA. |
||
703 | * |
||
704 | * @return mixed The class instance if successful, false otherwise. |
||
705 | */ |
||
706 | public static function getMUA($mua) |
||
719 | |||
720 | /** |
||
721 | * Returns the server name. |
||
722 | * |
||
723 | * @static |
||
724 | * |
||
725 | * @return string The server name. |
||
726 | */ |
||
727 | public static function getServerName() |
||
738 | |||
739 | /** |
||
740 | * Send the e-mail according with the current settings. |
||
741 | * |
||
742 | * @return bool True if successful, false otherwise. |
||
743 | * |
||
744 | * @todo Enhance error handling using exceptions |
||
745 | */ |
||
746 | public function send() |
||
828 | |||
829 | /** |
||
830 | * Set the "From" address. |
||
831 | * |
||
832 | * @param string $address User e-mail address. |
||
833 | * @param string $name User name (optional). |
||
834 | * |
||
835 | * @return bool True if successful, false otherwise. |
||
836 | */ |
||
837 | public function setFrom($address, $name = null) |
||
841 | |||
842 | /** |
||
843 | * Set an HTML message providing also a plain text alternative message, |
||
844 | * if not already set using the $messageAlt property. |
||
845 | * Besides it is possible to put resources as inline attachments. |
||
846 | * |
||
847 | * @param string $message HTML message. |
||
848 | * @param bool $sanitize Strip out potentially unsecured HTML tags. Defaults to false. |
||
849 | * @param bool $inline Add images as inline attachments. Defaults to false. |
||
850 | */ |
||
851 | public function setHTMLMessage($message, $sanitize = false, $inline = false) |
||
893 | |||
894 | /** |
||
895 | * Set the "Reply-to" address. |
||
896 | * |
||
897 | * @param string $address User e-mail address. |
||
898 | * @param string $name User name (optional). |
||
899 | * |
||
900 | * @return bool True if successful, false otherwise. |
||
901 | */ |
||
902 | public function setReplyTo($address, $name = null) |
||
906 | |||
907 | /** |
||
908 | * Set the "Return-Path" address. |
||
909 | * |
||
910 | * @param string $address User e-mail address. |
||
911 | * |
||
912 | * @return bool True if successful, false otherwise. |
||
913 | */ |
||
914 | public function setReturnPath($address) |
||
918 | |||
919 | /** |
||
920 | * Set the "Sender" address. |
||
921 | * |
||
922 | * @param string $address User e-mail address. |
||
923 | * @param string $name User name (optional). |
||
924 | * |
||
925 | * @return bool True if successful, false otherwise. |
||
926 | */ |
||
927 | public function setSender($address, $name = null) |
||
931 | |||
932 | /** |
||
933 | * Remove any previous "From" address. |
||
934 | * |
||
935 | * @return bool True if successful, false otherwise. |
||
936 | */ |
||
937 | public function unsetFrom() |
||
943 | |||
944 | /** |
||
945 | * Validate an address as an e-mail address. |
||
946 | * |
||
947 | * @param string $address E-Mail address |
||
948 | * |
||
949 | * @return bool True if the given address is a valid e-mail address, false otherwise. |
||
950 | */ |
||
951 | public static function validateEmail($address) |
||
972 | |||
973 | /** |
||
974 | * Wraps the lines contained into the given message. |
||
975 | * |
||
976 | * @param string $message Message. |
||
977 | * @param int $width Column width. Defaults to 72. |
||
978 | * @param bool $cut Cutting a word is allowed. Defaults to false. |
||
979 | * |
||
980 | * @return string The given message, wrapped as requested. |
||
981 | */ |
||
982 | public function wrapLines($message, $width = 72, $cut = false) |
||
1000 | |||
1001 | /** |
||
1002 | * If the email spam protection has been activated from the general |
||
1003 | * phpMyFAQ configuration this method converts an email address e.g. |
||
1004 | * from "[email protected]" to "user_AT_example_DOT_org". Otherwise |
||
1005 | * it will return the plain email address. |
||
1006 | * |
||
1007 | * @param string $email E-mail address |
||
1008 | * @static |
||
1009 | * |
||
1010 | * @return string |
||
1011 | */ |
||
1012 | public function safeEmail($email) |
||
1020 | } |
||
1021 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..