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 commentItem 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 commentItem, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 12 | class commentItem extends BaseObject  | 
            ||
| 13 | { | 
            ||
| 14 | |||
| 15 | /**  | 
            ||
| 16 | * comment number  | 
            ||
| 17 | * @var int  | 
            ||
| 18 | */  | 
            ||
| 19 | var $comment_srl = 0;  | 
            ||
| 20 | |||
| 21 | /**  | 
            ||
| 22 | * Get the column list int the table  | 
            ||
| 23 | * @var array  | 
            ||
| 24 | */  | 
            ||
| 25 | var $columnList = array();  | 
            ||
| 26 | |||
| 27 | /**  | 
            ||
| 28 | * Constructor  | 
            ||
| 29 | * @param int $comment_srl  | 
            ||
| 30 | * @param array $columnList  | 
            ||
| 31 | * @return void  | 
            ||
| 32 | */  | 
            ||
| 33 | function commentItem($comment_srl = 0, $columnList = array())  | 
            ||
| 39 | |||
| 40 | function setComment($comment_srl)  | 
            ||
| 45 | |||
| 46 | /**  | 
            ||
| 47 | * Load comment data from DB and set to commentItem object  | 
            ||
| 48 | * @return void  | 
            ||
| 49 | */  | 
            ||
| 50 | function _loadFromDB()  | 
            ||
| 63 | |||
| 64 | /**  | 
            ||
| 65 | * Comment attribute set to BaseObject object  | 
            ||
| 66 | * @return void  | 
            ||
| 67 | */  | 
            ||
| 68 | function setAttribute($attribute)  | 
            ||
| 88 | |||
| 89 | function isExists()  | 
            ||
| 93 | |||
| 94 | function isGranted()  | 
            ||
| 125 | |||
| 126 | function setGrant()  | 
            ||
| 131 | |||
| 132 | function setAccessible()  | 
            ||
| 136 | |||
| 137 | function isEditable()  | 
            ||
| 145 | |||
| 146 | function isSecret()  | 
            ||
| 150 | |||
| 151 | function isAccessible()  | 
            ||
| 174 | |||
| 175 | function useNotify()  | 
            ||
| 179 | |||
| 180 | /**  | 
            ||
| 181 | * Notify to comment owner  | 
            ||
| 182 | * @return void  | 
            ||
| 183 | */  | 
            ||
| 184 | function notify($type, $content)  | 
            ||
| 224 | |||
| 225 | View Code Duplication | function getIpAddress()  | 
            |
| 234 | |||
| 235 | function isExistsHomepage()  | 
            ||
| 244 | |||
| 245 | function getHomepageUrl()  | 
            ||
| 260 | |||
| 261 | function getMemberSrl()  | 
            ||
| 265 | |||
| 266 | function getUserID()  | 
            ||
| 270 | |||
| 271 | function getUserName()  | 
            ||
| 275 | |||
| 276 | function getNickName()  | 
            ||
| 280 | |||
| 281 | /**  | 
            ||
| 282 | * Return content with htmlspecialchars  | 
            ||
| 283 | * @return string  | 
            ||
| 284 | */  | 
            ||
| 285 | function getContentText($strlen = 0)  | 
            ||
| 301 | |||
| 302 | /**  | 
            ||
| 303 | * Return content after filter  | 
            ||
| 304 | * @return string  | 
            ||
| 305 | */  | 
            ||
| 306 | function getContent($add_popup_menu = TRUE, $add_content_info = TRUE, $add_xe_content_class = TRUE)  | 
            ||
| 347 | |||
| 348 | /**  | 
            ||
| 349 | * Return summary content  | 
            ||
| 350 | * @return string  | 
            ||
| 351 | */  | 
            ||
| 352 | View Code Duplication | function getSummary($str_size = 50, $tail = '...')  | 
            |
| 379 | |||
| 380 | function getRegdate($format = 'Y.m.d H:i:s')  | 
            ||
| 384 | |||
| 385 | View Code Duplication | function getRegdateTime()  | 
            |
| 396 | |||
| 397 | function getRegdateGM()  | 
            ||
| 401 | |||
| 402 | function getUpdate($format = 'Y.m.d H:i:s')  | 
            ||
| 406 | |||
| 407 | function getPermanentUrl()  | 
            ||
| 411 | |||
| 412 | View Code Duplication | function getUpdateTime()  | 
            |
| 422 | |||
| 423 | function getUpdateGM()  | 
            ||
| 427 | |||
| 428 | View Code Duplication | function hasUploadedFiles()  | 
            |
| 436 | |||
| 437 | function getUploadedFiles()  | 
            ||
| 453 | |||
| 454 | /**  | 
            ||
| 455 | * Return the editor html  | 
            ||
| 456 | * @return string  | 
            ||
| 457 | */  | 
            ||
| 458 | View Code Duplication | function getEditor()  | 
            |
| 468 | |||
| 469 | /**  | 
            ||
| 470 | * Return author's profile image  | 
            ||
| 471 | * @return object  | 
            ||
| 472 | */  | 
            ||
| 473 | View Code Duplication | function getProfileImage()  | 
            |
| 488 | |||
| 489 | /**  | 
            ||
| 490 | * Return author's signiture  | 
            ||
| 491 | * @return string  | 
            ||
| 492 | */  | 
            ||
| 493 | View Code Duplication | function getSignature()  | 
            |
| 522 | |||
| 523 | function thumbnailExists($width = 80, $height = 0, $type = '')  | 
            ||
| 537 | |||
| 538 | function getThumbnail($width = 80, $height = 0, $thumbnail_type = '')  | 
            ||
| 539 | 	{ | 
            ||
| 540 | // return false if no doc exists  | 
            ||
| 541 | if(!$this->comment_srl)  | 
            ||
| 542 | 		{ | 
            ||
| 543 | return;  | 
            ||
| 544 | }  | 
            ||
| 545 | |||
| 546 | if($this->isSecret() && !$this->isGranted())  | 
            ||
| 547 | 		{ | 
            ||
| 548 | return;  | 
            ||
| 549 | }  | 
            ||
| 550 | |||
| 551 | // If signiture height setting is omitted, create a square  | 
            ||
| 552 | if(!$height)  | 
            ||
| 553 | 		{ | 
            ||
| 554 | $height = $width;  | 
            ||
| 555 | }  | 
            ||
| 556 | |||
| 557 | 		$content = $this->get('content'); | 
            ||
| 558 | View Code Duplication | if(!$this->hasUploadedFiles())  | 
            |
| 559 | 		{ | 
            ||
| 560 | if(!$content)  | 
            ||
| 561 | 			{ | 
            ||
| 562 | $args = new stdClass();  | 
            ||
| 563 | $args->comment_srl = $this->comment_srl;  | 
            ||
| 564 | 				$output = executeQuery('document.getComment', $args, array('content')); | 
            ||
| 565 | if($output->toBool() && $output->data)  | 
            ||
| 566 | 				{ | 
            ||
| 567 | $content = $output->data->content;  | 
            ||
| 568 | 					$this->add('content', $content); | 
            ||
| 569 | }  | 
            ||
| 570 | }  | 
            ||
| 571 | |||
| 572 | 			if(!preg_match("!<img!is", $content)) return; | 
            ||
| 573 | }  | 
            ||
| 574 | |||
| 575 | // get thumbail generation info on the doc module configuration.  | 
            ||
| 576 | 		if(!in_array($thumbnail_type, array('crop', 'ratio'))) | 
            ||
| 577 | 		{ | 
            ||
| 578 | $thumbnail_type = 'crop';  | 
            ||
| 579 | }  | 
            ||
| 580 | |||
| 581 | // Define thumbnail information  | 
            ||
| 582 | 		$thumbnail_path = sprintf('files/thumbnails/%s', getNumberingPath($this->comment_srl, 3)); | 
            ||
| 583 | 		$thumbnail_file = sprintf('%s%dx%d.%s.jpg', $thumbnail_path, $width, $height, $thumbnail_type); | 
            ||
| 584 | 		$thumbnail_lockfile = sprintf('%s%dx%d.%s.lock', $thumbnail_path, $width, $height, $thumbnail_type); | 
            ||
| 585 | $thumbnail_url = Context::getRequestUri() . $thumbnail_file;  | 
            ||
| 586 | |||
| 587 | // return false if a size of existing thumbnail file is 0. otherwise return the file path  | 
            ||
| 588 | View Code Duplication | if(file_exists($thumbnail_file) || file_exists($thumbnail_lockfile))  | 
            |
| 589 | 		{ | 
            ||
| 590 | if(filesize($thumbnail_file) < 1)  | 
            ||
| 591 | 			{ | 
            ||
| 592 | return FALSE;  | 
            ||
| 593 | }  | 
            ||
| 594 | else  | 
            ||
| 595 | 			{ | 
            ||
| 596 | return $thumbnail_url;  | 
            ||
| 597 | }  | 
            ||
| 598 | }  | 
            ||
| 599 | |||
| 600 | // Create lockfile to prevent race condition  | 
            ||
| 601 | FileHandler::writeFile($thumbnail_lockfile, '', 'w');  | 
            ||
| 602 | |||
| 603 | // Target file  | 
            ||
| 604 | $source_file = NULL;  | 
            ||
| 605 | $is_tmp_file = FALSE;  | 
            ||
| 606 | |||
| 607 | // find an image file among attached files  | 
            ||
| 608 | View Code Duplication | if($this->hasUploadedFiles())  | 
            |
| 609 | 		{ | 
            ||
| 610 | $file_list = $this->getUploadedFiles();  | 
            ||
| 611 | |||
| 612 | $first_image = null;  | 
            ||
| 613 | foreach($file_list as $file)  | 
            ||
| 614 | 			{ | 
            ||
| 615 | if($file->direct_download !== 'Y') continue;  | 
            ||
| 616 | |||
| 617 | if($file->cover_image === 'Y' && file_exists($file->uploaded_filename))  | 
            ||
| 618 | 				{ | 
            ||
| 619 | $source_file = $file->uploaded_filename;  | 
            ||
| 620 | break;  | 
            ||
| 621 | }  | 
            ||
| 622 | |||
| 623 | if($first_image) continue;  | 
            ||
| 624 | |||
| 625 | 				if(preg_match("/\.(jpe?g|png|gif|bmp)$/i", $file->source_filename)) | 
            ||
| 626 | 				{ | 
            ||
| 627 | if(file_exists($file->uploaded_filename))  | 
            ||
| 628 | 					{ | 
            ||
| 629 | $first_image = $file->uploaded_filename;  | 
            ||
| 630 | }  | 
            ||
| 631 | }  | 
            ||
| 632 | }  | 
            ||
| 633 | |||
| 634 | if(!$source_file && $first_image)  | 
            ||
| 635 | 			{ | 
            ||
| 636 | $source_file = $first_image;  | 
            ||
| 637 | }  | 
            ||
| 638 | }  | 
            ||
| 639 | |||
| 640 | // get an image file from the doc content if no file attached.  | 
            ||
| 641 | $is_tmp_file = false;  | 
            ||
| 642 | View Code Duplication | if(!$source_file)  | 
            |
| 643 | 		{ | 
            ||
| 644 | $random = new Password();  | 
            ||
| 645 | |||
| 646 | 			preg_match_all("!<img[^>]*src=(?:\"|\')([^\"\']*?)(?:\"|\')!is", $content, $matches, PREG_SET_ORDER); | 
            ||
| 647 | |||
| 648 | foreach($matches as $target_image)  | 
            ||
| 649 | 			{ | 
            ||
| 650 | $target_src = trim($target_image[1]);  | 
            ||
| 651 | 				if(preg_match('/\/(common|modules|widgets|addons|layouts|m\.layouts)\//i', $target_src)) continue; | 
            ||
| 652 | |||
| 653 | 				if(!preg_match('/^(http|https):\/\//i',$target_src)) | 
            ||
| 654 | 				{ | 
            ||
| 655 | $target_src = Context::getRequestUri().$target_src;  | 
            ||
| 656 | }  | 
            ||
| 657 | |||
| 658 | $target_src = htmlspecialchars_decode($target_src);  | 
            ||
| 659 | |||
| 660 | $tmp_file = _XE_PATH_ . 'files/cache/tmp/' . $random->createSecureSalt(32, 'hex');  | 
            ||
| 661 | FileHandler::getRemoteFile($target_src, $tmp_file);  | 
            ||
| 662 | if(!file_exists($tmp_file)) continue;  | 
            ||
| 663 | |||
| 664 | $imageinfo = getimagesize($tmp_file);  | 
            ||
| 665 | list($_w, $_h) = $imageinfo;  | 
            ||
| 666 | 				if($imageinfo === false || ($_w < ($width * 0.3) && $_h < ($height * 0.3))) { | 
            ||
| 667 | FileHandler::removeFile($tmp_file);  | 
            ||
| 668 | continue;  | 
            ||
| 669 | }  | 
            ||
| 670 | |||
| 671 | $source_file = $tmp_file;  | 
            ||
| 672 | $is_tmp_file = true;  | 
            ||
| 673 | break;  | 
            ||
| 674 | }  | 
            ||
| 675 | }  | 
            ||
| 676 | |||
| 677 | $output = FileHandler::createImageFile($source_file, $thumbnail_file, $width, $height, 'jpg', $thumbnail_type);  | 
            ||
| 678 | |||
| 679 | // Remove source file if it was temporary  | 
            ||
| 680 | if($is_tmp_file)  | 
            ||
| 681 | 		{ | 
            ||
| 682 | FileHandler::removeFile($source_file);  | 
            ||
| 683 | }  | 
            ||
| 684 | |||
| 685 | // Remove lockfile  | 
            ||
| 686 | FileHandler::removeFile($thumbnail_lockfile);  | 
            ||
| 687 | |||
| 688 | // Return the thumbnail path if it was successfully generated  | 
            ||
| 689 | if($output)  | 
            ||
| 690 | 		{ | 
            ||
| 691 | return $thumbnail_url;  | 
            ||
| 692 | }  | 
            ||
| 693 | // Create an empty file if thumbnail generation failed  | 
            ||
| 694 | else  | 
            ||
| 695 | 		{ | 
            ||
| 696 | FileHandler::writeFile($thumbnail_file, '','w');  | 
            ||
| 697 | }  | 
            ||
| 698 | |||
| 699 | return;  | 
            ||
| 700 | }  | 
            ||
| 701 | |||
| 702 | function isCarted()  | 
            ||
| 706 | |||
| 707 | /**  | 
            ||
| 708 | * Returns the comment's mid in order to construct SEO friendly URLs  | 
            ||
| 709 | * @return string  | 
            ||
| 710 | */  | 
            ||
| 711 | function getCommentMid()  | 
            ||
| 717 | |||
| 718 | }  | 
            ||
| 719 | /* End of file comment.item.php */  | 
            ||
| 721 |