Issues (225)

20220101000200_FixExecutedMigrationsPaths.php (3 issues)

Severity
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;
8
9
/**
10
 * Make paths of all executed migrations relative, if possible
11
 */
12
class FixExecutedMigrationsPaths implements MigrationInterface
13
{
14
    private $container;
15
    private $dbHandler;
16
    private $migrationsTableName;
17
18
    // The API says we have to have a static method, but we like better non-static... :-P
19
    public static function execute(ContainerInterface $container)
20
    {
21
        $migration = new self($container);
22
        $migration->goForIt();
23
    }
24
25
    private function __construct(ContainerInterface $container)
26
    {
27
        $this->container = $container;
28
    }
29
30
    private function goForIt()
31
    {
32
        $this->migrationsTableName = $this->container->getParameter('ez_migration_bundle.table_name');
33
34
        $this->dbHandler = $this->container->get('ezpublish.connection');
35
36
        /** @var \Kaliop\eZMigrationBundle\Core\Helper\ConsoleIO $io */
37
        $io = $this->container->get('ez_migration_bundle.helper.console_io');
38
        // NB: in theory this could be null!
39
        $output = $io->getOutput();
40
41
        if (!$this->tableExist($this->migrationsTableName))
42
        {
43
            $output->writeln("Nothing to update: database table '{$this->migrationsTableName}' not found");
44
            return;
45
        }
46
47
        $toMigrate = $this->loadAllMigrations();
48
        $output->writeln("<info>Found " . count($toMigrate) . ' migrations in the database table</info>');
49
50
        $rootDir = realpath($this->container->get('kernel')->getRootDir() . '/..') . '/';
51
52
        foreach ($toMigrate as $legacyMigration) {
53
            $name = $legacyMigration['migration'];
54
            $path = $legacyMigration['path'];
55
            // note: we handle the case of 'current dir', but path is expected to include a filename...
56
            if (strpos($path, './') === 0 && $path !== './') {
57
                $this->updateMigrationPath($name, substr($path, 2));
58
                $output->writeln("Updated path info for migration: {$name} ({$path})");
59
            } elseif (strpos($path, $rootDir) === 0) {
60
                if ($path === $rootDir) {
61
                    $this->updateMigrationPath($name, './');
62
                } else {
63
                    $this->updateMigrationPath($name, substr($path, strlen($rootDir)));
64
                }
65
                $output->writeln("Updated path info for migration: {$name} ({$path})");
66
            }
67
        }
68
69
        $output->writeln("<info>All known migrations have been modified to use a relative path</info>");
70
    }
71
72
    private function tableExist($tableName)
73
    {
74
        /** @var \Doctrine\DBAL\Schema\AbstractSchemaManager $sm */
75
        $sm = $this->dbHandler->getConnection()->getSchemaManager();
76
        foreach ($sm->listTables() as $table) {
77
            if ($table->getName() == $tableName) {
78
                return true;
79
            }
80
        }
81
82
        return false;
83
    }
84
85
    private function loadAllMigrations()
86
    {
87
        /** @var \eZ\Publish\Core\Persistence\Database\SelectQuery $q */
88
        $q = $this->dbHandler->createSelectQuery();
89
        $q->select('migration, path')
0 ignored issues
show
The call to eZ\Publish\Core\Persiste...e\SelectQuery::select() has too many arguments starting with 'migration, path'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

89
        $q->/** @scrutinizer ignore-call */ 
90
            select('migration, path')

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.

Loading history...
90
            ->from($this->migrationsTableName)
0 ignored issues
show
The call to eZ\Publish\Core\Persiste...ase\SelectQuery::from() has too many arguments starting with $this->migrationsTableName. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

90
            ->/** @scrutinizer ignore-call */ from($this->migrationsTableName)

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.

Loading history...
91
            ->orderBy('migration', SelectQuery::ASC);
92
        $stmt = $q->prepare();
93
        $stmt->execute();
94
        $results = $stmt->fetchAll();
95
96
        return $results;
97
    }
98
99
    private function updateMigrationPath($migrationName, $path)
100
    {
101
        /** @var \eZ\Publish\Core\Persistence\Database\UpdateQuery $q */
102
        $q = $this->dbHandler->createUpdateQuery();
103
        $q
104
            ->update($this->migrationsTableName)
105
            ->set(
106
                'path',
107
                $q->bindValue($path)
108
            )
109
            ->where(
110
                $q->expr->eq(
0 ignored issues
show
The call to eZ\Publish\Core\Persiste...se\UpdateQuery::where() has too many arguments starting with $q->expr->eq('migration'...dValue($migrationName)). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
            ->/** @scrutinizer ignore-call */ where(

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.

Loading history...
111
                    'migration',
112
                    $q->bindValue($migrationName)
113
                )
114
            );
115
        $q->prepare()->execute();
116
    }
117
}
118