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 Generator 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 Generator, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 22 | class Generator  | 
            ||
| 23 | { | 
            ||
| 24 | /** @var DatabaseInterface */  | 
            ||
| 25 | protected $database;  | 
            ||
| 26 | |||
| 27 | /** @var \samsonphp\generator\Generator */  | 
            ||
| 28 | protected $generator;  | 
            ||
| 29 | |||
| 30 | /** @var Metadata[] Collection of entities metadata */  | 
            ||
| 31 | protected $metadata;  | 
            ||
| 32 | |||
| 33 | /**  | 
            ||
| 34 | * Transliterate string to english.  | 
            ||
| 35 | *  | 
            ||
| 36 | * @param string $string Source string  | 
            ||
| 37 | * @return string Transliterated string  | 
            ||
| 38 | */  | 
            ||
| 39 | protected function transliterated($string)  | 
            ||
| 40 |     { | 
            ||
| 41 | return str_replace(  | 
            ||
| 42 | ' ',  | 
            ||
| 43 | '',  | 
            ||
| 44 |             ucwords(iconv("UTF-8", "UTF-8//IGNORE", strtr($string, array( | 
            ||
| 45 | "'" => "",  | 
            ||
| 46 | "`" => "",  | 
            ||
| 47 | "-" => " ",  | 
            ||
| 48 | "_" => " ",  | 
            ||
| 49 | "а" => "a", "А" => "a",  | 
            ||
| 50 | "б" => "b", "Б" => "b",  | 
            ||
| 51 | "в" => "v", "В" => "v",  | 
            ||
| 52 | "г" => "g", "Г" => "g",  | 
            ||
| 53 | "д" => "d", "Д" => "d",  | 
            ||
| 54 | "е" => "e", "Е" => "e",  | 
            ||
| 55 | "ж" => "zh", "Ж" => "zh",  | 
            ||
| 56 | "з" => "z", "З" => "z",  | 
            ||
| 57 | "и" => "i", "И" => "i",  | 
            ||
| 58 | "й" => "y", "Й" => "y",  | 
            ||
| 59 | "к" => "k", "К" => "k",  | 
            ||
| 60 | "л" => "l", "Л" => "l",  | 
            ||
| 61 | "м" => "m", "М" => "m",  | 
            ||
| 62 | "н" => "n", "Н" => "n",  | 
            ||
| 63 | "о" => "o", "О" => "o",  | 
            ||
| 64 | "п" => "p", "П" => "p",  | 
            ||
| 65 | "р" => "r", "Р" => "r",  | 
            ||
| 66 | "с" => "s", "С" => "s",  | 
            ||
| 67 | "т" => "t", "Т" => "t",  | 
            ||
| 68 | "у" => "u", "У" => "u",  | 
            ||
| 69 | "ф" => "f", "Ф" => "f",  | 
            ||
| 70 | "х" => "h", "Х" => "h",  | 
            ||
| 71 | "ц" => "c", "Ц" => "c",  | 
            ||
| 72 | "ч" => "ch", "Ч" => "ch",  | 
            ||
| 73 | "ш" => "sh", "Ш" => "sh",  | 
            ||
| 74 | "щ" => "sch", "Щ" => "sch",  | 
            ||
| 75 | "ъ" => "", "Ъ" => "",  | 
            ||
| 76 | "ы" => "y", "Ы" => "y",  | 
            ||
| 77 | "ь" => "", "Ь" => "",  | 
            ||
| 78 | "э" => "e", "Э" => "e",  | 
            ||
| 79 | "ю" => "yu", "Ю" => "yu",  | 
            ||
| 80 | "я" => "ya", "Я" => "ya",  | 
            ||
| 81 | "і" => "i", "І" => "i",  | 
            ||
| 82 | "ї" => "yi", "Ї" => "yi",  | 
            ||
| 83 | "є" => "e", "Є" => "e"  | 
            ||
| 84 | )  | 
            ||
| 85 | )  | 
            ||
| 86 | )  | 
            ||
| 87 | )  | 
            ||
| 88 | );  | 
            ||
| 89 | }  | 
            ||
| 90 | |||
| 91 | /**  | 
            ||
| 92 | * Get class constant name by its value.  | 
            ||
| 93 | *  | 
            ||
| 94 | * @param string $value Constant value  | 
            ||
| 95 | * @param string $className Class name  | 
            ||
| 96 | * @return string Full constant name  | 
            ||
| 97 | */  | 
            ||
| 98 | protected function constantNameByValue($value, $className = Field::ENTITY)  | 
            ||
| 99 |     { | 
            ||
| 100 | // Get array where class constants are values and their values are keys  | 
            ||
| 101 | $nameByValue = array_flip((new \ReflectionClass($className))->getConstants());  | 
            ||
| 102 | |||
| 103 | // Try to find constant by its value  | 
            ||
| 104 |         if (null !== $nameByValue[$value]) { | 
            ||
| 105 | // Return constant name  | 
            ||
| 106 | return $nameByValue[$value];  | 
            ||
| 107 | }  | 
            ||
| 108 | |||
| 109 | return '';  | 
            ||
| 110 | }  | 
            ||
| 111 | |||
| 112 | /**  | 
            ||
| 113 | * Get correct entity name.  | 
            ||
| 114 | *  | 
            ||
| 115 | * @param string $navigationName Original navigation entity name  | 
            ||
| 116 | * @return string Correct PHP-supported entity name  | 
            ||
| 117 | */  | 
            ||
| 118 | protected function entityName($navigationName)  | 
            ||
| 119 |     { | 
            ||
| 120 | return ucfirst($this->getValidName($this->transliterated($navigationName)));  | 
            ||
| 121 | }  | 
            ||
| 122 | |||
| 123 | /**  | 
            ||
| 124 | * Remove all wrong characters from entity name  | 
            ||
| 125 | *  | 
            ||
| 126 | * @param string $navigationName Original navigation entity name  | 
            ||
| 127 | * @return string Correct PHP-supported entity name  | 
            ||
| 128 | */  | 
            ||
| 129 | protected function getValidName($navigationName)  | 
            ||
| 130 |     { | 
            ||
| 131 |         return preg_replace('/(^\d*)|([^\w\d_])/', '', $navigationName); | 
            ||
| 132 | }  | 
            ||
| 133 | |||
| 134 | /**  | 
            ||
| 135 | * Get correct full entity name with name space.  | 
            ||
| 136 | *  | 
            ||
| 137 | * @param string $navigationName Original navigation entity name  | 
            ||
| 138 | * @param string $namespace Namespace  | 
            ||
| 139 | * @return string Correct PHP-supported entity name  | 
            ||
| 140 | */  | 
            ||
| 141 | protected function fullEntityName($navigationName, $namespace = __NAMESPACE__)  | 
            ||
| 142 |     { | 
            ||
| 143 | return '\\'.$namespace.'\\'.$this->entityName($navigationName);  | 
            ||
| 144 | }  | 
            ||
| 145 | |||
| 146 | /**  | 
            ||
| 147 | * Get correct field name.  | 
            ||
| 148 | *  | 
            ||
| 149 | * @param string $fieldName Original field name  | 
            ||
| 150 | * @return string Correct PHP-supported field name  | 
            ||
| 151 | */  | 
            ||
| 152 | protected function fieldName($fieldName)  | 
            ||
| 153 |     { | 
            ||
| 154 | return $fieldName = lcfirst($this->transliterated($fieldName));  | 
            ||
| 
                                                                                                    
                        
                         | 
                |||
| 155 | }  | 
            ||
| 156 | |||
| 157 | /**  | 
            ||
| 158 | * Get additional field type in form of Field constant name  | 
            ||
| 159 | * by database additional field type identifier.  | 
            ||
| 160 | *  | 
            ||
| 161 | * @param integer $fieldType Additional field type identifier  | 
            ||
| 162 | * @return string Additional field type constant  | 
            ||
| 163 | */  | 
            ||
| 164 | protected function additionalFieldType($fieldType)  | 
            ||
| 165 |     { | 
            ||
| 166 | return 'Field::'.$this->constantNameByValue($fieldType);  | 
            ||
| 167 | }  | 
            ||
| 168 | |||
| 169 | /**  | 
            ||
| 170 | * Generate Query::where() analog for specific field.  | 
            ||
| 171 | *  | 
            ||
| 172 | * @param string $fieldName Field name  | 
            ||
| 173 | * @param string $fieldId Field primary identifier  | 
            ||
| 174 | * @param string $fieldType Field PHP type  | 
            ||
| 175 | * @return string Generated PHP method code  | 
            ||
| 176 | */  | 
            ||
| 177 | View Code Duplication | protected function generateFieldConditionMethod($fieldName, $fieldId, $fieldType)  | 
            |
| 178 |     { | 
            ||
| 179 | $code = "\n\t" . '/**';  | 
            ||
| 180 | $code .= "\n\t" . ' * Add '.$fieldName.'(#' . $fieldId . ') field query condition.';  | 
            ||
| 181 | $code .= "\n\t" . ' * @param '.Field::phpType($fieldType).' $value Field value';  | 
            ||
| 182 | $code .= "\n\t" . ' * @return $this Chaining';  | 
            ||
| 183 | $code .= "\n\t" . ' * @see Generic::where()';  | 
            ||
| 184 | $code .= "\n\t" . ' */';  | 
            ||
| 185 | $code .= "\n\t" . 'public function ' . $fieldName . '($value, $relation = ArgumentInterface::EQUAL)';  | 
            ||
| 186 |         $code .= "\n\t" . "{"; | 
            ||
| 187 |         $code .= "\n\t\t" . 'return $this->where("'.$fieldName.'", $value, $relation);'; | 
            ||
| 188 | |||
| 189 | return $code . "\n\t" . "}"."\n";  | 
            ||
| 190 | }  | 
            ||
| 191 | |||
| 192 | /**  | 
            ||
| 193 | * Generate Query::where() analog for specific field.  | 
            ||
| 194 | *  | 
            ||
| 195 | * @param string $fieldName Field name  | 
            ||
| 196 | * @param string $fieldId Field primary identifier  | 
            ||
| 197 | * @param string $fieldType Field PHP type  | 
            ||
| 198 | * @return string Generated PHP method code  | 
            ||
| 199 | */  | 
            ||
| 200 | View Code Duplication | protected function generateLocalizedFieldConditionMethod($fieldName, $fieldId, $fieldType)  | 
            |
| 201 |     { | 
            ||
| 202 | $code = "\n\t" . '/**';  | 
            ||
| 203 | $code .= "\n\t" . ' * Add '.$fieldName.'(#' . $fieldId . ') field query condition.';  | 
            ||
| 204 | $code .= "\n\t" . ' * @param '.Field::phpType($fieldType).' $value Field value';  | 
            ||
| 205 | $code .= "\n\t" . ' * @return $this Chaining';  | 
            ||
| 206 | $code .= "\n\t" . ' * @see Generic::where()';  | 
            ||
| 207 | $code .= "\n\t" . ' */';  | 
            ||
| 208 | $code .= "\n\t" . 'public function ' . $fieldName . '($value)';  | 
            ||
| 209 |         $code .= "\n\t" . "{"; | 
            ||
| 210 |         $code .= "\n\t\t" . 'return $this->where("'.$fieldName.'", $value);'; | 
            ||
| 211 | |||
| 212 | return $code . "\n\t" . "}"."\n";  | 
            ||
| 213 | }  | 
            ||
| 214 | |||
| 215 | /**  | 
            ||
| 216 | * Create entity PHP class code.  | 
            ||
| 217 | *  | 
            ||
| 218 | * @param Metadata $metadata Entity metadata  | 
            ||
| 219 | * @return string Generated entity query PHP class code  | 
            ||
| 220 | */  | 
            ||
| 221 | protected function createEntityClass(Metadata $metadata)  | 
            ||
| 222 |     { | 
            ||
| 223 | $this->generator  | 
            ||
| 224 |             ->multiComment(array('"'.$metadata->entityRealName.'" entity class')) | 
            ||
| 225 | ->defClass($metadata->entity, null !== $metadata->parent ? $metadata->parent->className : 'Entity')  | 
            ||
| 226 |             ->commentVar('string', '@deprecated Entity full class name, use ::class') | 
            ||
| 227 |             ->defClassConst('ENTITY', $metadata->className) | 
            ||
| 228 |             ->commentVar('string', 'Entity manager full class name') | 
            ||
| 229 |             ->defClassConst('MANAGER', $metadata->className.'Query') | 
            ||
| 230 |             ->commentVar('string', 'Entity database identifier') | 
            ||
| 231 |             ->defClassConst('IDENTIFIER', $metadata->entityID) | 
            ||
| 232 |             ->commentVar('string', 'Not transliterated entity name') | 
            ||
| 233 |             ->defClassVar('$viewName', 'protected static', $metadata->entityRealName); | 
            ||
| 234 | |||
| 235 |         foreach ($metadata->allFieldIDs as $fieldID => $fieldName) { | 
            ||
| 236 | $this->generator  | 
            ||
| 237 |                 ->commentVar('string', $metadata->fieldDescriptions[$fieldID].' variable name') | 
            ||
| 238 |                 ->defClassConst('F_' . $fieldName, $fieldName) | 
            ||
| 239 | ->commentVar($metadata->allFieldTypes[$fieldID], $metadata->fieldDescriptions[$fieldID])  | 
            ||
| 240 |                 ->defClassVar('$' . $fieldName, 'public'); | 
            ||
| 241 | }  | 
            ||
| 242 | |||
| 243 | return $this->generator  | 
            ||
| 244 |             ->defClassVar('$_sql_select', 'public static ', $metadata->arSelect) | 
            ||
| 245 |             ->defClassVar('$_attributes', 'public static ', $metadata->arAttributes) | 
            ||
| 246 |             ->defClassVar('$_map', 'public static ', $metadata->arMap) | 
            ||
| 247 |             ->defClassVar('$_sql_from', 'public static ', $metadata->arFrom) | 
            ||
| 248 |             ->defClassVar('$_own_group', 'public static ', $metadata->arGroup) | 
            ||
| 249 |             ->defClassVar('$_relation_alias', 'public static ', $metadata->arRelationAlias) | 
            ||
| 250 |             ->defClassVar('$_relation_type', 'public static ', $metadata->arRelationType) | 
            ||
| 251 |             ->defClassVar('$_relations', 'public static ', $metadata->arRelations) | 
            ||
| 252 | ->endclass()  | 
            ||
| 253 | ->flush();  | 
            ||
| 254 | }  | 
            ||
| 255 | |||
| 256 | /**  | 
            ||
| 257 | * Generate FieldsTable::values() analog for specific field.  | 
            ||
| 258 | *  | 
            ||
| 259 | * @param string $fieldName Field name  | 
            ||
| 260 | * @param string $fieldId Field primary identifier  | 
            ||
| 261 | * @param string $fieldType Field PHP type  | 
            ||
| 262 | * @return string Generated PHP method code  | 
            ||
| 263 | */  | 
            ||
| 264 | protected function generateTableFieldMethod($fieldName, $fieldId, $fieldType)  | 
            ||
| 265 |     { | 
            ||
| 266 | $code = "\n\t" . '/**';  | 
            ||
| 267 | $code .= "\n\t" . ' * Get table column '.$fieldName.'(#' . $fieldId . ') values.';  | 
            ||
| 268 |         $code .= "\n\t" . ' * @return array Collection('.Field::phpType($fieldType).') of table column values'; | 
            ||
| 269 | $code .= "\n\t" . ' */';  | 
            ||
| 270 | $code .= "\n\t" . 'public function ' . $fieldName . '()';  | 
            ||
| 271 |         $code .= "\n\t" . "{"; | 
            ||
| 272 |         $code .= "\n\t\t" . 'return $this->values('.$fieldId.');'; | 
            ||
| 273 | |||
| 274 | return $code . "\n\t" . "}"."\n";  | 
            ||
| 275 | }  | 
            ||
| 276 | |||
| 277 | /**  | 
            ||
| 278 | * Create fields table row PHP class code.  | 
            ||
| 279 | *  | 
            ||
| 280 | * @param string $navigationName Original entity name  | 
            ||
| 281 | * @param string $entityName PHP entity name  | 
            ||
| 282 | * @param array $navigationFields Collection of entity additional fields  | 
            ||
| 283 | * @return string Generated entity query PHP class code  | 
            ||
| 284 | */  | 
            ||
| 285 | protected function createTableRowClass($navigationName, $entityName, $navigationFields)  | 
            ||
| 286 |     { | 
            ||
| 287 | $class = "\n";  | 
            ||
| 288 | $class .= "\n" . '/**';  | 
            ||
| 289 | $class .= "\n" . ' * Class for getting "'.$navigationName.'" fields table rows';  | 
            ||
| 290 | $class .= "\n" . ' */';  | 
            ||
| 291 | $class .= "\n" . 'class ' . $entityName . ' extends Row';  | 
            ||
| 292 |         $class .= "\n" . '{'; | 
            ||
| 293 | |||
| 294 | // Iterate additional fields  | 
            ||
| 295 | $constants = '';  | 
            ||
| 296 | $variables = '';  | 
            ||
| 297 |         foreach ($navigationFields as $fieldID => $fieldRow) { | 
            ||
| 298 | $fieldName = $this->fieldName($fieldRow['Name']);  | 
            ||
| 299 | |||
| 300 | $constants .= "\n\t" . '/** ' . Field::phpType($fieldRow['Type']) . ' '.$fieldRow['Description'].' Field #' . $fieldID . ' variable name */';  | 
            ||
| 301 | // Store original field name  | 
            ||
| 302 | $constants .= "\n\t" . 'const F_' . strtoupper($fieldName) . ' = "'.$fieldName.'";';  | 
            ||
| 303 | |||
| 304 | $variables .= "\n\t" . '/** ' . Field::phpType($fieldRow['Type']) . ' '.$fieldRow['Description'].' Field #' . $fieldID . ' row value */';  | 
            ||
| 305 | $variables .= "\n\t" . 'public $' . $fieldName . ';';  | 
            ||
| 306 | }  | 
            ||
| 307 | |||
| 308 | $class .= $constants;  | 
            ||
| 309 | $class .= "\n\t";  | 
            ||
| 310 | $class .= $variables;  | 
            ||
| 311 | $class .= "\n" . '}';  | 
            ||
| 312 | |||
| 313 | return $class;  | 
            ||
| 314 | }  | 
            ||
| 315 | |||
| 316 | /**  | 
            ||
| 317 | * Create fields table PHP class code.  | 
            ||
| 318 | *  | 
            ||
| 319 | * @param integer $navigationID Entity navigation identifier  | 
            ||
| 320 | * @param string $navigationName Original entity name  | 
            ||
| 321 | * @param string $entityName PHP entity name  | 
            ||
| 322 | * @param array $navigationFields Collection of entity additional fields  | 
            ||
| 323 | * @param string $rowClassName Row class name  | 
            ||
| 324 | *  | 
            ||
| 325 | * @return string Generated entity query PHP class code  | 
            ||
| 326 | * @throws exception\AdditionalFieldTypeNotFound  | 
            ||
| 327 | */  | 
            ||
| 328 | protected function createTableClass($navigationID, $navigationName, $entityName, $navigationFields, $rowClassName)  | 
            ||
| 329 |     { | 
            ||
| 330 | $this->generator  | 
            ||
| 331 |             ->multiComment(array('Class for getting "'.$navigationName.'" fields table')) | 
            ||
| 332 | ->defClass($entityName, 'FieldsTable');  | 
            ||
| 333 | |||
| 334 | // Iterate additional fields  | 
            ||
| 335 | $fields = array();  | 
            ||
| 336 |         foreach ($navigationFields as $fieldID => $fieldRow) { | 
            ||
| 337 | $fieldName = $this->fieldName($fieldRow['Name']);  | 
            ||
| 338 | |||
| 339 | $this->generator  | 
            ||
| 340 | ->text($this->generateTableFieldMethod(  | 
            ||
| 341 | $fieldName,  | 
            ||
| 342 | $fieldRow[Field::F_PRIMARY],  | 
            ||
| 343 | $fieldRow[Field::F_TYPE]  | 
            ||
| 344 | ))  | 
            ||
| 345 | ->commentVar(Field::phpType($fieldRow['Type']), $fieldRow['Description'] . ' Field #' . $fieldID . ' variable name')  | 
            ||
| 346 |                 ->defClassConst('F_' . $fieldName, $fieldName); | 
            ||
| 347 | |||
| 348 | // Collection original to new one field names  | 
            ||
| 349 | $fields[$fieldRow['Name']] = $fieldName;  | 
            ||
| 350 | }  | 
            ||
| 351 | |||
| 352 | // TODO: Add generator method generation logic  | 
            ||
| 353 | $class = "\n\t".'/**';  | 
            ||
| 354 | $class .= "\n\t".' * @param QueryInterface $query Database query instance';  | 
            ||
| 355 | $class .= "\n\t".' * @param ViewInterface $renderer Rendering instance';  | 
            ||
| 356 | $class .= "\n\t".' * @param integer $entityID Entity identifier to whom this table belongs';  | 
            ||
| 357 | $class .= "\n\t".' * @param string $locale Localization identifier';  | 
            ||
| 358 | $class .= "\n\t".' */';  | 
            ||
| 359 | $class .= "\n\t".'public function __construct(QueryInterface $query, ViewInterface $renderer, $entityID, $locale = null)';  | 
            ||
| 360 |         $class .= "\n\t".'{'; | 
            ||
| 361 | $class .= "\n\t\t".'parent::__construct($query, $renderer, static::$navigationIDs, $entityID, $locale);';  | 
            ||
| 362 | $class .= "\n\t".'}'."\n";  | 
            ||
| 363 | |||
| 364 | $this->generator->text($class);  | 
            ||
| 365 | |||
| 366 | return $this->generator  | 
            ||
| 367 |             ->commentVar('array', 'Collection of real additional field names') | 
            ||
| 368 |             ->defClassVar('$fieldsRealNames', 'public static', $fields) | 
            ||
| 369 |             ->commentVar('array', 'Collection of navigation identifiers') | 
            ||
| 370 |             ->defClassVar('$navigationIDs', 'protected static', array($navigationID)) | 
            ||
| 371 |             ->commentVar('string', 'Row class name') | 
            ||
| 372 |             ->defClassVar('$identifier', 'protected', $this->fullEntityName($rowClassName)) | 
            ||
| 373 | ->endClass()  | 
            ||
| 374 | ->flush();  | 
            ||
| 375 | }  | 
            ||
| 376 | |||
| 377 | /**  | 
            ||
| 378 | * Create entity query PHP class code.  | 
            ||
| 379 | *  | 
            ||
| 380 | * @param integer $navigationID Entity navigation identifier  | 
            ||
| 381 | * @param string $navigationName Original entity name  | 
            ||
| 382 | * @param string $entityName PHP entity name  | 
            ||
| 383 | * @param array $navigationFields Collection of entity additional fields  | 
            ||
| 384 | * @param string $parentClass Parent entity class name  | 
            ||
| 385 | * @return string Generated entity query PHP class code  | 
            ||
| 386 | */  | 
            ||
| 387 | View Code Duplication | protected function createCollectionClass($navigationID, $navigationName, $entityName, $navigationFields, $parentClass = '\samsoncms\api\renderable\Collection')  | 
            |
| 388 |     { | 
            ||
| 389 | $this->generator  | 
            ||
| 390 |             ->multiComment(array('Class for getting "'.$navigationName.'" instances from database',)) | 
            ||
| 391 | ->defClass($entityName, $parentClass)  | 
            ||
| 392 | ;  | 
            ||
| 393 | |||
| 394 | // Iterate additional fields  | 
            ||
| 395 | $localizedFieldIDs = array();  | 
            ||
| 396 | $notLocalizedFieldIDs = array();  | 
            ||
| 397 | $allFieldIDs = array();  | 
            ||
| 398 | $allFieldNames = array();  | 
            ||
| 399 | $allFieldValueColumns = array();  | 
            ||
| 400 | $realNames = array();  | 
            ||
| 401 |         foreach ($navigationFields as $fieldID => $fieldRow) { | 
            ||
| 402 | $fieldName = $this->fieldName($fieldRow['Name']);  | 
            ||
| 403 | |||
| 404 | // TODO: Add different method generation depending on their field type  | 
            ||
| 405 | $this->generator->text($this->generateFieldConditionMethod(  | 
            ||
| 406 | $fieldName,  | 
            ||
| 407 | $fieldRow[Field::F_PRIMARY],  | 
            ||
| 408 | $fieldRow[Field::F_TYPE]  | 
            ||
| 409 | ));  | 
            ||
| 410 | |||
| 411 | // Store field metadata  | 
            ||
| 412 | $realNames[$fieldRow['Name']] = $fieldName;  | 
            ||
| 413 | $allFieldIDs[$fieldID] = $fieldName;  | 
            ||
| 414 | $allFieldNames[$fieldName] = $fieldID;  | 
            ||
| 415 | $allFieldValueColumns[$fieldID] = Field::valueColumn($fieldRow[Field::F_TYPE]);  | 
            ||
| 416 |             if ($fieldRow[Field::F_LOCALIZED] == 1) { | 
            ||
| 417 | $localizedFieldIDs[$fieldID] = $fieldName;  | 
            ||
| 418 |             } else { | 
            ||
| 419 | $notLocalizedFieldIDs[$fieldID] = $fieldName;  | 
            ||
| 420 | }  | 
            ||
| 421 | }  | 
            ||
| 422 | |||
| 423 | // TODO: Add generator method generation logic  | 
            ||
| 424 | $class = "\n\t".'/**';  | 
            ||
| 425 | $class .= "\n\t".' * @param ViewInterface $renderer Rendering instance';  | 
            ||
| 426 | $class .= "\n\t".' * @param QueryInterface $query Querying instance';  | 
            ||
| 427 | $class .= "\n\t".' * @param string $locale Localization identifier';  | 
            ||
| 428 | $class .= "\n\t".' */';  | 
            ||
| 429 | $class .= "\n\t".'public function __construct(ViewInterface $renderer, QueryInterface $query = null, $locale = null)';  | 
            ||
| 430 |         $class .= "\n\t".'{'; | 
            ||
| 431 | $class .= "\n\t\t".'parent::__construct($renderer, $query === null ? new dbQuery() : $query, $locale);';  | 
            ||
| 432 | $class .= "\n\t".'}'."\n";  | 
            ||
| 433 | |||
| 434 | return $this->generator  | 
            ||
| 435 |             ->commentVar('array', 'Collection of real additional field names') | 
            ||
| 436 |             ->defClassVar('$fieldRealNames', 'public static', $realNames) | 
            ||
| 437 |             ->commentVar('array', 'Collection of navigation identifiers') | 
            ||
| 438 |             ->defClassVar('$navigationIDs', 'protected static', array($navigationID)) | 
            ||
| 439 |             ->commentVar('string', 'Not transliterated entity name') | 
            ||
| 440 |             ->defClassVar('$identifier', 'protected static', $this->fullEntityName($navigationName)) | 
            ||
| 441 |             ->commentVar('array', 'Collection of localized additional fields identifiers') | 
            ||
| 442 |             ->defClassVar('$localizedFieldIDs', 'protected static', $localizedFieldIDs) | 
            ||
| 443 |             ->commentVar('array', 'Collection of NOT localized additional fields identifiers') | 
            ||
| 444 |             ->defClassVar('$notLocalizedFieldIDs', 'protected static', $notLocalizedFieldIDs) | 
            ||
| 445 |             ->commentVar('array', 'Collection of localized additional fields identifiers') | 
            ||
| 446 |             ->defClassVar('$fieldIDs', 'protected static', $allFieldIDs) | 
            ||
| 447 |             ->commentVar('array', 'Collection of additional fields value column names') | 
            ||
| 448 |             ->defClassVar('$fieldValueColumns', 'protected static', $allFieldValueColumns) | 
            ||
| 449 |             ->commentVar('array', 'Collection of additional field names') | 
            ||
| 450 |             ->defClassVar('$fieldNames', 'public static', $allFieldNames) | 
            ||
| 451 | ->text($class)  | 
            ||
| 452 | ->endClass()  | 
            ||
| 453 | ->flush()  | 
            ||
| 454 | ;  | 
            ||
| 455 | }  | 
            ||
| 456 | |||
| 457 | /**  | 
            ||
| 458 | * Create entity query PHP class code.  | 
            ||
| 459 | *  | 
            ||
| 460 | * @param integer $navigationID Entity navigation identifier  | 
            ||
| 461 | * @param string $navigationName Original entity name  | 
            ||
| 462 | * @param string $entityName PHP entity name  | 
            ||
| 463 | * @param array $navigationFields Collection of entity additional fields  | 
            ||
| 464 | * @param string $parentClass Parent entity class name  | 
            ||
| 465 | * @return string Generated entity query PHP class code  | 
            ||
| 466 | */  | 
            ||
| 467 | View Code Duplication | protected function createQueryClass($navigationID, $navigationName, $entityName, $navigationFields, $parentClass = '\samsoncms\api\query\Entity')  | 
            |
| 468 |     { | 
            ||
| 469 | $this->generator  | 
            ||
| 470 |             ->multiComment(array('Class for getting "'.$navigationName.'" instances from database')) | 
            ||
| 471 | ->defClass($entityName, $parentClass)  | 
            ||
| 472 | ;  | 
            ||
| 473 | |||
| 474 | // Iterate additional fields  | 
            ||
| 475 | $localizedFieldIDs = array();  | 
            ||
| 476 | $notLocalizedFieldIDs = array();  | 
            ||
| 477 | $allFieldIDs = array();  | 
            ||
| 478 | $allFieldNames = array();  | 
            ||
| 479 | $allFieldValueColumns = array();  | 
            ||
| 480 | $realNames = array();  | 
            ||
| 481 |         foreach ($navigationFields as $fieldID => $fieldRow) { | 
            ||
| 482 | $fieldName = $this->fieldName($fieldRow['Name']);  | 
            ||
| 483 | |||
| 484 | // TODO: Add different method generation depending on their field type  | 
            ||
| 485 | $this->generator->text($this->generateFieldConditionMethod(  | 
            ||
| 486 | $fieldName,  | 
            ||
| 487 | $fieldRow[Field::F_PRIMARY],  | 
            ||
| 488 | $fieldRow[Field::F_TYPE]  | 
            ||
| 489 | ));  | 
            ||
| 490 | |||
| 491 | // Store field metadata  | 
            ||
| 492 | $realNames[$fieldRow['Name']] = $fieldName;  | 
            ||
| 493 | $allFieldIDs[$fieldID] = $fieldName;  | 
            ||
| 494 | $allFieldNames[$fieldName] = $fieldID;  | 
            ||
| 495 | $allFieldValueColumns[$fieldID] = Field::valueColumn($fieldRow[Field::F_TYPE]);  | 
            ||
| 496 |             if ($fieldRow[Field::F_LOCALIZED] == 1) { | 
            ||
| 497 | $localizedFieldIDs[$fieldID] = $fieldName;  | 
            ||
| 498 |             } else { | 
            ||
| 499 | $notLocalizedFieldIDs[$fieldID] = $fieldName;  | 
            ||
| 500 | }  | 
            ||
| 501 | }  | 
            ||
| 502 | |||
| 503 | // TODO: Add generator method generation logic  | 
            ||
| 504 | $class = "\n\t".'/**';  | 
            ||
| 505 | $class .= "\n\t".' * @param QueryInterface $query Rendering instance';  | 
            ||
| 506 | $class .= "\n\t".' * @param string $locale Localization identifier';  | 
            ||
| 507 | $class .= "\n\t".' */';  | 
            ||
| 508 | $class .= "\n\t".'public function __construct(QueryInterface $query = null, $locale = null)';  | 
            ||
| 509 |         $class .= "\n\t".'{'; | 
            ||
| 510 | $class .= "\n\t\t".'parent::__construct($query === null ? new dbQuery() : $query, $locale);';  | 
            ||
| 511 | $class .= "\n\t".'}'."\n";  | 
            ||
| 512 | |||
| 513 | return $this->generator  | 
            ||
| 514 |             ->commentVar('array', 'Collection of real additional field names') | 
            ||
| 515 |             ->defClassVar('$fieldRealNames', 'public static', $realNames) | 
            ||
| 516 |             ->commentVar('array', 'Collection of navigation identifiers') | 
            ||
| 517 |             ->defClassVar('$navigationIDs', 'protected static', array($navigationID)) | 
            ||
| 518 |             ->commentVar('string', 'Not transliterated entity name') | 
            ||
| 519 |             ->defClassVar('$identifier', 'protected static', $this->fullEntityName($navigationName)) | 
            ||
| 520 |             ->commentVar('array', 'Collection of localized additional fields identifiers') | 
            ||
| 521 |             ->defClassVar('$localizedFieldIDs', 'protected static', $localizedFieldIDs) | 
            ||
| 522 |             ->commentVar('array', 'Collection of NOT localized additional fields identifiers') | 
            ||
| 523 |             ->defClassVar('$notLocalizedFieldIDs', 'protected static', $notLocalizedFieldIDs) | 
            ||
| 524 |             ->commentVar('array', 'Collection of localized additional fields identifiers') | 
            ||
| 525 |             ->defClassVar('$fieldIDs', 'protected static', $allFieldIDs) | 
            ||
| 526 |             ->commentVar('array', 'Collection of additional fields value column names') | 
            ||
| 527 |             ->defClassVar('$fieldValueColumns', 'protected static', $allFieldValueColumns) | 
            ||
| 528 |             ->commentVar('array', 'Collection of additional field names') | 
            ||
| 529 |             ->defClassVar('$fieldNames', 'public static', $allFieldNames) | 
            ||
| 530 | ->text($class)  | 
            ||
| 531 | ->endClass()  | 
            ||
| 532 | ->flush()  | 
            ||
| 533 | ;  | 
            ||
| 534 | }  | 
            ||
| 535 | |||
| 536 | /** @return string Entity state hash */  | 
            ||
| 537 | public function entityHash()  | 
            ||
| 538 |     { | 
            ||
| 539 | // Получим информацию о всех таблицах из БД  | 
            ||
| 540 | return md5(serialize($this->database->fetch(  | 
            ||
| 541 | 'SELECT `TABLES`.`TABLE_NAME` as `TABLE_NAME`  | 
            ||
| 542 | FROM `information_schema`.`TABLES` as `TABLES`  | 
            ||
| 543 | WHERE `TABLES`.`TABLE_SCHEMA`="' . $this->database->database() . '";'  | 
            ||
| 544 | )));  | 
            ||
| 545 | }  | 
            ||
| 546 | |||
| 547 | /**  | 
            ||
| 548 | * Find entity parent.  | 
            ||
| 549 | *  | 
            ||
| 550 | * @param $entityID  | 
            ||
| 551 | *  | 
            ||
| 552 | * @return null|int Parent entity identifier  | 
            ||
| 553 | */  | 
            ||
| 554 | public function entityParent($entityID)  | 
            ||
| 555 |     { | 
            ||
| 556 |         $parentData = $this->database->fetch(' | 
            ||
| 557 | SELECT *  | 
            ||
| 558 | FROM structure_relation as sm  | 
            ||
| 559 | JOIN structure as s ON s.StructureID = sm.parent_id  | 
            ||
| 560 | WHERE sm.child_id = "' . $entityID . '"  | 
            ||
| 561 | AND s.StructureID != "' . $entityID . '"  | 
            ||
| 562 | ');  | 
            ||
| 563 | |||
| 564 | // Get parent entity identifier  | 
            ||
| 565 | return count($parentData) ? $parentData[0]['StructureID'] : null;  | 
            ||
| 566 | }  | 
            ||
| 567 | |||
| 568 | /** @return array Get collection of navigation objects */  | 
            ||
| 569 | protected function entityNavigations($type = 0)  | 
            ||
| 570 |     { | 
            ||
| 571 |         return $this->database->fetch(' | 
            ||
| 572 | SELECT * FROM `structure`  | 
            ||
| 573 | WHERE `Active` = "1" AND `Type` = "'.$type.'"  | 
            ||
| 574 | ORDER BY `ParentID` ASC  | 
            ||
| 575 | ');  | 
            ||
| 576 | }  | 
            ||
| 577 | |||
| 578 | /** @return array Collection of navigation additional fields */  | 
            ||
| 579 | protected function navigationFields($navigationID)  | 
            ||
| 591 | |||
| 592 | /**  | 
            ||
| 593 | * Generate entity classes.  | 
            ||
| 594 | *  | 
            ||
| 595 | * @param string $namespace Base namespace for generated classes  | 
            ||
| 596 | * @return string Generated PHP code for entity classes  | 
            ||
| 597 | */  | 
            ||
| 598 | public function createEntityClasses($namespace = __NAMESPACE__)  | 
            ||
| 599 |     { | 
            ||
| 600 | $classes = "\n" . 'namespace ' . $namespace . ';';  | 
            ||
| 601 | $classes .= "\n";  | 
            ||
| 602 | $classes .= "\n" . 'use '.$namespace.'\renderable\FieldsTable;';  | 
            ||
| 603 | $classes .= "\n" . 'use '.$namespace.'\field\Row;';  | 
            ||
| 604 | $classes .= "\n" . 'use \samsonframework\core\ViewInterface;';  | 
            ||
| 605 | $classes .= "\n" . 'use \samsonframework\orm\ArgumentInterface;';  | 
            ||
| 606 | $classes .= "\n" . 'use \samsonframework\orm\QueryInterface;';  | 
            ||
| 607 | $classes .= "\n" . 'use \samson\activerecord\dbQuery;';  | 
            ||
| 608 | $classes .= "\n";  | 
            ||
| 609 | |||
| 736 | |||
| 737 | /**  | 
            ||
| 738 | * Generator constructor.  | 
            ||
| 739 | * @param DatabaseInterface $database Database instance  | 
            ||
| 740 | */  | 
            ||
| 741 | public function __construct(DatabaseInterface $database)  | 
            ||
| 746 | }  | 
            ||
| 747 | |||
| 749 | 
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVarassignment in line 1 and the$higherassignment in line 2 are dead. The first because$myVaris never used and the second because$higheris always overwritten for every possible time line.