BlocksCreateTask   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 204
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 93
c 2
b 1
f 0
dl 0
loc 204
rs 10
wmc 25

7 Methods

Rating   Name   Duplication   Size   Complexity  
A createStyles() 0 21 2
A getScssFolder() 0 8 3
B run() 0 52 9
A getThemeDir() 0 15 4
A createBlockClass() 0 61 4
A isAdminTheme() 0 8 2
A migrateFromOldClass() 0 6 1
1
<?php
2
3
namespace LeKoala\Blocks;
4
5
use Exception;
6
use SilverStripe\ORM\DB;
7
use LeKoala\Blocks\Block;
8
use LeKoala\Blocks\BlocksPage;
9
use SilverStripe\Dev\BuildTask;
10
use SilverStripe\View\SSViewer;
11
use SilverStripe\Control\Director;
12
13
/**
14
 * Assist in building blocks for your website
15
 *
16
 * @author lekoala
17
 */
18
class BlocksCreateTask extends BuildTask
19
{
20
    protected $title = "Create Blocks";
21
    protected $description = 'Create block classes and styles based on your templates.';
22
    private static $segment = 'BlocksCreateTask';
0 ignored issues
show
introduced by
The private property $segment is not used, and could be removed.
Loading history...
23
24
    public function run($request)
25
    {
26
        $themeBlocksPath = Director::baseFolder() . DIRECTORY_SEPARATOR . $this->getThemeDir() . '/templates/Blocks';
27
        $mysiteBlocksPath = Director::baseFolder() . DIRECTORY_SEPARATOR . project() . '/templates/Blocks';
28
29
        $classes = Block::listTemplates();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $classes is correct as LeKoala\Blocks\Block::listTemplates() targeting LeKoala\Blocks\Block::listTemplates() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
30
31
        $files = [];
32
        $files = array_merge($files, glob($themeBlocksPath . '/*.ss'));
33
        $files = array_merge($files, glob($mysiteBlocksPath . '/*.ss'));
34
35
        if (empty($files)) {
36
            $this->message("No blocks found");
0 ignored issues
show
Bug introduced by
The method message() does not exist on LeKoala\Blocks\BlocksCreateTask. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

36
            $this->/** @scrutinizer ignore-call */ 
37
                   message("No blocks found");
Loading history...
37
            $this->message("Please make sure you have blocks in $themeBlocksPath or in $mysiteBlocksPath");
38
        }
39
40
        $classCreated = false;
41
        $allBlocks = [];
42
        $scssDir = dirname($this->getScssFolder(true));
43
44
        foreach ($files as $file) {
45
            $content = file_get_contents($file);
46
47
            // Check for lost $Content variable
48
            if (strpos($content, '$Content') !== false) {
49
                throw new Exception("Blocks cannot nest Content");
50
            }
51
52
            $result = $this->createBlockClass($file, $classes);
53
            if ($result) {
54
                $classCreated = true;
55
            }
56
            if (is_dir($scssDir)) {
57
                $result = $this->createStyles($file);
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
58
            }
59
            $allBlocks[] = pathinfo($file, PATHINFO_FILENAME);
60
        }
61
62
63
        if (is_dir($scssDir)) {
64
            $this->message("Refresh all styles");
65
            $scssFile = $scssDir . '/_blocks.scss';
66
            $data = '/* This file is automatically generated */' . "\n";
67
            foreach ($allBlocks as $blockName) {
68
                $data .= '@import "blocks/' . $blockName . '";' . "\n";
69
            }
70
            file_put_contents($scssFile, $data);
71
        }
72
73
        // A new class was added, regenerate the manifest
74
        if ($classCreated) {
75
            $this->regenerateClassManifest();
0 ignored issues
show
Bug introduced by
The method regenerateClassManifest() does not exist on LeKoala\Blocks\BlocksCreateTask. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

75
            $this->/** @scrutinizer ignore-call */ 
76
                   regenerateClassManifest();
Loading history...
76
        }
77
    }
78
79
    public static function migrateFromOldClass()
80
    {
81
        DB::prepared_query("UPDATE Block SET ClassName = ?", [Block::class]);
82
        DB::prepared_query("UPDATE SiteTree SET ClassName = ? WHERE ClassName = ? OR ClassName = '' OR ClassName = 0", [BlocksPage::class, "LeKoala\\Base\\Blocks\\BlocksPage"]);
83
        DB::prepared_query("UPDATE SiteTree_Live SET ClassName = ? WHERE ClassName = ? OR ClassName = '' OR ClassName = 0", [BlocksPage::class, "LeKoala\\Base\\Blocks\\BlocksPage"]);
84
        DB::prepared_query("UPDATE SiteTree_Versions SET ClassName = ? WHERE ClassName = ? OR ClassName = '' OR ClassName = 0", [BlocksPage::class, "LeKoala\\Base\\Blocks\\BlocksPage"]);
85
    }
86
87
    /**
88
     * @param boolean $createBase
89
     * @return string
90
     */
91
    protected function getScssFolder($createBase = false)
0 ignored issues
show
Unused Code introduced by
The parameter $createBase is not used and could be removed. ( Ignorable by Annotation )

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

91
    protected function getScssFolder(/** @scrutinizer ignore-unused */ $createBase = false)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
92
    {
93
        $base =  Director::baseFolder() . DIRECTORY_SEPARATOR . $this->getThemeDir() . '/sass';
94
        // We have a sass dir but no blocks folder
95
        if (is_dir($base) && !is_dir($base . '/blocks')) {
96
            mkdir($base . '/blocks', 0755);
97
        }
98
        return $base . '/blocks';
99
    }
100
101
    protected function createStyles($file)
102
    {
103
        $name = pathinfo($file, PATHINFO_FILENAME);
104
        $scssBlocksPath = $this->getScssFolder();
105
106
        $scssFile = $scssBlocksPath . '/_' . $name . '.scss';
0 ignored issues
show
Bug introduced by
Are you sure $name of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

106
        $scssFile = $scssBlocksPath . '/_' . /** @scrutinizer ignore-type */ $name . '.scss';
Loading history...
107
        if (is_file($scssFile)) {
108
            $this->message("Skip styles for $name");
109
            return false;
110
        }
111
112
        $this->message("Creating styles for $name", "created");
113
114
        $data = <<<SCSS
115
.Block-$name {
116
117
}
118
SCSS;
119
        file_put_contents($scssFile, $data);
120
121
        return true;
122
    }
123
124
    protected function createBlockClass($file, $classes)
125
    {
126
        $name = pathinfo($file, PATHINFO_FILENAME);
127
        if (isset($classes[$name])) {
128
            $this->message("Skip block $name");
129
            return false;
130
        }
131
        $this->message("Creating block $name", "created");
132
133
        $baseFolder = 'mysite/code';
134
        if (project() == 'app') {
135
            $baseFolder = 'app/src';
136
        }
137
        $mysite = Director::baseFolder() . DIRECTORY_SEPARATOR . $baseFolder . '/Blocks';
138
        if (!is_dir($mysite)) {
139
            mkdir($mysite);
140
        }
141
142
        $filename = $mysite . DIRECTORY_SEPARATOR . $name . '.php';
0 ignored issues
show
Bug introduced by
Are you sure $name of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

142
        $filename = $mysite . DIRECTORY_SEPARATOR . /** @scrutinizer ignore-type */ $name . '.php';
Loading history...
143
144
        $data = <<<PHP
145
<?php
146
147
use LeKoala\Blocks\BaseBlock;
148
use LeKoala\Blocks\BlockFieldList;
149
150
/**
151
 * $name block
152
 */
153
class $name extends BaseBlock
154
{
155
    public function updateFields(BlockFieldList \$fields)
156
    {
157
        //\$fields->removeByName('Image');
158
        \$fields->addText('Title');
159
    }
160
161
    /**
162
     * Extra data to feed to the template
163
     * @return array
164
     */
165
    public function ExtraData()
166
    {
167
        return [];
168
    }
169
170
    public function Collection()
171
    {
172
        return false;
173
    }
174
175
    public function SharedCollection()
176
    {
177
        return false;
178
    }
179
}
180
181
PHP;
182
        \file_put_contents($filename, $data);
183
184
        return true;
185
    }
186
187
    /**
188
     * Get current theme dir (regardless of current theme set)
189
     *
190
     * This will work in admin for instance
191
     *
192
     * @return string
193
     */
194
    public function getThemeDir()
195
    {
196
        // $themes = SSViewer::config()->uninherited('themes');
197
        $themes = SSViewer::config()->themes;
198
        if (!$themes) {
199
            $themes = SSViewer::get_themes();
200
        }
201
        if ($themes) {
202
            do {
203
                $mainTheme = array_shift($themes);
204
            } while (strpos($mainTheme, '$') === 0);
205
206
            return 'themes/' . $mainTheme;
207
        }
208
        return project();
209
    }
210
211
    /**
212
     * @return boolean
213
     */
214
    public function isAdminTheme()
215
    {
216
        $themes = SSViewer::get_themes();
217
        if (empty($themes)) {
218
            return false;
219
        }
220
        $theme = $themes[0];
221
        return strpos($theme, 'silverstripe/admin') === 0;
222
    }
223
}
224