GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( b445d1...3a4be1 )
by Robert
02:18
created

MigrationsCommand::execute()   F

Complexity

Conditions 24
Paths 11441

Size

Total Lines 145
Code Lines 88

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 93
CRAP Score 24.1975

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 145
ccs 93
cts 100
cp 0.93
rs 2
cc 24
eloc 88
nc 11441
nop 2
crap 24.1975

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Gruberro\MongoDbMigrations\Console\Command;
4
5
use Gruberro\MongoDbMigrations;
6
use Symfony\Component\Console;
7
8
class MigrationsCommand extends Console\Command\Command
9
{
10
    /**
11
     * {@inheritdoc}
12
     */
13 6
    protected function configure()
14
    {
15 6
        $this
16 6
            ->setName('php-mongodb-migrations:migrate')
17 6
            ->setDescription('Execute all open migrations')
18 6
            ->addOption(
19 6
                'server',
20 6
                's',
21 6
                Console\Input\InputOption::VALUE_REQUIRED,
22 6
                'The connection string (e.g. mongodb://[username:password@]host1[:port1][,host2[:port2:],...]/db)',
23
                'mongodb://localhost:27017'
24 6
            )
25 6
            ->addOption(
26 6
                'contexts',
27 6
                'c',
28 6
                Console\Input\InputOption::VALUE_IS_ARRAY | Console\Input\InputOption::VALUE_REQUIRED,
29 6
                'A list of contexts evaluated with each migration of type ContextualMigrationInterface',
30 6
                []
31 6
            )
32 6
            ->addArgument(
33 6
                'database',
34 6
                Console\Input\InputArgument::REQUIRED,
35
                'The database to connect to'
36 6
            )
37 6
            ->addArgument(
38 6
                'migration-directories',
39 6
                Console\Input\InputArgument::IS_ARRAY,
40 6
                'List of directories containing migration classes',
41 6
                []
42 6
            )
43
        ;
44 6
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49 7
    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
50
    {
51 7
        $client = new \MongoClient($input->getOption('server'));
52 7
        $db = $client->selectDB($input->getArgument('database'));
53 7
        $output->writeln("<info>✓ Successfully established database connection</info>", $output::VERBOSITY_VERBOSE);
54
55 7
        $directories = $input->getArgument('migration-directories');
56 7
        foreach ($directories as $directory) {
57 7
            if (! is_dir($directory)) {
58 1
                throw new Console\Exception\InvalidArgumentException("'{$directory}' is no valid directory");
59
            }
60
61 7
            $output->writeln("<comment>Iterating '{$directory}' for potential migrations classes</comment>", $output::VERBOSITY_DEBUG);
62 7
            $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory), \RecursiveIteratorIterator::LEAVES_ONLY);
63
64
            /** @var \SplFileInfo $file */
65 7
            foreach ($iterator as $file) {
66 7
                if ($file->getBasename('.php') === $file->getBasename()) {
67 7
                    continue;
68
                }
69
70 7
                require_once $file->getRealPath();
71
72 7
                $output->writeln("<comment>Loaded potential migration '{$file->getRealPath()}'</comment>", $output::VERBOSITY_DEBUG);
73 7
            }
74 7
        }
75
76
        /** @var MongoDbMigrations\MigrationInterface[] $migrations */
77 6
        $migrations = [];
78 6
        foreach (get_declared_classes() as $className) {
79 6
            $reflectionClass = new \ReflectionClass($className);
80
81 6
            if ($reflectionClass->implementsInterface(MongoDbMigrations\MigrationInterface::class)) {
82
                /** @var MongoDbMigrations\MigrationInterface $newInstance */
83 6
                $newInstance = $reflectionClass->newInstance();
84 6
                $id = md5($newInstance->getId());
85
86 6
                if (isset($migrations[$id])) {
87 1
                    $existingMigrationClass = get_class($migrations[$id]);
88 1
                    throw new Console\Exception\RuntimeException("Found a non unique migration id '{$newInstance->getId()}' in '{$reflectionClass->getName()}', already defined by migration class '{$existingMigrationClass}'");
1 ignored issue
show
Bug introduced by
Consider using $reflectionClass->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
89
                }
90
91 6
                $migrations[$id] = $newInstance;
92
93 6
                $output->writeln("<comment>Found valid migration class '{$reflectionClass->getName()}'</comment>", $output::VERBOSITY_DEBUG);
1 ignored issue
show
Bug introduced by
Consider using $reflectionClass->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
94 6
            }
95 6
        }
96
97 5
        $migrationClassesCount = count($migrations);
98 5
        $output->writeln("<info>✓ Found {$migrationClassesCount} valid migration classes</info>", $output::VERBOSITY_VERBOSE);
99
100 5
        uasort($migrations, function (MongoDbMigrations\MigrationInterface $a, MongoDbMigrations\MigrationInterface $b) {
101 5
            if ($a->getCreateDate() === $b->getCreateDate()) {
102
                return 0;
103
            }
104
105 5
            return $a->getCreateDate() < $b->getCreateDate() ? -1 : 1;
106 5
        });
107
108 5
        $output->writeln("<info>✓ Reordered all migration classes according to their create date</info>", $output::VERBOSITY_VERBOSE);
109
110 5
        $databaseMigrationsLockCollection = $db->selectCollection('DATABASE_MIGRATIONS_LOCK');
111
112 5
        $currentLock = $databaseMigrationsLockCollection->findAndModify(['locked' => ['$exists' => true]], ['locked' => true, 'last_locked_date' => new \MongoDate()], [], ['upsert' => true]);
113 5
        if ($currentLock !== null && $currentLock['locked'] === true) {
114 1
            throw new Console\Exception\RuntimeException('Concurrent migrations are not allowed');
115
        }
116
117
        try {
118 4
            $output->writeln("<info>✓ Successfully acquired migration lock</info>", $output::VERBOSITY_VERBOSE);
119
120 4
            $databaseMigrationsCollection = $db->selectCollection('DATABASE_MIGRATIONS');
121
122 4
            if (count($databaseMigrationsCollection->getIndexInfo()) <= 1) {
123 3
                $databaseMigrationsCollection->createIndex(['migration_id' => 1],
124 3
                    ['unique' => true, 'background' => false]);
125 3
            }
126
127 4
            $progress = new Console\Helper\ProgressBar($output, count($migrations));
128
129 4
            switch ($output->getVerbosity()) {
130 4
                case $output::VERBOSITY_VERBOSE:
131
                    $format = 'verbose';
132
                    break;
133 4
                case $output::VERBOSITY_VERY_VERBOSE:
134
                    $format = 'very_verbose';
135
                    break;
136 4
                case $output::VERBOSITY_DEBUG:
137
                    $format = 'debug';
138
                    break;
139 4
                default:
140 4
                    $format = 'normal';
141 4
            }
142
143 4
            $progress->setFormat($format);
144 4
            $progress->start();
145 4
            $executedMigrations = 0;
146
147 4
            foreach ($migrations as $id => $migration) {
148 4
                $progress->advance();
149
150 4
                if ($migration instanceof MongoDbMigrations\ContextualMigrationInterface && $input->getOption('contexts') !== []) {
151 3
                    if (array_intersect($migration->getContexts(), $input->getOption('contexts')) === []) {
152 1
                        continue;
153
                    }
154 2
                }
155
156 4
                if (!$migration instanceof MongoDbMigrations\RunAlwaysMigrationInterface) {
157 4
                    if ($databaseMigrationsCollection->count(['migration_id' => $id]) > 0) {
158 1
                        continue;
159
                    }
160 3
                }
161
162 4
                $migration->execute($db);
163 4
                $executedMigrations++;
164
165
                $migrationInfo = [
166 4
                    'migration_id' => $id,
167 4
                    'migration_class' => get_class($migration),
168 4
                    'last_execution_date' => new \MongoDate(),
169 4
                    'run_always' => $migration instanceof MongoDbMigrations\RunAlwaysMigrationInterface,
170 4
                ];
171
172 4
                if ($migration instanceof MongoDbMigrations\ContextualMigrationInterface) {
173 2
                    $migrationInfo['contexts'] = $migration->getContexts();
174 2
                }
175
176 4
                $databaseMigrationsCollection->update(
177 4
                    ['migration_id' => $id],
178 4
                    $migrationInfo,
179 4
                    ['upsert' => true]
180 4
                );
181 4
            }
182
183 3
            $progress->finish();
184 3
            $output->writeln('');
185
186 3
            $output->writeln("<info>✓ Successfully executed {$executedMigrations} migrations</info>");
187 4
        } catch (\Exception $e) {
188 1
            throw new Console\Exception\RuntimeException('Error while executing migrations', $e->getCode(), $e);
189 3
        } finally {
190 4
            $databaseMigrationsLockCollection->update(['locked' => true], ['$set' => ['locked' => false]]);
191 4
            $output->writeln("<info>✓ Successfully released migration lock</info>", $output::VERBOSITY_VERBOSE);
192
        }
193 3
    }
194
}
195