Passed
Push — dependabot/npm_and_yarn/docs/w... ( a770a9...3a5b31 )
by
unknown
07:47
created

GenerateBlocks::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
namespace A17\Twill\Commands;
4
5
use Illuminate\Console\Command;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, A17\Twill\Commands\Command. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use Illuminate\Filesystem\Filesystem;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Str;
9
use Illuminate\View\Factory as ViewFactory;
10
11
class GenerateBlocks extends Command
12
{
13
    const NO_BLOCKS_DEFINED = "There are no blocks defined yet. Please refer to https://twill.io/docs/#block-editor-3 in order to create blocks.";
14
    const SCANNING_BLOCKS = "Starting to scan block views directory...";
15
16
    /**
17
     * The name and signature of the console command.
18
     *
19
     * @var string
20
     */
21
    protected $signature = 'twill:blocks';
22
23
    /**
24
     * The console command description.
25
     *
26
     * @var string
27
     */
28
    protected $description = "Generate blocks as single file Vue components from blade views";
29
30
    /**
31
     * @var Filesystem
32
     */
33
    protected $filesystem;
34
35
    /**
36
     * @var ViewFactory
37
     */
38
    protected $viewFactory;
39
40
    /**
41
     * @param Filesystem $filesystem
42
     * @param ViewFactory $viewFactory
43
     */
44 69
    public function __construct(Filesystem $filesystem, ViewFactory $viewFactory)
45
    {
46 69
        parent::__construct();
47
48 69
        $this->filesystem = $filesystem;
49 69
        $this->viewFactory = $viewFactory;
50 69
    }
51
52
    /**
53
     * Executes the console command.
54
     *
55
     * @return mixed
56
     */
57
    public function handle()
58
    {
59
        if (!$this->filesystem->exists($path = resource_path('views/admin/blocks'))) {
60
            $this->error(self::NO_BLOCKS_DEFINED);
61
62
            return;
63
        }
64
65
        $this->info(self::SCANNING_BLOCKS);
66
67
        Collection::make($this->filesystem->files($path))->each(function ($viewFile) {
68
            $blockName = $viewFile->getBasename('.blade.php');
69
70
            $vueBlockTemplate = $this->viewFactory->make('admin.blocks.' . $blockName, ['renderForBlocks' => true])->render();
71
72
            $vueBlockContent = $this->viewFactory->make('twill::blocks.builder', [
73
                'render' => $this->sanitize($vueBlockTemplate),
0 ignored issues
show
Bug introduced by
It seems like $vueBlockTemplate can also be of type array; however, parameter $html of A17\Twill\Commands\GenerateBlocks::sanitize() 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

73
                'render' => $this->sanitize(/** @scrutinizer ignore-type */ $vueBlockTemplate),
Loading history...
74
            ])->render();
75
76
            $vueBlockPath = $this->makeDirectory(resource_path(config('twill.block_editor.custom_vue_blocks_resource_path', 'assets/js/blocks'))) . '/Block' . Str::title($blockName) . '.vue';
77
78
            $this->filesystem->put($vueBlockPath, $vueBlockContent);
0 ignored issues
show
Bug introduced by
It seems like $vueBlockContent can also be of type array; however, parameter $contents of Illuminate\Filesystem\Filesystem::put() 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

78
            $this->filesystem->put($vueBlockPath, /** @scrutinizer ignore-type */ $vueBlockContent);
Loading history...
79
80
            $this->info("Block " . Str::title($blockName) . " generated successfully");
81
        });
82
83
        $this->info("All blocks have been generated!");
84
    }
85
86
    /**
87
     * Recursively make a directory.
88
     *
89
     * @param string $directory
90
     * @return string
91
     */
92
    public function makeDirectory($directory)
93
    {
94
        if (!$this->filesystem->exists($directory)) {
95
            $this->filesystem->makeDirectory($directory, 0755, true);
96
        }
97
        return $directory;
98
    }
99
100
    /**
101
     * Sanitizes the given HTML code by removing redundant spaces and comments.
102
     *
103
     * @param string $html
104
     * @return string
105
     */
106
    private function sanitize($html)
107
    {
108
        $search = array(
109
            '/\>[^\S ]+/s', // strip whitespaces after tags, except space
110
            '/[^\S ]+\</s', // strip whitespaces before tags, except space
111
            '/(\s)+/s', // shorten multiple whitespace sequences
112
            '/<!--(.|\s)*?-->/', // Remove HTML comments
113
        );
114
115
        $replace = array(
116
            '>',
117
            '<',
118
            '\\1',
119
            '',
120
        );
121
122
        return preg_replace($search, $replace, $html);
123
    }
124
}
125