Completed
Push — master ( e11ac2...ace11e )
by Thierry
03:34
created

Manager::getReadyScript()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 42
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 29
nc 2
nop 0
dl 0
loc 42
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Manager.php - Jaxon plugin manager
5
 *
6
 * Register Jaxon plugins, generate corresponding code, handle request
7
 * and redirect them to the right plugin.
8
 *
9
 * @package jaxon-core
10
 * @author Jared White
11
 * @author J. Max Wilson
12
 * @author Joseph Woolley
13
 * @author Steffen Konerow
14
 * @author Thierry Feuzeu <[email protected]>
15
 * @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
16
 * @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White  & J. Max Wilson
17
 * @copyright 2016 Thierry Feuzeu <[email protected]>
18
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
19
 * @link https://github.com/jaxon-php/jaxon-core
20
 */
21
22
namespace Jaxon\Plugin;
23
24
use Jaxon\Jaxon;
25
use RecursiveDirectoryIterator;
26
use RecursiveIteratorIterator;
27
use RegexIterator;
28
use RecursiveRegexIterator;
29
30
class Manager
31
{
32
    use \Jaxon\Utils\Traits\Manager;
33
    use \Jaxon\Utils\Traits\Config;
34
    use \Jaxon\Utils\Traits\Cache;
35
    use \Jaxon\Utils\Traits\Minifier;
36
    use \Jaxon\Utils\Traits\Template;
37
    use \Jaxon\Utils\Traits\Translator;
38
39
    /**
40
     * The response type.
41
     *
42
     * @var string
43
     */
44
    const RESPONSE_TYPE = 'JSON';
45
46
    /**
47
     * All plugins, indexed by priority
48
     *
49
     * @var array
50
     */
51
    private $aPlugins;
52
53
    /**
54
     * Request plugins, indexed by name
55
     *
56
     * @var array
57
     */
58
    private $aRequestPlugins;
59
60
    /**
61
     * Response plugins, indexed by name
62
     *
63
     * @var array
64
     */
65
    private $aResponsePlugins;
66
67
    /**
68
     * Directories where Jaxon classes to be registered are found
69
     *
70
     * @var array
71
     */
72
    private $aClassDirs;
73
74
    /**
75
     * True if the Composer autoload is enabled
76
     *
77
     * @var boolean
78
     */
79
    private $bAutoloadEnabled;
80
81
    /**
82
     * The Composer autoloader
83
     *
84
     * @var Autoloader
85
     */
86
    private $xAutoloader;
87
88
    /**
89
     * Javascript confirm function
90
     *
91
     * @var \Jaxon\Request\Interfaces\Confirm
92
     */
93
    private $xConfirm;
94
95
    /**
96
     * Default javascript confirm function
97
     *
98
     * @var \Jaxon\Request\Support\Confirm
99
     */
100
    private $xDefaultConfirm;
101
102
    /**
103
     * Javascript alert function
104
     *
105
     * @var \Jaxon\Request\Interfaces\Alert
106
     */
107
    private $xAlert;
108
109
    /**
110
     * Default javascript alert function
111
     *
112
     * @var \Jaxon\Request\Support\Alert
113
     */
114
    private $xDefaultAlert;
115
116
    /**
117
     * Initialize the Jaxon Plugin Manager
118
     */
119
    public function __construct()
120
    {
121
        $this->aRequestPlugins = array();
122
        $this->aResponsePlugins = array();
123
        $this->aPlugins = array();
124
        $this->aClassDirs = array();
125
126
        $this->bAutoloadEnabled = true;
127
        $this->xAutoloader = null;
128
129
        // Javascript confirm function
130
        $this->xConfirm = null;
131
        $this->xDefaultConfirm = new \Jaxon\Request\Support\Confirm();
132
133
        // Javascript alert function
134
        $this->xAlert = null;
135
        $this->xDefaultAlert = new \Jaxon\Request\Support\Alert();
136
    }
137
138
    /**
139
     * Use the Composer autoloader
140
     *
141
     * @return void
142
     */
143
    public function useComposerAutoloader()
144
    {
145
        $this->bAutoloadEnabled = true;
146
        $this->xAutoloader = require(__DIR__ . '/../../../../autoload.php');
147
    }
148
149
    /**
150
     * Disable the autoloader in the library
151
     *
152
     * The user shall provide an alternative autoload system.
153
     *
154
     * @return void
155
     */
156
    public function disableAutoload()
157
    {
158
        $this->bAutoloadEnabled = false;
159
        $this->xAutoloader = null;
160
    }
161
162
    /**
163
     * Set the javascript confirm function
164
     *
165
     * @param \Jaxon\Request\Interfaces\Confirm         $xConfirm     The javascript confirm function
166
     *
167
     * @return void
168
     */
169
    public function setConfirm(\Jaxon\Request\Interfaces\Confirm $xConfirm)
170
    {
171
        $this->xConfirm = $xConfirm;
172
    }
173
174
    /**
175
     * Get the javascript confirm function
176
     *
177
     * @return \Jaxon\Request\Interfaces\Confirm
178
     */
179
    public function getConfirm()
180
    {
181
        return (($this->xConfirm) ? $this->xConfirm : $this->xDefaultConfirm);
182
    }
183
184
    /**
185
     * Get the default javascript confirm function
186
     *
187
     * @return \Jaxon\Request\Support\Confirm
188
     */
189
    public function getDefaultConfirm()
190
    {
191
        return $this->xDefaultConfirm;
192
    }
193
194
    /**
195
     * Set the javascript alert function
196
     *
197
     * @param \Jaxon\Request\Interfaces\Alert           $xAlert       The javascript alert function
198
     *
199
     * @return void
200
     */
201
    public function setAlert(\Jaxon\Request\Interfaces\Alert $xAlert)
202
    {
203
        $this->xAlert = $xAlert;
204
    }
205
206
    /**
207
     * Get the javascript alert function
208
     *
209
     * @return \Jaxon\Request\Interfaces\Alert
210
     */
211
    public function getAlert()
212
    {
213
        return (($this->xAlert) ? $this->xAlert : $this->xDefaultAlert);
214
    }
215
216
    /**
217
     * Get the default javascript alert function
218
     *
219
     * @return \Jaxon\Request\Support\Alert
220
     */
221
    public function getDefaultAlert()
222
    {
223
        return $this->xDefaultAlert;
224
    }
225
226
    /**
227
     * Inserts an entry into an array given the specified priority number
228
     *
229
     * If a plugin already exists with the given priority, the priority is automatically incremented until a free spot is found.
230
     * The plugin is then inserted into the empty spot in the array.
231
     *
232
     * @param Plugin         $xPlugin               An instance of a plugin
233
     * @param integer        $nPriority             The desired priority, used to order the plugins
234
     *
235
     * @return void
236
     */
237
    private function setPluginPriority(Plugin $xPlugin, $nPriority)
238
    {
239
        while (isset($this->aPlugins[$nPriority]))
240
        {
241
            $nPriority++;
242
        }
243
        $this->aPlugins[$nPriority] = $xPlugin;
244
        // Sort the array by ascending keys
245
        ksort($this->aPlugins);
246
    }
247
248
    /**
249
     * Register a plugin
250
     *
251
     * Below is a table for priorities and their description:
252
     * - 0 thru 999: Plugins that are part of or extensions to the jaxon core
253
     * - 1000 thru 8999: User created plugins, typically, these plugins don't care about order
254
     * - 9000 thru 9999: Plugins that generally need to be last or near the end of the plugin list
255
     *
256
     * @param Plugin         $xPlugin               An instance of a plugin
257
     * @param integer        $nPriority             The plugin priority, used to order the plugins
258
     *
259
     * @return void
260
     */
261
    public function registerPlugin(Plugin $xPlugin, $nPriority = 1000)
262
    {
263
        $bIsAlert = ($xPlugin instanceof \Jaxon\Request\Interfaces\Alert);
264
        $bIsConfirm = ($xPlugin instanceof \Jaxon\Request\Interfaces\Confirm);
265
        if($xPlugin instanceof Request)
266
        {
267
            // The name of a request plugin is used as key in the plugin table
268
            $this->aRequestPlugins[$xPlugin->getName()] = $xPlugin;
269
        }
270
        elseif($xPlugin instanceof Response)
271
        {
272
            // The name of a response plugin is used as key in the plugin table
273
            $this->aResponsePlugins[$xPlugin->getName()] = $xPlugin;
274
        }
275
        elseif(!$bIsConfirm && !$bIsAlert)
276
        {
277
            throw new \Jaxon\Exception\Error($this->trans('errors.register.invalid', array('name' => get_class($xPlugin))));
278
        }
279
        // This plugin implements the Alert interface
280
        if($bIsAlert)
281
        {
282
            $this->setAlert($xPlugin);
283
        }
284
        // This plugin implements the Confirm interface
285
        if($bIsConfirm)
286
        {
287
            $this->setConfirm($xPlugin);
288
        }
289
        // Register the plugin as an event listener
290
        if($xPlugin instanceof \Jaxon\Utils\Interfaces\EventListener)
291
        {
292
            $this->addEventListener($xPlugin);
293
        }
294
295
        $this->setPluginPriority($xPlugin, $nPriority);
296
    }
297
298
    /**
299
     * Generate a hash for all the javascript code generated by the library
300
     *
301
     * @return string
302
     */
303
    private function generateHash()
304
    {
305
        $sHash = $this->getVersion();
306
        foreach($this->aPlugins as $xPlugin)
307
        {
308
            $sHash .= $xPlugin->generateHash();
309
        }
310
        return md5($sHash);
311
    }
312
313
    /**
314
     * Check if the current request can be processed
315
     *
316
     * Calls each of the request plugins and determines if the current request can be processed by one of them.
317
     * If no processor identifies the current request, then the request must be for the initial page load.
318
     *
319
     * @return boolean
320
     */
321
    public function canProcessRequest()
322
    {
323
        foreach($this->aRequestPlugins as $xPlugin)
324
        {
325
            if($xPlugin->getName() != Jaxon::FILE_UPLOAD && $xPlugin->canProcessRequest())
326
            {
327
                return true;
328
            }
329
        }
330
        return false;
331
    }
332
333
    /**
334
     * Process the current request
335
     *
336
     * Calls each of the request plugins to request that they process the current request.
337
     * If any plugin processes the request, it will return true.
338
     *
339
     * @return boolean
340
     */
341
    public function processRequest()
342
    {
343
        $xUploadPlugin = $this->getRequestPlugin(Jaxon::FILE_UPLOAD);
344
        foreach($this->aRequestPlugins as $xPlugin)
345
        {
346
            if($xPlugin->getName() != Jaxon::FILE_UPLOAD && $xPlugin->canProcessRequest())
347
            {
348
                // Process uploaded files
349
                if($xUploadPlugin != null)
350
                {
351
                    $xUploadPlugin->processRequest();
352
                }
353
                // Process the request
354
                return $xPlugin->processRequest();
355
            }
356
        }
357
        // Todo: throw an exception
358
        return false;
359
    }
360
    
361
    /**
362
     * Register a function, event or callable object
363
     *
364
     * Call each of the request plugins and give them the opportunity to handle the
365
     * registration of the specified function, event or callable object.
366
     *
367
     * @param array         $aArgs                The registration data
368
     *
369
     * @return mixed
370
     */
371
    public function register($aArgs)
372
    {
373
        foreach($this->aRequestPlugins as $xPlugin)
374
        {
375
            $mResult = $xPlugin->register($aArgs);
376
            if($mResult instanceof \Jaxon\Request\Request || is_array($mResult) || $mResult === true)
377
            {
378
                return $mResult;
379
            }
380
        }
381
        throw new \Jaxon\Exception\Error($this->trans('errors.register.method', array('args' => print_r($aArgs, true))));
382
    }
383
384
    /**
385
     * Add a path to the class directories
386
     *
387
     * @param string            $sDirectory             The path to the directory
388
     * @param string|null       $sNamespace             The associated namespace
389
     * @param string            $sSeparator             The character to use as separator in javascript class names
390
     * @param array             $aProtected             The functions that are not to be exported
391
     *
392
     * @return boolean
393
     */
394
    public function addClassDir($sDirectory, $sNamespace = '', $sSeparator = '.', array $aProtected = array())
395
    {
396
        if(!is_dir(($sDirectory = trim($sDirectory))))
397
        {
398
            return false;
399
        }
400
        // Only '.' and '_' are allowed to be used as separator. Any other value is ignored and '.' is used instead.
401
        if(($sSeparator = trim($sSeparator)) != '_')
402
        {
403
            $sSeparator = '.';
404
        }
405
        if(!($sNamespace = trim($sNamespace, ' \\')))
406
        {
407
            $sNamespace = '';
408
        }
409
        if(($sNamespace))
410
        {
411
            // If there is an autoloader, register the dir with PSR4 autoloading
412
            if(($this->xAutoloader))
413
            {
414
                $this->xAutoloader->setPsr4($sNamespace . '\\', $sDirectory);
415
            }
416
        }
417
        elseif(($this->xAutoloader))
418
        {
419
            // If there is an autoloader, register the dir with classmap autoloading
420
            $itDir = new RecursiveDirectoryIterator($sDirectory);
421
            $itFile = new RecursiveIteratorIterator($itDir);
422
            // Iterate on dir content
423
            foreach($itFile as $xFile)
424
            {
425
                // skip everything except PHP files
426
                if(!$xFile->isFile() || $xFile->getExtension() != 'php')
427
                {
428
                    continue;
429
                }
430
                $this->xAutoloader->addClassMap(array($xFile->getBasename('.php') => $xFile->getPathname()));
431
            }
432
        }
433
        $this->aClassDirs[] = array(
434
            'directory' => rtrim($sDirectory, DIRECTORY_SEPARATOR),
435
            'namespace' => $sNamespace,
436
            'separator' => $sSeparator,
437
            'protected' => $aProtected
438
        );
439
        return true;
440
    }
441
442
    /**
443
     * Register an instance of a given class from a file
444
     *
445
     * @param object            $xFile                  The PHP file containing the class
446
     * @param string            $sDirectory             The path to the directory
447
     * @param string|''         $sNamespace             The associated namespace
0 ignored issues
show
Documentation introduced by
The doc-type string|'' could not be parsed: Unknown type name "''" at position 7. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
448
     * @param string            $sSeparator             The character to use as separator in javascript class names
449
     * @param array             $aProtected             The functions that are not to be exported
450
     * @param array             $aOptions               The options to register the class with
451
     *
452
     * @return void
453
     */
454
    protected function registerClassFromFile($xFile, $sDirectory, $sNamespace = '', $sSeparator = '.',
455
        array $aProtected = array(), array $aOptions = array())
456
    {
457
        $sDS = DIRECTORY_SEPARATOR;
458
        // Get the corresponding class path and name
459
        $sClassPath = substr($xFile->getPath(), strlen($sDirectory));
460
        $sClassPath = str_replace($sDS, '\\', trim($sClassPath, $sDS));
461
        $sClassName = $xFile->getBasename('.php');
462
        if(($sNamespace))
463
        {
464
            $sClassPath = ($sClassPath) ? $sNamespace . '\\' . $sClassPath : $sNamespace;
465
            $sClassName = '\\' . $sClassPath . '\\' . $sClassName;
466
        }
467
        // Require the file only if autoload is enabled but there is no autoloader
468
        if(($this->bAutoloadEnabled) && !($this->xAutoloader))
469
        {
470
            require_once($xFile->getPathname());
471
        }
472
        // Create and register an instance of the class
473
        if(!array_key_exists('*', $aOptions) || !is_array($aOptions['*']))
474
        {
475
            $aOptions['*'] = array();
476
        }
477
        $aOptions['*']['separator'] = $sSeparator;
478
        if(($sNamespace))
479
        {
480
            $aOptions['*']['namespace'] = $sNamespace;
481
        }
482
        if(($sClassPath))
483
        {
484
            $aOptions['*']['classpath'] = $sClassPath;
485
        }
486
        // Filter excluded methods
487
        $aProtected = array_filter($aProtected, function ($sName) {return is_string($sName);});
488
        if(count($aProtected) > 0)
489
        {
490
            $aOptions['*']['protected'] = $aProtected;
491
        }
492
        $this->register(array(Jaxon::CALLABLE_OBJECT, $sClassName, $aOptions));
493
    }
494
495
    /**
496
     * Register callable objects from all class directories
497
     *
498
     * @param array             $aOptions               The options to register the classes with
499
     *
500
     * @return void
501
     */
502
    public function registerClasses(array $aOptions = array())
503
    {
504
        $sDS = DIRECTORY_SEPARATOR;
505
        // Change the keys in $aOptions to have "\" as separator
506
        $aNewOptions = array();
507
        foreach($aOptions as $key => $aOption)
508
        {
509
            $key = trim(str_replace(['.', '_'], ['\\', '\\'], $key), ' \\');
510
            $aNewOptions[$key] = $aOption;
511
        }
512
513
        foreach($this->aClassDirs as $aClassDir)
514
        {
515
            // Get the directory
516
            $sDirectory = $aClassDir['directory'];
517
            // Get the namespace
518
            $sNamespace = $aClassDir['namespace'];
519
520
            $itDir = new RecursiveDirectoryIterator($sDirectory);
521
            $itFile = new RecursiveIteratorIterator($itDir);
522
            // Iterate on dir content
523
            foreach($itFile as $xFile)
524
            {
525
                // skip everything except PHP files
526
                if(!$xFile->isFile() || $xFile->getExtension() != 'php')
527
                {
528
                    continue;
529
                }
530
531
                // Get the class name
532
                $sClassPath = substr($xFile->getPath(), strlen($sDirectory));
533
                $sClassPath = trim(str_replace($sDS, '\\', $sClassPath), '\\');
534
                $sClassName = $sClassPath . '\\' . $xFile->getBasename('.php');
535
                if(($sNamespace))
536
                {
537
                    $sClassName = $sNamespace . '\\' . $sClassName;
538
                }
539
                // Get the class options
540
                $aClassOptions = [];
541
                if(array_key_exists($sClassName, $aNewOptions))
542
                {
543
                    $aClassOptions = $aNewOptions[$sClassName];
544
                }
545
546
                $this->registerClassFromFile($xFile, $sDirectory, $sNamespace,
547
                    $aClassDir['separator'], $aClassDir['protected'], $aClassOptions);
548
            }
549
        }
550
    }
551
552
    /**
553
     * Register an instance of a given class
554
     *
555
     * @param string            $sClassName             The name of the class to be registered
556
     * @param array             $aOptions               The options to register the class with
557
     *
558
     * @return bool
559
     */
560
    public function registerClass($sClassName, array $aOptions = array())
561
    {
562
        if(!($sClassName = trim($sClassName, ' \\._')))
563
        {
564
            return false;
565
        }
566
        $sDS = DIRECTORY_SEPARATOR;
567
568
        // Replace "." and "_" with antislashes, and set the class path.
569
        $sClassName = str_replace(['.', '_'], ['\\', '\\'], $sClassName);
570
        $sClassPath = '';
571
        if(($nLastSlashPosition = strrpos($sClassName, '\\')) !== false)
572
        {
573
            $sClassPath = substr($sClassName, 0, $nLastSlashPosition);
574
            $sClassName = substr($sClassName, $nLastSlashPosition + 1);
575
        }
576
        // Path to the file, relative to a registered directory.
577
        $sPartPath = str_replace('\\', $sDS, $sClassPath) . $sDS . $sClassName . '.php';
578
579
        // Search for the class file in all directories.
580
        foreach($this->aClassDirs as $aClassDir)
581
        {
582
            // Get the separator
583
            $sSeparator = $aClassDir['separator'];
584
            // Get the namespace
585
            $sNamespace = $aClassDir['namespace'];
586
            $nLen = strlen($sNamespace);
587
            $sFullPath = '';
588
            // Check if the class belongs to the namespace
589
            if(($sNamespace) && substr($sClassPath, 0, $nLen) == $sNamespace)
590
            {
591
                $sFullPath = $aClassDir['directory'] . $sDS . substr($sPartPath, $nLen + 1);
592
            }
593
            elseif(!($sNamespace))
594
            {
595
                $sFullPath = $aClassDir['directory'] . $sDS . $sPartPath;
596
            }
597
            if(($sFullPath) && is_file($sFullPath))
598
            {
599
                // Found the file in this directory
600
                $xFileInfo = new \SplFileInfo($sFullPath);
601
                $sDirectory = $aClassDir['directory'];
602
                $aProtected = $aClassDir['protected'];
603
                $this->registerClassFromFile($xFileInfo, $sDirectory, $sNamespace, $sSeparator, $aProtected, $aOptions);
604
                return true;
605
            }
606
        }
607
        return false;
608
    }
609
610
    /**
611
     * Find a user registered callable object by class name
612
     *
613
     * @param string        $sClassName            The class name of the callable object
614
     *
615
     * @return object
616
     */
617
    public function getRegisteredObject($sClassName)
618
    {
619
        $xObject = null; // The user registered object
620
        $xPlugin = $this->getRequestPlugin('CallableObject'); // The CallableObject plugin
621
        if(($xPlugin))
622
        {
623
            $xObject = $xPlugin->getRegisteredObject($sClassName);
624
        }
625
        return $xObject;
626
    }
627
628
    /**
629
     * Get the base URI of the Jaxon library javascript files
630
     *
631
     * @return string
632
     */
633
    private function getJsLibUri()
634
    {
635
        if(!$this->hasOption('js.lib.uri'))
636
        {
637
            return 'https://cdn.jsdelivr.net/jaxon/1.2.0/';
638
        }
639
        // Todo: check the validity of the URI
640
        return rtrim($this->getOption('js.lib.uri'), '/') . '/';
641
    }
642
    
643
    /**
644
     * Get the extension of the Jaxon library javascript files
645
     *
646
     * The returned string is '.min.js' if the files are minified.
647
     *
648
     * @return string
649
     */
650
    private function getJsLibExt()
651
    {
652
        $jsDelivrUri = 'https://cdn.jsdelivr.net';
653
        $nLen = strlen($jsDelivrUri);
654
        // The jsDelivr CDN only hosts minified files
655
        if(($this->getOption('js.app.minify')) || substr($this->getJsLibUri(), 0, $nLen) == $jsDelivrUri)
656
        {
657
            return '.min.js';
658
        }
659
        return '.js';
660
    }
661
662
    /**
663
     * Check if the javascript code generated by Jaxon can be exported to an external file
664
     *
665
     * @return boolean
666
     */
667
    public function canExportJavascript()
668
    {
669
        // Check config options
670
        // - The js.app.extern option must be set to true
671
        // - The js.app.uri and js.app.dir options must be set to non null values
672
        if(!$this->getOption('js.app.extern') ||
673
            !$this->getOption('js.app.uri') ||
674
            !$this->getOption('js.app.dir'))
675
        {
676
            return false;
677
        }
678
        // Check dir access
679
        // - The js.app.dir must be writable
680
        $sJsAppDir = $this->getOption('js.app.dir');
681
        if(!is_dir($sJsAppDir) || !is_writable($sJsAppDir))
682
        {
683
            return false;
684
        }
685
        return true;
686
    }
687
688
    /**
689
     * Set the cache directory for the template engine
690
     *
691
     * @return void
692
     */
693
    private function setTemplateCacheDir()
694
    {
695
        if($this->hasOption('core.template.cache_dir'))
696
        {
697
            $this->setCacheDir($this->getOption('core.template.cache_dir'));
698
        }
699
    }
700
701
    /**
702
     * Get the HTML tags to include Jaxon javascript files into the page
703
     *
704
     * @return string
705
     */
706
    public function getJs()
707
    {
708
        $sJsLibUri = $this->getJsLibUri();
709
        $sJsLibExt = $this->getJsLibExt();
710
        $sJsCoreUrl = $sJsLibUri . 'jaxon.core' . $sJsLibExt;
711
        $sJsDebugUrl = $sJsLibUri . 'jaxon.debug' . $sJsLibExt;
712
        $sJsVerboseUrl = $sJsLibUri . 'jaxon.verbose' . $sJsLibExt;
0 ignored issues
show
Unused Code introduced by
$sJsVerboseUrl is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
713
        $sJsLanguageUrl = $sJsLibUri . 'lang/jaxon.' . $this->getOption('core.language') . $sJsLibExt;
714
715
        // Add component files to the javascript file array;
716
        $aJsFiles = array($sJsCoreUrl);
717
        if($this->getOption('core.debug.on'))
718
        {
719
            $aJsFiles[] = $sJsDebugUrl;
720
            $aJsFiles[] = $sJsLanguageUrl;
721
            /*if($this->getOption('core.debug.verbose'))
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
722
            {
723
                $aJsFiles[] = $sJsVerboseUrl;
724
            }*/
725
        }
726
727
        // Set the template engine cache dir
728
        $this->setTemplateCacheDir();
729
        $sCode = $this->render('jaxon::plugins/includes.js', array(
730
            'sJsOptions' => $this->getOption('js.app.options'),
731
            'aUrls' => $aJsFiles,
732
        ));
733
        foreach($this->aResponsePlugins as $xPlugin)
734
        {
735
            $sCode .= rtrim($xPlugin->getJs(), " \n") . "\n";
736
        }
737
        return $sCode;
738
    }
739
740
    /**
741
     * Get the HTML tags to include Jaxon CSS code and files into the page
742
     *
743
     * @return string
744
     */
745
    public function getCss()
746
    {
747
        // Set the template engine cache dir
748
        $this->setTemplateCacheDir();
749
750
        $sCode = '';
751
        foreach($this->aResponsePlugins as $xPlugin)
752
        {
753
            $sCode .= rtrim($xPlugin->getCss(), " \n") . "\n";
754
        }
755
        return $sCode;
756
    }
757
758
    /**
759
     * Get the correspondances between previous and current config options
760
     *
761
     * They are used to keep the deprecated config options working.
762
     * They will be removed when the deprecated options will lot be supported anymore.
763
     *
764
     * @return array
765
     */
766
    private function getOptionVars()
767
    {
768
        return array(
769
            'sResponseType'             => self::RESPONSE_TYPE,
770
            'sVersion'                  => $this->getOption('core.version'),
771
            'sLanguage'                 => $this->getOption('core.language'),
772
            'bLanguage'                 => $this->hasOption('core.language') ? true : false,
773
            'sRequestURI'               => $this->getOption('core.request.uri'),
774
            'sDefaultMode'              => $this->getOption('core.request.mode'),
775
            'sDefaultMethod'            => $this->getOption('core.request.method'),
776
            'sCsrfMetaName'             => $this->getOption('core.request.csrf_meta'),
777
            'bDebug'                    => $this->getOption('core.debug.on'),
778
            'bVerboseDebug'             => $this->getOption('core.debug.verbose'),
779
            'sDebugOutputID'            => $this->getOption('core.debug.output_id'),
780
            'nResponseQueueSize'        => $this->getOption('js.lib.queue_size'),
781
            'sStatusMessages'           => $this->getOption('js.lib.show_status') ? 'true' : 'false',
782
            'sWaitCursor'               => $this->getOption('js.lib.show_cursor') ? 'true' : 'false',
783
            'sDefer'                    => $this->getOption('js.app.options'),
784
        );
785
    }
786
787
    /**
788
     * Get the javascript code for Jaxon client side configuration
789
     *
790
     * @return string
791
     */
792
    private function getConfigScript()
793
    {
794
        $aVars = $this->getOptionVars();
795
        $sYesScript = 'jaxon.confirm.skip(command);jaxon.tools.queue.process(command.response)';
796
        $sNoScript = 'jaxon.tools.queue.process(command.response)';
797
        $sConfirmScript = $this->getConfirm()->confirm('msg', $sYesScript, $sNoScript);
798
        $aVars['sConfirmScript'] = $this->render('jaxon::plugins/confirm.js', array('sConfirmScript' => $sConfirmScript));
799
800
        return $this->render('jaxon::plugins/config.js', $aVars);
801
    }
802
803
    /**
804
     * Get the javascript code to be run after page load
805
     *
806
     * Also call each of the response plugins giving them the opportunity
807
     * to output some javascript to the page being generated.
808
     *
809
     * @return string
810
     */
811
    private function getReadyScript()
812
    {
813
        // Print Jaxon config vars
814
        $sJsLibUri = $this->getJsLibUri();
815
        $sJsLibExt = $this->getJsLibExt();
816
        $sJsCoreUrl = $sJsLibUri . 'jaxon.core' . $sJsLibExt;
817
        $sJsDebugUrl = $sJsLibUri . 'jaxon.debug' . $sJsLibExt;
818
        $sJsVerboseUrl = $sJsLibUri . 'jaxon.verbose' . $sJsLibExt;
819
        $sJsLanguageUrl = $sJsLibUri . 'lang/jaxon.' . $this->getOption('core.language') . $sJsLibExt;
820
821
        $sJsCoreError = $this->trans('errors.component.load', array(
822
            'name' => 'jaxon',
823
            'url' => $sJsCoreUrl,
824
        ));
825
        $sJsDebugError = $this->trans('errors.component.load', array(
826
            'name' => 'jaxon.debug',
827
            'url' => $sJsDebugUrl,
828
        ));
829
        $sJsVerboseError = $this->trans('errors.component.load', array(
830
            'name' => 'jaxon.debug.verbose',
831
            'url' => $sJsVerboseUrl,
832
        ));
833
        $sJsLanguageError = $this->trans('errors.component.load', array(
834
            'name' => 'jaxon.debug.lang',
835
            'url' => $sJsLanguageUrl,
836
        ));
837
838
        $sPluginScript = '';
839
        foreach($this->aResponsePlugins as $xPlugin)
840
        {
841
            $sPluginScript .= "\n" . trim($xPlugin->getScript(), " \n");
842
        }
843
844
        $aVars = $this->getOptionVars();
845
        $aVars['sPluginScript'] = $sPluginScript;
846
        $aVars['sJsCoreError'] = $sJsCoreError;
847
        $aVars['sJsDebugError'] = $sJsDebugError;
848
        $aVars['sJsVerboseError'] = $sJsVerboseError;
849
        $aVars['sJsLanguageError'] = $sJsLanguageError;
850
851
        return $this->render('jaxon::plugins/ready.js', $aVars);
852
    }
853
854
    /**
855
     * Get the javascript code to be sent to the browser
856
     *
857
     * Also call each of the request plugins giving them the opportunity
858
     * to output some javascript to the page being generated.
859
     * This is called only when the page is being loaded initially.
860
     * This is not called when processing a request.
861
     *
862
     * @return string
863
     */
864
    private function getAllScripts()
865
    {
866
        // Get the config and plugins scripts
867
        $sScript = $this->getConfigScript() . "\n" . $this->getReadyScript() . "\n";
868
        foreach($this->aRequestPlugins as $xPlugin)
869
        {
870
            $sScript .= "\n" . trim($xPlugin->getScript(), " \n");
871
        }
872
        return $sScript;
873
    }
874
875
    /**
876
     * Get the javascript code to be sent to the browser
877
     *
878
     * Also call each of the request plugins giving them the opportunity
879
     * to output some javascript to the page being generated.
880
     * This is called only when the page is being loaded initially.
881
     * This is not called when processing a request.
882
     *
883
     * @return string
884
     */
885
    public function getScript()
886
    {
887
        // Set the template engine cache dir
888
        $this->setTemplateCacheDir();
889
890
        if($this->canExportJavascript())
891
        {
892
            $sJsAppURI = rtrim($this->getOption('js.app.uri'), '/') . '/';
893
            $sJsAppDir = rtrim($this->getOption('js.app.dir'), '/') . '/';
894
895
            // The plugins scripts are written into the javascript app dir
896
            $sHash = $this->generateHash();
897
            $sOutFile = $sHash . '.js';
898
            $sMinFile = $sHash . '.min.js';
899
            if(!is_file($sJsAppDir . $sOutFile))
900
            {
901
                file_put_contents($sJsAppDir . $sOutFile, $this->getAllScripts());
902
            }
903
            if(($this->getOption('js.app.minify')) && !is_file($sJsAppDir . $sMinFile))
904
            {
905
                if(($this->minify($sJsAppDir . $sOutFile, $sJsAppDir . $sMinFile)))
906
                {
907
                    $sOutFile = $sMinFile;
908
                }
909
            }
910
911
            // The returned code loads the generated javascript file
912
            $sScript = $this->render('jaxon::plugins/include.js', array(
913
                'sJsOptions' => $this->getOption('js.app.options'),
914
                'sUrl' => $sJsAppURI . $sOutFile,
915
            ));
916
        }
917
        else
918
        {
919
            // The plugins scripts are wrapped with javascript tags
920
            $sScript = $this->render('jaxon::plugins/wrapper.js', array(
921
                'sJsOptions' => $this->getOption('js.app.options'),
922
                'sScript' => $this->getAllScripts(),
923
            ));
924
        }
925
        
926
        return $sScript;
927
    }
928
929
    /**
930
     * Find the specified response plugin by name and return a reference to it if one exists
931
     *
932
     * @param string        $sName                The name of the plugin
933
     *
934
     * @return \Jaxon\Plugin\Response
935
     */
936
    public function getResponsePlugin($sName)
937
    {
938
        if(array_key_exists($sName, $this->aResponsePlugins))
939
        {
940
            return $this->aResponsePlugins[$sName];
941
        }
942
        return null;
943
    }
944
945
    /**
946
     * Find the specified request plugin by name and return a reference to it if one exists
947
     *
948
     * @param string        $sName                The name of the plugin
949
     *
950
     * @return \Jaxon\Plugin\Request
951
     */
952
    public function getRequestPlugin($sName)
953
    {
954
        if(array_key_exists($sName, $this->aRequestPlugins))
955
        {
956
            return $this->aRequestPlugins[$sName];
957
        }
958
        return null;
959
    }
960
}
961