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 namespace Limoncello\Application\Data; |
||
32 | abstract class BaseMigrationRunner |
||
33 | { |
||
34 | /** Migrations table name */ |
||
35 | const MIGRATIONS_TABLE = '_migrations'; |
||
36 | |||
37 | /** Migration column name */ |
||
38 | const MIGRATIONS_COLUMN_ID = 'id'; |
||
39 | |||
40 | /** Migration column name */ |
||
41 | const MIGRATIONS_COLUMN_CLASS = 'class'; |
||
42 | |||
43 | /** Migration column name */ |
||
44 | const MIGRATIONS_COLUMN_MIGRATED_AT = 'migrated_at'; |
||
45 | |||
46 | /** Seeds table name */ |
||
47 | const SEEDS_TABLE = '_seeds'; |
||
48 | |||
49 | /** |
||
50 | * @var IoInterface |
||
51 | */ |
||
52 | private $inOut; |
||
53 | |||
54 | /** |
||
55 | * @return string[] |
||
56 | */ |
||
57 | abstract protected function getMigrationClasses(): array; |
||
58 | |||
59 | /** |
||
60 | * @param IoInterface $inOut |
||
61 | */ |
||
62 | 2 | public function __construct(IoInterface $inOut) |
|
66 | |||
67 | /** |
||
68 | * @param ContainerInterface $container |
||
69 | * |
||
70 | * @return void |
||
71 | */ |
||
72 | 1 | public function migrate(ContainerInterface $container): void |
|
73 | { |
||
74 | 1 | View Code Duplication | foreach ($this->getMigrations($container) as $class) { |
|
|||
75 | 1 | assert(is_string($class)); |
|
76 | 1 | $this->getIO()->writeInfo("Starting migration for `$class`..." . PHP_EOL, IoInterface::VERBOSITY_VERBOSE); |
|
77 | /** @var MigrationInterface $migration */ |
||
78 | 1 | $migration = new $class($container); |
|
79 | 1 | $migration->init($container)->migrate(); |
|
80 | 1 | $this->getIO()->writeInfo("Migration finished for `$class`." . PHP_EOL, IoInterface::VERBOSITY_NORMAL); |
|
81 | } |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * @param ContainerInterface $container |
||
86 | * |
||
87 | * @return void |
||
88 | */ |
||
89 | 1 | public function rollback(ContainerInterface $container): void |
|
90 | { |
||
91 | 1 | View Code Duplication | foreach ($this->getRollbacks($container) as $class) { |
92 | 1 | assert(is_string($class)); |
|
93 | 1 | $this->getIO()->writeInfo("Starting rollback for `$class`..." . PHP_EOL, IoInterface::VERBOSITY_VERBOSE); |
|
94 | /** @var MigrationInterface $migration */ |
||
95 | 1 | $migration = new $class($container); |
|
96 | 1 | $migration->init($container)->rollback(); |
|
97 | 1 | $this->getIO()->writeInfo("Rollback finished for `$class`." . PHP_EOL, IoInterface::VERBOSITY_NORMAL); |
|
98 | } |
||
99 | |||
100 | 1 | $manager = $this->getConnection($container)->getSchemaManager(); |
|
101 | 1 | if ($manager->tablesExist([static::MIGRATIONS_TABLE]) === true) { |
|
102 | 1 | $manager->dropTable(static::MIGRATIONS_TABLE); |
|
103 | } |
||
104 | 1 | if ($manager->tablesExist([static::SEEDS_TABLE]) === true) { |
|
105 | 1 | $manager->dropTable(static::SEEDS_TABLE); |
|
106 | } |
||
107 | } |
||
108 | |||
109 | /** |
||
110 | * @return IoInterface |
||
111 | */ |
||
112 | 1 | protected function getIO(): IoInterface |
|
116 | |||
117 | /** |
||
118 | * @param IoInterface $inOut |
||
119 | * |
||
120 | * @return self |
||
121 | */ |
||
122 | 2 | private function setIO(IoInterface $inOut): self |
|
128 | |||
129 | /** |
||
130 | * @param ContainerInterface $container |
||
131 | * |
||
132 | * @return Generator |
||
133 | * |
||
134 | * @SuppressWarnings(PHPMD.ElseExpression) |
||
135 | */ |
||
136 | 1 | View Code Duplication | private function getMigrations(ContainerInterface $container): Generator |
155 | |||
156 | /** |
||
157 | * @param ContainerInterface $container |
||
158 | * |
||
159 | * @return Generator |
||
160 | */ |
||
161 | 1 | private function getRollbacks(ContainerInterface $container): Generator |
|
171 | |||
172 | /** |
||
173 | * @param ContainerInterface $container |
||
174 | * |
||
175 | * @return Connection |
||
176 | */ |
||
177 | 1 | private function getConnection(ContainerInterface $container): Connection |
|
181 | |||
182 | /** |
||
183 | * @param AbstractSchemaManager $manager |
||
184 | * |
||
185 | * @return void |
||
186 | */ |
||
187 | 1 | View Code Duplication | private function createMigrationsTable(AbstractSchemaManager $manager): void |
206 | |||
207 | /** |
||
208 | * @param Connection $connection |
||
209 | * |
||
210 | * @return array |
||
211 | */ |
||
212 | 1 | private function readMigrated(Connection $connection): array |
|
233 | |||
234 | /** |
||
235 | * @param Connection $connection |
||
236 | * @param string $class |
||
237 | * |
||
238 | * @return void |
||
239 | */ |
||
240 | 1 | View Code Duplication | private function saveMigration(Connection $connection, string $class): void |
249 | |||
250 | /** |
||
251 | * @param Connection $connection |
||
252 | * @param int $index |
||
253 | * |
||
254 | * @return void |
||
255 | */ |
||
256 | 1 | private function removeMigration(Connection $connection, int $index): void |
|
260 | } |
||
261 |
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.