1 | <?php |
||||||
2 | |||||||
3 | use Kaliop\eZMigrationBundle\API\MigrationInterface; |
||||||
4 | use Symfony\Component\DependencyInjection\ContainerInterface; |
||||||
5 | use Kaliop\eZMigrationBundle\API\Value\Migration; |
||||||
6 | use Kaliop\eZMigrationBundle\API\Value\MigrationDefinition; |
||||||
7 | use \eZ\Publish\Core\Persistence\Database\SelectQuery; |
||||||
0 ignored issues
–
show
|
|||||||
8 | |||||||
9 | class MigrateV1ToV2 implements MigrationInterface |
||||||
10 | { |
||||||
11 | private $container; |
||||||
12 | private $dbHandler; |
||||||
13 | private $activeBundles; |
||||||
14 | private $legacyTableName; |
||||||
15 | private $legacyMigrationsDir; |
||||||
16 | |||||||
17 | // The API says we have to have a static method, but we like better non-static... :-P |
||||||
18 | public static function execute(ContainerInterface $container) |
||||||
19 | { |
||||||
20 | $migration = new self($container); |
||||||
21 | $migration->goForIt(); |
||||||
22 | } |
||||||
23 | |||||||
24 | private function __construct(ContainerInterface $container) |
||||||
25 | { |
||||||
26 | $this->container = $container; |
||||||
27 | } |
||||||
28 | |||||||
29 | private function goForIt() |
||||||
30 | { |
||||||
31 | $this->legacyTableName = $this->container->getParameter('kaliop_bundle_migration.table_name'); |
||||||
32 | $this->legacyMigrationsDir = $this->container->get('ez_migration_bundle.helper.config.resolver')->getParameter('kaliop_bundle_migration.version_directory'); |
||||||
33 | |||||||
34 | $migrationStorageService = $this->container->get('ez_migration_bundle.storage_handler'); |
||||||
35 | $this->dbHandler = $this->container->get('ezpublish.connection'); |
||||||
36 | |||||||
37 | $this->activeBundles = array(); |
||||||
38 | foreach ($this->container->get('kernel')->getBundles() as $bundle) |
||||||
39 | { |
||||||
40 | $this->activeBundles[$bundle->getName()] = $bundle->getPath(); |
||||||
41 | } |
||||||
42 | |||||||
43 | /** @var \Kaliop\eZMigrationBundle\Core\Helper\ConsoleIO $io */ |
||||||
44 | $io = $this->container->get('ez_migration_bundle.helper.console_io'); |
||||||
45 | // NB: in theory this could be null! |
||||||
46 | $output = $io->getOutput(); |
||||||
47 | |||||||
48 | if (!$this->tableExist($this->legacyTableName)) |
||||||
49 | { |
||||||
50 | $output->writeln("Nothing to update: v1 database table '{$this->legacyTableName}' not found"); |
||||||
51 | return; |
||||||
52 | } |
||||||
53 | |||||||
54 | $toMigrate = $this->loadLegacyMigrations(); |
||||||
55 | $output->writeln("<info>Found " . count($toMigrate) . ' migration versions in the v1 database table</info>'); |
||||||
56 | |||||||
57 | // we need to decide of a random time to stamp existing migrations. We use 'now - 1 minute'... |
||||||
58 | $executionDate = time() - 60; |
||||||
59 | foreach ($toMigrate as $legacyMigration) { |
||||||
60 | $name = $legacyMigration['version']; |
||||||
61 | |||||||
62 | $path = $this->getLegacyMigrationDefinition($legacyMigration['version'], $legacyMigration['bundle']); |
||||||
63 | if ($path != false) { |
||||||
64 | $name = basename($path); |
||||||
65 | $content = file_get_contents($path); |
||||||
66 | $md5 = md5($content); |
||||||
67 | } else { |
||||||
68 | $path = 'unknown'; |
||||||
69 | $content = ''; |
||||||
70 | $md5 = 'unknown'; |
||||||
71 | } |
||||||
72 | |||||||
73 | // take care: what if the migration already exists in the v2 table ??? |
||||||
74 | $existingMigration = $migrationStorageService->loadMigration($name); |
||||||
75 | if ($existingMigration != null) { |
||||||
76 | $output->writeln("<info>Info for migration version: {$legacyMigration['bundle']} {$legacyMigration['version']} was already migrated, skipping it</info>"); |
||||||
77 | continue; |
||||||
78 | } |
||||||
79 | |||||||
80 | $migrationDefinition = new MigrationDefinition( |
||||||
81 | $name, $path, $content, MigrationDefinition::STATUS_PARSED |
||||||
82 | ); |
||||||
83 | $migrationStorageService->startMigration($migrationDefinition); |
||||||
84 | $migration = new Migration( |
||||||
85 | $name, |
||||||
86 | $md5, |
||||||
87 | $path, |
||||||
88 | $executionDate, |
||||||
89 | Migration::STATUS_DONE |
||||||
90 | ); |
||||||
91 | $migrationStorageService->endMigration($migration); |
||||||
92 | |||||||
93 | // we leave legacy info in the legacy table, in case someone wants to roll back in the future... |
||||||
94 | //$this->deleteLegacyMigration($legacyMigration['version'], $legacyMigration['bundle']); |
||||||
95 | |||||||
96 | $output->writeln("Updated info for migration version: {$legacyMigration['bundle']} {$legacyMigration['version']}"); |
||||||
97 | } |
||||||
98 | |||||||
99 | $output->writeln("<info>All known legacy migration versions have been migrated to the v2 database table</info>"); |
||||||
100 | } |
||||||
101 | |||||||
102 | private function tableExist($tableName) |
||||||
103 | { |
||||||
104 | /** @var \Doctrine\DBAL\Schema\AbstractSchemaManager $sm */ |
||||||
105 | $sm = $this->dbHandler->getConnection()->getSchemaManager(); |
||||||
106 | foreach ($sm->listTables() as $table) { |
||||||
107 | if ($table->getName() == $tableName) { |
||||||
108 | return true; |
||||||
109 | } |
||||||
110 | } |
||||||
111 | |||||||
112 | return false; |
||||||
113 | } |
||||||
114 | |||||||
115 | private function loadLegacyMigrations() |
||||||
116 | { |
||||||
117 | /** @var \eZ\Publish\Core\Persistence\Database\SelectQuery $q */ |
||||||
118 | $q = $this->dbHandler->createSelectQuery(); |
||||||
119 | $q->select('version, bundle') |
||||||
0 ignored issues
–
show
The call to
eZ\Publish\Core\Persiste...e\SelectQuery::select() has too many arguments starting with 'version, bundle' .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
120 | ->from($this->legacyTableName) |
||||||
0 ignored issues
–
show
The call to
eZ\Publish\Core\Persiste...ase\SelectQuery::from() has too many arguments starting with $this->legacyTableName .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
121 | ->orderBy('version', SelectQuery::ASC); |
||||||
122 | $stmt = $q->prepare(); |
||||||
123 | $stmt->execute(); |
||||||
124 | $results = $stmt->fetchAll(); |
||||||
125 | |||||||
126 | return $results; |
||||||
127 | } |
||||||
128 | |||||||
129 | private function deleteLegacyMigration($version, $bundle) |
||||||
0 ignored issues
–
show
|
|||||||
130 | { |
||||||
131 | $this->dbHandler->getConnection()->delete($this->legacyTableName, array('version' => $version, 'bundle' => $bundle)); |
||||||
132 | } |
||||||
133 | |||||||
134 | /** |
||||||
135 | * Attempts to find the migration definition file. If more than one matches, the 1st found is returned |
||||||
136 | * @param string $version |
||||||
137 | * @param string $bundle |
||||||
138 | * @return string|false |
||||||
139 | */ |
||||||
140 | private function getLegacyMigrationDefinition($version, $bundle) |
||||||
141 | { |
||||||
142 | if (!isset($this->activeBundles[$bundle])) { |
||||||
143 | return false; |
||||||
144 | } |
||||||
145 | |||||||
146 | $versionsDir = $this->activeBundles[$bundle] . '/' . $this->legacyMigrationsDir; |
||||||
147 | $versionDefinitions = glob($versionsDir . "/$version*"); |
||||||
148 | |||||||
149 | if (!is_array($versionDefinitions)) { |
||||||
0 ignored issues
–
show
|
|||||||
150 | return false; |
||||||
151 | } |
||||||
152 | |||||||
153 | foreach ($versionDefinitions as $key => $versionDefinition) { |
||||||
154 | if (!in_array(pathinfo($versionDefinition, PATHINFO_EXTENSION), array('php', 'yml', 'sql'))) { |
||||||
155 | unset($versionDefinitions[$key]); |
||||||
156 | } |
||||||
157 | } |
||||||
158 | |||||||
159 | if (empty($versionDefinitions)) { |
||||||
160 | return false; |
||||||
161 | } |
||||||
162 | |||||||
163 | return $versionDefinitions[0]; |
||||||
164 | } |
||||||
165 | } |
||||||
166 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths