Completed
Push — 1.1-phpstan-level-2 ( 261c61 )
by Kamil
195:32 queued 171:07
created

DatabaseSetupCommandsProvider::getEntityManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sylius\Bundle\CoreBundle\Installer\Provider;
15
16
use Doctrine\Bundle\DoctrineBundle\Registry;
17
use Doctrine\DBAL\Schema\AbstractSchemaManager;
18
use Doctrine\ORM\EntityManagerInterface;
19
use Symfony\Component\Console\Helper\QuestionHelper;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Output\OutputInterface;
22
use Symfony\Component\Console\Question\ConfirmationQuestion;
23
use Symfony\Component\Console\Style\SymfonyStyle;
24
25
final class DatabaseSetupCommandsProvider implements DatabaseSetupCommandsProviderInterface
26
{
27
    /**
28
     * @var Registry
29
     */
30
    private $doctrineRegistry;
31
32
    /**
33
     * @param Registry $doctrineRegistry
34
     */
35
    public function __construct(Registry $doctrineRegistry)
36
    {
37
        $this->doctrineRegistry = $doctrineRegistry;
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function getCommands(InputInterface $input, OutputInterface $output, QuestionHelper $questionHelper): array
44
    {
45
        if (!$this->isDatabasePresent()) {
46
            return [
47
                'doctrine:database:create',
48
                'doctrine:migrations:migrate' => ['--no-interaction' => true],
49
            ];
50
        }
51
52
        return array_merge($this->getRequiredCommands($input, $output, $questionHelper), [
53
            'doctrine:migrations:version' => [
54
                '--add' => true,
55
                '--all' => true,
56
                '--no-interaction' => true,
57
            ],
58
        ]);
59
    }
60
61
    /**
62
     * @return bool
63
     *
64
     * @throws \Exception
65
     */
66
    private function isDatabasePresent(): bool
67
    {
68
        $databaseName = $this->getDatabaseName();
69
70
        try {
71
            $schemaManager = $this->getSchemaManager();
72
73
            return in_array($databaseName, $schemaManager->listDatabases());
74
        } catch (\Exception $exception) {
75
            $message = $exception->getMessage();
76
77
            $mysqlDatabaseError = false !== strpos($message, sprintf("Unknown database '%s'", $databaseName));
78
            $postgresDatabaseError = false !== strpos($message, sprintf('database "%s" does not exist', $databaseName));
79
80
            if ($mysqlDatabaseError || $postgresDatabaseError) {
81
                return false;
82
            }
83
84
            throw $exception;
85
        }
86
    }
87
88
    /**
89
     * @param InputInterface $input
90
     * @param OutputInterface $output
91
     * @param QuestionHelper $questionHelper
92
     *
93
     * @return array
94
     */
95
    private function getRequiredCommands(InputInterface $input, OutputInterface $output, QuestionHelper $questionHelper): array
96
    {
97
        if ($input->getOption('no-interaction')) {
98
            $commands['doctrine:migrations:migrate'] = ['--no-interaction' => true];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$commands was never initialized. Although not strictly required by PHP, it is generally a good practice to add $commands = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
99
        }
100
101
        return $this->setupDatabase($input, $output, $questionHelper);
102
    }
103
104
    /**
105
     * @param InputInterface $input
106
     * @param OutputInterface $output
107
     * @param QuestionHelper $questionHelper
108
     *
109
     * @return array
110
     */
111
    private function setupDatabase(InputInterface $input, OutputInterface $output, QuestionHelper $questionHelper): array
112
    {
113
        $outputStyle = new SymfonyStyle($input, $output);
114
        $outputStyle->writeln('It appears that your database already exists.');
115
        $outputStyle->writeln('<error>Warning! This action will erase your database.</error>');
116
117
        $question = new ConfirmationQuestion('Would you like to reset it? (y/N) ', false);
118
        if ($questionHelper->ask($input, $output, $question)) {
119
            return [
120
                'doctrine:database:drop' => ['--force' => true],
121
                'doctrine:database:create',
122
                'doctrine:migrations:migrate' => ['--no-interaction' => true],
123
            ];
124
        }
125
126
        if (!$this->isSchemaPresent()) {
127
            return ['doctrine:migrations:migrate' => ['--no-interaction' => true]];
128
        }
129
130
        $outputStyle->writeln('Seems like your database contains schema.');
131
        $outputStyle->writeln('<error>Warning! This action will erase your database.</error>');
132
        $question = new ConfirmationQuestion('Do you want to reset it? (y/N) ', false);
133
        if ($questionHelper->ask($input, $output, $question)) {
134
            return [
135
                'doctrine:schema:drop' => ['--force' => true],
136
                'doctrine:migrations:migrate' => ['--no-interaction' => true],
137
            ];
138
        }
139
140
        return [];
141
    }
142
143
    /**
144
     * @return bool
145
     */
146
    private function isSchemaPresent(): bool
147
    {
148
        return 0 !== count($this->getSchemaManager()->listTableNames());
149
    }
150
151
    /**
152
     * @return string
153
     */
154
    private function getDatabaseName(): string
155
    {
156
        return $this->getEntityManager()->getConnection()->getDatabase();
157
    }
158
159
    /**
160
     * @return AbstractSchemaManager
161
     */
162
    private function getSchemaManager(): AbstractSchemaManager
163
    {
164
        return $this->getEntityManager()->getConnection()->getSchemaManager();
165
    }
166
167
    private function getEntityManager(): EntityManagerInterface
168
    {
169
        return $this->doctrineRegistry->getManager();
170
    }
171
}
172