Completed
Push — master ( 664783...554f9d )
by
unknown
15:59
created

MongodbMigrateCommand::getConfiguration()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 0
cts 13
cp 0
rs 9.2
c 0
b 0
f 0
cc 2
eloc 12
nc 2
nop 2
crap 6
1
<?php
2
/**
3
 * graviton:mongodb:migrations:execute command
4
 */
5
6
namespace Graviton\MigrationBundle\Command;
7
8
use Symfony\Component\Console\Command\Command;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Symfony\Component\Console\Input\ArrayInput;
12
use Symfony\Component\DependencyInjection\ContainerInterface;
13
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
14
use Symfony\Component\Finder\Finder;
15
use Graviton\MigrationBundle\Command\Helper\DocumentManager as DocumentManagerHelper;
16
use AntiMattr\MongoDB\Migrations\OutputWriter;
17
18
/**
19
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
20
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
21
 * @link     http://swisscom.ch
22
 */
23
class MongodbMigrateCommand extends Command
24
{
25
    /**
26
     * @var ContainerInterface
27
     */
28
    private $container;
29
30
    /**
31
     * @var Finder
32
     */
33
    private $finder;
34
35
    /**
36
     * @var DocumentManagerHelper
37
     */
38
    private $documentManager;
39
40
    /**
41
     * @var string
42
     */
43
    private $databaseName;
44
45
    /**
46
     * @var array
47
     */
48
    private $errors = [];
49
50
    /**
51
     * @param ContainerInterface    $container       container instance for injecting into aware migrations
52
     * @param Finder                $finder          finder that finds configs
53
     * @param DocumentManagerHelper $documentManager dm helper to get access to db in command
54
     * @param string                $databaseName    name of database where data is found in
55
     */
56 4
    public function __construct(
57
        ContainerInterface $container,
58
        Finder $finder,
59
        DocumentManagerHelper $documentManager,
60
        $databaseName
61
    ) {
62 4
        $this->container = $container;
63 4
        $this->finder = $finder;
64 4
        $this->documentManager = $documentManager;
65 4
        $this->databaseName = $databaseName;
66
67 4
        parent::__construct();
68 4
    }
69
70
    /**
71
     * setup command
72
     *
73
     * @return void
74
     */
75 4
    protected function configure()
76
    {
77 4
        parent::configure();
78
79 4
        $this->setName('graviton:mongodb:migrate');
80 4
    }
81
82
    /**
83
     * call execute on found commands
84
     *
85
     * @param InputInterface  $input  user input
86
     * @param OutputInterface $output command output
87
     *
88
     * @return void
0 ignored issues
show
Documentation introduced by
Should the return type not be integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
89
     */
90
    public function execute(InputInterface $input, OutputInterface $output)
91
    {
92
        // graviton root
93
        $baseDir = __DIR__.'/../../../';
94
95
        // vendorized? - go back some more..
96
        if (strpos($baseDir, '/vendor/') !== false) {
97
            $baseDir .= '../../../';
98
        }
99
100
        $this->finder
101
            ->in($baseDir)
102
            ->path('Resources/config')
103
            ->name('/migrations.(xml|yml)/')
104
            ->files();
105
106
        foreach ($this->finder as $file) {
107
            if (!$file->isFile()) {
108
                continue;
109
            }
110
111
            $output->writeln('Found '.$file->getRelativePathname());
112
113
            $command = $this->getApplication()->find('mongodb:migrations:migrate');
114
115
            $helperSet = $command->getHelperSet();
116
            $helperSet->set($this->documentManager, 'dm');
117
            $command->setHelperSet($helperSet);
118
119
            $configuration = $this->getConfiguration($file->getPathname(), $output);
120
            self::injectContainerToMigrations($this->container, $configuration->getMigrations());
121
            $command->setMigrationConfiguration($configuration);
122
123
            $arguments = $input->getArguments();
124
            $arguments['command'] = 'mongodb:migrations:migrate';
125
            $arguments['--configuration'] = $file->getPathname();
126
127
            $migrateInput = new ArrayInput($arguments);
128
            $migrateInput->setInteractive($input->isInteractive());
129
            $returnCode = $command->run($migrateInput, $output);
130
131
            if ($returnCode !== 0) {
132
                $this->errors[] = sprintf(
133
                    'Calling mongodb:migrations:migrate failed for %s',
134
                    $file->getRelativePathname()
135
                );
136
            }
137
        }
138
139
        if (!empty($this->errors)) {
140
            $output->writeln(
141
                sprintf('<error>%s</error>', implode(PHP_EOL, $this->errors))
142
            );
143
            return -1;
144
        }
145
146
        return 0;
147
    }
148
149
    /**
150
     * get configration object for migration script
151
     *
152
     * This is based on antromattr/mongodb-migartion code but extends it so we can inject
153
     * non local stuff centrally.
154
     *
155
     * @param string $filepath path to configuration file
156
     * @param Output $output   ouput interface need by config parser to do stuff
157
     *
158
     * @return AntiMattr\MongoDB\Migrations\Configuration\Configuration
159
     */
160
    private function getConfiguration($filepath, $output)
161
    {
162
        $outputWriter = new OutputWriter(
163
            function ($message) use ($output) {
164
                return $output->writeln($message);
165
            }
166
        );
167
168
        $info = pathinfo($filepath);
169
        $namespace = 'AntiMattr\MongoDB\Migrations\Configuration';
170
        $class = $info['extension'] === 'xml' ? 'XmlConfiguration' : 'YamlConfiguration';
171
        $class = sprintf('%s\%s', $namespace, $class);
172
        $configuration = new $class($this->documentManager->getDocumentManager()->getConnection(), $outputWriter);
173
174
        // register databsae name before loading to ensure that loading does not fail
175
        $configuration->setMigrationsDatabaseName($this->databaseName);
176
177
        // load additional config from migrations.(yml|xml)
178
        $configuration->load($filepath);
179
180
        return $configuration;
181
    }
182
183
    /**
184
     * Injects the container to migrations aware of it
185
     *
186
     * @param ContainerInterface $container container to inject into container aware migrations
187
     * @param array              $versions  versions that might need injecting a container
188
     *
189
     * @return void
190
     */
191
    private static function injectContainerToMigrations(ContainerInterface $container, array $versions)
192
    {
193
        foreach ($versions as $version) {
194
            $migration = $version->getMigration();
195
            if ($migration instanceof ContainerAwareInterface) {
196
                $migration->setContainer($container);
197
            }
198
        }
199
    }
200
}
201