Passed
Push — master ( f54e31...ad3cee )
by Thierry
09:31 queued 04:37
created

Generator::getJsLibUri()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Generator.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
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
14
15
namespace Jaxon\Plugin\Code;
16
17
use Jaxon\Utils\Template\Engine as TemplateEngine;
18
use Jaxon\Utils\Http\URI;
19
20
use Jaxon\Plugin\Code\Contracts\Generator as GeneratorContract;
21
22
class Generator
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class Generator
Loading history...
23
{
24
    use \Jaxon\Features\Config;
25
    use \Jaxon\Features\Minifier;
26
27
    /**
28
     * The response type.
29
     *
30
     * @var string
31
     */
32
    const RESPONSE_TYPE = 'JSON';
33
34
    /**
35
     * The objects that generate code
36
     *
37
     * @var array<GeneratorContract>
38
     */
39
    protected $aGenerators = [];
40
41
    /**
42
     * The Jaxon template engine
43
     *
44
     * @var TemplateEngine
45
     */
46
    protected $xTemplateEngine;
47
48
    /**
49
     * HTML tags to include CSS code and files into the page
50
     *
51
     * @var string
52
     */
53
    protected $sCssCode = '';
54
55
    /**
56
     * HTML tags to include javascript code and files into the page
57
     *
58
     * @var string
59
     */
60
    protected $sJsCode = '';
61
62
    /**
63
     * Javascript code to include into the page
64
     *
65
     * @var string
66
     */
67
    protected $sJsScript = '';
68
69
    /**
70
     * Javascript code to execute after page load
71
     *
72
     * @var string
73
     */
74
    protected $sJsReadyScript = '';
75
76
    /**
77
     * Code already generated
78
     *
79
     * @var boolean
80
     */
81
    protected $sCodeGenerated = false;
82
83
    /**
84
     * Default library URL
85
     *
86
     * @var string
87
     */
88
    protected $sJsLibraryUrl = 'https://cdn.jsdelivr.net/gh/jaxon-php/[email protected]/dist';
89
90
    /**
91
     * The constructor
92
     *
93
     * @param TemplateEngine        $xTemplateEngine      The template engine
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 6 found
Loading history...
94
     */
95
    public function __construct(TemplateEngine $xTemplateEngine)
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 1 found
Loading history...
96
    {
97
        $this->xTemplateEngine = $xTemplateEngine;
98
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
99
100
    /**
101
     * Add a new generator to the list
102
     *
103
     * @param GeneratorContract     $xGenerator     The code generator
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 5 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 5 found
Loading history...
104
     * @param integer               $nPriority      The desired priority, used to order the plugins
0 ignored issues
show
Coding Style introduced by
Expected 11 spaces after parameter type; 15 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 6 found
Loading history...
105
     *
106
     * @return void
107
     */
108
    public function addGenerator(GeneratorContract $xGenerator, $nPriority)
109
    {
110
        while(isset($this->aGenerators[$nPriority]))
111
        {
112
            $nPriority++;
113
        }
114
        $this->aGenerators[$nPriority] = $xGenerator;
115
        // Sort the array by ascending keys
116
        ksort($this->aGenerators);
117
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
118
119
    /**
120
     * Generate a hash for all the javascript code generated by the library
121
     *
122
     * @return string
123
     */
124
    private function getHash()
125
    {
126
        $sHash = jaxon()->getVersion();
127
        foreach($this->aGenerators as $xGenerator)
128
        {
129
            $sHash .= $xGenerator->getHash();
130
        }
131
        return md5($sHash);
132
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
133
134
    /**
135
     * Get the HTML tags to include Jaxon javascript files into the page
136
     *
137
     * @return void
138
     */
139
    private function generateCode()
140
    {
141
        if($this->sCodeGenerated)
142
        {
143
            return;
144
        }
145
        $this->sCodeGenerated = true;
146
147
        foreach($this->aGenerators as $xGenerator)
148
        {
149
            if(($sCssCode = $xGenerator->getCss()))
0 ignored issues
show
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
150
            {
151
                $this->sCssCode .= rtrim($sCssCode, " \n") . "\n";
152
            }
153
            if(($sJsCode = $xGenerator->getJs()))
0 ignored issues
show
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
154
            {
155
                $this->sJsCode .= rtrim($sJsCode, " \n") . "\n";
156
            }
157
            if(($sJsScript = $xGenerator->getScript()))
0 ignored issues
show
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
158
            {
159
                $this->sJsScript .= rtrim($sJsScript, " \n") . "\n";
160
            }
161
            if(($sJsReadyScript = $xGenerator->getReadyScript()))
0 ignored issues
show
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
162
            {
163
                $this->sJsReadyScript .= rtrim($sJsReadyScript, " \n") . "\n";
164
            }
165
        }
166
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
167
168
    /**
169
     * Get the base URI of the Jaxon library javascript files
170
     *
171
     * @return string
172
     */
173
    private function getJsLibUri()
174
    {
175
        return rtrim($this->getOption('js.lib.uri', $this->sJsLibraryUrl), '/') . '/';
176
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
177
178
    /**
179
     * Get the extension of the Jaxon library javascript files
180
     *
181
     * The returned string is '.min.js' if the files are minified.
182
     *
183
     * @return string
184
     */
185
    private function getJsLibExt()
186
    {
187
        if(($this->getOption('js.app.minify')))
188
        {
189
            return '.min.js';
190
        }
191
        return '.js';
192
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
193
194
    /**
195
     * Check if the javascript code generated by Jaxon can be exported to an external file
196
     *
197
     * @return boolean
198
     */
199
    public function canExportJavascript()
200
    {
201
        // Check config options
202
        // - The js.app.export option must be set to true
203
        // - The js.app.uri and js.app.dir options must be set to non null values
204
        if(!$this->getOption('js.app.export') ||
205
            !$this->getOption('js.app.uri') ||
206
            !$this->getOption('js.app.dir'))
207
        {
208
            return false;
209
        }
210
        // Check dir access
211
        // - The js.app.dir must be writable
212
        $sJsAppDir = $this->getOption('js.app.dir');
213
        if(!is_dir($sJsAppDir) || !is_writable($sJsAppDir))
214
        {
215
            return false;
216
        }
217
        return true;
218
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
219
220
    /**
221
     * Get the HTML tags to include Jaxon javascript files into the page
222
     *
223
     * @return string
224
     */
225
    public function getJs()
226
    {
227
        $sJsLibUri = $this->getJsLibUri();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 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...
228
        $sJsLibExt = $this->getJsLibExt();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 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...
229
        $sJsCoreUrl = $sJsLibUri . 'jaxon.core' . $sJsLibExt;
1 ignored issue
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 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...
230
        $sJsDebugUrl = $sJsLibUri . 'jaxon.debug' . $sJsLibExt;
231
        // $sJsVerboseUrl = $sJsLibUri . 'jaxon.verbose' . $sJsLibExt;
232
        $sJsLanguageUrl = $sJsLibUri . 'lang/jaxon.' . $this->getOption('core.language') . $sJsLibExt;
233
234
        // Add component files to the javascript file array;
235
        $aJsFiles = [$sJsCoreUrl];
236
        if($this->getOption('core.debug.on'))
237
        {
238
            $aJsFiles[] = $sJsDebugUrl;
239
            $aJsFiles[] = $sJsLanguageUrl;
240
            /*if($this->getOption('core.debug.verbose'))
0 ignored issues
show
Coding Style introduced by
Block comment text must start on a new line
Loading history...
241
            {
242
                $aJsFiles[] = $sJsVerboseUrl;
243
            }*/
244
        }
245
246
        // Set the template engine cache dir
247
        $this->generateCode();
248
249
        return $this->xTemplateEngine->render('jaxon::plugins/includes.js', [
250
            'sJsOptions' => $this->getOption('js.app.options', ''),
251
            'aUrls' => $aJsFiles,
252
        ]) . $this->sJsCode;
253
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
254
255
    /**
256
     * Get the HTML tags to include Jaxon CSS code and files into the page
257
     *
258
     * @return string
259
     */
260
    public function getCss()
261
    {
262
        // Set the template engine cache dir
263
        $this->generateCode();
264
265
        return $this->sCssCode;
266
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
267
268
    /**
269
     * Get the correspondances between previous and current config options
270
     *
271
     * They are used to keep the deprecated config options working.
272
     * They will be removed when the deprecated options will lot be supported anymore.
273
     *
274
     * @return array
275
     */
276
    private function getOptionVars()
277
    {
278
        return [
279
            'sResponseType'             => self::RESPONSE_TYPE,
280
            'sVersion'                  => $this->getOption('core.version'),
281
            'sLanguage'                 => $this->getOption('core.language'),
282
            'bLanguage'                 => $this->hasOption('core.language') ? true : false,
283
            'sRequestURI'               => $this->getOption('core.request.uri'),
284
            'sDefaultMode'              => $this->getOption('core.request.mode'),
285
            'sDefaultMethod'            => $this->getOption('core.request.method'),
286
            'sCsrfMetaName'             => $this->getOption('core.request.csrf_meta'),
287
            'bDebug'                    => $this->getOption('core.debug.on'),
288
            'bVerboseDebug'             => $this->getOption('core.debug.verbose'),
289
            'sDebugOutputID'            => $this->getOption('core.debug.output_id'),
290
            'nResponseQueueSize'        => $this->getOption('js.lib.queue_size'),
291
            'sStatusMessages'           => $this->getOption('js.lib.show_status') ? 'true' : 'false',
292
            'sWaitCursor'               => $this->getOption('js.lib.show_cursor') ? 'true' : 'false',
293
            'sDefer'                    => $this->getOption('js.app.options', ''),
294
        ];
295
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
296
297
    /**
298
     * Get the javascript code to be sent to the browser
299
     *
300
     * @return string
301
     */
302
    private function _getScript()
303
    {
304
        $aVars = $this->getOptionVars();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 20 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...
305
        $sYesScript = 'jaxon.ajax.response.process(command.response)';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 15 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...
306
        $sNoScript = 'jaxon.confirm.skip(command);jaxon.ajax.response.process(command.response)';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 16 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...
307
        $sQuestionScript = jaxon()->dialog()->confirm('msg', $sYesScript, $sNoScript);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 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...
308
        $aVars['sQuestionScript'] = $this->xTemplateEngine->render('jaxon::plugins/confirm.js', [
309
            'sQuestionScript' => $sQuestionScript,
310
        ]);
311
312
        return $this->xTemplateEngine->render('jaxon::plugins/config.js', $aVars) . '
313
' . $this->sJsScript . '
314
jaxon.dom.ready(function() {
315
    jaxon.command.handler.register("cc", jaxon.confirm.commands);
316
317
' . $this->sJsReadyScript . '
318
});
319
';
320
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
321
322
    /**
323
     * Write javascript files and return the corresponding URI
324
     *
325
     * @return string
326
     */
327
    private function _writeFiles()
328
    {
329
        $sJsAppURI = rtrim($this->getOption('js.app.uri'), '/') . '/';
1 ignored issue
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 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...
330
        $sJsAppDir = rtrim($this->getOption('js.app.dir'), '/') . '/';
1 ignored issue
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 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...
331
        $sFinalFile = $this->getOption('js.app.file');
332
        $sExtension = $this->getJsLibExt();
333
334
        // Check if the final file already exists
335
        if(($sFinalFile) && is_file($sJsAppDir . $sFinalFile . $sExtension))
336
        {
337
            return $sJsAppURI . $sFinalFile . $sExtension;
338
        }
339
340
        // The plugins scripts are written into the javascript app dir
341
        $sHash = $this->getHash();
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...
342
        $sOutFile = $sHash . '.js';
343
        $sMinFile = $sHash . '.min.js';
344
        if(!is_file($sJsAppDir . $sOutFile))
345
        {
346
            file_put_contents($sJsAppDir . $sOutFile, $this->_getScript());
347
        }
348
        if(($this->getOption('js.app.minify')))
349
        {
350
            if(is_file($sJsAppDir . $sMinFile))
351
            {
352
                $sOutFile = $sMinFile; // The file was already minified
353
            }
354
            elseif(($this->minify($sJsAppDir . $sOutFile, $sJsAppDir . $sMinFile)))
355
            {
356
                $sOutFile = $sMinFile;
357
            }
358
        }
359
        // Copy the file to its final location
360
        if(($sFinalFile))
361
        {
362
            if(copy($sJsAppDir . $sOutFile, $sJsAppDir . $sFinalFile . $sExtension))
363
            {
364
                $sOutFile = $sFinalFile . $sExtension;
365
            }
366
        }
367
368
        return $sJsAppURI . $sOutFile;
369
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
370
371
    /**
372
     * Get the javascript code to be sent to the browser
373
     *
374
     * Also call each of the request plugins giving them the opportunity
375
     * to output some javascript to the page being generated.
376
     * This is called only when the page is being loaded initially.
377
     * This is not called when processing a request.
378
     *
379
     * @param boolean        $bIncludeJs            Also get the JS files
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 12 found
Loading history...
380
     * @param boolean        $bIncludeCss        Also get the CSS files
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 8 found
Loading history...
381
     *
382
     * @return string
383
     */
384
    public function getScript($bIncludeJs, $bIncludeCss)
385
    {
386
        if(!$this->getOption('core.request.uri'))
387
        {
388
            $this->setOption('core.request.uri', jaxon()->di()->get(URI::class)->detect());
389
        }
390
391
        // Set the template engine cache dir
392
        $this->generateCode();
393
394
        $sScript = '';
395
        if(($bIncludeCss))
396
        {
397
            $sScript .= $this->getCss() . "\n";
398
        }
399
        if(($bIncludeJs))
400
        {
401
            $sScript .= $this->getJs() . "\n";
402
        }
403
404
        if($this->canExportJavascript())
405
        {
406
            // The returned code loads the generated javascript file
407
            return $sScript . $this->xTemplateEngine->render('jaxon::plugins/include.js', [
408
                'sJsOptions' => $this->getOption('js.app.options', ''),
409
                'sUrl' => $this->_writeFiles(),
410
            ]);
411
        }
412
413
        // The plugins scripts are wrapped with javascript tags
414
        return $sScript . $this->xTemplateEngine->render('jaxon::plugins/wrapper.js', [
415
            'sJsOptions' => $this->getOption('js.app.options', ''),
416
            'sScript' => $this->_getScript(),
417
        ]);
418
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
419
}
420