Complex classes like Bookmarks 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 Bookmarks, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 31 | class Bookmarks { | 
            ||
| 32 | |||
| 33 | /**  | 
            ||
| 34 | * @brief Finds all tags for bookmarks  | 
            ||
| 35 | * @param $userId UserId  | 
            ||
| 36 | * @param IDb $db Database Interface  | 
            ||
| 37 | * @param filterTags array of tag to look for if empty then every tag  | 
            ||
| 38 | * @param offset integer offset  | 
            ||
| 39 | * @param limit integer of item to return  | 
            ||
| 40 | * @return Found Tags  | 
            ||
| 41 | */  | 
            ||
| 42 | 1 | 	public static function findTags($userId, IDb $db, $filterTags = array(), $offset = 0, $limit = -1) { | 
            |
| 62 | |||
| 63 | /**  | 
            ||
| 64 | * @brief Finds Bookmark with certain ID  | 
            ||
| 65 | * @param $id BookmarkId  | 
            ||
| 66 | * @param $userId UserId  | 
            ||
| 67 | * @param IDb $db Database Interface  | 
            ||
| 68 | * @return Specific Bookmark  | 
            ||
| 69 | */  | 
            ||
| 70 | 2 | 	public static function findUniqueBookmark($id, $userId, IDb $db) { | 
            |
| 85 | |||
| 86 | /**  | 
            ||
| 87 | * @brief Check if an URL is bookmarked  | 
            ||
| 88 | * @param $url Url of a possible bookmark  | 
            ||
| 89 | * @param $userId UserId  | 
            ||
| 90 | * @param IDb $db Database Interface  | 
            ||
| 91 | * @return boolean if the url is already bookmarked  | 
            ||
| 92 | */  | 
            ||
| 93 | 1 | 	public static function bookmarkExists($url, $userId, IDb $db) { | 
            |
| 104 | |||
| 105 | /**  | 
            ||
| 106 | * @brief Finds all bookmarks, matching the filter  | 
            ||
| 107 | * @param $userid UserId  | 
            ||
| 108 | * @param IDb $db Database Interface  | 
            ||
| 109 | * @param int $offset offset  | 
            ||
| 110 | * @param string $sqlSortColumn result with this column  | 
            ||
| 111 | * @param string|array $filters filters can be: empty -> no filter, a string -> filter this, a string array -> filter for all strings  | 
            ||
| 112 | * @param bool $filterTagOnly true, filter affects only tags, else filter affects url, title and tags  | 
            ||
| 113 | * @param int $limit limit of items to return (default 10) if -1 or false then all items are returned  | 
            ||
| 114 | * @param bool $public check if only public bookmarks should be returned  | 
            ||
| 115 | * @param array $requestedAttributes select all the attributes that should be returned. default is * + tags  | 
            ||
| 116 | * @param string $tagFilterConjunction select wether the filterTagOnly should filter with an AND or an OR conjunction  | 
            ||
| 117 | * @return Collection of specified bookmarks  | 
            ||
| 118 | */  | 
            ||
| 119 | 3 | public static function findBookmarks(  | 
            |
| 189 | |||
| 190 | 2 | 	private static function findBookmarksBuildFilter(&$sql, &$params, $filters, $filterTagOnly, $tagFilterConjunction, $CONFIG_DBTYPE) { | 
            |
| 229 | |||
| 230 | /**  | 
            ||
| 231 | * @brief Delete bookmark with specific id  | 
            ||
| 232 | * @param $userId UserId  | 
            ||
| 233 | * @param IDb $db Database Interface  | 
            ||
| 234 | * @param $id Bookmark ID to delete  | 
            ||
| 235 | * @return boolean Success of operation  | 
            ||
| 236 | */  | 
            ||
| 237 | 1 | 	public static function deleteUrl($userId, IDb $db, $id) { | 
            |
| 267 | |||
| 268 | /**  | 
            ||
| 269 | * @brief Rename a tag  | 
            ||
| 270 | * @param $userId UserId  | 
            ||
| 271 | * @param IDb $db Database Interface  | 
            ||
| 272 | * @param string $old Old Tag Name  | 
            ||
| 273 | * @param string $new New Tag Name  | 
            ||
| 274 | * @return boolean Success of operation  | 
            ||
| 275 | */  | 
            ||
| 276 | 	public static function renameTag($userId, IDb $db, $old, $new) { | 
            ||
| 277 | $user_id = $userId;  | 
            ||
| 278 | 		$CONFIG_DBTYPE = \OCP\Config::getSystemValue('dbtype', 'sqlite'); | 
            ||
| 279 | |||
| 280 | |||
| 281 | 		if ($CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3') { | 
            ||
| 282 | // Update tags to the new label unless it already exists a tag like this  | 
            ||
| 283 | 			$query = $db->prepareQuery(" | 
            ||
| 284 | UPDATE OR REPLACE `*PREFIX*bookmarks_tags`  | 
            ||
| 285 | SET `tag` = ?  | 
            ||
| 286 | WHERE `tag` = ?  | 
            ||
| 287 | AND exists( select `b`.`id` from `*PREFIX*bookmarks` `b`  | 
            ||
| 288 | WHERE `b`.`user_id` = ? AND `bookmark_id` = `b`.`id`)  | 
            ||
| 289 | ");  | 
            ||
| 290 | |||
| 291 | $params = array(  | 
            ||
| 292 | $new,  | 
            ||
| 293 | $old,  | 
            ||
| 294 | $user_id,  | 
            ||
| 295 | );  | 
            ||
| 296 | |||
| 297 | $query->execute($params);  | 
            ||
| 298 | 		} else { | 
            ||
| 299 | |||
| 300 | // Remove potentialy duplicated tags  | 
            ||
| 301 | 			$query = $db->prepareQuery(" | 
            ||
| 302 | DELETE FROM `*PREFIX*bookmarks_tags` as `tgs` WHERE `tgs`.`tag` = ?  | 
            ||
| 303 | AND exists( SELECT `id` FROM `*PREFIX*bookmarks` WHERE `user_id` = ?  | 
            ||
| 304 | AND `tgs`.`bookmark_id` = `id`)  | 
            ||
| 305 | AND exists( SELECT `t`.`tag` FROM `*PREFIX*bookmarks_tags` `t` where `t`.`tag` = ?  | 
            ||
| 306 | AND `tgs`.`bookmark_id` = `t`.`bookmark_id`)");  | 
            ||
| 307 | |||
| 308 | $params = array(  | 
            ||
| 309 | $new,  | 
            ||
| 310 | $user_id,  | 
            ||
| 311 | $new  | 
            ||
| 312 | );  | 
            ||
| 313 | |||
| 314 | $query->execute($params);  | 
            ||
| 315 | |||
| 316 | |||
| 317 | // Update tags to the new label unless it already exists a tag like this  | 
            ||
| 318 | 			$query = $db->prepareQuery(" | 
            ||
| 319 | UPDATE `*PREFIX*bookmarks_tags`  | 
            ||
| 320 | SET `tag` = ?  | 
            ||
| 321 | WHERE `tag` = ?  | 
            ||
| 322 | AND exists( SELECT `b`.`id` FROM `*PREFIX*bookmarks` `b`  | 
            ||
| 323 | WHERE `b`.`user_id` = ? AND `bookmark_id` = `b`.`id`)  | 
            ||
| 324 | ");  | 
            ||
| 325 | |||
| 326 | $params = array(  | 
            ||
| 327 | $new,  | 
            ||
| 328 | $old,  | 
            ||
| 329 | $user_id  | 
            ||
| 330 | );  | 
            ||
| 331 | |||
| 332 | $query->execute($params);  | 
            ||
| 333 | }  | 
            ||
| 334 | |||
| 335 | |||
| 336 | return true;  | 
            ||
| 337 | }  | 
            ||
| 338 | |||
| 339 | /**  | 
            ||
| 340 | * @brief Delete a tag  | 
            ||
| 341 | * @param $userid UserId  | 
            ||
| 342 | * @param IDb $db Database Interface  | 
            ||
| 343 | * @param string $old Tag Name to delete  | 
            ||
| 344 | * @return boolean Success of operation  | 
            ||
| 345 | */  | 
            ||
| 346 | 	public static function deleteTag($userid, IDb $db, $old) { | 
            ||
| 363 | |||
| 364 | /**  | 
            ||
| 365 | * Edit a bookmark  | 
            ||
| 366 | * @param $userid UserId  | 
            ||
| 367 | * @param IDb $db Database Interface  | 
            ||
| 368 | * @param int $id The id of the bookmark to edit  | 
            ||
| 369 | * @param string $url The url to set  | 
            ||
| 370 | * @param string $title Name of the bookmark  | 
            ||
| 371 | * @param array $tags Simple array of tags to qualify the bookmark (different tags are taken from values)  | 
            ||
| 372 | * @param string $description A longer description about the bookmark  | 
            ||
| 373 | * @param boolean $is_public True if the bookmark is publishable to not registered users  | 
            ||
| 374 | * @return null  | 
            ||
| 375 | */  | 
            ||
| 376 | 1 | 	public static function editBookmark($userid, IDb $db, $id, $url, $title, $tags = array(), $description = '', $is_public = false) { | 
            |
| 417 | |||
| 418 | /**  | 
            ||
| 419 | * Add a bookmark  | 
            ||
| 420 | * @param $userid UserId  | 
            ||
| 421 | * @param IDb $db Database Interface  | 
            ||
| 422 | * @param string $url  | 
            ||
| 423 | * @param string $title Name of the bookmark  | 
            ||
| 424 | * @param array $tags Simple array of tags to qualify the bookmark (different tags are taken from values)  | 
            ||
| 425 | * @param string $description A longer description about the bookmark  | 
            ||
| 426 | * @param boolean $public True if the bookmark is publishable to not registered users  | 
            ||
| 
                                                                                                    
                        
                         | 
                |||
| 427 | * @return int The id of the bookmark created  | 
            ||
| 428 | */  | 
            ||
| 429 | 8 | 	public static function addBookmark($userid, IDb $db, $url, $title, $tags = array(), $description = '', $is_public = false) { | 
            |
| 482 | |||
| 483 | /**  | 
            ||
| 484 | * @brief Add a set of tags for a bookmark  | 
            ||
| 485 | * @param IDb $db Database Interface  | 
            ||
| 486 | * @param int $bookmarkID The bookmark reference  | 
            ||
| 487 | * @param array $tags Set of tags to add to the bookmark  | 
            ||
| 488 | * @return null  | 
            ||
| 489 | * */  | 
            ||
| 490 | 8 | 	private static function addTags(IDb $db, $bookmarkID, $tags) { | 
            |
| 510 | |||
| 511 | /**  | 
            ||
| 512 | * @brief Import Bookmarks from html formatted file  | 
            ||
| 513 | * @param $user User imported Bookmarks should belong to  | 
            ||
| 514 | * @param IDb $db Database Interface  | 
            ||
| 515 | * @param $file Content to import  | 
            ||
| 516 | * @return null  | 
            ||
| 517 | * */  | 
            ||
| 518 | 	public static function importFile($user, IDb $db, $file) { | 
            ||
| 543 | |||
| 544 | /**  | 
            ||
| 545 | * @brief Load Url and receive Metadata (Title)  | 
            ||
| 546 | * @param $url Url to load and analyze  | 
            ||
| 547 | * @return array Metadata for url;  | 
            ||
| 548 | * */  | 
            ||
| 549 | 1 | 	public static function getURLMetadata($url) { | 
            |
| 550 | |||
| 551 | 1 | $metadata = array();  | 
            |
| 552 | 1 | $metadata['url'] = $url;  | 
            |
| 553 | 1 | $page = "";  | 
            |
| 554 | |||
| 555 | 		try { | 
            ||
| 556 | 1 | $request = \OC::$server->getHTTPClientService()->newClient()->get($url);  | 
            |
| 557 | 1 | $page = $request->getBody();  | 
            |
| 558 | 1 | 			$contentType = $request->getHeader('Content-Type'); | 
            |
| 559 | 1 | 		} catch (\Exception $e) { | 
            |
| 560 | throw $e;  | 
            ||
| 561 | }  | 
            ||
| 562 | |||
| 563 | //Check for encoding of site.  | 
            ||
| 564 | //If not UTF-8 convert it.  | 
            ||
| 565 | 1 | $encoding = array();  | 
            |
| 566 | 1 | 		preg_match('#.+?/.+?;\\s?charset\\s?=\\s?(.+)#i', $contentType, $encoding); | 
            |
| 567 | 1 | 		if(empty($encoding)) { | 
            |
| 568 | 1 | 			preg_match('/charset="?(.*?)["|;]/i', $page, $encoding); | 
            |
| 569 | 1 | }  | 
            |
| 570 | |||
| 571 | 1 | 		if (isset($encoding[1])) { | 
            |
| 572 | 1 | $decodeFrom = strtoupper($encoding[1]);  | 
            |
| 573 | 1 | 		} else { | 
            |
| 574 | $decodeFrom = 'UTF-8';  | 
            ||
| 575 | }  | 
            ||
| 576 | |||
| 577 | 1 | 		if ($page) { | 
            |
| 578 | |||
| 579 | 1 | 			if ($decodeFrom != 'UTF-8') { | 
            |
| 580 | 1 | $page = iconv($decodeFrom, "UTF-8", $page);  | 
            |
| 581 | 1 | }  | 
            |
| 582 | |||
| 583 | 1 | 			preg_match("/<title>(.*)<\/title>/si", $page, $match); | 
            |
| 584 | |||
| 585 | 1 | 			if (isset($match[1])) { | 
            |
| 586 | 1 | $metadata['title'] = html_entity_decode($match[1]);  | 
            |
| 587 | 1 | }  | 
            |
| 588 | 1 | }  | 
            |
| 589 | |||
| 590 | 1 | return $metadata;  | 
            |
| 591 | }  | 
            ||
| 592 | |||
| 593 | /**  | 
            ||
| 594 | * @brief Seperate Url String at comma charachter  | 
            ||
| 595 | * @param $line String of Tags  | 
            ||
| 596 | * @return array Array of Tags  | 
            ||
| 597 | * */  | 
            ||
| 598 | 	public static function analyzeTagRequest($line) { | 
            ||
| 607 | |||
| 608 | }  | 
            ||
| 609 | 
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.
Consider the following example. The parameter
$irelandis not defined by the methodfinale(...).The most likely cause is that the parameter was changed, but the annotation was not.