Passed
Push — master ( 56a418...cabf25 )
by Thierry
02:43
created

Generator::generateCode()   C

Complexity

Conditions 13
Paths 133

Size

Total Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
nc 133
nop 0
dl 0
loc 45
rs 6.3416
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Plugin\Code\Contracts\Generator as GeneratorContract;
18
use Jaxon\Utils\Template\Engine as TemplateEngine;
19
use Jaxon\Utils\Http\URI;
20
21
class Generator
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class Generator
Loading history...
22
{
23
    use \Jaxon\Features\Config;
24
    use \Jaxon\Features\Minifier;
25
26
    /**
27
     * Default library URL
28
     *
29
     * @var string
30
     */
31
    const JS_LIB_URL = 'https://cdn.jsdelivr.net/gh/jaxon-php/[email protected]/dist';
32
33
    /**
34
     * The objects that generate code
35
     *
36
     * @var array<GeneratorContract>
37
     */
38
    protected $aGenerators = [];
39
40
    /**
41
     * The Jaxon template engine
42
     *
43
     * @var TemplateEngine
44
     */
45
    protected $xTemplateEngine;
46
47
    /**
48
     * The constructor
49
     *
50
     * @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...
51
     */
52
    public function __construct(TemplateEngine $xTemplateEngine)
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 1 found
Loading history...
53
    {
54
        $this->xTemplateEngine = $xTemplateEngine;
55
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
56
57
    /**
58
     * Get the correspondances between previous and current config options
59
     *
60
     * They are used to keep the deprecated config options working.
61
     * They will be removed when the deprecated options will lot be supported anymore.
62
     *
63
     * @return array
64
     */
65
    private function getOptionVars()
66
    {
67
        return [
68
            'sResponseType'             => 'JSON',
69
            'sVersion'                  => $this->getOption('core.version'),
70
            'sLanguage'                 => $this->getOption('core.language'),
71
            'bLanguage'                 => $this->hasOption('core.language') ? true : false,
72
            'sRequestURI'               => $this->getOption('core.request.uri'),
73
            'sDefaultMode'              => $this->getOption('core.request.mode'),
74
            'sDefaultMethod'            => $this->getOption('core.request.method'),
75
            'sCsrfMetaName'             => $this->getOption('core.request.csrf_meta'),
76
            'bDebug'                    => $this->getOption('core.debug.on'),
77
            'bVerboseDebug'             => $this->getOption('core.debug.verbose'),
78
            'sDebugOutputID'            => $this->getOption('core.debug.output_id'),
79
            'nResponseQueueSize'        => $this->getOption('js.lib.queue_size'),
80
            'sStatusMessages'           => $this->getOption('js.lib.show_status') ? 'true' : 'false',
81
            'sWaitCursor'               => $this->getOption('js.lib.show_cursor') ? 'true' : 'false',
82
            'sDefer'                    => $this->getOption('js.app.options', ''),
83
        ];
84
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
85
86
    /**
87
     * Render a template in the 'plugins' subdir
88
     *
89
     * @param string    $sTemplate      The template filename
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 4 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 6 found
Loading history...
90
     * @param array     $aVars          The template variables
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 5 found
Loading history...
Coding Style introduced by
Expected 5 spaces after parameter name; 10 found
Loading history...
91
     *
92
     * @return string
93
     */
94
    private function _render($sTemplate, array $aVars = [])
95
    {
96
        $aVars['sJsOptions'] = $this->getOption('js.app.options', '');
97
        return $this->xTemplateEngine->render("jaxon::plugins/$sTemplate", $aVars);
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 CSS code and files into the page
136
     *
137
     * @return string
138
     */
139
    public function getCss()
140
    {
141
        $sCssCode = '';
142
        foreach($this->aGenerators as $xGenerator)
143
        {
144
            $sCssCode = rtrim($sCssCode, " \n") . "\n" . $xGenerator->getCss();
145
        }
146
        return rtrim($sCssCode, " \n") . "\n";
147
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
148
149
    /**
150
     * Get the HTML tags to include Jaxon javascript files into the page
151
     *
152
     * @return string
153
     */
154
    public function getJs()
155
    {
156
        $sJsExtension = $this->getOption('js.app.minify') ? '.min.js' : '.js';
157
158
        // The URI for the javascript library files
159
        $sJsLibUri = rtrim($this->getOption('js.lib.uri', self::JS_LIB_URL), '/') . '/';
160
        // Add component files to the javascript file array;
161
        $aJsFiles = [$sJsLibUri . 'jaxon.core' . $sJsExtension];
162
        if($this->getOption('core.debug.on'))
163
        {
164
            $sLanguage = $this->getOption('core.language');
165
            $aJsFiles[] = $sJsLibUri . 'jaxon.debug' . $sJsExtension;
166
            $aJsFiles[] = $sJsLibUri . 'lang/jaxon.' . $sLanguage . $sJsExtension;
167
            /*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...
168
            {
169
                $aJsFiles[] = $sJsLibUri . 'jaxon.verbose' . $sJsExtension;
170
            }*/
171
        }
172
        $sJsFiles = $this->_render('includes.js', ['aUrls' => $aJsFiles]);
173
174
        $sJsCode = '';
175
        foreach($this->aGenerators as $xGenerator)
176
        {
177
            $sJsCode = rtrim($sJsCode, " \n") . "\n" . $xGenerator->getJs();
178
        }
179
        return $sJsFiles . "\n" . rtrim($sJsCode, " \n") . "\n";
180
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
181
182
    /**
183
     * Get the javascript code to be sent to the browser
184
     *
185
     * @return string
186
     */
187
    private function _getScript()
188
    {
189
        $aConfigVars = $this->getOptionVars();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 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...
190
        $sYesScript = 'jaxon.ajax.response.process(command.response)';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 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...
191
        $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 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...
192
        $sQuestionScript = jaxon()->dialog()->confirm('msg', $sYesScript, $sNoScript);
193
194
        $aConfigVars['sQuestionScript'] = $this->_render('confirm.js', [
195
            'sQuestionScript' => $sQuestionScript,
196
        ]);
197
198
        $sScript = '';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 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...
199
        $sReadyScript = '';
200
        foreach($this->aGenerators as $xGenerator)
201
        {
202
            $sScript .= rtrim($xGenerator->getScript(), " \n") . "\n";
203
            if($xGenerator->readyEnabled() && !$xGenerator->readyInlined())
204
            {
205
                // Ready code which can nbe exported to an external file.
206
                $sReadyScript .= rtrim($xGenerator->getReadyScript(), " \n") . "\n";
207
            }
208
        }
209
210
        // These three parts are always rendered together
211
        return $this->_render('config.js', $aConfigVars) . "\n" . $sScript . "\n" .
212
            $this->_render('ready.js', ['sScript' => $sReadyScript]);
213
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
214
215
    /**
216
     * Get the javascript code to include directly in HTML
217
     *
218
     * @return string
219
     */
220
    private function _getInlineScript()
221
    {
222
        $sScript = '';
223
        foreach($this->aGenerators as $xGenerator)
224
        {
225
            if($xGenerator->readyEnabled() && $xGenerator->readyInlined())
226
            {
227
                // Ready code which must be inlined in HTML.
228
                $sScript .= rtrim($xGenerator->getReadyScript(), " \n") . "\n";
229
            }
230
        }
231
        return $this->_render('ready.js', ['sScript' => $sScript]);
232
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
233
234
    /**
235
     * Get the HTML tags to include Jaxon javascript files into the page
236
     *
237
     * @return void
238
     */
239
    private function getJsFileName()
240
    {
241
        // Check config options
242
        // - The js.app.export option must be set to true
243
        // - The js.app.uri and js.app.dir options must be set to non null values
244
        if(!$this->getOption('js.app.export') ||
245
            !$this->getOption('js.app.uri') ||
246
            !$this->getOption('js.app.dir'))
247
        {
248
            return '';
249
        }
250
251
        // The file name
252
        return $this->hasOption('js.app.file') ? $this->getOption('js.app.file') : $this->getHash();
253
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
254
255
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $sJsDirectory should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $sJsFileName should have a doc-comment as per coding-style.
Loading history...
256
     * Write javascript files and return the corresponding URI
257
     *
258
     * @return string
259
     */
260
    public function createFiles($sJsDirectory, $sJsFileName)
261
    {
262
        // Check dir access
263
        // - The js.app.dir must be writable
264
        if(!$sJsFileName || !is_dir($sJsDirectory) || !is_writable($sJsDirectory))
265
        {
266
            return '';
267
        }
268
269
        $sOutFile = $sJsFileName . '.js';
270
        $sMinFile = $sJsFileName . '.min.js';
271
        if(!is_file($sJsDirectory . $sOutFile))
272
        {
273
            if(!file_put_contents($sJsDirectory . $sOutFile, $this->_getScript()))
274
            {
275
                return '';
276
            }
277
        }
278
        if(($this->getOption('js.app.minify')) && !is_file($sJsDirectory . $sMinFile))
279
        {
280
            if(!$this->minify($sJsDirectory . $sOutFile, $sJsDirectory . $sMinFile))
281
            {
282
                return '';
283
            }
284
        }
285
286
        $sJsAppUri = rtrim($this->getOption('js.app.uri'), '/') . '/';
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...
287
        $sJsExtension = $this->getOption('js.app.minify') ? '.min.js' : '.js';
288
        return $sJsAppUri . $sJsFileName . $sJsExtension;
289
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
290
291
    /**
292
     * Get the javascript code to be sent to the browser
293
     *
294
     * @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; 9 found
Loading history...
295
     * @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...
296
     *
297
     * @return string
298
     */
299
    public function getScript($bIncludeJs, $bIncludeCss)
300
    {
301
        if(!$this->getOption('core.request.uri'))
302
        {
303
            $this->setOption('core.request.uri', jaxon()->di()->get(URI::class)->detect());
304
        }
305
306
        $sScript = '';
307
        if(($bIncludeCss))
308
        {
309
            $sScript .= $this->getCss() . "\n";
310
        }
311
        if(($bIncludeJs))
312
        {
313
            $sScript .= $this->getJs() . "\n";
314
        }
315
316
        $sJsDirectory = rtrim($this->getOption('js.app.dir'), '/') . '/';
317
        $sUrl = $this->createFiles($sJsDirectory, $this->getJsFileName());
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 9 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...
318
        if(($sUrl))
319
        {
320
            return $sScript . $this->_render('include.js', ['sUrl' => $sUrl]) . "\n" .
321
                $this->_render('wrapper.js', ['sScript' => $this->_getInlineScript()]);
322
        }
323
324
        return $sScript . $this->_render('wrapper.js', [
325
            'sScript' => $this->_getScript() . "\n" . $this->_getInlineScript()
326
        ]);
327
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
328
}
329