Complex classes like Smarty_Internal_Runtime_Inheritance 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 Smarty_Internal_Runtime_Inheritance, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 11 | class Smarty_Internal_Runtime_Inheritance |
||
| 12 | { |
||
| 13 | |||
| 14 | /** |
||
| 15 | * State machine |
||
| 16 | * - 0 idle next extends will create a new inheritance tree |
||
| 17 | * - 1 processing child template |
||
| 18 | * - 2 wait for next inheritance template |
||
| 19 | * - 3 assume parent template, if child will loaded goto state 1 |
||
| 20 | * a call to a sub template resets the state to 0 |
||
| 21 | * |
||
| 22 | * @var int |
||
| 23 | */ |
||
| 24 | public $state = 0; |
||
| 25 | |||
| 26 | /** |
||
| 27 | * Array of root child {block} objects |
||
| 28 | * |
||
| 29 | * @var Smarty_Internal_Block[] |
||
| 30 | */ |
||
| 31 | public $childRoot = array(); |
||
| 32 | |||
| 33 | /** |
||
| 34 | * inheritance template nesting level |
||
| 35 | * |
||
| 36 | * @var int |
||
| 37 | */ |
||
| 38 | public $inheritanceLevel = 0; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * inheritance template index |
||
| 42 | * |
||
| 43 | * @var int |
||
| 44 | */ |
||
| 45 | public $tplIndex = - 1; |
||
| 46 | |||
| 47 | /** |
||
| 48 | * Array of template source objects |
||
| 49 | * - key template index |
||
| 50 | * |
||
| 51 | * @var Smarty_Template_Source[] |
||
| 52 | */ |
||
| 53 | public $sources = array(); |
||
| 54 | |||
| 55 | /** |
||
| 56 | * Stack of source objects while executing block code |
||
| 57 | * |
||
| 58 | * @var Smarty_Template_Source[] |
||
| 59 | */ |
||
| 60 | public $sourceStack = array(); |
||
| 61 | |||
| 62 | /** |
||
| 63 | * Initialize inheritance |
||
| 64 | * |
||
| 65 | * @param \Smarty_Internal_Template $tpl template object of caller |
||
| 66 | * @param bool $initChild if true init for child template |
||
| 67 | * @param array $blockNames outer level block name |
||
| 68 | * |
||
| 69 | */ |
||
| 70 | public function init(Smarty_Internal_Template $tpl, $initChild, $blockNames = array()) |
||
| 97 | |||
| 98 | /** |
||
| 99 | * End of child template(s) |
||
| 100 | * - if outer level is reached flush output buffer and switch to wait for parent template state |
||
| 101 | * |
||
| 102 | * @param \Smarty_Internal_Template $tpl |
||
| 103 | * @param null|string $template optinal name of inheritance parent template |
||
| 104 | * @param null|string $uid uid of inline template |
||
| 105 | * @param null|string $func function call name of inline template |
||
| 106 | */ |
||
| 107 | public function endChild(Smarty_Internal_Template $tpl, $template = null, $uid = null, $func = null) |
||
| 119 | |||
| 120 | /** |
||
| 121 | * Smarty_Internal_Block constructor. |
||
| 122 | * - if outer level {block} of child template ($state == 1) save it as child root block |
||
| 123 | * - otherwise process inheritance and render |
||
| 124 | * |
||
| 125 | * @param \Smarty_Internal_Template $tpl |
||
| 126 | * @param $className |
||
| 127 | * @param string $name |
||
| 128 | * @param int|null $tplIndex index of outer level {block} if nested |
||
| 129 | */ |
||
| 130 | public function instanceBlock(Smarty_Internal_Template $tpl, $className, $name, $tplIndex = null) |
||
| 131 | { |
||
| 132 | $block = new $className($name, isset($tplIndex) ? $tplIndex : $this->tplIndex); |
||
| 133 | if (isset($this->childRoot[ $name ])) { |
||
| 134 | $block->child = $this->childRoot[ $name ]; |
||
| 135 | } |
||
| 136 | if ($this->state == 1) { |
||
| 137 | $this->childRoot[ $name ] = $block; |
||
| 138 | return; |
||
| 139 | } |
||
| 140 | // make sure we got child block of child template of current block |
||
| 141 | while ($block->child && $block->tplIndex <= $block->child->tplIndex) { |
||
| 142 | $block->child = $block->child->child; |
||
| 143 | } |
||
| 144 | $this->process($tpl, $block); |
||
| 145 | } |
||
| 146 | |||
| 147 | /** |
||
| 148 | * Goto child block or render this |
||
| 149 | * |
||
| 150 | * @param \Smarty_Internal_Template $tpl |
||
| 151 | * @param \Smarty_Internal_Block $block |
||
| 152 | * @param \Smarty_Internal_Block|null $parent |
||
| 153 | * |
||
| 154 | * @throws \SmartyException |
||
| 155 | */ |
||
| 156 | public function process(Smarty_Internal_Template $tpl, Smarty_Internal_Block $block, |
||
| 157 | Smarty_Internal_Block $parent = null) |
||
| 158 | { |
||
| 159 | if ($block->hide && !isset($block->child)) { |
||
| 160 | return; |
||
| 161 | } |
||
| 162 | if (isset($block->child) && $block->child->hide && !isset($block->child->child)) { |
||
| 163 | $block->child = null; |
||
| 164 | } |
||
| 165 | $block->parent = $parent; |
||
| 166 | if ($block->append && !$block->prepend && isset($parent)) { |
||
| 167 | $this->callParent($tpl, $block); |
||
| 168 | } |
||
| 169 | if ($block->callsChild || !isset($block->child) || ($block->child->hide && !isset($block->child->child))) { |
||
| 170 | $this->callBlock($block, $tpl); |
||
| 171 | } else { |
||
| 172 | $this->process($tpl, $block->child, $block); |
||
| 173 | } |
||
| 174 | if ($block->prepend && isset($parent)) { |
||
| 175 | $this->callParent($tpl, $block); |
||
| 176 | if ($block->append) { |
||
| 177 | if ($block->callsChild || !isset($block->child) || |
||
| 178 | ($block->child->hide && !isset($block->child->child)) |
||
| 179 | ) { |
||
| 180 | $this->callBlock($block, $tpl); |
||
| 181 | } else { |
||
| 182 | $this->process($tpl, $block->child, $block); |
||
| 183 | } |
||
| 184 | } |
||
| 185 | } |
||
| 186 | $block->parent = null; |
||
| 187 | } |
||
| 188 | |||
| 189 | /** |
||
| 190 | * Render child on {$smarty.block.child} |
||
| 191 | * |
||
| 192 | * @param \Smarty_Internal_Template $tpl |
||
| 193 | * @param \Smarty_Internal_Block $block |
||
| 194 | */ |
||
| 195 | public function callChild(Smarty_Internal_Template $tpl, Smarty_Internal_Block $block) |
||
| 196 | { |
||
| 197 | if (isset($block->child)) { |
||
| 198 | $this->process($tpl, $block->child, $block); |
||
| 199 | } |
||
| 200 | } |
||
| 201 | |||
| 202 | /** |
||
| 203 | * Render parent on {$smarty.block.parent} or {block append/prepend} * |
||
| 204 | * |
||
| 205 | * @param \Smarty_Internal_Template $tpl |
||
| 206 | * @param \Smarty_Internal_Block $block |
||
| 207 | * |
||
| 208 | * @param null $name |
||
| 209 | * |
||
| 210 | * @throws \SmartyException |
||
| 211 | */ |
||
| 212 | public function callParent(Smarty_Internal_Template $tpl, Smarty_Internal_Block $block, $name = null) |
||
| 213 | { |
||
| 214 | if (isset($name)) { |
||
| 215 | $block = $block->parent; |
||
| 216 | while (isset($block)) { |
||
| 217 | if (isset($block->subBlocks[ $name ])) { |
||
| 218 | } else { |
||
| 219 | $block = $block->parent; |
||
| 220 | } |
||
| 221 | } |
||
| 222 | return; |
||
| 223 | } else if (isset($block->parent)) { |
||
| 224 | $this->callBlock($block->parent, $tpl); |
||
| 225 | } else { |
||
| 226 | throw new SmartyException("inheritance: illegal {\$smarty.block.parent} or {block append/prepend} used in parent template '{$tpl->inheritance->sources[$block->tplIndex]->filepath}' block '{$block->name}'"); |
||
| 227 | } |
||
| 228 | } |
||
| 229 | |||
| 230 | /** |
||
| 231 | * @param \Smarty_Internal_Block $block |
||
| 232 | * @param \Smarty_Internal_Template $tpl |
||
| 233 | */ |
||
| 234 | public function callBlock(Smarty_Internal_Block $block, Smarty_Internal_Template $tpl) |
||
| 235 | { |
||
| 236 | $this->sourceStack[] = $tpl->source; |
||
| 237 | $tpl->source = $this->sources[ $block->tplIndex ]; |
||
| 238 | $block->callBlock($tpl); |
||
| 239 | $tpl->source = array_pop($this->sourceStack); |
||
| 240 | } |
||
| 241 | } |
||
| 242 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.