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:
| 1 | <?php |
||
| 11 | abstract class FrontMatterObject |
||
| 12 | { |
||
| 13 | /** |
||
| 14 | * Set to true if the permalink has been sanitized |
||
| 15 | * |
||
| 16 | * @var bool |
||
| 17 | */ |
||
| 18 | protected $permalinkEvaluated; |
||
| 19 | |||
| 20 | /** |
||
| 21 | * Set to true if the front matter has already been evaluated with variable interpolation |
||
| 22 | * |
||
| 23 | * @var bool |
||
| 24 | */ |
||
| 25 | protected $frontMatterEvaluated; |
||
| 26 | |||
| 27 | /** |
||
| 28 | * An array containing the Yaml of the file |
||
| 29 | * |
||
| 30 | * @var array |
||
| 31 | */ |
||
| 32 | protected $frontMatter; |
||
| 33 | |||
| 34 | /** |
||
| 35 | * Set to true if the body has already been parsed as markdown or any other format |
||
| 36 | * |
||
| 37 | * @var bool |
||
| 38 | */ |
||
| 39 | protected $bodyContentEvaluated; |
||
| 40 | |||
| 41 | /** |
||
| 42 | * Only the body of the file, i.e. the content |
||
| 43 | * |
||
| 44 | * @var string |
||
| 45 | */ |
||
| 46 | protected $bodyContent; |
||
| 47 | |||
| 48 | /** |
||
| 49 | * The extension of the file |
||
| 50 | * |
||
| 51 | * @var string |
||
| 52 | */ |
||
| 53 | protected $extension; |
||
| 54 | |||
| 55 | /** |
||
| 56 | * The original file path to the ContentItem |
||
| 57 | * |
||
| 58 | * @var string |
||
| 59 | */ |
||
| 60 | protected $filePath; |
||
| 61 | |||
| 62 | /** |
||
| 63 | * A filesystem object |
||
| 64 | * |
||
| 65 | * @var Filesystem |
||
| 66 | */ |
||
| 67 | protected $fs; |
||
| 68 | |||
| 69 | /** |
||
| 70 | * ContentItem constructor. |
||
| 71 | * |
||
| 72 | * @param string $filePath The path to the file that will be parsed into a ContentItem |
||
| 73 | * |
||
| 74 | * @throws FileNotFoundException The given file path does not exist |
||
| 75 | * @throws IOException The file was not a valid ContentItem. This would meam there was no front matter or |
||
| 76 | * no body |
||
| 77 | */ |
||
| 78 | 28 | public function __construct ($filePath) |
|
| 92 | |||
| 93 | /** |
||
| 94 | * The magic getter returns values from the front matter in order to make these values accessible to Twig templates |
||
| 95 | * in a simple fashion |
||
| 96 | * |
||
| 97 | * @param string $name The key in the front matter |
||
| 98 | * |
||
| 99 | * @return mixed|null |
||
| 100 | */ |
||
| 101 | public function __get ($name) |
||
| 105 | |||
| 106 | /** |
||
| 107 | * The magic getter returns true if the value exists in the Front Matter. This is used in conjunction with the __get |
||
| 108 | * function |
||
| 109 | * |
||
| 110 | * @param string $name The name of the Front Matter value being looked for |
||
| 111 | * |
||
| 112 | * @return bool |
||
| 113 | */ |
||
| 114 | public function __isset ($name) |
||
| 118 | |||
| 119 | /** |
||
| 120 | * Return the body of the Content Item |
||
| 121 | * |
||
| 122 | * @return string |
||
| 123 | */ |
||
| 124 | abstract public function getContent (); |
||
| 125 | |||
| 126 | /** |
||
| 127 | * @param array|null $variables An array of YAML variables to use in evaluating the `$permalink` value |
||
| 128 | */ |
||
| 129 | final public function evaluateFrontMatter ($variables = null) |
||
| 138 | |||
| 139 | /** |
||
| 140 | * Get the Front Matter of a ContentItem as an array |
||
| 141 | * |
||
| 142 | * @param bool $evaluateYaml When set to true, the YAML will be evaluated for variables |
||
| 143 | * |
||
| 144 | * @return array |
||
| 145 | */ |
||
| 146 | final public function getFrontMatter ($evaluateYaml = true) |
||
| 160 | |||
| 161 | /** |
||
| 162 | * Get the permalink of this Content Item |
||
| 163 | * |
||
| 164 | * @return string |
||
| 165 | */ |
||
| 166 | final public function getPermalink () |
||
| 181 | |||
| 182 | /** |
||
| 183 | * Get the destination of where this Content Item would be written to when the website is compiled |
||
| 184 | * |
||
| 185 | * @return string |
||
| 186 | */ |
||
| 187 | final public function getTargetFile () |
||
| 199 | |||
| 200 | /** |
||
| 201 | * Get the name of the item, which is just the file name without the extension |
||
| 202 | * |
||
| 203 | * @return string |
||
| 204 | */ |
||
| 205 | final public function getName () |
||
| 209 | |||
| 210 | /** |
||
| 211 | * Get the original file path |
||
| 212 | * |
||
| 213 | * @return string |
||
| 214 | */ |
||
| 215 | final public function getFilePath () |
||
| 219 | |||
| 220 | /** |
||
| 221 | * Get the relative path to this file relative to the root of the Stakx website |
||
| 222 | * |
||
| 223 | * @return string |
||
| 224 | */ |
||
| 225 | final public function getRelativeFilePath () |
||
| 226 | { |
||
| 227 | 4 | return $this->fs->getRelativePath($this->filePath); |
|
| 228 | } |
||
| 229 | |||
| 230 | /** |
||
| 231 | * Read the file, and parse its contents |
||
| 232 | */ |
||
| 233 | final public function refreshFileContent () |
||
| 263 | |||
| 264 | /** |
||
| 265 | * Evaluate an array of data for FrontMatter variables. This function will modify the array in place. |
||
| 266 | * |
||
| 267 | * @param array $yaml An array of data containing FrontMatter variables |
||
| 268 | * |
||
| 269 | * @throws YamlVariableUndefinedException A FrontMatter variable used does not exist |
||
| 270 | */ |
||
| 271 | final protected function evaluateYaml (&$yaml) |
||
| 285 | |||
| 286 | /** |
||
| 287 | * Evaluate an string for FrontMatter variables and replace them with the corresponding values |
||
| 288 | * |
||
| 289 | * @param string $string The string that will be evaluated |
||
| 290 | * @param array $yaml The existing front matter from which the variable values will be pulled from |
||
| 291 | * |
||
| 292 | * @return string The final string with variables evaluated |
||
| 293 | * |
||
| 294 | * @throws YamlVariableUndefinedException A FrontMatter variable used does not exist |
||
| 295 | */ |
||
| 296 | private function evaluateYamlVar ($string, $yaml) |
||
| 320 | |||
| 321 | /** |
||
| 322 | * Handle special front matter values that need special treatment or have special meaning to a Content Item |
||
| 323 | */ |
||
| 324 | private function handleSpecialFrontMatter () |
||
| 347 | |||
| 348 | /** |
||
| 349 | * Get the permalink based off the location of where the file is relative to the website. This permalink is to be |
||
| 350 | * used as a fallback in the case that a permalink is not explicitly specified in the Front Matter. |
||
| 351 | * |
||
| 352 | * @return string |
||
| 353 | */ |
||
| 354 | private function getPathPermalink () |
||
| 372 | |||
| 373 | /** |
||
| 374 | * Sanitize a permalink to remove unsupported characters or multiple '/' and replace spaces with hyphens |
||
| 375 | * |
||
| 376 | * @param string $permalink A permalink |
||
| 377 | * |
||
| 378 | * @return string $permalink The sanitized permalink |
||
| 379 | */ |
||
| 380 | private function sanitizePermalink ($permalink) |
||
| 410 | } |
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.