Test Failed
Push — develop ( 0ede07...29e3d8 )
by nguereza
02:43
created

AbstractSeedCommand::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nc 1
nop 3
dl 0
loc 11
rs 10
1
<?php
2
3
/**
4
 * Platine Framework
5
 *
6
 * Platine Framework is a lightweight, high-performance, simple and elegant
7
 * PHP Web framework
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Framework
12
 *
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
14
 * of this software and associated documentation files (the "Software"), to deal
15
 * in the Software without restriction, including without limitation the rights
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 * copies of the Software, and to permit persons to whom the Software is
18
 * furnished to do so, subject to the following conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all
21
 * copies or substantial portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
 * SOFTWARE.
30
 */
31
32
/**
33
 *  @file AbstractSeedCommand.php
34
 *
35
 *  The Base seed command class
36
 *
37
 *  @package    Platine\Framework\Migration\Seed\Command
38
 *  @author Platine Developers team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   http://www.iacademy.cf
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\Framework\Migration\Seed\Command;
49
50
use Platine\Config\Config;
51
use Platine\Console\Command\Command;
52
use Platine\Database\Connection;
53
use Platine\Filesystem\DirectoryInterface;
54
use Platine\Filesystem\FileInterface;
55
use Platine\Filesystem\Filesystem;
56
use Platine\Framework\App\Application;
57
use Platine\Framework\Migration\Seed\AbstractSeed;
58
use Platine\Stdlib\Helper\Path;
59
use Platine\Stdlib\Helper\Str;
60
use RuntimeException;
61
62
/**
63
 * @class AbstractSeedCommand
64
 * @package Platine\Framework\Migration\Seed\Command
65
 * @template T
66
 */
67
abstract class AbstractSeedCommand extends Command
68
{
69
70
    /**
71
     * The configuration to use
72
     * @var Config<T>
73
     */
74
    protected Config $config;
75
76
    /**
77
     * The file system to use
78
     * @var Filesystem
79
     */
80
    protected Filesystem $filesystem;
81
82
    /**
83
     * The Platine Application
84
     * @var Application
85
     */
86
    protected Application $application;
87
88
    /**
89
     * The seed files path
90
     * @var string
91
     */
92
    protected string $seedPath = '';
93
94
    /**
95
     * Create new instance
96
     * @param Application $app
97
     * @param Config<T> $config
98
     * @param Filesystem $filesystem
99
     */
100
    public function __construct(
101
        Application $app,
102
        Config $config,
103
        Filesystem $filesystem
104
    ) {
105
        parent::__construct('seed', 'Command to manage database seed');
106
        $this->application = $app;
107
        $this->config = $config;
108
        $this->filesystem = $filesystem;
109
        $path = Path::convert2Absolute($config->get('database.migration.seed_path', 'seeds'));
110
        $this->seedPath = Path::normalizePathDS($path, true);
111
    }
112
113
    /**
114
     * Check the seed directory
115
     * @return void
116
     */
117
    protected function checkSeedPath(): void
118
    {
119
        $directory = $this->filesystem->directory($this->seedPath);
120
121
        if (!$directory->exists() || !$directory->isWritable()) {
122
            throw new RuntimeException(sprintf(
123
                'Seed directory [%s] does not exist or is writable',
124
                $this->seedPath
125
            ));
126
        }
127
    }
128
129
    /**
130
     * Create seed class for the given name
131
     * @param string $description
132
     * @return AbstractSeed
133
     */
134
    protected function createSeedClass(string $description): AbstractSeed
135
    {
136
        $this->checkSeedPath();
137
138
        $className = $this->getSeedClassName($description);
139
        $filename = $this->getFilenameFromClass($className);
140
        $fullPath = $this->seedPath . $filename;
141
142
        $file = $this->filesystem->file($fullPath);
143
        $fullClassName = 'Platine\\Framework\\Migration\\Seed\\' . $className;
144
145
        if (!$file->exists()) {
146
            throw new RuntimeException(sprintf(
147
                'Seed file [%s] does not exist',
148
                $fullPath
149
            ));
150
        }
151
152
        require_once $fullPath;
153
154
        if (!class_exists($fullClassName)) {
155
            throw new RuntimeException(sprintf(
156
                'Seed class [%s] does not exist',
157
                $fullClassName
158
            ));
159
        }
160
161
        $connection = $this->application->get(Connection::class);
162
163
        return new $fullClassName($connection);
164
    }
165
166
    /**
167
     * Return all seed files available
168
     * @return array<string, string>
169
     */
170
    protected function getAvailableSeeds(): array
171
    {
172
        $this->checkSeedPath();
173
174
        $directory = $this->filesystem->directory($this->seedPath);
175
        $result = [];
176
        /** @var FileInterface[] $files */
177
        $files = $directory->read(DirectoryInterface::FILE);
178
        foreach ($files as $file) {
179
            $matches = [];
180
            if (preg_match('/^([a-z_]+)Seed\.php$/i', $file->getName(), $matches)) {
181
                $result[$matches[1]] = str_replace('_', ' ', Str::snake($matches[1]));
182
            }
183
        }
184
185
        ksort($result);
186
187
        return $result;
188
    }
189
190
    /**
191
     * Return the seed class name for the given name
192
     * @param string $description
193
     * @return string
194
     */
195
    protected function getSeedClassName(string $description): string
196
    {
197
        return Str::camel($description, false) . 'Seed';
198
    }
199
200
    /**
201
     * Return the name of the seed file
202
     * @param string $className
203
     * @return string
204
     */
205
    protected function getFilenameFromClass(string $className): string
206
    {
207
        return $filename = sprintf(
0 ignored issues
show
Unused Code introduced by
The assignment to $filename is dead and can be removed.
Loading history...
208
            '%s.php',
209
            Str::snake($className)
210
        );
211
    }
212
}
213