Completed
Pull Request — master (#3)
by Rougin
02:26
created

CreateMigrationCommand::getFileName()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 11
cts 11
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 10
nc 2
nop 2
crap 3
1
<?php
2
3
namespace Rougin\Refinery\Commands;
4
5
use Symfony\Component\Console\Input\InputOption;
6
use Symfony\Component\Console\Input\InputArgument;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Output\OutputInterface;
9
10
/**
11
 * Create Migration Command
12
 *
13
 * Creates a new migration file based on its file name.
14
 *
15
 * @package Refinery
16
 * @author  Rougin Royce Gutib <[email protected]>
17
 */
18
class CreateMigrationCommand extends AbstractCommand
19
{
20
    /**
21
     * Sets the configurations of the specified command.
22
     *
23
     * @return void
24
     */
25 33
    protected function configure()
26
    {
27 33
        $this->setName('create')
28 33
            ->setDescription('Creates a new migration file')
29 33
            ->addArgument('name', InputArgument::REQUIRED, 'Name of the migration file')
30 33
            ->addOption('from-database', null, InputOption::VALUE_NONE, 'Generates a migration based from the database')
31 33
            ->addOption('sequential', null, InputOption::VALUE_NONE, 'Generates a migration file with a sequential identifier')
32 33
            ->addOption('type', null, InputOption::VALUE_OPTIONAL, 'Data type of the column', 'varchar')
33 33
            ->addOption('length', null, InputOption::VALUE_OPTIONAL, 'Length of the column', 50)
34 33
            ->addOption('auto_increment', null, InputOption::VALUE_OPTIONAL, 'Generates an "AUTO_INCREMENT" flag on the column', false)
35 33
            ->addOption('default', null, InputOption::VALUE_OPTIONAL, 'Generates a default value in the column definition', '')
36 33
            ->addOption('null', null, InputOption::VALUE_OPTIONAL, 'Generates a "NULL" value in the column definition', false)
37 33
            ->addOption('primary', null, InputOption::VALUE_OPTIONAL, 'Generates a "PRIMARY" value in the column definition', false)
38 33
            ->addOption('unsigned', null, InputOption::VALUE_OPTIONAL, 'Generates an "UNSIGNED" value in the column definition', false);
39 33
    }
40
41
    /**
42
     * Executes the command.
43
     *
44
     * @param  \Symfony\Component\Console\Input\InputInterface   $input
45
     * @param  \Symfony\Component\Console\Output\OutputInterface $output
46
     * @return object|\Symfony\Component\Console\Output\OutputInterface
47
     */
48 27
    protected function execute(InputInterface $input, OutputInterface $output)
49
    {
50 27
        $fileName = $this->getFileName($input->getArgument('name'), $input->getOption('sequential'));
51 27
        $keywords = $this->getKeywords($input->getArgument('name'));
52
53 27
        $data = $this->prepareData($input, $keywords);
54
55 24
        if ($data['command_name'] != 'create') {
56 6
            $data = $this->defineColumns($input, $keywords, $data);
57 6
        }
58
59 24
        $rendered = $this->renderer->render('Migration.twig', $data);
60
61 24
        $this->filesystem->write('application/migrations/' . $fileName . '.php', $rendered);
62
63 24
        return $output->writeln('<info>"' . $fileName . '" has been created.</info>');
64
    }
65
66
    /**
67
     * Defines the columns to be included in the migration.
68
     *
69
     * @param  \Symfony\Component\Console\Input\InputInterface $input
70
     * @param  array                                           $keywords
71
     * @param  array                                           $data
72
     * @return array
73
     */
74 6
    protected function defineColumns(InputInterface $input, array $keywords, array $data)
75
    {
76 6
        $data['table_name'] = $keywords[3];
77
78 6
        array_push($data['columns'], $this->setColumn($input, $keywords[1]));
79
80 6
        if ($data['command_name'] == 'modify') {
81 3
            foreach ($this->describe->getTable($data['table_name']) as $column) {
82 3
                $column->getField() != $keywords[1] || array_push($data['defaults'], $column);
83 3
            }
84 3
        }
85
86 6
        return $data;
87
    }
88
89
    /**
90
     * Gets the file name of the specified migration.
91
     *
92
     * @param  string  $name
93
     * @param  boolean $isSequential
94
     * @return string
95
     */
96 27
    protected function getFileName($name, $isSequential = false)
97
    {
98 27
        $migrationType = $this->getMigrationType();
99
100 27
        $fileName = date('YmdHis') . '_' . underscore($name);
101
102 27
        if ($migrationType == 'sequential' || $isSequential) {
103 27
            $number = 1;
104
105 27
            $files = new \FilesystemIterator(APPPATH . 'migrations', \FilesystemIterator::SKIP_DOTS);
106
107 27
            $number += iterator_count($files);
108
109 27
            $sequence = sprintf('%03d', $number);
110 27
            $fileName = $sequence . '_' . substr($fileName, 15);
111 27
        }
112
113 27
        return $fileName;
114
    }
115
116
    /**
117
     * Gets the defined keywords from the command.
118
     *
119
     * @param  string $name
120
     * @return array
121
     */
122 27
    protected function getKeywords($name)
123
    {
124 27
        $path = APPPATH . 'migrations';
125
126 27
        file_exists($path) || mkdir($path);
127
128 27
        $keywords = [ '', '', '', '' ];
129
130 27
        return array_replace($keywords, explode('_', underscore($name)));
131
    }
132
133
    /**
134
     * Prepares the data to be inserted in the template.
135
     *
136
     * @param  \Symfony\Component\Console\Input\InputInterface $input
137
     * @param  array                                           $keywords
138
     * @return array
139
     */
140 27
    protected function prepareData(InputInterface $input, array $keywords)
141
    {
142 27
        $data = [];
143
144 27
        $data['command_name'] = $keywords[0];
145 27
        $data['data_types']   = [ 'string' => 'VARCHAR', 'integer' => 'INT' ];
146 27
        $data['class_name']   = underscore($input->getArgument('name'));
147 27
        $data['table_name']   = $keywords[1];
148
149 27
        $data['columns']  = [];
150 27
        $data['defaults'] = [];
151
152 27
        if ($input->getOption('from-database') === true) {
153 6
            if ($data['command_name'] != 'create') {
154 3
                $message = '--from-database is only available to create_*table*_table keyword';
155
156 3
                throw new \InvalidArgumentException($message);
157
            }
158
159 3
            $data['columns'] = $this->describe->getTable($data['table_name']);
160 3
        }
161
162 24
        return $data;
163
    }
164
165
    /**
166
     * Sets properties for a specified column
167
     *
168
     * @param  \Symfony\Component\Console\Input\InputInterface $input
169
     * @param  string                                          $fieldName
170
     * @return \Rougin\Describe\Column
171
     */
172 6
    protected function setColumn(InputInterface $input, $fieldName)
173
    {
174 6
        $column = new \Rougin\Describe\Column;
175
176 6
        $column->setField($fieldName);
177 6
        $column->setNull($input->getOption('null'));
178 6
        $column->setDataType($input->getOption('type'));
179 6
        $column->setLength($input->getOption('length'));
180 6
        $column->setPrimary($input->getOption('primary'));
181 6
        $column->setUnsigned($input->getOption('unsigned'));
182 6
        $column->setDefaultValue($input->getOption('default'));
183 6
        $column->setAutoIncrement($input->getOption('auto_increment'));
184
185 6
        return $column;
186
    }
187
}
188