Passed
Pull Request — master (#148)
by Rustam
12:16
created

DownCommand   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 9
eloc 35
c 0
b 0
f 0
dl 0
loc 60
ccs 0
cts 32
cp 0
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
B execute() 0 47 8
A __construct() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Cycle\Command\Migration;
6
7
use Cycle\Migrations\MigrationInterface;
8
use Cycle\Migrations\State;
9
use Psr\EventDispatcher\EventDispatcherInterface;
10
use Symfony\Component\Console\Helper\QuestionHelper;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Symfony\Component\Console\Question\ConfirmationQuestion;
14
use Yiisoft\Yii\Console\ExitCode;
15
use Yiisoft\Yii\Cycle\Command\CycleDependencyProxy;
16
use Yiisoft\Yii\Cycle\Event\AfterMigrate;
17
use Yiisoft\Yii\Cycle\Event\BeforeMigrate;
18
19
final class DownCommand extends BaseMigrationCommand
20
{
21
    protected static $defaultName = 'migrate/down';
22
    protected static $defaultDescription = 'Rolls back the last applied migration';
23
24
    private EventDispatcherInterface $eventDispatcher;
25
26
    public function __construct(CycleDependencyProxy $promise, EventDispatcherInterface $eventDispatcher)
27
    {
28
        $this->eventDispatcher = $eventDispatcher;
29
        parent::__construct($promise);
30
    }
31
32
    protected function execute(InputInterface $input, OutputInterface $output): int
33
    {
34
        $migrations = $this->findMigrations($output);
35
        // check any executed migration
36
        foreach (array_reverse($migrations) as $migration) {
37
            if ($migration->getState()->getStatus() === State::STATUS_EXECUTED) {
38
                $exist = true;
0 ignored issues
show
Unused Code introduced by
The assignment to $exist is dead and can be removed.
Loading history...
39
                break;
40
            }
41
        }
42
        if (!isset($migration)) {
43
            $output->writeln('<fg=red>No migration found for rollback</>');
44
            return ExitCode::OK;
45
        }
46
47
        $migrator = $this->promise->getMigrator();
48
49
        // Confirm
50
        if (!$migrator->getConfig()->isSafe()) {
51
            $output->writeln('<fg=yellow>Migration to be reverted:</>');
52
            $output->writeln('— <fg=cyan>' . $migration->getState()->getName() . '</>');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $migration seems to be defined by a foreach iteration on line 36. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
53
            if ($input->isInteractive()) {
54
                /** @var QuestionHelper $qaHelper */
55
                $qaHelper = $this->getHelper('question');
56
                $question = new ConfirmationQuestion('Revert the above migration? (yes|no) ', false);
57
                if (!$qaHelper->ask($input, $output, $question)) {
58
                    return ExitCode::OK;
59
                }
60
            }
61
        }
62
63
        $this->eventDispatcher->dispatch(new BeforeMigrate());
64
        try {
65
            $migrator->rollback();
66
            if (!$migration instanceof MigrationInterface) {
67
                throw new \Exception('Migration not found');
68
            }
69
70
            $state = $migration->getState();
71
            $status = $state->getStatus();
72
            $output->writeln(
73
                sprintf('<fg=cyan>%s</>: %s', $state->getName(), self::MIGRATION_STATUS[$status] ?? $status)
74
            );
75
        } finally {
76
            $this->eventDispatcher->dispatch(new AfterMigrate());
77
        }
78
        return ExitCode::OK;
79
    }
80
}
81