CodeGenerator   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 287
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 24
eloc 73
c 4
b 0
f 0
dl 0
loc 287
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A renderCodes() 0 18 3
A render() 0 4 1
A getHash() 0 5 1
A generatePluginCodes() 0 16 5
A addCodeGenerator() 0 7 2
A getJsScript() 0 3 1
A getJs() 0 4 1
A getCss() 0 4 1
A generateCodes() 0 42 4
A getScript() 0 20 4
1
<?php
2
3
/**
4
 * CodeGenerator.php - Jaxon code generator
5
 *
6
 * Generate HTML, CSS and Javascript code for Jaxon.
7
 *
8
 * @package jaxon-core
0 ignored issues
show
Coding Style introduced by
Package name "jaxon-core" is not valid; consider "Jaxoncore" instead
Loading history...
9
 * @author Thierry Feuzeu <[email protected]>
10
 * @copyright 2016 Thierry Feuzeu <[email protected]>
11
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
12
 * @link https://github.com/jaxon-php/jaxon-core
13
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
PHP version not specified
Loading history...
14
15
namespace Jaxon\Plugin\Code;
16
17
use Jaxon\Di\Container;
18
use Jaxon\Plugin\Plugin;
19
use Jaxon\Utils\Http\UriException;
20
use Jaxon\Utils\Template\TemplateEngine;
21
22
use function array_reduce;
23
use function is_subclass_of;
24
use function ksort;
25
use function md5;
26
use function trim;
27
28
class CodeGenerator
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class CodeGenerator
Loading history...
29
{
30
    /**
31
     * @var string
32
     */
33
    private $sVersion;
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line(s) before first member var; 0 found
Loading history...
34
35
    /**
36
     * @var Container
37
     */
38
    private $di;
39
40
    /**
41
     * The Jaxon template engine
42
     *
43
     * @var TemplateEngine
44
     */
45
    protected $xTemplateEngine;
46
47
    /**
48
     * @var AssetManager
49
     */
50
    private $xAssetManager;
51
52
    /**
53
     * The classes that generate code
54
     *
55
     * @var array<string>
56
     */
57
    protected $aCodeGenerators = [];
58
59
    /**
60
     * @var string
61
     */
62
    protected $sJsOptions;
63
64
    /**
65
     * @var string
66
     */
67
    protected $sCss = '';
68
69
    /**
70
     * @var string
71
     */
72
    protected $sJs = '';
73
74
    /**
75
     * @var string
76
     */
77
    protected $sJsScript = '';
78
79
    /**
80
     * @var string
81
     */
82
    protected $sJsReadyScript = '';
83
84
    /**
85
     * @var string
86
     */
87
    protected $sJsInlineScript = '';
88
89
    /**
90
     * @var string
91
     */
92
    protected $bGenerated = false;
93
94
    /**
95
     * The constructor
96
     *
97
     * @param string $sVersion
0 ignored issues
show
Coding Style introduced by
Expected 9 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
98
     * @param Container $di
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 6 spaces after parameter type; 1 found
Loading history...
99
     * @param TemplateEngine $xTemplateEngine
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
100
     */
