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

GenerateXmlTable::saveFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
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 GeneratePhpModel.
34
 *
35
 * @author Francesc Pineda Segarra <[email protected]>
36
 */
37
class GenerateXmlTable 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
     * Folder destiny path.
61
     *
62
     * @var string
63
     */
64
    private $folderDstPath;
65
66
    /**
67
     * Start point to run the command.
68
     *
69
     * @param array $params
70
     *
71
     * @return int
72
     */
73
    public function run(...$params): int
74
    {
75
        if (!\DB_CONNECTION) {
76
            echo 'A database connection is needed. Do you set your config.php file?';
77
        }
78
79
        $status = $this->checkOptions($params);
80
        if ($status !== 0) {
81
            return $status;
82
        }
83
84
        $status = $this->checkParams($params);
85
        if ($status !== 0) {
86
            return $status;
87
        }
88
89
        echo 'Generating XML table file' . \PHP_EOL . \PHP_EOL;
90
        echo '   Options setted:' . \PHP_EOL;
91
        echo '      Table name: ' . $this->tableName . \PHP_EOL;
92
        echo '      Destiny path: ' . $this->folderDstPath . \PHP_EOL;
93
94
        if (!$this->areYouSure()) {
95
            echo '   Options [TABLE NAME] [DST]' . \PHP_EOL;
96
            return self::RETURN_SUCCESS;
97
        }
98
99
        $status = $this->check();
100
        if ($status !== 0) {
101
            return $status;
102
        }
103
104
        return $this->generateModel();
105
    }
106
107
    /**
108
     * Return description about this class.
109
     *
110
     * @return string
111
     */
112
    public function getDescription(): string
113
    {
114
        return 'Generate a XML table definition for model from database table.';
115
    }
116
117
    /**
118
     * Print help information to the user.
119
     *
120
     * @return string
121
     */
122
    public function getHelpMsg(): string
123
    {
124
        $array = \explode('\\', __CLASS__);
125
        $class = array_pop($array);
126
        return 'Use as: php vendor/bin/console ' . $class . ' [OPTIONS]' . \PHP_EOL
127
            . 'Available options:' . \PHP_EOL
128
            . '   -h, --help        Show this help.' . \PHP_EOL
129
            . '   -t, --tables      Show tables.' . \PHP_EOL
130
            . '   -g, --gen         Generate model.' . \PHP_EOL
131
            . \PHP_EOL
132
            . '   OPTION1           Table name' . \PHP_EOL
133
            . '   OPTION2           Destiny path' . \PHP_EOL
134
            . \PHP_EOL;
135
    }
136
137
    /**
138
     * Returns an associative array of available methods for the user.
139
     * Add more options if you want to add support for custom methods.
140
     *      [
141
     *          '-h'        => 'getHelpMsg',
142
     *          '--help'    => 'getHelpMsg',
143
     *      ]
144
     *
145
     * @return array
146
     */
147
    public function getUserMethods(): array
148
    {
149
        // Adding extra method
150
        $methods = parent::getUserMethods();
151
        $methods['-t'] = 'getTablesMsg';
152
        $methods['--tables'] = 'getTablesMsg';
153
        $methods['-g'] = 'generateModel';
154
        $methods['--gen'] = 'generateModel';
155
        return $methods;
156
    }
157
158
    /**
159
     * Return a list of tables.
160
     *
161
     * @return string
162
     */
163
    public function getTablesMsg(): string
164
    {
165
        return \implode(', ', $this->getTables($this->dataBase));
166
    }
167
168
    /**
169
     * Set table name to use.
170
     *
171
     * @param string $tableName
172
     *
173
     * @return $this
174
     */
175
    public function setTableName(string $tableName): self
176
    {
177
        $this->tableName = $tableName;
178
        return $this;
179
    }
180
181
    /**
182
     * Set destiny folder.
183
     *
184
     * @param string $folderDstPath
185
     *
186
     * @return $this
187
     */
188
    public function setFolderDstPath(string $folderDstPath): self
189
    {
190
        $this->folderDstPath = $folderDstPath;
191
        return $this;
192
    }
193
194
    /**
195
     * Set database.
196
     *
197
     * @param DataBase $dataBase
198
     */
199
    public function setDataBase(DataBase $dataBase)
200
    {
201
        $this->dataBase = $dataBase;
202
    }
203
204
    /**
205
     * Return the table name.
206
     *
207
     * @return string
208
     */
209
    public function getTableName(): string
210
    {
211
        return $this->tableName;
212
    }
213
214
    /**
215
     * Return the folder destiny path.
216
     *
217
     * @return string
218
     */
219
    public function getFolderDstPath(): string
220
    {
221
        return $this->folderDstPath;
222
    }
223
224
    /**
225
     * Return the DataBase object.
226
     *
227
     * @return DataBase
228
     */
