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 Utility 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 Utility, and based on these observations, apply Extract Interface, too.
| 1 | <?php namespace XoopsModules\Marquee; |
||
| 9 | class Utility |
||
| 10 | { |
||
| 11 | use Common\VersionChecks; //checkVerXoops, checkVerPhp Traits |
||
| 12 | |||
| 13 | use Common\ServerStats; // getServerStats Trait |
||
| 14 | |||
| 15 | use Common\FilesManagement; // Files Management Trait |
||
| 16 | |||
| 17 | //--------------- Custom module methods ----------------------------- |
||
| 18 | const MODULE_NAME = 'marquee'; |
||
| 19 | |||
| 20 | /** |
||
| 21 | * truncateHtml can truncate a string up to a number of characters while preserving whole words and HTML tags |
||
| 22 | * www.gsdesign.ro/blog/cut-html-string-without-breaking-the-tags |
||
| 23 | * www.cakephp.org |
||
| 24 | * |
||
| 25 | * @param string $text String to truncate. |
||
| 26 | * @param integer $length Length of returned string, including ellipsis. |
||
| 27 | * @param string $ending Ending to be appended to the trimmed string. |
||
| 28 | * @param boolean $exact If false, $text will not be cut mid-word |
||
| 29 | * @param boolean $considerHtml If true, HTML tags would be handled correctly |
||
| 30 | * |
||
| 31 | * @return string Trimmed string. |
||
| 32 | */ |
||
| 33 | public static function truncateHtml($text, $length = 100, $ending = '...', $exact = false, $considerHtml = true) |
||
| 124 | |||
| 125 | /** |
||
| 126 | * Access the only instance of this class |
||
| 127 | * |
||
| 128 | * @return \XoopsModules\Marquee\Utility |
||
| 129 | * |
||
| 130 | * @static |
||
| 131 | * @staticvar object |
||
| 132 | */ |
||
| 133 | public static function getInstance() |
||
| 142 | |||
| 143 | /** |
||
| 144 | * Returns a module's option (with cache) |
||
| 145 | * |
||
| 146 | * @param string $option module option's name |
||
| 147 | * @param boolean $withCache Do we have to use some cache ? |
||
| 148 | * |
||
| 149 | * @return mixed option's value |
||
| 150 | */ |
||
| 151 | // public static function getModuleOption($option, $withCache = true) |
||
| 152 | // { |
||
| 153 | // global $xoopsModuleConfig, $xoopsModule; |
||
| 154 | // $repmodule = self::MODULE_NAME; |
||
| 155 | // static $options = []; |
||
| 156 | // if (is_array($options) && array_key_exists($option, $options) && $withCache) { |
||
| 157 | // return $options[$option]; |
||
| 158 | // } |
||
| 159 | // |
||
| 160 | // $retval = false; |
||
| 161 | // if (null !== $xoopsModuleConfig && (is_object($xoopsModule) && ($xoopsModule->getVar('dirname') == $repmodule) && $xoopsModule->getVar('isactive'))) { |
||
| 162 | // if (isset($xoopsModuleConfig[$option])) { |
||
| 163 | // $retval = $xoopsModuleConfig[$option]; |
||
| 164 | // } |
||
| 165 | // } else { |
||
| 166 | // /** @var \XoopsModuleHandler $moduleHandler */ |
||
| 167 | // $moduleHandler = xoops_getHandler('module'); |
||
| 168 | // $module = $moduleHandler->getByDirname($repmodule); |
||
| 169 | // $configHandler = xoops_getHandler('config'); |
||
| 170 | // if ($module) { |
||
| 171 | // $moduleConfig = $configHandler->getConfigsByCat(0, $module->getVar('mid')); |
||
| 172 | // if (isset($moduleConfig[$option])) { |
||
| 173 | // $retval = $moduleConfig[$option]; |
||
| 174 | // } |
||
| 175 | // } |
||
| 176 | // } |
||
| 177 | // $options[$option] = $retval; |
||
| 178 | // |
||
| 179 | // return $retval; |
||
| 180 | // } |
||
| 181 | |||
| 182 | /** |
||
| 183 | * Is Xoops 2.3.x ? |
||
| 184 | * |
||
| 185 | * @return boolean need to say it ? |
||
| 186 | */ |
||
| 187 | // function isX23() |
||
| 188 | // { |
||
| 189 | // $x23 = false; |
||
| 190 | // $xv = str_replace('XOOPS ', '', XOOPS_VERSION); |
||
| 191 | // if ((int)(substr($xv, 2, 1)) >= 3) { |
||
| 192 | // $x23 = true; |
||
| 193 | // } |
||
| 194 | // |
||
| 195 | // return $x23; |
||
| 196 | // } |
||
| 197 | |||
| 198 | /** |
||
| 199 | * Retreive an editor according to the module's option "form_options" |
||
| 200 | * |
||
| 201 | * @param string $caption Caption to give to the editor |
||
| 202 | * @param string $name Editor's name |
||
| 203 | * @param string $value Editor's value |
||
| 204 | * @param string $width Editor's width |
||
| 205 | * @param string $height Editor's height |
||
| 206 | * @param string $supplemental |
||
| 207 | * |
||
| 208 | * @return \XoopsFormDhtmlTextArea|\XoopsFormEditor The editor to use |
||
| 209 | */ |
||
| 210 | public static function getWysiwygForm( |
||
| 233 | |||
| 234 | /** |
||
| 235 | * Create (in a link) a javascript confirmation's box |
||
| 236 | * |
||
| 237 | * @param string $message Message to display |
||
| 238 | * @param boolean $form Is this a confirmation for a form ? |
||
| 239 | * |
||
| 240 | * @return string the javascript code to insert in the link (or in the form) |
||
| 241 | */ |
||
| 242 | public static function javascriptLinkConfirm($message, $form = false) |
||
| 250 | |||
| 251 | /** |
||
| 252 | * Redirect user with a message |
||
| 253 | * |
||
| 254 | * @param string $message message to display |
||
| 255 | * @param string $url The place where to go |
||
| 256 | * @param integer timeout Time to wait before to redirect |
||
| 257 | */ |
||
| 258 | public static function redirect($message = '', $url = 'index.php', $time = 2) |
||
| 262 | |||
| 263 | /** |
||
| 264 | * Internal function used to get the handler of the current module |
||
| 265 | * |
||
| 266 | * @return \XoopsModule The module |
||
| 267 | */ |
||
| 268 | protected static function getModule() |
||
| 283 | |||
| 284 | /** |
||
| 285 | * Returns the module's name (as defined by the user in the module manager) with cache |
||
| 286 | * |
||
| 287 | * @return string Module's name |
||
| 288 | */ |
||
| 289 | public static function getModuleName() |
||
| 299 | |||
| 300 | /** |
||
| 301 | * This function indicates if the current Xoops version needs to add asterisks to required fields in forms |
||
| 302 | * |
||
| 303 | * @return boolean Yes = we need to add them, false = no |
||
| 304 | */ |
||
| 305 | public static function needsAsterisk() |
||
| 322 | |||
| 323 | /** |
||
| 324 | * Mark the mandatory fields of a form with a star |
||
| 325 | * |
||
| 326 | * @param \XoopsThemeForm $sform The form to modify |
||
| 327 | * |
||
| 328 | * @internal param string $caracter The character to use to mark fields |
||
| 329 | * @return \XoopsThemeForm The modified form |
||
| 330 | */ |
||
| 331 | public static function formMarkRequiredFields(&$sform) |
||
| 349 | |||
| 350 | View Code Duplication | public static function getModuleOption($option, $repmodule = 'marquee') |
|
| 381 | |||
| 382 | /** |
||
| 383 | * Verify if the current "user" is a bot or not |
||
| 384 | * |
||
| 385 | * If you have a problem with this function, insert the folowing code just before the line if (isset($_SESSION['news_cache_bot'])) { : |
||
| 386 | * return false; |
||
| 387 | * |
||
| 388 | * @package Marquee |
||
| 389 | * @author Hervé Thouzard (http://www.herve-thouzard.com) |
||
| 390 | * @copyright (c) Hervé Thouzard |
||
| 391 | */ |
||
| 392 | View Code Duplication | public static function isBot() |
|
| 415 | |||
| 416 | /** |
||
| 417 | * Escape a string so that it can be included in a javascript string |
||
| 418 | * |
||
| 419 | * @param $string |
||
| 420 | * |
||
| 421 | * @return mixed |
||
| 422 | */ |
||
| 423 | public static function javascriptEscape($string) |
||
| 427 | } |
||
| 428 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.