101
    public function __construct(string $sVersion, Container $di, TemplateEngine $xTemplateEngine)
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 1 found
Loading history...
102
    {
103
        $this->sVersion = $sVersion;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
104
        $this->di = $di;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 14 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
105
        $this->xTemplateEngine = $xTemplateEngine;
106
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
107
108
    /**
109
     * Add a code generator to the list
110
     *
111
     * @param string $sClassName    The code generator class
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
112
     * @param int $nPriority    The desired priority, used to order the plugins
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 4 found
Loading history...
113
     *
114
     * @return void
115
     */
116
    public function addCodeGenerator(string $sClassName, int $nPriority)
117
    {
118
        while(isset($this->aCodeGenerators[$nPriority]))
119
        {
120
            $nPriority++;
121
        }
122
        $this->aCodeGenerators[$nPriority] = $sClassName;
123
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
124
125
    /**
126
     * Generate a hash for all the javascript code generated by the library
127
     *
128
     * @return string
129
     */
130
    public function getHash(): string
131
    {
132
        return md5(array_reduce($this->aCodeGenerators, function($sHash, $sClassName) {
133
            return $sHash . $this->di->g($sClassName)->getHash();
134
        }, $this->sVersion));
135
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
136
137
    /**
138
     * Render a template in the 'plugins' subdir
139
     *
140
     * @param string $sTemplate    The template filename
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
141
     * @param array $aVars    The template variables
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 5 spaces after parameter name; 4 found
Loading history...
142
     *
143
     * @return string
144
     */
145
    private function render(string $sTemplate, array $aVars = []): string
146
    {
147
        $aVars['sJsOptions'] = $this->sJsOptions;
148
        return $this->xTemplateEngine->render("jaxon::plugins/$sTemplate", $aVars);
149
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
150
151
    /**
152
     * Generate the Jaxon CSS and js codes for a given plugin
153
     *
154
     * @param string $sClassName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
155
     *
156
     * @return void
157
     */
158
    private function generatePluginCodes(string $sClassName)
159
    {
160
        $xGenerator = $this->di->g($sClassName);
161
        if(!is_subclass_of($xGenerator, Plugin::class) || $this->xAssetManager->shallIncludeAssets($xGenerator))
162
        {
163
            // HTML tags for CSS
164
            $this->sCss = trim($this->sCss) . "\n" . trim($xGenerator->getCss(), " \n");
165
            // HTML tags for js
166
            $this->sJs = trim($this->sJs) . "\n" . trim($xGenerator->getJs(), " \n");
167
        }
168
        // Javascript code
169
        $this->sJsScript = trim($this->sJsScript) . "\n\n" . trim($xGenerator->getScript(), " \n");
170
        if($xGenerator->readyEnabled())
171
        {
172
            $sScriptAttr = $xGenerator->readyInlined() ? 'sJsInlineScript' : 'sJsReadyScript';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
173
            $this->$sScriptAttr = trim($this->$sScriptAttr) . "\n\n" . trim($xGenerator->getReadyScript(), " \n");
174
        }
175
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
176
177
    /**
178
     * Render the generated CSS ans js codes
179
     *
180
     * @return void
181
     */
182
    private function renderCodes()
183
    {
184
        $this->sCss = trim($this->sCss, " \n");
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 12 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
185
        $this->sJs = trim($this->sJs, " \n");
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 13 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
186
        $this->sJsScript = trim($this->sJsScript, " \n");
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
187
        $this->sJsReadyScript = trim($this->sJsReadyScript, " \n");
188
        $this->sJsInlineScript = trim($this->sJsInlineScript, " \n");
189
        if(($this->sJsReadyScript))
190
        {
191
            $this->sJsReadyScript = $this->render('ready.js', ['sScript' => $this->sJsReadyScript . "\n"]);
192
        }
193
        if(($this->sJsInlineScript))
194
        {
195
            $this->sJsInlineScript = $this->render('ready.js', ['sScript' => $this->sJsInlineScript . "\n"]);
196
        }
197
        // Prepend Jaxon javascript files to HTML tags for Js
198
        $aJsFiles = $this->xAssetManager->getJsLibFiles();
199
        $this->sJs = trim($this->render('includes.js', ['aUrls' => $aJsFiles])) . "\n\n" . $this->sJs;
200
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
201
202
    /**
203
     * Generate the Jaxon CSS ans js codes
204
     *
205
     * @return void
206
     * @throws UriException
207
     */
208
    private function generateCodes()
209
    {
210
        if($this->bGenerated)
211
        {
212
            return;
213
        }
214
215
        // Sort the code generators by ascending priority
216
        ksort($this->aCodeGenerators);
217
218
        $this->xAssetManager = $this->di->getAssetManager();
219
        $this->sJsOptions = $this->xAssetManager->getJsOptions();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
220
        foreach($this->aCodeGenerators as $sClassName)
221
        {
222
            $this->generatePluginCodes($sClassName);
223
        }
224
        $this->renderCodes();
225
226
        $sJsConfigVars = $this->render('config.js', $this->xAssetManager->getOptionVars());
227
        // These three parts are always rendered together
228
        $this->sJsScript = trim($sJsConfigVars) . "\n\n" .
229
            trim($this->sJsScript) . "\n\n" . trim($this->sJsReadyScript);
230
        // For js lib versions prior to 4.0, register the redirect command.
231
        $sJsLibVersion = $this->di->getJsLibVersion();
232
        if((int)$sJsLibVersion[0] < 4)
233
        {
234
            $this->sJsScript .= '
235
236
    jaxon.command.handler.register("rd", (command) => {
237
        const { data: sUrl, delay: nDelay } = command;
238
        if (nDelay <= 0) {
239
            window.location = sUrl;
240
            return true;
241
        }
242
        window.setTimeout(() => window.location = sUrl, nDelay * 1000);
243
        return true;
244
    });
245
';
246
        }
247
248
        // The codes are already generated.
249
        $this->bGenerated = true;
0 ignored issues
show
Documentation Bug introduced by
The property $bGenerated was declared of type string, but true is of type true. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
250
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
251
252
    /**
253
     * Get the HTML tags to include Jaxon CSS code and files into the page
254
     *
255
     * @return string
256
     * @throws UriException
257
     */
258
    public function getCss(): string
259
    {
260
        $this->generateCodes();
261
        return $this->sCss;
262
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
263
264
    /**
265
     * Get the HTML tags to include Jaxon javascript files into the page
266
     *
267
     * @return string
268
     * @throws UriException
269
     */
270
    public function getJs(): string
271
    {
272
        $this->generateCodes();
273
        return $this->sJs;
274
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
275
276
    /**
277
     * Get the generated javascript code
278
     *
279
     * @return string
280
     */
281
    public function getJsScript(): string
282
    {
283
        return $this->sJsScript;
284
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
285
286
    /**
287
     * Get the javascript code to be sent to the browser
288
     *
289
     * @param bool $bIncludeJs Also get the JS files
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
290
     * @param bool $bIncludeCss Also get the CSS files
291
     *
292
     * @return string
293
     * @throws UriException
294
     */
295
    public function getScript(bool $bIncludeJs, bool $bIncludeCss): string
296
    {
297
        $this->generateCodes();
298
        $sScript = '';
299
        if(($bIncludeCss))
300
        {
301
            $sScript .= $this->getCss() . "\n";
302
        }
303
        if(($bIncludeJs))
304
        {
305
            $sScript .= $this->getJs() . "\n";
306
        }
307
308
        if(!($sUrl = $this->xAssetManager->createJsFiles($this)))
0 ignored issues
show
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
309
        {
310
            return trim($sScript) . "\n\n" . $this->render('wrapper.js',
311
                ['sScript' => trim($this->sJsScript) . "\n\n" . trim($this->sJsInlineScript)]);
312
        }
313
        return trim($sScript) . "\n\n" . trim($this->render('include.js', ['sUrl' => $sUrl])) .
314
            "\n\n" . $this->render('wrapper.js', ['sScript' => $this->sJsInlineScript]);
315
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
316
}
317