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 |
||
39 | class ORM extends Component implements SingletonInterface |
||
40 | { |
||
41 | use LoggerTrait; |
||
42 | |||
43 | /** |
||
44 | * Declares to IoC that component instance should be treated as singleton. |
||
45 | */ |
||
46 | const SINGLETON = self::class; |
||
47 | |||
48 | /** |
||
49 | * Memory section to store ORM schema. |
||
50 | */ |
||
51 | const MEMORY = 'orm.schema'; |
||
52 | |||
53 | /** |
||
54 | * Normalized record constants. |
||
55 | */ |
||
56 | const M_ROLE_NAME = 0; |
||
57 | const M_SOURCE = 1; |
||
58 | const M_TABLE = 2; |
||
59 | const M_DB = 3; |
||
60 | const M_HIDDEN = SchematicEntity::SH_HIDDEN; |
||
61 | const M_SECURED = SchematicEntity::SH_SECURED; |
||
62 | const M_FILLABLE = SchematicEntity::SH_FILLABLE; |
||
63 | const M_MUTATORS = SchematicEntity::SH_MUTATORS; |
||
64 | const M_VALIDATES = SchematicEntity::SH_VALIDATES; |
||
65 | const M_COLUMNS = 9; |
||
66 | const M_NULLABLE = 10; |
||
67 | const M_RELATIONS = 11; |
||
68 | const M_PRIMARY_KEY = 12; |
||
69 | |||
70 | /** |
||
71 | * Normalized relation options. |
||
72 | */ |
||
73 | const R_TYPE = 0; |
||
74 | const R_TABLE = 1; |
||
75 | const R_DEFINITION = 2; |
||
76 | const R_DATABASE = 3; |
||
77 | |||
78 | /** |
||
79 | * Pivot table data location in Record fields. Pivot data only provided when record is loaded |
||
80 | * using many-to-many relation. |
||
81 | */ |
||
82 | const PIVOT_DATA = '@pivot'; |
||
83 | |||
84 | /** |
||
85 | * @var EntityCache |
||
86 | */ |
||
87 | private $cache = null; |
||
88 | |||
89 | /** |
||
90 | * @var ORMConfig |
||
91 | */ |
||
92 | protected $config = null; |
||
93 | |||
94 | /** |
||
95 | * Cached records schema. |
||
96 | * |
||
97 | * @var array|null |
||
98 | */ |
||
99 | protected $schema = null; |
||
100 | |||
101 | /** |
||
102 | * @invisible |
||
103 | * @var DatabaseManager |
||
104 | */ |
||
105 | protected $databases = null; |
||
106 | |||
107 | /** |
||
108 | * @invisible |
||
109 | * @var FactoryInterface |
||
110 | */ |
||
111 | protected $factory = null; |
||
112 | |||
113 | /** |
||
114 | * @invisible |
||
115 | * @var HippocampusInterface |
||
116 | */ |
||
117 | protected $memory = null; |
||
118 | |||
119 | /** |
||
120 | * @param ORMConfig $config |
||
121 | * @param EntityCache $cache |
||
122 | * @param HippocampusInterface $memory |
||
123 | * @param DatabaseManager $databases |
||
124 | * @param FactoryInterface $factory |
||
125 | */ |
||
126 | public function __construct( |
||
143 | |||
144 | /** |
||
145 | * @param EntityCache $cache |
||
146 | * @return $this |
||
147 | */ |
||
148 | public function setCache(EntityCache $cache) |
||
154 | |||
155 | /** |
||
156 | * @return EntityCache |
||
157 | */ |
||
158 | public function cache() |
||
162 | |||
163 | /** |
||
164 | * When ORM is cloned we are automatically flushing it's cache and creating new isolated area. |
||
165 | * Basically we have cache enabled per selection. |
||
166 | * |
||
167 | * @see RecordSelector::getIterator() |
||
168 | */ |
||
169 | public function __clone() |
||
177 | |||
178 | /** |
||
179 | * Get database by it's name from DatabaseManager associated with ORM component. |
||
180 | * |
||
181 | * @param string $database |
||
182 | * @return Database |
||
183 | */ |
||
184 | public function database($database) |
||
188 | |||
189 | /** |
||
190 | * Construct instance of Record or receive it from cache (if enabled). Only records with |
||
191 | * declared primary key can be cached. |
||
192 | * |
||
193 | * @param string $class Record class name. |
||
194 | * @param array $data |
||
195 | * @param bool $cache Add record to entity cache if enabled. |
||
196 | * @return RecordInterface |
||
197 | */ |
||
198 | public function record($class, array $data = [], $cache = true) |
||
228 | |||
229 | /** |
||
230 | * Get ORM source for given class. |
||
231 | * |
||
232 | * @param string $class |
||
233 | * @return RecordSource |
||
234 | * @throws ORMException |
||
235 | */ |
||
236 | View Code Duplication | public function source($class) |
|
246 | |||
247 | /** |
||
248 | * Get ORM selector for given class. |
||
249 | * |
||
250 | * @param string $class |
||
251 | * @param Loader $loader |
||
252 | * @return RecordSelector |
||
253 | */ |
||
254 | public function selector($class, Loader $loader = null) |
||
258 | |||
259 | /** |
||
260 | * Get cached schema for specified record by it's name. |
||
261 | * |
||
262 | * @param string $record |
||
263 | * @return array |
||
264 | * @throws ORMException |
||
265 | */ |
||
266 | View Code Duplication | public function schema($record) |
|
278 | |||
279 | /** |
||
280 | * Create record relation instance by given relation type, parent and definition (options). |
||
281 | * |
||
282 | * @param int $type |
||
283 | * @param RecordInterface $parent |
||
284 | * @param array $definition Relation definition. |
||
285 | * @param array $data |
||
286 | * @param bool $loaded |
||
287 | * @return RelationInterface |
||
288 | * @throws ORMException |
||
289 | */ |
||
290 | View Code Duplication | public function relation( |
|
306 | |||
307 | /** |
||
308 | * Get instance of relation/selection loader based on relation type and definition. |
||
309 | * |
||
310 | * @param int $type Relation type. |
||
311 | * @param string $container Container related to parent loader. |
||
312 | * @param array $definition Relation definition. |
||
313 | * @param Loader $parent Parent loader (if presented). |
||
314 | * @return LoaderInterface |
||
315 | * @throws ORMException |
||
316 | */ |
||
317 | View Code Duplication | public function loader($type, $container, array $definition, Loader $parent = null) |
|
328 | |||
329 | /** |
||
330 | * Update ORM records schema, synchronize declared and database schemas and return instance of |
||
331 | * SchemaBuilder. |
||
332 | * |
||
333 | * @param SchemaBuilder $builder User specified schema builder. |
||
334 | * @param bool $syncronize Create all required tables and columns |
||
335 | * @return SchemaBuilder |
||
336 | */ |
||
337 | View Code Duplication | public function updateSchema(SchemaBuilder $builder = null, $syncronize = false) |
|
359 | |||
360 | /** |
||
361 | * Get instance of ORM SchemaBuilder. |
||
362 | * |
||
363 | * @param ClassLocatorInterface $locator |
||
364 | * @return SchemaBuilder |
||
365 | */ |
||
366 | public function schemaBuilder(ClassLocatorInterface $locator = null) |
||
374 | |||
375 | /** |
||
376 | * Create instance of relation schema based on relation type and given definition (declared in |
||
377 | * record). Resolve using container to support any possible relation type. You can create your |
||
378 | * own relations, loaders and schemas by altering ORM config. |
||
379 | * |
||
380 | * @param mixed $type |
||
381 | * @param SchemaBuilder $builder |
||
382 | * @param RecordSchema $record |
||
383 | * @param string $name |
||
384 | * @param array $definition |
||
385 | * @return Schemas\RelationInterface |
||
386 | */ |
||
387 | public function relationSchema( |
||
404 | } |
||
405 |
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.