| Total Complexity | 47 |
| Total Lines | 262 |
| Duplicated Lines | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Complex classes like HtmlDropdown 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.
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 HtmlDropdown, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 16 | class HtmlDropdown extends HtmlButton { |
||
| 17 | protected $btnCaption="Dropdown button"; |
||
| 18 | protected $class="dropdown-toggle"; |
||
| 19 | protected $mClass="dropdown"; |
||
| 20 | protected $mTagName="div"; |
||
| 21 | protected $items=array (); |
||
| 22 | |||
| 23 | /** |
||
| 24 | * |
||
| 25 | * @param string $identifier the id |
||
| 26 | */ |
||
| 27 | public function __construct($identifier, $value="", $items=array(), $cssStyle=null, $onClick=null) { |
||
| 28 | parent::__construct($identifier, "", $cssStyle, $onClick); |
||
| 29 | $this->_template=include 'templates/tplDropdown.php'; |
||
| 30 | $this->btnCaption=$value; |
||
| 31 | $this->tagName="a"; |
||
| 32 | $this->fromArray($items); |
||
| 33 | if ($cssStyle!==NULL) { |
||
| 34 | $this->asButton($cssStyle); |
||
| 35 | } |
||
| 36 | } |
||
| 37 | |||
| 38 | /** |
||
| 39 | * Define the tagName of the main element |
||
| 40 | * @param string $value default : div |
||
| 41 | */ |
||
| 42 | public function setMTagName($value) { |
||
| 43 | $this->mTagName=$value; |
||
| 44 | } |
||
| 45 | |||
| 46 | /** |
||
| 47 | * define the button style |
||
| 48 | * avaible values : "btn-default","btn-primary","btn-success","btn-info","btn-warning","btn-danger" |
||
| 49 | * @param string|int $cssStyle |
||
| 50 | * @return \Ajax\bootstrap\html\HtmlDropdown default : "btn-default" |
||
| 51 | */ |
||
| 52 | public function setStyle($cssStyle) { |
||
| 53 | if (is_int($cssStyle)) { |
||
| 54 | return $this->addToMember($this->class, CssRef::buttonStyles()[$cssStyle]); |
||
| 55 | } |
||
| 56 | if (JString::startsWith($cssStyle, "btn-")===false) { |
||
| 57 | $cssStyle="btn".$cssStyle; |
||
| 58 | } |
||
| 59 | return $this->addToMemberCtrl($this->class, $cssStyle, CssRef::buttonStyles()); |
||
| 60 | } |
||
| 61 | |||
| 62 | /* |
||
| 63 | * (non-PHPdoc) |
||
| 64 | * @see \Ajax\bootstrap\html\HtmlButton::setValue() |
||
| 65 | */ |
||
| 66 | public function setValue($value) { |
||
| 67 | $this->btnCaption=$value; |
||
| 68 | } |
||
| 69 | |||
| 70 | /** |
||
| 71 | * define the buttons size |
||
| 72 | * available values : "btn-group-lg","","btn-group-sm","btn-group-xs" |
||
| 73 | * @param string|int $size |
||
| 74 | * @return HtmlDropdown |
||
| 75 | * default : "" |
||
| 76 | */ |
||
| 77 | public function setSize($size) { |
||
| 78 | if (is_int($size)) { |
||
| 79 | return $this->addToProperty("class", CssRef::sizes("btn-group")[$size]); |
||
| 80 | } |
||
| 81 | return $this->addToPropertyCtrl("class", $size, CssRef::sizes("btn-group")); |
||
| 82 | } |
||
| 83 | |||
| 84 | /** |
||
| 85 | * add an HtmlDropdownItem |
||
| 86 | * @param string $caption |
||
| 87 | * @param string $href |
||
| 88 | * @return HtmlDropdownItem |
||
| 89 | */ |
||
| 90 | public function addItem($caption, $href="#") { |
||
| 91 | if($caption instanceof HtmlDropdownItem){ |
||
| 92 | $item=$caption; |
||
| 93 | }else{ |
||
| 94 | $iid=$this->getItemsCount()+1; |
||
| 95 | $item=new HtmlDropdownItem($this->identifier."-dropdown-item-".$iid); |
||
| 96 | $item->setCaption($caption)->setHref($href); |
||
| 97 | } |
||
| 98 | $this->items []=$item; |
||
| 99 | return $item; |
||
| 100 | } |
||
| 101 | |||
| 102 | public function addDivider() { |
||
| 103 | return $this->addItem("-"); |
||
| 104 | } |
||
| 105 | |||
| 106 | public function addHeader($caption) { |
||
| 107 | return $this->addItem("-".$caption); |
||
| 108 | } |
||
| 109 | |||
| 110 | public function addItems($items) { |
||
| 111 | $iid=$this->getItemsCount()+1; |
||
| 112 | if (\is_array($items)) { |
||
| 113 | foreach ( $items as $item ) { |
||
| 114 | if (is_string($item)) { |
||
| 115 | $this->addItem($item); |
||
| 116 | } else if (\is_array($item)) { |
||
| 117 | $dropDownItem=new HtmlDropdownItem($this->identifier."-dropdown-item-".$iid); |
||
| 118 | $dropDownItem->fromArray($item); |
||
| 119 | $this->items []=$dropDownItem; |
||
| 120 | } else if ($item instanceof HtmlDropdownItem) { |
||
| 121 | $this->items []=$item; |
||
| 122 | } |
||
| 123 | } |
||
| 124 | } |
||
| 125 | return $this; |
||
| 126 | } |
||
| 127 | |||
| 128 | /* |
||
| 129 | * (non-PHPdoc) |
||
| 130 | * @see BaseHtml::fromArray() |
||
| 131 | */ |
||
| 132 | public function fromArray($array) { |
||
| 133 | if (array_keys($array)!==range(0, count($array)-1)) |
||
| 134 | return parent::fromArray($array); |
||
| 135 | else |
||
| 136 | return $this->addItems($array); |
||
| 137 | } |
||
| 138 | |||
| 139 | public function setItems($items) { |
||
| 140 | $this->items=array (); |
||
| 141 | $this->addItems($items); |
||
| 142 | } |
||
| 143 | |||
| 144 | /** |
||
| 145 | * Return the item at $index |
||
| 146 | * @param int $index |
||
| 147 | * @return HtmlDropdownItem |
||
| 148 | */ |
||
| 149 | public function getItem($index) { |
||
| 150 | return $this->items [$index]; |
||
| 151 | } |
||
| 152 | |||
| 153 | public function setBtnClass($value) { |
||
| 154 | $this->class=$value; |
||
| 155 | } |
||
| 156 | |||
| 157 | public function setMClass($value) { |
||
| 158 | $this->mClass=$value; |
||
| 159 | } |
||
| 160 | |||
| 161 | public function addBtnClass($value) { |
||
| 162 | $this->addToMember($this->class, $value); |
||
| 163 | } |
||
| 164 | |||
| 165 | public function addmClass($value) { |
||
| 166 | $this->addToMember($this->mClass, $value); |
||
| 167 | } |
||
| 168 | |||
| 169 | /* |
||
| 170 | * (non-PHPdoc) |
||
| 171 | * @see BaseHtml::run() |
||
| 172 | */ |
||
| 173 | public function run(JsUtils $js) { |
||
| 174 | if ($this->getProperty("role")==="nav") { |
||
| 175 | foreach ( $this->items as $dropdownItem ) { |
||
| 176 | $dropdownItem->runNav($js); |
||
| 177 | } |
||
| 178 | } |
||
| 179 | $this->_bsComponent=$js->bootstrap()->dropdown("#".$this->identifier); |
||
| 180 | $this->addEventsOnRun($js); |
||
| 181 | return $this->_bsComponent; |
||
| 182 | } |
||
| 183 | |||
| 184 | /** |
||
| 185 | * Sets the tagName's dropdown |
||
| 186 | * @see BaseHtml::setTagName() |
||
| 187 | */ |
||
| 188 | public function setTagName($tagName) { |
||
| 189 | if ($tagName=="button") |
||
| 190 | $this->class="btn dropdown-toggle"; |
||
| 191 | return parent::setTagName($tagName); |
||
| 192 | } |
||
| 193 | |||
| 194 | public function __toString() { |
||
| 195 | return $this->compile(); |
||
| 196 | } |
||
| 197 | |||
| 198 | public function setBtnCaption($btnCaption) { |
||
| 199 | $this->btnCaption=$btnCaption; |
||
| 200 | return $this; |
||
| 201 | } |
||
| 202 | |||
| 203 | public function getItemsCount() { |
||
| 205 | } |
||
| 206 | |||
| 207 | public function setAlignment($alignment) { |
||
| 208 | if (is_int($alignment)) |
||
| 209 | $alignment="dropdown-menu-".CssRef::alignment()[$alignment]; |
||
| 210 | return $this->addToMemberCtrl($this->class, $alignment, CssRef::alignment()); |
||
| 211 | } |
||
| 212 | |||
| 213 | public function dropup() { |
||
| 214 | $this->addToMember($this->mClass, "dropup"); |
||
| 215 | } |
||
| 216 | |||
| 217 | public function getItems() { |
||
| 218 | return $this->items; |
||
| 219 | } |
||
| 220 | |||
| 221 | public function asButton($cssStyle="btn-primary") { |
||
| 222 | $this->setTagName("button"); |
||
| 223 | $this->setBtnClass("btn dropdown-toggle"); |
||
| 224 | $this->setStyle($cssStyle); |
||
| 225 | } |
||
| 226 | |||
| 227 | /** |
||
| 228 | * This event fires immediately when the show instance method is called. |
||
| 229 | * @param string $jsCode |
||
| 230 | * @return $this |
||
| 231 | */ |
||
| 232 | public function onShow($jsCode) { |
||
| 233 | return $this->addEvent("show.bs.dropdown", $jsCode); |
||
| 234 | } |
||
| 235 | |||
| 236 | /** |
||
| 237 | * This event is fired when a dropdown element has been made visible to the user (will wait for CSS transitions to complete). |
||
| 238 | * @param string $jsCode |
||
| 239 | * @return $this |
||
| 240 | */ |
||
| 241 | public function onShown($jsCode) { |
||
| 242 | return $this->addEvent("shown.bs.dropdown", $jsCode); |
||
| 243 | } |
||
| 244 | |||
| 245 | /** |
||
| 246 | * This event is fired immediately when the hide method has been called. |
||
| 247 | * @param string $jsCode |
||
| 248 | * @return $this |
||
| 249 | */ |
||
| 250 | public function onHide($jsCode) { |
||
| 251 | return $this->addEvent("hide.bs.dropdown", $jsCode); |
||
| 252 | } |
||
| 253 | |||
| 254 | /** |
||
| 255 | * This event is fired when a dropdown element has been hidden from the user (will wait for CSS transitions to complete). |
||
| 256 | * @param string $jsCode |
||
| 257 | * @return $this |
||
| 258 | */ |
||
| 259 | public function onHidden($jsCode) { |
||
| 261 | } |
||
| 262 | |||
| 263 | |||
| 264 | /* (non-PHPdoc) |
||
| 265 | * @see \Ajax\bootstrap\html\base\BaseHtml::on() |
||
| 266 | */ |
||
| 267 | public function on($event, $jsCode, $stopPropagation = false, $preventDefault = false) { |
||
| 268 | foreach ($this->items as $item){ |
||
| 269 | $item->on($event, $jsCode,$stopPropagation,$preventDefault); |
||
| 270 | } |
||
| 271 | } |
||
| 272 | |||
| 273 | /* (non-PHPdoc) |
||
| 274 | * @see \Ajax\bootstrap\html\base\BaseHtml::fromDatabaseObject() |
||
| 275 | */ |
||
| 276 | public function fromDatabaseObject($object, $function) { |
||
| 277 | $this->addItem($function($object)); |
||
| 278 | } |
||
| 279 | |||
| 280 | } |
||
| 281 |