229
    public function getDataBase()
230
    {
231
        return $this->dataBase;
232
    }
233
234
    /**
235
     * Return constraints grouped by name.
236
     *
237
     * @return array
238
     */
239
    public function getConstraintsGroupByName()
240
    {
241
        $constraint = [];
242
        foreach ($this->getConstraintFromTable($this->getDataBase(), $this->getTableName()) as $cons) {
243
            if (isset($constraint[$cons['name']])) {
244
                $constraint[$cons['name']]['column_name'] .= ', ' . $cons['column_name'];
245
            } else {
246
                $constraint[$cons['name']] = $cons;
247
            }
248
        }
249
        \ksort($constraint);
250
        return $constraint;
251
    }
252
253
    /**
254
     * Check if options are looking for help.
255
     *
256
     * @param array $params
257
     *
258
     * @return int
259
     */
260
    private function checkOptions(array $params = []): int
261
    {
262
        if (isset($params[0])) {
263
            switch ($params[0]) {
264
                case '-h':
265
                case '--help':
266
                    echo $this->getHelpMsg();
267
                    return -1;
268
                case '-t':
269
                case '--tables':
270
                    $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...XmlTable::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

270
                    $this->setDataBase(/** @scrutinizer ignore-type */ $params[1] ?? null);
Loading history...
271
                    echo $this->getTablesMsg();
272
                    return -1;
273
                case '-g':
274
                case '--gen':
275
                    $this->setTableName($params[1] ?? '');
276
                    $this->setFolderDstPath(\FS_FOLDER . $params[2] ?? '');
277
                    $this->setDataBase($params[3] ?? null);
278
            }
279
        }
280
        return 0;
281
    }
282
283
    /**
284
     * Check if options are looking for help.
285
     *
286
     * @param array $params
287
     *
288
     * @return int
289
     */
290
    private function checkParams(array $params = []): int
291
    {
292
        if (!isset($params[0])) {
293
            echo 'No table name setted.' . \PHP_EOL;
294
            return -1;
295
        }
296
        if (!isset($params[1])) {
297
            echo 'No model name setted.' . \PHP_EOL;
298
            return -1;
299
        }
300
        return 0;
301
    }
302
303
    /**
304
     * Launch basic checks.
305
     *
306
     * @return int
307
     */
308
    private function check(): int
309
    {
310
        if ($this->tableName === null) {
311
            echo 'ERROR: Table name not setted.' . \PHP_EOL . \PHP_EOL;
312
            return self::RETURN_TABLE_NAME_NOT_SET;
313
        }
314
        if ($this->folderDstPath === null) {
315
            echo 'ERROR: Destiny folder not setted.' . \PHP_EOL . \PHP_EOL;
316
            return self::RETURN_DST_FOLDER_NOT_SET;
317
        }
318
        if (!is_file($this->folderDstPath) && !@mkdir($this->folderDstPath) && !is_dir($this->folderDstPath)) {
319
            echo "ERROR: Can't create folder " . $this->folderDstPath . '.' . \PHP_EOL . \PHP_EOL;
320
            return self::RETURN_CANT_CREATE_FOLDER;
321
        }
322
        if (!\in_array($this->tableName, $this->dataBase->getTables(), false)) {
323
            echo 'ERROR: Table not exists.' . \PHP_EOL . \PHP_EOL;
324
            return self::RETURN_TABLE_NOT_EXISTS;
325
        }
326
        return self::RETURN_SUCCESS;
327
    }
328
329
    /**
330
     * Generate model file.
331
     *
332
     * @return int
333
     */
334
    private function generateModel(): int
335
    {
336
        $loader = new Twig_Loader_Filesystem([__DIR__ . '/../Template']);
337
        $twig = new Twig_Environment($loader, ['debug' => \FS_DEBUG,]);
338
        $twig->addExtension(new Twig_Extension_Debug());
339
        $txt = $twig->render(
340
            'XmlTable.xml.twig',
341
            ['fsc' => $this]
342
        );
343
344
        $status = $this->saveFile($this->folderDstPath . $this->tableName . '.xml', $txt);
345
        if (\is_bool($status)) {
0 ignored issues
show
introduced by
The condition is_bool($status) is always false.
Loading history...
346
            echo "Can't save " . $this->folderDstPath . $this->tableName . '.xml"' . \PHP_EOL;
347
            return $status;
348
        }
349
        echo 'Finished! Look at "' . $this->folderDstPath . '"' . \PHP_EOL;
350
        return self::RETURN_SUCCESS;
351
    }
352
353
    /**
354
     * Save file.
355
     *
356
     * @param string $pathName
357
     * @param string $content
358
     *
359
     * @return int
360
     */
361
    private function saveFile(string $pathName, string $content): int
362
    {
363
        return (int) file_put_contents($pathName, $content);
364
    }
365
}
366