CreateHandler   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 143
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 6

Importance

Changes 3
Bugs 1 Features 0
Metric Value
wmc 11
c 3
b 1
f 0
lcom 0
cbo 6
dl 0
loc 143
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
B handle() 0 58 7
B generate() 0 31 1
A writeClass() 0 21 3
1
<?php
2
3
/*
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the MIT license. For more information, see
18
 * <http://www.doctrine-project.org>.
19
 */
20
21
namespace Baleen\Cli\CommandBus\Repository;
22
23
use Baleen\Cli\Config\Config;
24
use Baleen\Cli\Exception\CliException;
25
use Baleen\Migrations\Migration\SimpleMigration;
26
use League\Flysystem\Filesystem;
27
use phpDocumentor\Reflection\DocBlock\Tag;
28
use Zend\Code\Generator\ClassGenerator;
29
use Zend\Code\Generator\DocBlock\Tag\GenericTag;
30
use Zend\Code\Generator\DocBlockGenerator;
31
use Zend\Code\Generator\FileGenerator;
32
use Zend\Code\Generator\MethodGenerator;
33
34
/**
35
 * Class CreateHandler.
36
 *
37
 * @author Gabriel Somoza <[email protected]>
38
 */
39
class CreateHandler
40
{
41
    /**
42
     * handle.
43
     *
44
     * @param CreateMessage $command
45
     *
46
     * @return false|string
47
     *
48
     * @throws CliException
49
     */
50
    public function handle(CreateMessage $command)
51
    {
52
        $input = $command->getInput();
53
        $output = $command->getOutput();
54
55
        /** @var Config $config */
56
        $config = $command->getConfig();
57
58
        $directory = $config->getMigrationsDirectory();
59
        $filesystem = $command->getFilesystem();
60
        if (!$filesystem->has($directory)) {
61
            throw new CliException(sprintf(
62
                'Migrations directory "%s" does not exist.',
63
                $directory
64
            ));
65
        }
66
67
        $namespace = $input->getOption('namespace');
68
        $editorCmd = $input->getOption('editor-cmd');
69
70
        if (null === $namespace) {
71
            $namespace = $config->getMigrationsNamespace();
72
        }
73
        if (!empty($namespace)) {
74
            $namespace = rtrim($namespace, '\\');
75
            $namespace = preg_replace('/[^A-Za-z\d_\\\\]+/', '', $namespace);
76
        }
77
78
        $timestamp = date('YmdHis');
79
        $className = ['v'.$timestamp];
80
        $title = $input->getArgument('title');
81
        if (!empty($title)) {
82
            $title = preg_replace('/[^A-Za-z\d_]+/', '', $title);
83
            $className[] = $title;
84
        }
85
86
        $class = $this->generate(implode('_', $className), $namespace);
87
        $result = $this->writeClass($class, $filesystem, $directory);
88
89
        if ($result) {
90
            $output->writeln(sprintf(
91
                'Created new Migration file at "<info>./%s</info>"',
92
                $result
93
            ));
94
            if ($editorCmd) {
95
                $pipes = [];
96
                $baseDir = dirname($config->getMigrationsDirectoryPath());
97
                $command = $editorCmd . ' ' . escapeshellarg($baseDir . DIRECTORY_SEPARATOR . $result);
98
                proc_open($command, array(), $pipes);
99
            }
100
        } else {
101
            $output->writeln(
102
                'An error occurred creating a new Migration file. Please check directory permissions and configuration.'
103
            );
104
        }
105
106
        return $result;
107
    }
108
109
    /**
110
     * @param string $className
111
     * @param string $namespace
112
     *
113
     * @return ClassGenerator
114
     *
115
     * @throws CliException
116
     */
117
    protected function generate($className, $namespace = null)
118
    {
119
        $class = new ClassGenerator(
120
            $className,
121
            $namespace,
122
            null,
123
            'SimpleMigration',
124
            [],
125
            [],
126
            [
127
                new MethodGenerator(
128
                    'up',
129
                    [],
130
                    'public',
131
                    null,
132
                    new DocBlockGenerator('Executed when migrating upwards.', 'TODO: implement')
133
                ),
134
                new MethodGenerator(
135
                    'down',
136
                    [],
137
                    'public',
138
                    null,
139
                    new DocBlockGenerator('Executed when migrating downwards / rolling back.', 'TODO: implement')
140
                ),
141
            ],
142
            new DocBlockGenerator($className . ' class', null, [new GenericTag('link', 'http://baleen.org')])
143
        );
144
        $class->addUse(SimpleMigration::class);
145
146
        return $class;
147
    }
148
149
    /**
150
     * Function writeClass.
151
     *
152
     * @param ClassGenerator $class
153
     * @param Filesystem     $filesystem
154
     * @param $destinationDir
155
     *
156
     * @return string|false
157
     *
158
     * @throws CliException
159
     */
160
    protected function writeClass(ClassGenerator $class, Filesystem $filesystem, $destinationDir)
161
    {
162
        $className = $class->getName();
163
        $file = new FileGenerator([
164
            'fileName' => $className.'.php',
165
            'classes' => [$class],
166
        ]);
167
        $contents = $file->generate();
168
169
        $relativePath = $destinationDir.DIRECTORY_SEPARATOR.$file->getFilename();
170
        if ($filesystem->has($relativePath)) {
171
            throw new CliException(sprintf(
172
                'Could not generate migration. File already exists: %s',
173
                $relativePath
174
            ));
175
        }
176
177
        $result = $filesystem->write($relativePath, $contents);
178
179
        return $result ? $relativePath : false;
180
    }
181
}
182