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 JToggleColumn 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 JToggleColumn, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 9 | class JToggleColumn extends BDataColumn |
||
| 10 | { |
||
| 11 | /** |
||
| 12 | * @var string the attribute name of the data model. Used for column sorting, filtering and to render the corresponding |
||
| 13 | * attribute value in each data cell. If {@link value} is specified it will be used to rendered the data cell instead of the attribute value. |
||
| 14 | * @see value |
||
| 15 | * @see sortable |
||
| 16 | */ |
||
| 17 | public $name; |
||
| 18 | |||
| 19 | /** |
||
| 20 | * @var array the HTML options for the data cell tags. |
||
| 21 | */ |
||
| 22 | public $htmlOptions = array('class' => 'toggle-column'); |
||
| 23 | |||
| 24 | /** |
||
| 25 | * @var array the HTML options for the header cell tag. |
||
| 26 | */ |
||
| 27 | public $headerHtmlOptions = array('class' => 'toggle-column'); |
||
| 28 | |||
| 29 | /** |
||
| 30 | * @var array the HTML options for the footer cell tag. |
||
| 31 | */ |
||
| 32 | public $footerHtmlOptions = array('class' => 'toggle-column'); |
||
| 33 | |||
| 34 | /** |
||
| 35 | * @var string the label for the toggle button. Defaults to "toggle". |
||
| 36 | * Note that the label will not be HTML-encoded when rendering. |
||
| 37 | */ |
||
| 38 | public $checkedButtonLabel; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * @var string the label for the toggle button. Defaults to "toggle". |
||
| 42 | * Note that the label will not be HTML-encoded when rendering. |
||
| 43 | */ |
||
| 44 | public $uncheckedButtonLabel; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * @var string the image URL for the toggle button. If not set, an integrated image will be used. |
||
| 48 | * You may set this property to be false to render a text link instead. |
||
| 49 | */ |
||
| 50 | public $checkedButtonImageUrl; |
||
| 51 | |||
| 52 | /** |
||
| 53 | * @var string the image URL for the toggle button. If not set, an integrated image will be used. |
||
| 54 | * You may set this property to be false to render a text link instead. |
||
| 55 | */ |
||
| 56 | public $uncheckedButtonImageUrl; |
||
| 57 | |||
| 58 | /** |
||
| 59 | * @var array the configuration for toggle button. |
||
| 60 | */ |
||
| 61 | public $toggle_button = array(); |
||
| 62 | |||
| 63 | /** |
||
| 64 | * @var boolean whether the column is sortable. If so, the header cell will contain a link that may trigger the sorting. |
||
| 65 | * Defaults to true. Note that if {@link name} is not set, or if {@link name} is not allowed by {@link CSort}, |
||
| 66 | * this property will be treated as false. |
||
| 67 | * @see name |
||
| 68 | */ |
||
| 69 | public $sortable = true; |
||
| 70 | |||
| 71 | /** |
||
| 72 | * @var mixed the HTML code representing a filter input (eg a text field, a dropdown list) |
||
| 73 | * that is used for this data column. This property is effective only when |
||
| 74 | * {@link CGridView::filter} is set. |
||
| 75 | * If this property is not set, a text field will be generated as the filter input; |
||
| 76 | * If this property is an array, a dropdown list will be generated that uses this property value as |
||
| 77 | * the list options. |
||
| 78 | * If you don't want a filter for this data column, set this value to false. |
||
| 79 | * @since 1.1.1 |
||
| 80 | */ |
||
| 81 | public $filter; |
||
| 82 | |||
| 83 | /** |
||
| 84 | * @var string Name of the action |
||
| 85 | */ |
||
| 86 | public $action; |
||
| 87 | |||
| 88 | /** |
||
| 89 | * @var string |
||
| 90 | */ |
||
| 91 | public $ajaxUrl; |
||
| 92 | |||
| 93 | /** |
||
| 94 | * @var string Assets url |
||
| 95 | */ |
||
| 96 | private $_assetsUrl; |
||
| 97 | |||
| 98 | /** |
||
| 99 | * Returns assets url, where check and uncheck images are located |
||
| 100 | * @return string |
||
| 101 | */ |
||
| 102 | public function getAssetsUrl() |
||
| 108 | |||
| 109 | /** |
||
| 110 | * Initializes the column. |
||
| 111 | * This method registers necessary client script for the button column. |
||
| 112 | */ |
||
| 113 | public function init() |
||
| 126 | |||
| 127 | /** |
||
| 128 | * Initializes the default buttons (toggle). |
||
| 129 | */ |
||
| 130 | protected function initDefaultButtons() |
||
| 176 | |||
| 177 | /** |
||
| 178 | * Registers the client scripts for the button column. |
||
| 179 | */ |
||
| 180 | protected function registerClientScript() |
||
| 191 | |||
| 192 | /** |
||
| 193 | * Renders the data cell content. |
||
| 194 | * This method renders the view, update and toggle buttons in the data cell. |
||
| 195 | * |
||
| 196 | * @param integer $row the row number (zero-based) |
||
| 197 | * @param mixed $data the data associated with the row |
||
| 198 | */ |
||
| 199 | protected function renderDataCellContent($row, $data) |
||
| 208 | |||
| 209 | /** |
||
| 210 | * Renders the header cell content. |
||
| 211 | * This method will render a link that can trigger the sorting if the column is sortable. |
||
| 212 | */ |
||
| 213 | protected function renderHeaderCellContent() |
||
| 227 | |||
| 228 | /** |
||
| 229 | * Renders a toggle button. |
||
| 230 | * |
||
| 231 | * @param array $button the button configuration which may contain 'label', 'url', 'imageUrl' and 'options' elements. |
||
| 232 | * @param integer $row the row number (zero-based) |
||
| 233 | * @param mixed $data the data object associated with the row |
||
| 234 | * |
||
| 235 | * @internal param string $id the ID of the button |
||
| 236 | */ |
||
| 237 | protected function renderButton($button, $row, $data) |
||
| 255 | |||
| 256 | /** |
||
| 257 | * Renders the filter cell content. |
||
| 258 | * This method will render the {@link filter} as is if it is a string. |
||
| 259 | * If {@link filter} is an array, it is assumed to be a list of options, and a dropdown selector will be rendered. |
||
| 260 | * Otherwise if {@link filter} is not false, a text field is rendered. |
||
| 261 | * @since 1.1.1 |
||
| 262 | */ |
||
| 263 | protected function renderFilterCellContent() |
||
| 282 | |||
| 283 | protected function renderFilterDivContent() |
||
| 293 | } |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.