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 AbstractTemplateView 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 AbstractTemplateView, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 25 | abstract class AbstractTemplateView extends AbstractView  | 
            ||
| 26 | { | 
            ||
| 27 | |||
| 28 | /**  | 
            ||
| 29 | * Constants defining possible rendering types  | 
            ||
| 30 | */  | 
            ||
| 31 | const RENDERING_TEMPLATE = 1;  | 
            ||
| 32 | const RENDERING_PARTIAL = 2;  | 
            ||
| 33 | const RENDERING_LAYOUT = 3;  | 
            ||
| 34 | |||
| 35 | /**  | 
            ||
| 36 | * The initial rendering context for this template view.  | 
            ||
| 37 | * Due to the rendering stack, another rendering context might be active  | 
            ||
| 38 | * at certain points while rendering the template.  | 
            ||
| 39 | *  | 
            ||
| 40 | * @var RenderingContextInterface  | 
            ||
| 41 | */  | 
            ||
| 42 | protected $baseRenderingContext;  | 
            ||
| 43 | |||
| 44 | /**  | 
            ||
| 45 | * Stack containing the current rendering type, the current rendering context, and the current parsed template  | 
            ||
| 46 | * Do not manipulate directly, instead use the methods"getCurrent*()", "startRendering(...)" and "stopRendering()"  | 
            ||
| 47 | *  | 
            ||
| 48 | * @var array  | 
            ||
| 49 | */  | 
            ||
| 50 | protected $renderingStack = [];  | 
            ||
| 51 | |||
| 52 | /**  | 
            ||
| 53 | * Constructor  | 
            ||
| 54 | *  | 
            ||
| 55 | * @param null|RenderingContextInterface $context  | 
            ||
| 56 | */  | 
            ||
| 57 | public function __construct(RenderingContextInterface $context = null)  | 
            ||
| 66 | |||
| 67 | /**  | 
            ||
| 68 | * Initialize the RenderingContext. This method can be overridden in your  | 
            ||
| 69 | * View implementation to manipulate the rendering context *before* it is  | 
            ||
| 70 | * passed during rendering.  | 
            ||
| 71 | */  | 
            ||
| 72 | public function initializeRenderingContext()  | 
            ||
| 76 | |||
| 77 | /**  | 
            ||
| 78 | * Sets the cache to use in RenderingContext.  | 
            ||
| 79 | *  | 
            ||
| 80 | * @param FluidCacheInterface $cache  | 
            ||
| 81 | * @return void  | 
            ||
| 82 | */  | 
            ||
| 83 | public function setCache(FluidCacheInterface $cache)  | 
            ||
| 87 | |||
| 88 | /**  | 
            ||
| 89 | * Gets the TemplatePaths instance from RenderingContext  | 
            ||
| 90 | *  | 
            ||
| 91 | * @return TemplatePaths  | 
            ||
| 92 | */  | 
            ||
| 93 | public function getTemplatePaths()  | 
            ||
| 97 | |||
| 98 | /**  | 
            ||
| 99 | * Gets the ViewHelperResolver instance from RenderingContext  | 
            ||
| 100 | *  | 
            ||
| 101 | * @return ViewHelperResolver  | 
            ||
| 102 | */  | 
            ||
| 103 | public function getViewHelperResolver()  | 
            ||
| 107 | |||
| 108 | /**  | 
            ||
| 109 | * Gets the RenderingContext used by the View  | 
            ||
| 110 | *  | 
            ||
| 111 | * @return RenderingContextInterface  | 
            ||
| 112 | */  | 
            ||
| 113 | public function getRenderingContext()  | 
            ||
| 117 | |||
| 118 | /**  | 
            ||
| 119 | * Injects a fresh rendering context  | 
            ||
| 120 | *  | 
            ||
| 121 | * @param RenderingContextInterface $renderingContext  | 
            ||
| 122 | * @return void  | 
            ||
| 123 | */  | 
            ||
| 124 | public function setRenderingContext(RenderingContextInterface $renderingContext)  | 
            ||
| 129 | |||
| 130 | /**  | 
            ||
| 131 | * Assign a value to the variable container.  | 
            ||
| 132 | *  | 
            ||
| 133 | * @param string $key The key of a view variable to set  | 
            ||
| 134 | * @param mixed $value The value of the view variable  | 
            ||
| 135 | * @return $this  | 
            ||
| 136 | * @api  | 
            ||
| 137 | */  | 
            ||
| 138 | public function assign($key, $value)  | 
            ||
| 143 | |||
| 144 | /**  | 
            ||
| 145 | * Assigns multiple values to the JSON output.  | 
            ||
| 146 | * However, only the key "value" is accepted.  | 
            ||
| 147 | *  | 
            ||
| 148 | * @param array $values Keys and values - only a value with key "value" is considered  | 
            ||
| 149 | * @return $this  | 
            ||
| 150 | * @api  | 
            ||
| 151 | */  | 
            ||
| 152 | public function assignMultiple(array $values)  | 
            ||
| 160 | |||
| 161 | /**  | 
            ||
| 162 | * Loads the template source and render the template.  | 
            ||
| 163 | * If "layoutName" is set in a PostParseFacet callback, it will render the file with the given layout.  | 
            ||
| 164 | *  | 
            ||
| 165 | * @param string|null $actionName If set, this action's template will be rendered instead of the one defined in the context.  | 
            ||
| 166 | * @return string Rendered Template  | 
            ||
| 167 | * @api  | 
            ||
| 168 | */  | 
            ||
| 169 | public function render($actionName = null)  | 
            ||
| 207 | |||
| 208 | /**  | 
            ||
| 209 | * Renders a given section.  | 
            ||
| 210 | *  | 
            ||
| 211 | * @param string $sectionName Name of section to render  | 
            ||
| 212 | * @param array $variables The variables to use  | 
            ||
| 213 | * @param boolean $ignoreUnknown Ignore an unknown section and just return an empty string  | 
            ||
| 214 | * @return string rendered template for the section  | 
            ||
| 215 | * @throws InvalidSectionException  | 
            ||
| 216 | */  | 
            ||
| 217 | public function renderSection($sectionName, array $variables = [], $ignoreUnknown = false)  | 
            ||
| 288 | |||
| 289 | /**  | 
            ||
| 290 | * Renders a partial.  | 
            ||
| 291 | *  | 
            ||
| 292 | * @param string $partialName  | 
            ||
| 293 | * @param string $sectionName  | 
            ||
| 294 | * @param array $variables  | 
            ||
| 295 | * @param boolean $ignoreUnknown Ignore an unknown section and just return an empty string  | 
            ||
| 296 | * @return string  | 
            ||
| 297 | */  | 
            ||
| 298 | public function renderPartial($partialName, $sectionName, array $variables, $ignoreUnknown = false)  | 
            ||
| 334 | |||
| 335 | /**  | 
            ||
| 336 | * Start a new nested rendering. Pushes the given information onto the $renderingStack.  | 
            ||
| 337 | *  | 
            ||
| 338 | * @param integer $type one of the RENDERING_* constants  | 
            ||
| 339 | * @param ParsedTemplateInterface $template  | 
            ||
| 340 | * @param RenderingContextInterface $context  | 
            ||
| 341 | * @return void  | 
            ||
| 342 | */  | 
            ||
| 343 | protected function startRendering($type, ParsedTemplateInterface $template, RenderingContextInterface $context)  | 
            ||
| 347 | |||
| 348 | /**  | 
            ||
| 349 | * Stops the current rendering. Removes one element from the $renderingStack. Make sure to always call this  | 
            ||
| 350 | * method pair-wise with startRendering().  | 
            ||
| 351 | *  | 
            ||
| 352 | * @return void  | 
            ||
| 353 | */  | 
            ||
| 354 | protected function stopRendering()  | 
            ||
| 359 | |||
| 360 | /**  | 
            ||
| 361 | * Get the current rendering type.  | 
            ||
| 362 | *  | 
            ||
| 363 | * @return integer one of RENDERING_* constants  | 
            ||
| 364 | */  | 
            ||
| 365 | protected function getCurrentRenderingType()  | 
            ||
| 370 | |||
| 371 | /**  | 
            ||
| 372 | * Get the parsed template which is currently being rendered or compiled.  | 
            ||
| 373 | *  | 
            ||
| 374 | * @return ParsedTemplateInterface  | 
            ||
| 375 | */  | 
            ||
| 376 | protected function getCurrentParsedTemplate()  | 
            ||
| 399 | |||
| 400 | /**  | 
            ||
| 401 | * Get the rendering context which is currently used.  | 
            ||
| 402 | *  | 
            ||
| 403 | * @return RenderingContextInterface  | 
            ||
| 404 | */  | 
            ||
| 405 | protected function getCurrentRenderingContext()  | 
            ||
| 410 | }  | 
            ||
| 411 | 
In PHP, under loose comparison (like
==, or!=, orswitchconditions), values of different types might be equal.For
stringvalues, the empty string''is a special case, in particular the following results might be unexpected: