Test Failed
Push — develop ( f7f0fb...a5cb71 )
by nguereza
03:14
created

VendorPublishCommand::publishTemplate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 9
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 15
rs 9.9666
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 VendorPublishCommand.php
34
 *
35
 *  The Composer vendor publish command class
36
 *
37
 *  @package    Platine\Framework\Console\Command
38
 *  @author Platine Developers team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   https://www.platine-php.com
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\Framework\Console\Command;
49
50
use Platine\Config\Config;
51
use Platine\Console\Command\Command;
52
use Platine\Filesystem\DirectoryInterface;
53
use Platine\Filesystem\FileInterface;
54
use Platine\Filesystem\Filesystem;
55
use Platine\Framework\App\Application;
56
use Platine\Stdlib\Helper\Composer;
57
use Platine\Stdlib\Helper\Path;
58
59
/**
60
 * @class VendorPublishCommand
61
 * @package Platine\Framework\Console\Command
62
 * @template T
63
 */
64
class VendorPublishCommand extends Command
65
{
66
    /**
67
     * Application instance
68
     * @var Application
69
     */
70
    protected Application $application;
71
72
    /**
73
     * The vendor path
74
     * @var string
75
     */
76
    protected string $vendorPath;
77
78
    /**
79
     * The package installation path
80
     * @var string
81
     */
82
    protected string $packagePath = '';
83
84
    /**
85
     * The file system to use
86
     * @var Filesystem
87
     */
88
    protected Filesystem $filesystem;
89
90
    /**
91
     * Package manifest information
92
     * @var array<string, mixed>
93
     */
94
    protected array $manifest = [];
95
96
    /**
97
     * The configuration to use
98
     * @var Config<T>
99
     */
100
    protected Config $config;
101
102
    /**
103
     * Create new instance
104
     * @param Application $app
105
     * @param Filesystem $filesystem
106
     * @param Config<T> $config
107
     */
108
    public function __construct(
109
        Application $app,
110
        Filesystem $filesystem,
111
        Config $config
112
    ) {
113
        parent::__construct(
114
            'vendor:publish',
115
            'Command to publish composer vendor configuration, migration, language etc.'
116
        );
117
        $this->addArgument('name', 'The package name', null, true);
118
        $this->addOption('-o|--overwrite', 'Overwrite existing files.', false, false);
119
        $this->addOption('-c|--config', 'Publish only the configuration.', false, false);
120
        $this->addOption('-m|--migration', 'Publish only the migrations.', false, false);
121
        $this->addOption('-l|--lang', 'Publish only the languages.', false, false);
122
        $this->addOption('-t|--template', 'Publish only the templates.', false, false);
123
        $this->addOption('-a|--all', 'Publish all files.', false, false);
124
125
        $this->config = $config;
126
        $this->filesystem = $filesystem;
127
        $this->application = $app;
128
        $this->vendorPath = Path::normalizePathDS($app->getVendorPath(), true);
129
    }
130
131
    /**
132
     * {@inheritdoc}
133
     */
134
    public function execute()
135
    {
136
        $writer = $this->io()->writer();
137
        $name = $this->getArgumentValue('name');
138
        $writer->boldGreen(sprintf('PUBLISH OF PACKAGE [%s]', $name), true)->eol();
139
140
        $package = $this->getPackageInfo($name);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type null; however, parameter $name of Platine\Framework\Consol...mmand::getPackageInfo() does only seem to accept string, 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

140
        $package = $this->getPackageInfo(/** @scrutinizer ignore-type */ $name);
Loading history...
141
        if (empty($package)) {
142
            $writer->red(sprintf(
143
                'Can not find the composer package [%s].',
144
                $name
145
            ), true);
146
            return;
147
        }
148
149
        $packagePath = $this->vendorPath . $name;
150
        $packagePath = Path::convert2Absolute($packagePath);
151
152
        $this->packagePath = $packagePath;
153
154
        $writer->bold('Name: ');
155
        $writer->boldBlueBgBlack($package['name'], true);
156
157
        $writer->bold('Description: ');
158
        $writer->boldBlueBgBlack($package['description'], true);
159
160
        $writer->bold('Version: ');
161
        $writer->boldBlueBgBlack($package['version'], true);
162
163
        $writer->bold('Type: ');
164
        $writer->boldBlueBgBlack($package['type'], true);
165
166
        $writer->bold('Path: ');
167
        $writer->boldBlueBgBlack($packagePath, true)->eol();
168
169
        $extras = $package['extra'] ?? [];
170
        $manifest = $extras['platine'] ?? [];
171
172
        if (empty($manifest)) {
173
            $writer->boldGreen('NOTHING TO PUBLISH, COMMAND ENDED!', true);
174
            return;
175
        }
176
177
        $this->manifest = $manifest;
178
179
        $this->publishPackage();
180
181
        $writer->eol();
182
        $writer->boldGreen('Command finished successfully')->eol();
183
    }
184
185
    /**
186
     * Package publication
187
     * @return void
188
     */
189
    protected function publishPackage(): void
190
    {
191
        $all = $this->getOptionValue('all');
192
        if ($all) {
193
            $this->publishAll();
194
            return;
195
        }
196
197
        $config = $this->getOptionValue('config');
198
        if ($config) {
199
            $this->publishConfiguration();
200
        }
201
202
        $migration = $this->getOptionValue('migration');
203
        if ($migration) {
204
            $this->publishMigration();
205
        }
206
207
        $lang = $this->getOptionValue('lang');
208
        if ($lang) {
209
            $this->publishLanguage();
210
        }
211
        
212
        $template = $this->getOptionValue('template');
213
        if ($template) {
214
            $this->publishTemplate();
215
        }
216
    }
217
218
    /**
219
     * Publish all assets for this package
220
     * @return void
221
     */
222
    protected function publishAll(): void
223
    {
224
        $this->publishConfiguration();
225
        $this->publishMigration();
226
        $this->publishLanguage();
227
        $this->publishTemplate();
228
    }
229
230
    /**
231
     * Publish the configuration
232
     * @return void
233
     */
234
    protected function publishConfiguration(): void
235
    {
236
        $writer = $this->io()->writer();
237
        $writer->boldYellow('Publish of package configuration', true);
238
239
        $manifest = $this->manifest;
240
        $config = $manifest['config'] ?? [];
241
        $destinationPath = Path::normalizePathDS(
242
            $this->application->getConfigPath(),
243
            true
244
        );
245
        foreach ($config as $cfg) {
246
            $this->publishItem($cfg, $destinationPath, 'configuration');
247
        }
248
    }
249
250
    /**
251
     * Publish the language
252
     * @return void
253
     */
254
    protected function publishLanguage(): void
255
    {
256
        $writer = $this->io()->writer();
257
        $writer->boldYellow('Publish of package language', true);
258
259
        $path = Path::convert2Absolute(
260
            $this->config->get('lang.translation_path')
0 ignored issues
show
Bug introduced by
It seems like $this->config->get('lang.translation_path') can also be of type null; however, parameter $path of Platine\Stdlib\Helper\Path::convert2Absolute() does only seem to accept string, 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

260
            /** @scrutinizer ignore-type */ $this->config->get('lang.translation_path')
Loading history...
261
        );
262
        $destinationPath = Path::normalizePathDS($path, true);
263
264
        $manifest = $this->manifest;
265
        $languages = $manifest['lang'] ?? [];
266
        foreach ($languages as $language) {
267
            $this->publishItem($language, $destinationPath, 'language');
268
        }
269
    }
270
271
    /**
272
     * Publish the migration
273
     * @return void
274
     */
275
    protected function publishMigration(): void
276
    {
277
        $writer = $this->io()->writer();
278
        $writer->boldYellow('Publish of package migration', true);
279
280
281
        $path = Path::convert2Absolute(
282
            $this->config->get('database.migration.path', 'migrations')
283
        );
284
        $destinationPath = Path::normalizePathDS($path, true);
285
286
        $manifest = $this->manifest;
287
        $migrations = $manifest['migration'] ?? [];
288
        foreach ($migrations as $migration) {
289
            $this->publishItem($migration, $destinationPath, 'migration');
290
        }
291
    }
292
    
293
    /**
294
     * Publish the template
295
     * @return void
296
     */
297
    protected function publishTemplate(): void
298
    {
299
        $writer = $this->io()->writer();
300
        $writer->boldYellow('Publish of package template', true);
301
302
303
        $path = Path::convert2Absolute(
304
            $this->config->get('template.template_dir', 'templates')
305
        );
306
        $destinationPath = Path::normalizePathDS($path, true);
307
308
        $manifest = $this->manifest;
309
        $templates = $manifest['template'] ?? [];
310
        foreach ($templates as $template) {
311
            $this->publishItem($template, $destinationPath, 'template');
312
        }
313
    }
314
315
    /**
316
     * Publish asset
317
     * @param string $src
318
     * @param string $dest
319
     * @param string $type
320
     * @return void
321
     */
322
    protected function publishItem(string $src, string $dest, string $type): void
323
    {
324
        $writer = $this->io()->writer();
325
326
        $sourcePath = $this->packagePath . '/' . $src;
327
        $asset = $this->filesystem->get($sourcePath);
328
        if ($asset === null) {
329
            $writer->red(sprintf(
330
                'Can not find the package file %s [%s].',
331
                $type,
332
                $sourcePath
333
            ), true);
334
            return;
335
        }
336
337
        if ($asset instanceof DirectoryInterface) {
338
            $this->publishDirectory($asset, $dest);
339
        } elseif ($asset instanceof FileInterface) {
0 ignored issues
show
introduced by
$asset is always a sub-type of Platine\Filesystem\FileInterface.
Loading history...
340
            $this->publishFile($asset, $dest);
341
        }
342
343
        $writer->boldGreen(
344
            sprintf(
345
                'Package %s [%s] publish successfully',
346
                $type,
347
                $src
348
            ),
349
            true
350
        );
351
    }
352
353
    /**
354
     * Copy file to the destination
355
     * @param FileInterface $file
356
     * @param string $dest
357
     * @return void
358
     */
359
    protected function publishFile(FileInterface $file, string $dest): void
360
    {
361
        $sourceFilename = $file->getName();
362
        $destFile = $this->filesystem->file(
363
            $dest . $sourceFilename
364
        );
365
366
        $overwrite = $this->getOptionValue('overwrite');
367
368
        $writer = $this->io()->writer();
369
        if ($destFile->exists() && !$overwrite) {
370
            $writer->red(sprintf(
371
                "File \n[%s]\n already exist, if you want to overwrite"
372
                    . ' use option "--overwrite".',
373
                $destFile->getPath()
374
            ), true);
375
        } else {
376
            $file->copyTo($dest);
377
        }
378
    }
379
380
    /**
381
     * Publish directory
382
     * @param DirectoryInterface $directory
383
     * @param string $dest
384
     * @return void
385
     */
386
    protected function publishDirectory(DirectoryInterface $directory, string $dest): void
387
    {
388
        foreach ($directory->read() as $item) {
389
            $item->copyTo($dest);
390
        }
391
    }
392
393
    /**
394
     * Return the information for given package
395
     * @param string $name
396
     * @return array<string, mixed>
397
     */
398
    protected function getPackageInfo(string $name): array
399
    {
400
        $packages = Composer::parseLockFile($this->application->getRootPath());
401
        foreach ($packages as $package) {
402
            $packageName = $package['name'] ?? '';
403
            if ($name === $packageName) {
404
                return $package;
405
            }
406
        }
407
408
        return [];
409
    }
410
}
411