Completed
Push — master ( 21cb38...ba1ce0 )
by José
10:54 queued 09:12
created

Init::resolvePath()   C

Complexity

Conditions 7
Paths 13

Size

Total Lines 43
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 9.2312

Importance

Changes 0
Metric Value
dl 0
loc 43
ccs 9
cts 14
cp 0.6429
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 21
nc 13
nop 1
crap 9.2312
1
<?php
2
/**
3
 * Phinx
4
 *
5
 * (The MIT license)
6
 * Copyright (c) 2015 Rob Morgan
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated * documentation files (the "Software"), to
10
 * deal in the Software without restriction, including without limitation the
11
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12
 * sell copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24
 * IN THE SOFTWARE.
25
 *
26
 * @package    Phinx
27
 * @subpackage Phinx\Console
28
 */
29
namespace Phinx\Console\Command;
30
31
use InvalidArgumentException;
32
use RuntimeException;
33
use Symfony\Component\Console\Command\Command;
34
use Symfony\Component\Console\Input\InputArgument;
35
use Symfony\Component\Console\Input\InputInterface;
36
use Symfony\Component\Console\Output\OutputInterface;
37
38
class Init extends Command
39
{
40
    const FILE_NAME = 'phinx';
41 35
42
    /**
43 35
     * {@inheritdoc}
44 35
     */
45 35
    protected function configure()
46 35
    {
47 35
        $this->setName($this->getName() ?: 'init')
48 35
            ->setDescription('Initialize the application for Phinx')
49
            ->addOption('--format', '-f', InputArgument::OPTIONAL, 'What format should we use to initialize?', 'yml')
50 35
            ->addArgument('path', InputArgument::OPTIONAL, 'Which path should we initialize for Phinx?')
51 35
            ->setHelp(sprintf(
52
                '%sInitializes the application for Phinx%s',
53
                PHP_EOL,
54
                PHP_EOL
55
            ));
56
    }
57
58
    /**
59
     * Initializes the application.
60
     *
61
     * @param \Symfony\Component\Console\Input\InputInterface   $input  Interface implemented by all input classes.
62 2
     * @param \Symfony\Component\Console\Output\OutputInterface $output Interface implemented by all output classes.
63
     *
64
     * @throws \RuntimeException
65 2
     * @throws \InvalidArgumentException
66
     * @return void
67 2
     */
68
    protected function execute(InputInterface $input, OutputInterface $output)
69
    {
70
        $path = $this->resolvePath($input);
71 2
        $format = strtolower($input->getOption('format'));
72
        $this->writeConfig($path, $format);
73 2
74
        $output->writeln("<info>created</info> {$path}");
75
    }
76
77
    /**
78
     * Return valid $path for Phinx's config file.
79
     *
80
     * @param \Symfony\Component\Console\Input\InputInterface $input Interface implemented by all input classes.
81 2
     *
82 2
     * @return string
83
     */
84 2
    protected function resolvePath(InputInterface $input)
85 1
    {
86 1
        // get the migration path from the config
87
        $path = $input->getArgument('path');
88 1
89
        $format = strtolower($input->getOption('format'));
90
        if (!in_array($format, ['yml', 'json', 'php'])) {
91
            throw new InvalidArgumentException(sprintf(
92 1
                'Invalid format "%s". Format must be either yml, json, or php.',
93
                $format
94
            ));
95 1
        }
96
97
        // Fallback
98 1
        if (!$path) {
99
            $path = getcwd() . DIRECTORY_SEPARATOR . self::FILE_NAME . '.' . $format;
100
        }
101
102
        // Adding file name if necessary
103
        if (is_dir($path)) {
104
            $path .= DIRECTORY_SEPARATOR . self::FILE_NAME . '.' . $format;
105 1
        }
106 1
107
        // Check if path is available
108
        $dirname = dirname($path);
109
        if (is_dir($dirname) && !is_file($path)) {
110
            return $path;
111
        }
112
113
        // Path is valid, but file already exists
114
        if (is_file($path)) {
115
            throw new InvalidArgumentException(sprintf(
116
                'Config file "%s" already exists.',
117
                $path
118
            ));
119
        }
120
121
        // Dir is invalid
122
        throw new InvalidArgumentException(sprintf(
123
            'Invalid path "%s" for config file.',
124
            $path
125
        ));
126
    }
127
128
    /**
129
     * Writes Phinx's config in provided $path
130
     *
131
     * @param string $path   Config file's path.
132
     * @param string $format Format to use for config file
133
     *
134
     * @throws \InvalidArgumentException
135
     * @throws \RuntimeException
136
     * @return void
137
     */
138
    protected function writeConfig($path, $format = 'yml')
139
    {
140
        // Check if dir is writable
141
        $dirname = dirname($path);
142
        if (!is_writable($dirname)) {
143
            throw new InvalidArgumentException(sprintf(
144
                'The directory "%s" is not writable',
145
                $dirname
146
            ));
147
        }
148
149
        // load the config template
150
        if (is_dir(__DIR__ . '/../../../data/Phinx')) {
151
            $contents = file_get_contents(__DIR__ . '/../../../data/Phinx/' . self::FILE_NAME . '.' . $format . '.dist');
152
        } elseif ($format === 'yml') {
153
            $contents = file_get_contents(__DIR__ . '/../../../../' . self::FILE_NAME . '.' . $format);
154
        } else {
155
            throw new RuntimeException(sprintf(
156
                'Could not find template for format "%s".',
157
                $format
158
            ));
159
        }
160
161
        if (file_put_contents($path, $contents) === false) {
162
            throw new RuntimeException(sprintf(
163
                'The file "%s" could not be written to',
164
                $path
165
            ));
166
        }
167
    }
168
}
169