Passed
Push — master ( 1065ba...625efe )
by Francesc
02:11
created

GenerateXmlEditModel::setModelName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of FSConsoleTools
4
 * Copyright (C) 2018 Francesc Pineda Segarra <[email protected]>
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation, either version 3 of the
9
 * License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
namespace FacturaScriptsUtils\Console\Command;
21
22
use FacturaScripts\Core\Base\DataBase;
0 ignored issues
show
Bug introduced by
The type FacturaScripts\Core\Base\DataBase was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use FacturaScriptsUtils\Console\ConsoleAbstract;
24
use Twig_Environment;
25
use Twig_Extension_Debug;
26
use Twig_Loader_Filesystem;
27
28
if (!\defined('DB_CONNECTION')) {
29
    \define('DB_CONNECTION', false);
30
}
31
32
/**
33
 * Class GenerateXmlEditModel.
34
 *
35
 * @author Francesc Pineda Segarra <[email protected]>
36
 */
37
class GenerateXmlEditModel extends ConsoleAbstract
38
{
39
    use Common\TableInformation;
40
41
    /**
42
     * Constant values for return, to easy know how execution ends.
43
     */
44
    const RETURN_SUCCESS = 0;
45
    const RETURN_TABLE_NAME_NOT_SET = 1;
46
    const RETURN_MODEL_NAME_NOT_SET = 2;
47
    const RETURN_DST_FOLDER_NOT_SET = 3;
48
    const RETURN_CANT_CREATE_FOLDER = 4;
49
    const RETURN_TABLE_NOT_EXISTS = 5;
50
    const RETURN_FAIL_SAVING_FILE = 6;
51
52
    /**
53
     * Name of the table.
54
     *
55
     * @var string
56
     */
57
    private $tableName;
58
59
    /**
60
     * Name of the model.
61
     *
62
     * @var string
63
     */
64
    private $modelName;
65
66
    /**
67
     * Folder destiny path.
68
     *
69
     * @var string
70
     */
71
    private $folderDstPath;
72
73
    /**
74
     * Start point to run the command.
75
     *
76
     * @param array $params
77
     *
78
     * @return int
79
     */
80
    public function run(...$params): int
81
    {
82
        if (!\DB_CONNECTION) {
83
            echo 'A database connection is needed. Do you set your config.php file?';
84
        }
85
86
        $status = $this->checkOptions($params);
87
        if ($status !== 0) {
88
            return $status;
89
        }
90
91
        $status = $this->checkParams($params);
92
        if ($status !== 0) {
93
            return $status;
94
        }
95
96
        echo 'Generating XMLView Edit file' . \PHP_EOL . \PHP_EOL;
97
        echo '   Options setted:' . \PHP_EOL;
98
        echo '      Table name: ' . $this->tableName . \PHP_EOL;
99
        echo '      Model name: ' . $this->modelName . \PHP_EOL;
100
        echo '      Destiny path: ' . $this->folderDstPath . \PHP_EOL;
101
102
        if (!$this->areYouSure()) {
103
            echo '   Options [TABLE NAME] [MODEL NAME] [DST]' . \PHP_EOL;
104
            return self::RETURN_SUCCESS;
105
        }
106
107
        $status = $this->check();
108
        if ($status !== 0) {
109
            return $status;
110
        }
111
112
        return $this->generateModel();
113
    }
114
115
    /**
116
     * Return description about this class.
117
     *
118
     * @return string
119
     */
120
    public function getDescription(): string
121
    {
122
        return 'Generate a XMLView Edit for model class from database table.';
123
    }
124
125
    /**
126
     * Print help information to the user.
127
     *
128
     * @return string
129
     */
130
    public function getHelpMsg(): string
131
    {
132
        $array = \explode('\\', __CLASS__);
133
        $class = array_pop($array);
134
        return 'Use as: php vendor/bin/console ' . $class . ' [OPTIONS]' . \PHP_EOL
135
            . 'Available options:' . \PHP_EOL
136
            . '   -h, --help        Show this help.' . \PHP_EOL
137
            . '   -t, --tables      Show tables.' . \PHP_EOL
138
            . '   -g, --gen         Generate model.' . \PHP_EOL
139
            . \PHP_EOL
140
            . '   OPTION1           Table name' . \PHP_EOL
141
            . '   OPTION2           Model name' . \PHP_EOL
142
            . '   OPTION3           Destiny path' . \PHP_EOL
143
            . \PHP_EOL;
144
    }
145
146
    /**
147
     * Returns an associative array of available methods for the user.
148
     * Add more options if you want to add support for custom methods.
149
     *      [
150
     *          '-h'        => 'getHelpMsg',
151
     *          '--help'    => 'getHelpMsg',
152
     *      ]
153
     *
154
     * @return array
155
     */
156
    public function getUserMethods(): array
157
    {
158
        // Adding extra method
159
        $methods = parent::getUserMethods();
160
        $methods['-t'] = 'getTablesMsg';
161
        $methods['--tables'] = 'getTablesMsg';
162
        $methods['-g'] = 'generateModel';
163
        $methods['--gen'] = 'generateModel';
164
        return $methods;
165
    }
166
167
    /**
168
     * Return a list of tables.
169
     *
170
     * @return string
171
     */
172
    public function getTablesMsg(): string
173
    {
174
        return \implode(', ', $this->getTables($this->dataBase));
175
    }
176
177
    /**
178
     * Set table name to use.
179
     *
180
     * @param string $tableName
181
     *
182
     * @return $this
183
     */
184
    public function setTableName(string $tableName): self
185
    {
186
        $this->tableName = $tableName;
187
        return $this;
188
    }
189
190
    /**
191
     * Set the model name to use.
192
     *
193
     * @param string $modelName
194
     *
195
     * @return $this
196
     */
197
    public function setModelName(string $modelName): self
198
    {
199
        $this->modelName = $modelName;
200
        return $this;
201
    }
202
203
    /**
204
     * Set destiny folder.
205
     *
206
     * @param string $folderDstPath
207
     *
208
     * @return $this
209
     */
210
    public function setFolderDstPath(string $folderDstPath): self
211
    {
212
        $this->folderDstPath = $folderDstPath;
213
        return $this;
214
    }
215
216
    /**
217
     * Set database.
218
     *
219
     * @param DataBase $dataBase
220
     */
221
    public function setDataBase(DataBase $dataBase)
222
    {
223
        $this->dataBase = $dataBase;
224
    }
225
226
    /**
227
     * Return the table name.
228
     *
229
     * @return string
230
     */
231
    public function getTableName(): string
232
    {
233
        return $this->tableName;
234
    }
235
236
    /**
237
     * Return the model name.
238
     *
239
     * @return string
240
     */
241
    public function getModelName(): string
242
    {
243
        return $this->modelName;
244
    }
245
246
    /**
247
     * Return the folder destiny path.
248
     *
249
     * @return string
250
     */
251
    public function getFolderDstPath(): string
252
    {
253
        return $this->folderDstPath;
254
    }
255
256
    /**
257
     * Return the DataBase object.
258
     *
259
     * @return DataBase
260
     */
261
    public function getDataBase()
262
    {
263
        return $this->dataBase;
264
    }
265
266
    /**
267
     * Return items from table by type.
268
     *
269
     * @param string $type
270
     *
271
     * @return array
272
     */
273
    public function getItemsFromTableBy(string $type = '')
274
    {
275
        $items = [];
276
        foreach ($this->getItemsFromTable($this->getDataBase(), $this->getTableName()) as $item) {
277
            $colType = $this->parseType($item['type'], 'view');
278
            if (0 === \strpos($colType, $type)) {
279
                $items[] = $item;
280
            }
281
        }
282
        return $items;
283
    }
284
285
    /**
286
     * Return constraints grouped by name.
287
     *
288
     * @return array
289
     */
290
    public function getConstraintsGroupByName()
291
    {
292
        $constraint = [];
293
        foreach ($this->getConstraintFromTable($this->getDataBase(), $this->getTableName()) as $cons) {
294
            if (isset($constraint[$cons['name']])) {
295
                $constraint[$cons['name']]['column_name'] .= ', ' . $cons['column_name'];
296
            } else {
297
                $constraint[$cons['name']] = $cons;
298
            }
299
        }
300
        \ksort($constraint);
301
        return $constraint;
302
    }
303
304
    /**
305
     * Return items from table ordered, primary key first.
306
     *
307
     * @return array
308
     */
309
    public function getItemsFromTableOrdered()
310
    {
311
        $items = [];
312
        $primaryKey = null;
313
        foreach ($this->getItemsFromTable($this->getDataBase(), $this->getTableName()) as $item) {
314
            $items[] = $item;
315
            if (0 === \strpos($item['default'], 'nextval')) {
316
                $primaryKey = array_pop($items);
317
            }
318
        }
319
        array_unshift($items, $primaryKey);
320
        return $items;
321
    }
322
323
    /**
324
     * Check if options are looking for help.
325
     *
326
     * @param array $params
327
     *
328
     * @return int
329
     */
330
    private function checkOptions(array $params = []): int
331
    {
332
        if (isset($params[0])) {
333
            switch ($params[0]) {
334
                case '-h':
335
                case '--help':
336
                    echo $this->getHelpMsg();
337
                    return -1;
338
                case '-t':
339
                case '--tables':
340
                    $this->setDataBase($params[1] ?? null);
0 ignored issues
show
Bug introduced by
It seems like $params[1] ?? null can also be of type null; however, parameter $dataBase of FacturaScriptsUtils\Cons...ditModel::setDataBase() does only seem to accept FacturaScripts\Core\Base\DataBase, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

340
                    $this->setDataBase(/** @scrutinizer ignore-type */ $params[1] ?? null);
Loading history...
341
                    echo $this->getTablesMsg();
342
                    return -1;
343
                case '-g':
344
                case '--gen':
345
                    $this->setTableName($params[1] ?? '');
346
                    $this->setModelName($params[2] ?? '');
347
                    $this->setFolderDstPath(\FS_FOLDER . $params[3] ?? '');
348
                    $this->setDataBase($params[4] ?? null);
349
            }
350
        }
351
        return 0;
352
    }
353
354
    /**
355
     * Check if options are looking for help.
356
     *
357
     * @param array $params
358
     *
359
     * @return int
360
     */
361
    private function checkParams(array $params = []): int
362
    {
363
        if (!isset($params[0])) {
364
            echo 'No table name setted.' . \PHP_EOL;
365
            return -1;
366
        }
367
        if (!isset($params[1])) {
368
            echo 'No model name setted.' . \PHP_EOL;
369
            return -1;
370
        }
371
        return 0;
372
    }
373
374
    /**
375
     * Launch basic checks.
376
     *
377
     * @return int
378
     */
379
    private function check(): int
380
    {
381
        if ($this->tableName === null) {
382
            echo 'ERROR: Table name not setted.' . \PHP_EOL . \PHP_EOL;
383
            return self::RETURN_TABLE_NAME_NOT_SET;
384
        }
385
        if ($this->modelName === null) {
386
            echo 'ERROR: Model name not setted.' . \PHP_EOL . \PHP_EOL;
387
            return self::RETURN_MODEL_NAME_NOT_SET;
388
        }
389
        if ($this->folderDstPath === null) {
390
            echo 'ERROR: Destiny folder not setted.' . \PHP_EOL . \PHP_EOL;
391
            return self::RETURN_DST_FOLDER_NOT_SET;
392
        }
393
        if (!is_file($this->folderDstPath) && !@mkdir($this->folderDstPath) && !is_dir($this->folderDstPath)) {
394
            echo "ERROR: Can't create folder " . $this->folderDstPath . '.' . \PHP_EOL . \PHP_EOL;
395
            return self::RETURN_CANT_CREATE_FOLDER;
396
        }
397
        if (!\in_array($this->tableName, $this->dataBase->getTables(), false)) {
398
            echo 'ERROR: Table not exists.' . \PHP_EOL . \PHP_EOL;
399
            return self::RETURN_TABLE_NOT_EXISTS;
400
        }
401
        return self::RETURN_SUCCESS;
402
    }
403
404
    /**
405
     * Generate model file.
406
     *
407
     * @return int
408
     */
409
    private function generateModel(): int
410
    {
411
        $loader = new Twig_Loader_Filesystem([__DIR__ . '/../Template']);
412
        $twig = new Twig_Environment($loader, ['debug' => \FS_DEBUG,]);
413
        $twig->addExtension(new Twig_Extension_Debug());
414
        $txt = $twig->render(
415
            'ViewEditModel.xml.twig',
416
            ['fsc' => $this]
417
        );
418
419
        $status = $this->saveFile($this->folderDstPath . 'Edit' . $this->modelName . '.xml', $txt);
420
        if (\is_bool($status)) {
0 ignored issues
show
introduced by
The condition is_bool($status) is always false.
Loading history...
421
            echo "Can't save " . $this->folderDstPath . 'Edit' . $this->modelName . '.xml"' . \PHP_EOL;
422
            return $status;
423
        }
424
        echo 'Finished! Look at "' . $this->folderDstPath . '"' . \PHP_EOL;
425
        return self::RETURN_SUCCESS;
426
    }
427
428
    /**
429
     * Save file.
430
     *
431
     * @param string $pathName
432
     * @param string $content
433
     *
434
     * @return int
435
     */
436
    private function saveFile(string $pathName, string $content): int
437
    {
438
        return (int) file_put_contents($pathName, $content);
439
    }
440
}
441