Complex classes like Subscription 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 Subscription, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 9 | class Subscription { | 
            ||
| 10 | |||
| 11 | /**  | 
            ||
| 12 | * Check if subscription system is enabled  | 
            ||
| 13 | *  | 
            ||
| 14 | * @return bool  | 
            ||
| 15 | */  | 
            ||
| 16 |     public function isenabled() { | 
            ||
| 19 | |||
| 20 | /**  | 
            ||
| 21 | * Return the subscription meta file for the given ID  | 
            ||
| 22 | *  | 
            ||
| 23 | * @author Adrian Lang <[email protected]>  | 
            ||
| 24 | *  | 
            ||
| 25 | * @param string $id The target page or namespace, specified by id; Namespaces  | 
            ||
| 26 | * are identified by appending a colon.  | 
            ||
| 27 | * @return string  | 
            ||
| 28 | */  | 
            ||
| 29 |     protected function file($id) { | 
            ||
| 39 | |||
| 40 | /**  | 
            ||
| 41 | * Lock subscription info  | 
            ||
| 42 | *  | 
            ||
| 43 | * We don't use io_lock() her because we do not wait for the lock and use a larger stale time  | 
            ||
| 44 | *  | 
            ||
| 45 | * @author Adrian Lang <[email protected]>  | 
            ||
| 46 | * @param string $id The target page or namespace, specified by id; Namespaces  | 
            ||
| 47 | * are identified by appending a colon.  | 
            ||
| 48 | * @return bool true, if you got a succesful lock  | 
            ||
| 49 | */  | 
            ||
| 50 |     protected function lock($id) { | 
            ||
| 68 | |||
| 69 | /**  | 
            ||
| 70 | * Unlock subscription info  | 
            ||
| 71 | *  | 
            ||
| 72 | * @author Adrian Lang <[email protected]>  | 
            ||
| 73 | * @param string $id The target page or namespace, specified by id; Namespaces  | 
            ||
| 74 | * are identified by appending a colon.  | 
            ||
| 75 | * @return bool  | 
            ||
| 76 | */  | 
            ||
| 77 |     protected function unlock($id) { | 
            ||
| 82 | |||
| 83 | /**  | 
            ||
| 84 | * Construct a regular expression for parsing a subscription definition line  | 
            ||
| 85 | *  | 
            ||
| 86 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 87 | *  | 
            ||
| 88 | * @param string|array $user  | 
            ||
| 89 | * @param string|array $style  | 
            ||
| 90 | * @param string|array $data  | 
            ||
| 91 | * @return string complete regexp including delimiters  | 
            ||
| 92 | * @throws Exception when no data is passed  | 
            ||
| 93 | */  | 
            ||
| 94 |     protected function buildregex($user = null, $style = null, $data = null) { | 
            ||
| 139 | |||
| 140 | /**  | 
            ||
| 141 | * Recursively search for matching subscriptions  | 
            ||
| 142 | *  | 
            ||
| 143 | * This function searches all relevant subscription files for a page or  | 
            ||
| 144 | * namespace.  | 
            ||
| 145 | *  | 
            ||
| 146 | * @author Adrian Lang <[email protected]>  | 
            ||
| 147 | *  | 
            ||
| 148 | * @param string $page The target object’s (namespace or page) id  | 
            ||
| 149 | * @param string|array $user  | 
            ||
| 150 | * @param string|array $style  | 
            ||
| 151 | * @param string|array $data  | 
            ||
| 152 | * @return array  | 
            ||
| 153 | */  | 
            ||
| 154 |     public function subscribers($page, $user = null, $style = null, $data = null) { | 
            ||
| 186 | |||
| 187 | /**  | 
            ||
| 188 | * Adds a new subscription for the given page or namespace  | 
            ||
| 189 | *  | 
            ||
| 190 | * This will automatically overwrite any existent subscription for the given user on this  | 
            ||
| 191 | * *exact* page or namespace. It will *not* modify any subscription that may exist in higher namespaces.  | 
            ||
| 192 | *  | 
            ||
| 193 | * @param string $id The target page or namespace, specified by id; Namespaces  | 
            ||
| 194 | * are identified by appending a colon.  | 
            ||
| 195 | * @param string $user  | 
            ||
| 196 | * @param string $style  | 
            ||
| 197 | * @param string $data  | 
            ||
| 198 | * @throws Exception when user or style is empty  | 
            ||
| 199 | * @return bool  | 
            ||
| 200 | */  | 
            ||
| 201 |     public function add($id, $user, $style, $data = '') { | 
            ||
| 219 | |||
| 220 | /**  | 
            ||
| 221 | * Removes a subscription for the given page or namespace  | 
            ||
| 222 | *  | 
            ||
| 223 | * This removes all subscriptions matching the given criteria on the given page or  | 
            ||
| 224 | * namespace. It will *not* modify any subscriptions that may exist in higher  | 
            ||
| 225 | * namespaces.  | 
            ||
| 226 | *  | 
            ||
| 227 | * @param string $id The target object’s (namespace or page) id  | 
            ||
| 228 | * @param string|array $user  | 
            ||
| 229 | * @param string|array $style  | 
            ||
| 230 | * @param string|array $data  | 
            ||
| 231 | * @return bool  | 
            ||
| 232 | */  | 
            ||
| 233 |     public function remove($id, $user = null, $style = null, $data = null) { | 
            ||
| 242 | |||
| 243 | /**  | 
            ||
| 244 | * Get data for $INFO['subscribed']  | 
            ||
| 245 | *  | 
            ||
| 246 | * $INFO['subscribed'] is either false if no subscription for the current page  | 
            ||
| 247 | * and user is in effect. Else it contains an array of arrays with the fields  | 
            ||
| 248 | * “target”, “style”, and optionally “data”.  | 
            ||
| 249 | *  | 
            ||
| 250 | * @param string $id Page ID, defaults to global $ID  | 
            ||
| 251 | * @param string $user User, defaults to $_SERVER['REMOTE_USER']  | 
            ||
| 252 | * @return array  | 
            ||
| 253 | * @author Adrian Lang <[email protected]>  | 
            ||
| 254 | */  | 
            ||
| 255 |     function user_subscription($id = '', $user = '') { | 
            ||
| 278 | |||
| 279 | /**  | 
            ||
| 280 | * Send digest and list subscriptions  | 
            ||
| 281 | *  | 
            ||
| 282 | * This sends mails to all subscribers that have a subscription for namespaces above  | 
            ||
| 283 | * the given page if the needed $conf['subscribe_time'] has passed already.  | 
            ||
| 284 | *  | 
            ||
| 285 | * This function is called form lib/exe/indexer.php  | 
            ||
| 286 | *  | 
            ||
| 287 | * @param string $page  | 
            ||
| 288 | * @return int number of sent mails  | 
            ||
| 289 | */  | 
            ||
| 290 |     public function send_bulk($page) { | 
            ||
| 380 | |||
| 381 | /**  | 
            ||
| 382 | * Send the diff for some page change  | 
            ||
| 383 | *  | 
            ||
| 384 | * @param string $subscriber_mail The target mail address  | 
            ||
| 385 |      * @param string   $template        Mail template ('subscr_digest', 'subscr_single', 'mailtext', ...) | 
            ||
| 386 | * @param string $id Page for which the notification is  | 
            ||
| 387 | * @param int|null $rev Old revision if any  | 
            ||
| 388 | * @param string $summary Change summary if any  | 
            ||
| 389 | * @param int|null $current_rev New revision if any  | 
            ||
| 390 | * @return bool true if successfully sent  | 
            ||
| 391 | */  | 
            ||
| 392 |     public function send_diff($subscriber_mail, $template, $id, $rev = null, $summary = '', $current_rev = null) { | 
            ||
| 443 | |||
| 444 | /**  | 
            ||
| 445 | * Send the diff for some media change  | 
            ||
| 446 | *  | 
            ||
| 447 | * @fixme this should embed thumbnails of images in HTML version  | 
            ||
| 448 | *  | 
            ||
| 449 | * @param string $subscriber_mail The target mail address  | 
            ||
| 450 |      * @param string   $template        Mail template ('uploadmail', ...) | 
            ||
| 451 | * @param string $id Media file for which the notification is  | 
            ||
| 452 | * @param int|bool $rev Old revision if any  | 
            ||
| 453 | * @param int|bool $current_rev New revision if any  | 
            ||
| 454 | */  | 
            ||
| 455 |     public function send_media_diff($subscriber_mail, $template, $id, $rev = false, $current_rev = false) { | 
            ||
| 481 | |||
| 482 | /**  | 
            ||
| 483 | * Send a notify mail on new registration  | 
            ||
| 484 | *  | 
            ||
| 485 | * @author Andreas Gohr <[email protected]>  | 
            ||
| 486 | *  | 
            ||
| 487 | * @param string $login login name of the new user  | 
            ||
| 488 | * @param string $fullname full name of the new user  | 
            ||
| 489 | * @param string $email email address of the new user  | 
            ||
| 490 | * @return bool true if a mail was sent  | 
            ||
| 491 | */  | 
            ||
| 492 |     public function send_register($login, $fullname, $email) { | 
            ||
| 510 | |||
| 511 | /**  | 
            ||
| 512 | * Send a digest mail  | 
            ||
| 513 | *  | 
            ||
| 514 | * Sends a digest mail showing a bunch of changes of a single page. Basically the same as send_diff()  | 
            ||
| 515 | * but determines the last known revision first  | 
            ||
| 516 | *  | 
            ||
| 517 | * @author Adrian Lang <[email protected]>  | 
            ||
| 518 | *  | 
            ||
| 519 | * @param string $subscriber_mail The target mail address  | 
            ||
| 520 | * @param string $id The ID  | 
            ||
| 521 | * @param int $lastupdate Time of the last notification  | 
            ||
| 522 | * @return bool  | 
            ||
| 523 | */  | 
            ||
| 524 |     protected function send_digest($subscriber_mail, $id, $lastupdate) { | 
            ||
| 538 | |||
| 539 | /**  | 
            ||
| 540 | * Send a list mail  | 
            ||
| 541 | *  | 
            ||
| 542 | * Sends a list mail showing a list of changed pages.  | 
            ||
| 543 | *  | 
            ||
| 544 | * @author Adrian Lang <[email protected]>  | 
            ||
| 545 | *  | 
            ||
| 546 | * @param string $subscriber_mail The target mail address  | 
            ||
| 547 | * @param array $ids Array of ids  | 
            ||
| 548 | * @param string $ns_id The id of the namespace  | 
            ||
| 549 | * @return bool true if a mail was sent  | 
            ||
| 550 | */  | 
            ||
| 551 |     protected function send_list($subscriber_mail, $ids, $ns_id) { | 
            ||
| 580 | |||
| 581 | /**  | 
            ||
| 582 | * Helper function for sending a mail  | 
            ||
| 583 | *  | 
            ||
| 584 | * @author Adrian Lang <[email protected]>  | 
            ||
| 585 | *  | 
            ||
| 586 | * @param string $subscriber_mail The target mail address  | 
            ||
| 587 | * @param string $subject The lang id of the mail subject (without the  | 
            ||
| 588 | * prefix “mail_”)  | 
            ||
| 589 | * @param string $context The context of this mail, eg. page or namespace id  | 
            ||
| 590 | * @param string $template The name of the mail template  | 
            ||
| 591 | * @param array $trep Predefined parameters used to parse the  | 
            ||
| 592 | * template (in text format)  | 
            ||
| 593 | * @param array $hrep Predefined parameters used to parse the  | 
            ||
| 594 | * template (in HTML format), null to default to $trep  | 
            ||
| 595 | * @param array $headers Additional mail headers in the form 'name' => 'value'  | 
            ||
| 596 | * @return bool  | 
            ||
| 597 | */  | 
            ||
| 598 |     protected function send($subscriber_mail, $subject, $context, $template, $trep, $hrep = null, $headers = array()) { | 
            ||
| 621 | |||
| 622 | /**  | 
            ||
| 623 | * Get a valid message id for a certain $id and revision (or the current revision)  | 
            ||
| 624 | *  | 
            ||
| 625 | * @param string $id The id of the page (or media file) the message id should be for  | 
            ||
| 626 | * @param string $rev The revision of the page, set to the current revision of the page $id if not set  | 
            ||
| 627 | * @return string  | 
            ||
| 628 | */  | 
            ||
| 629 |     protected function getMessageID($id, $rev = null) { | 
            ||
| 644 | |||
| 645 | /**  | 
            ||
| 646 | * Default callback for COMMON_NOTIFY_ADDRESSLIST  | 
            ||
| 647 | *  | 
            ||
| 648 | * Aggregates all email addresses of user who have subscribed the given page with 'every' style  | 
            ||
| 649 | *  | 
            ||
| 650 | * @author Steven Danz <[email protected]>  | 
            ||
| 651 | * @author Adrian Lang <[email protected]>  | 
            ||
| 652 | *  | 
            ||
| 653 | * @todo move the whole functionality into this class, trigger SUBSCRIPTION_NOTIFY_ADDRESSLIST instead,  | 
            ||
| 654 | * use an array for the addresses within it  | 
            ||
| 655 | *  | 
            ||
| 656 | * @param array &$data Containing the entries:  | 
            ||
| 657 | * - $id (the page id),  | 
            ||
| 658 | * - $self (whether the author should be notified,  | 
            ||
| 659 | * - $addresslist (current email address list)  | 
            ||
| 660 | * - $replacements (array of additional string substitutions, @KEY@ to be replaced by value)  | 
            ||
| 661 | */  | 
            ||
| 662 |     public function notifyaddresses(&$data) { | 
            ||
| 695 | }  | 
            ||
| 696 | 
If you suppress an error, we recommend checking for the error condition explicitly: