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 Jaxon\Plugin\Package; |
26
|
|
|
use RecursiveDirectoryIterator; |
27
|
|
|
use RecursiveIteratorIterator; |
28
|
|
|
use RegexIterator; |
29
|
|
|
use RecursiveRegexIterator; |
30
|
|
|
use Closure; |
31
|
|
|
|
32
|
|
|
class Manager |
33
|
|
|
{ |
34
|
|
|
use \Jaxon\Utils\Traits\Manager; |
35
|
|
|
use \Jaxon\Utils\Traits\Config; |
36
|
|
|
use \Jaxon\Utils\Traits\Cache; |
37
|
|
|
use \Jaxon\Utils\Traits\Event; |
38
|
|
|
use \Jaxon\Utils\Traits\Minifier; |
39
|
|
|
use \Jaxon\Utils\Traits\Template; |
40
|
|
|
use \Jaxon\Utils\Traits\Translator; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* The response type. |
44
|
|
|
* |
45
|
|
|
* @var string |
46
|
|
|
*/ |
47
|
|
|
const RESPONSE_TYPE = 'JSON'; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* All plugins, indexed by priority |
51
|
|
|
* |
52
|
|
|
* @var array |
53
|
|
|
*/ |
54
|
|
|
private $aPlugins = []; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* Request plugins, indexed by name |
58
|
|
|
* |
59
|
|
|
* @var array |
60
|
|
|
*/ |
61
|
|
|
private $aRequestPlugins = []; |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Response plugins, indexed by name |
65
|
|
|
* |
66
|
|
|
* @var array |
67
|
|
|
*/ |
68
|
|
|
private $aResponsePlugins = []; |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* An array of package names |
72
|
|
|
* |
73
|
|
|
* @var array |
74
|
|
|
*/ |
75
|
|
|
private $aPackages = []; |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Javascript confirm function |
79
|
|
|
* |
80
|
|
|
* @var \Jaxon\Request\Interfaces\Confirm |
81
|
|
|
*/ |
82
|
|
|
private $xConfirm; |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Default javascript confirm function |
86
|
|
|
* |
87
|
|
|
* @var \Jaxon\Request\Support\Confirm |
88
|
|
|
*/ |
89
|
|
|
private $xDefaultConfirm; |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Javascript alert function |
93
|
|
|
* |
94
|
|
|
* @var \Jaxon\Request\Interfaces\Alert |
95
|
|
|
*/ |
96
|
|
|
private $xAlert; |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Default javascript alert function |
100
|
|
|
* |
101
|
|
|
* @var \Jaxon\Request\Support\Alert |
102
|
|
|
*/ |
103
|
|
|
private $xDefaultAlert; |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* Initialize the Jaxon Plugin Manager |
107
|
|
|
*/ |
108
|
|
|
public function __construct() |
109
|
|
|
{ |
110
|
|
|
// Javascript confirm function |
111
|
|
|
$this->xConfirm = null; |
112
|
|
|
$this->xDefaultConfirm = new \Jaxon\Request\Support\Confirm(); |
113
|
|
|
|
114
|
|
|
// Javascript alert function |
115
|
|
|
$this->xAlert = null; |
116
|
|
|
$this->xDefaultAlert = new \Jaxon\Request\Support\Alert(); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Set the javascript confirm function |
121
|
|
|
* |
122
|
|
|
* @param \Jaxon\Request\Interfaces\Confirm $xConfirm The javascript confirm function |
123
|
|
|
* |
124
|
|
|
* @return void |
125
|
|
|
*/ |
126
|
|
|
public function setConfirm(\Jaxon\Request\Interfaces\Confirm $xConfirm) |
127
|
|
|
{ |
128
|
|
|
$this->xConfirm = $xConfirm; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Get the javascript confirm function |
133
|
|
|
* |
134
|
|
|
* @return \Jaxon\Request\Interfaces\Confirm |
135
|
|
|
*/ |
136
|
|
|
public function getConfirm() |
137
|
|
|
{ |
138
|
|
|
return (($this->xConfirm) ? $this->xConfirm : $this->xDefaultConfirm); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Get the default javascript confirm function |
143
|
|
|
* |
144
|
|
|
* @return \Jaxon\Request\Support\Confirm |
145
|
|
|
*/ |
146
|
|
|
public function getDefaultConfirm() |
147
|
|
|
{ |
148
|
|
|
return $this->xDefaultConfirm; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Set the javascript alert function |
153
|
|
|
* |
154
|
|
|
* @param \Jaxon\Request\Interfaces\Alert $xAlert The javascript alert function |
155
|
|
|
* |
156
|
|
|
* @return void |
157
|
|
|
*/ |
158
|
|
|
public function setAlert(\Jaxon\Request\Interfaces\Alert $xAlert) |
159
|
|
|
{ |
160
|
|
|
$this->xAlert = $xAlert; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Get the javascript alert function |
165
|
|
|
* |
166
|
|
|
* @return \Jaxon\Request\Interfaces\Alert |
167
|
|
|
*/ |
168
|
|
|
public function getAlert() |
169
|
|
|
{ |
170
|
|
|
return (($this->xAlert) ? $this->xAlert : $this->xDefaultAlert); |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* Get the default javascript alert function |
175
|
|
|
* |
176
|
|
|
* @return \Jaxon\Request\Support\Alert |
177
|
|
|
*/ |
178
|
|
|
public function getDefaultAlert() |
179
|
|
|
{ |
180
|
|
|
return $this->xDefaultAlert; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* Inserts an entry into an array given the specified priority number |
185
|
|
|
* |
186
|
|
|
* If a plugin already exists with the given priority, the priority is automatically incremented until a free spot is found. |
187
|
|
|
* The plugin is then inserted into the empty spot in the array. |
188
|
|
|
* |
189
|
|
|
* @param Plugin $xPlugin An instance of a plugin |
190
|
|
|
* @param integer $nPriority The desired priority, used to order the plugins |
191
|
|
|
* |
192
|
|
|
* @return void |
193
|
|
|
*/ |
194
|
|
|
private function setPluginPriority(Plugin $xPlugin, $nPriority) |
195
|
|
|
{ |
196
|
|
|
while (isset($this->aPlugins[$nPriority])) |
197
|
|
|
{ |
198
|
|
|
$nPriority++; |
199
|
|
|
} |
200
|
|
|
$this->aPlugins[$nPriority] = $xPlugin; |
201
|
|
|
// Sort the array by ascending keys |
202
|
|
|
ksort($this->aPlugins); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Register a plugin |
207
|
|
|
* |
208
|
|
|
* Below is a table for priorities and their description: |
209
|
|
|
* - 0 thru 999: Plugins that are part of or extensions to the jaxon core |
210
|
|
|
* - 1000 thru 8999: User created plugins, typically, these plugins don't care about order |
211
|
|
|
* - 9000 thru 9999: Plugins that generally need to be last or near the end of the plugin list |
212
|
|
|
* |
213
|
|
|
* @param Plugin $xPlugin An instance of a plugin |
214
|
|
|
* @param integer $nPriority The plugin priority, used to order the plugins |
215
|
|
|
* |
216
|
|
|
* @return void |
217
|
|
|
*/ |
218
|
|
|
public function registerPlugin(Plugin $xPlugin, $nPriority = 1000) |
219
|
|
|
{ |
220
|
|
|
$bIsAlert = ($xPlugin instanceof \Jaxon\Request\Interfaces\Alert); |
221
|
|
|
$bIsConfirm = ($xPlugin instanceof \Jaxon\Request\Interfaces\Confirm); |
222
|
|
|
if($xPlugin instanceof Request) |
223
|
|
|
{ |
224
|
|
|
// The name of a request plugin is used as key in the plugin table |
225
|
|
|
$this->aRequestPlugins[$xPlugin->getName()] = $xPlugin; |
226
|
|
|
} |
227
|
|
|
elseif($xPlugin instanceof Response) |
228
|
|
|
{ |
229
|
|
|
// The name of a response plugin is used as key in the plugin table |
230
|
|
|
$this->aResponsePlugins[$xPlugin->getName()] = $xPlugin; |
231
|
|
|
} |
232
|
|
|
elseif(!$bIsConfirm && !$bIsAlert) |
233
|
|
|
{ |
234
|
|
|
throw new \Jaxon\Exception\Error($this->trans('errors.register.invalid', array('name' => get_class($xPlugin)))); |
235
|
|
|
} |
236
|
|
|
// This plugin implements the Alert interface |
237
|
|
|
if($bIsAlert) |
238
|
|
|
{ |
239
|
|
|
$this->setAlert($xPlugin); |
240
|
|
|
} |
241
|
|
|
// This plugin implements the Confirm interface |
242
|
|
|
if($bIsConfirm) |
243
|
|
|
{ |
244
|
|
|
$this->setConfirm($xPlugin); |
245
|
|
|
} |
246
|
|
|
// Register the plugin as an event listener |
247
|
|
|
if($xPlugin instanceof \Jaxon\Utils\Interfaces\EventListener) |
248
|
|
|
{ |
249
|
|
|
$this->addEventListener($xPlugin); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
$this->setPluginPriority($xPlugin, $nPriority); |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
/** |
256
|
|
|
* Register a package |
257
|
|
|
* |
258
|
|
|
* @param string $sPackageClass The package class name |
259
|
|
|
* @param Closure $xClosure A closure to create package instance |
260
|
|
|
* |
261
|
|
|
* @return void |
262
|
|
|
*/ |
263
|
|
|
public function registerPackage(string $sPackageClass, Closure $xClosure) |
264
|
|
|
{ |
265
|
|
|
$this->aPackages[] = $sPackageClass; |
266
|
|
|
jaxon()->di()->set($sPackageClass, $xClosure); |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
/** |
270
|
|
|
* Generate a hash for all the javascript code generated by the library |
271
|
|
|
* |
272
|
|
|
* @return string |
273
|
|
|
*/ |
274
|
|
|
private function generateHash() |
275
|
|
|
{ |
276
|
|
|
$sHash = $this->getVersion(); |
277
|
|
|
foreach($this->aPlugins as $xPlugin) |
278
|
|
|
{ |
279
|
|
|
$sHash .= $xPlugin->generateHash(); |
280
|
|
|
} |
281
|
|
|
return md5($sHash); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
/** |
285
|
|
|
* Check if the current request can be processed |
286
|
|
|
* |
287
|
|
|
* Calls each of the request plugins and determines if the current request can be processed by one of them. |
288
|
|
|
* If no processor identifies the current request, then the request must be for the initial page load. |
289
|
|
|
* |
290
|
|
|
* @return boolean |
291
|
|
|
*/ |
292
|
|
|
public function canProcessRequest() |
293
|
|
|
{ |
294
|
|
|
foreach($this->aRequestPlugins as $xPlugin) |
295
|
|
|
{ |
296
|
|
|
if($xPlugin->getName() != Jaxon::FILE_UPLOAD && $xPlugin->canProcessRequest()) |
297
|
|
|
{ |
298
|
|
|
return true; |
299
|
|
|
} |
300
|
|
|
} |
301
|
|
|
return false; |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
/** |
305
|
|
|
* Process the current request |
306
|
|
|
* |
307
|
|
|
* Calls each of the request plugins to request that they process the current request. |
308
|
|
|
* If any plugin processes the request, it will return true. |
309
|
|
|
* |
310
|
|
|
* @return boolean |
311
|
|
|
*/ |
312
|
|
|
public function processRequest() |
313
|
|
|
{ |
314
|
|
|
$xUploadPlugin = $this->getRequestPlugin(Jaxon::FILE_UPLOAD); |
315
|
|
|
foreach($this->aRequestPlugins as $xPlugin) |
316
|
|
|
{ |
317
|
|
|
if($xPlugin->getName() != Jaxon::FILE_UPLOAD && $xPlugin->canProcessRequest()) |
318
|
|
|
{ |
319
|
|
|
// Process uploaded files |
320
|
|
|
if($xUploadPlugin != null) |
321
|
|
|
{ |
322
|
|
|
$xUploadPlugin->processRequest(); |
323
|
|
|
} |
324
|
|
|
// Process the request |
325
|
|
|
return $xPlugin->processRequest(); |
326
|
|
|
} |
327
|
|
|
} |
328
|
|
|
// Todo: throw an exception |
329
|
|
|
return false; |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
/** |
333
|
|
|
* Register a function, event or callable object |
334
|
|
|
* |
335
|
|
|
* Call each of the request plugins and give them the opportunity to handle the |
336
|
|
|
* registration of the specified function, event or callable object. |
337
|
|
|
* |
338
|
|
|
* @param array $aArgs The registration data |
339
|
|
|
* |
340
|
|
|
* @return mixed |
341
|
|
|
*/ |
342
|
|
|
public function register($aArgs) |
343
|
|
|
{ |
344
|
|
|
foreach($this->aRequestPlugins as $xPlugin) |
345
|
|
|
{ |
346
|
|
|
$mResult = $xPlugin->register($aArgs); |
347
|
|
|
if($mResult instanceof \Jaxon\Request\Request || is_array($mResult) || $mResult === true) |
348
|
|
|
{ |
349
|
|
|
return $mResult; |
350
|
|
|
} |
351
|
|
|
} |
352
|
|
|
throw new \Jaxon\Exception\Error($this->trans('errors.register.method', array('args' => print_r($aArgs, true)))); |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* Get the base URI of the Jaxon library javascript files |
357
|
|
|
* |
358
|
|
|
* @return string |
359
|
|
|
*/ |
360
|
|
|
private function getJsLibUri() |
361
|
|
|
{ |
362
|
|
|
if(!$this->hasOption('js.lib.uri')) |
363
|
|
|
{ |
364
|
|
|
// return 'https://cdn.jsdelivr.net/jaxon/1.2.0/'; |
365
|
|
|
return 'https://cdn.jsdelivr.net/gh/jaxon-php/[email protected]/dist/'; |
366
|
|
|
} |
367
|
|
|
// Todo: check the validity of the URI |
368
|
|
|
return rtrim($this->getOption('js.lib.uri'), '/') . '/'; |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
/** |
372
|
|
|
* Get the extension of the Jaxon library javascript files |
373
|
|
|
* |
374
|
|
|
* The returned string is '.min.js' if the files are minified. |
375
|
|
|
* |
376
|
|
|
* @return string |
377
|
|
|
*/ |
378
|
|
|
private function getJsLibExt() |
379
|
|
|
{ |
380
|
|
|
// $jsDelivrUri = 'https://cdn.jsdelivr.net'; |
381
|
|
|
// $nLen = strlen($jsDelivrUri); |
382
|
|
|
// The jsDelivr CDN only hosts minified files |
383
|
|
|
// if(($this->getOption('js.app.minify')) || substr($this->getJsLibUri(), 0, $nLen) == $jsDelivrUri) |
384
|
|
|
// Starting from version 2.0.0 of the js lib, the jsDelivr CDN also hosts non minified files. |
385
|
|
|
if(($this->getOption('js.app.minify'))) |
386
|
|
|
{ |
387
|
|
|
return '.min.js'; |
388
|
|
|
} |
389
|
|
|
return '.js'; |
390
|
|
|
} |
391
|
|
|
|
392
|
|
|
/** |
393
|
|
|
* Check if the javascript code generated by Jaxon can be exported to an external file |
394
|
|
|
* |
395
|
|
|
* @return boolean |
396
|
|
|
*/ |
397
|
|
|
public function canExportJavascript() |
398
|
|
|
{ |
399
|
|
|
// Check config options |
400
|
|
|
// - The js.app.extern option must be set to true |
401
|
|
|
// - The js.app.uri and js.app.dir options must be set to non null values |
402
|
|
|
if(!$this->getOption('js.app.extern') || |
403
|
|
|
!$this->getOption('js.app.uri') || |
404
|
|
|
!$this->getOption('js.app.dir')) |
405
|
|
|
{ |
406
|
|
|
return false; |
407
|
|
|
} |
408
|
|
|
// Check dir access |
409
|
|
|
// - The js.app.dir must be writable |
410
|
|
|
$sJsAppDir = $this->getOption('js.app.dir'); |
411
|
|
|
if(!is_dir($sJsAppDir) || !is_writable($sJsAppDir)) |
412
|
|
|
{ |
413
|
|
|
return false; |
414
|
|
|
} |
415
|
|
|
return true; |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
/** |
419
|
|
|
* Set the cache directory for the template engine |
420
|
|
|
* |
421
|
|
|
* @return void |
422
|
|
|
*/ |
423
|
|
|
private function setTemplateCacheDir() |
424
|
|
|
{ |
425
|
|
|
if($this->hasOption('core.template.cache_dir')) |
426
|
|
|
{ |
427
|
|
|
$this->setCacheDir($this->getOption('core.template.cache_dir')); |
428
|
|
|
} |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
/** |
432
|
|
|
* Get the HTML tags to include Jaxon javascript files into the page |
433
|
|
|
* |
434
|
|
|
* @return string |
435
|
|
|
*/ |
436
|
|
|
public function getJs() |
437
|
|
|
{ |
438
|
|
|
$sJsLibUri = $this->getJsLibUri(); |
439
|
|
|
$sJsLibExt = $this->getJsLibExt(); |
440
|
|
|
$sJsCoreUrl = $sJsLibUri . 'jaxon.core' . $sJsLibExt; |
441
|
|
|
$sJsDebugUrl = $sJsLibUri . 'jaxon.debug' . $sJsLibExt; |
442
|
|
|
// $sJsVerboseUrl = $sJsLibUri . 'jaxon.verbose' . $sJsLibExt; |
443
|
|
|
$sJsLanguageUrl = $sJsLibUri . 'lang/jaxon.' . $this->getOption('core.language') . $sJsLibExt; |
444
|
|
|
|
445
|
|
|
// Add component files to the javascript file array; |
446
|
|
|
$aJsFiles = array($sJsCoreUrl); |
447
|
|
|
if($this->getOption('core.debug.on')) |
448
|
|
|
{ |
449
|
|
|
$aJsFiles[] = $sJsDebugUrl; |
450
|
|
|
$aJsFiles[] = $sJsLanguageUrl; |
451
|
|
|
/*if($this->getOption('core.debug.verbose')) |
452
|
|
|
{ |
453
|
|
|
$aJsFiles[] = $sJsVerboseUrl; |
454
|
|
|
}*/ |
455
|
|
|
} |
456
|
|
|
|
457
|
|
|
// Set the template engine cache dir |
458
|
|
|
$this->setTemplateCacheDir(); |
459
|
|
|
$sCode = $this->render('jaxon::plugins/includes.js', array( |
460
|
|
|
'sJsOptions' => $this->getOption('js.app.options'), |
461
|
|
|
'aUrls' => $aJsFiles, |
462
|
|
|
)); |
463
|
|
|
foreach($this->aResponsePlugins as $xPlugin) |
464
|
|
|
{ |
465
|
|
|
if(($str = trim($xPlugin->getJs()))) |
466
|
|
|
{ |
467
|
|
|
$sCode .= rtrim($str, " \n") . "\n"; |
468
|
|
|
} |
469
|
|
|
} |
470
|
|
|
foreach($this->aPackages as $sClass) |
471
|
|
|
{ |
472
|
|
|
$xPackage = jaxon()->di()->get($sClass); |
473
|
|
|
if(($str = trim($xPackage->js()))) |
474
|
|
|
{ |
475
|
|
|
$sCode .= rtrim($str, " \n") . "\n"; |
476
|
|
|
} |
477
|
|
|
} |
478
|
|
|
return $sCode; |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
/** |
482
|
|
|
* Get the HTML tags to include Jaxon CSS code and files into the page |
483
|
|
|
* |
484
|
|
|
* @return string |
485
|
|
|
*/ |
486
|
|
View Code Duplication |
public function getCss() |
|
|
|
|
487
|
|
|
{ |
488
|
|
|
// Set the template engine cache dir |
489
|
|
|
$this->setTemplateCacheDir(); |
490
|
|
|
|
491
|
|
|
$sCode = ''; |
492
|
|
|
foreach($this->aResponsePlugins as $xPlugin) |
493
|
|
|
{ |
494
|
|
|
if(($str = trim($xPlugin->getCss()))) |
495
|
|
|
{ |
496
|
|
|
$sCode .= rtrim($str, " \n") . "\n"; |
497
|
|
|
} |
498
|
|
|
} |
499
|
|
|
foreach($this->aPackages as $sClass) |
500
|
|
|
{ |
501
|
|
|
$xPackage = jaxon()->di()->get($sClass); |
502
|
|
|
if(($str = trim($xPackage->css()))) |
503
|
|
|
{ |
504
|
|
|
$sCode .= rtrim($str, " \n") . "\n"; |
505
|
|
|
} |
506
|
|
|
} |
507
|
|
|
return $sCode; |
508
|
|
|
} |
509
|
|
|
|
510
|
|
|
/** |
511
|
|
|
* Get the correspondances between previous and current config options |
512
|
|
|
* |
513
|
|
|
* They are used to keep the deprecated config options working. |
514
|
|
|
* They will be removed when the deprecated options will lot be supported anymore. |
515
|
|
|
* |
516
|
|
|
* @return array |
517
|
|
|
*/ |
518
|
|
|
private function getOptionVars() |
519
|
|
|
{ |
520
|
|
|
return array( |
521
|
|
|
'sResponseType' => self::RESPONSE_TYPE, |
522
|
|
|
'sVersion' => $this->getOption('core.version'), |
523
|
|
|
'sLanguage' => $this->getOption('core.language'), |
524
|
|
|
'bLanguage' => $this->hasOption('core.language') ? true : false, |
525
|
|
|
'sRequestURI' => $this->getOption('core.request.uri'), |
526
|
|
|
'sDefaultMode' => $this->getOption('core.request.mode'), |
527
|
|
|
'sDefaultMethod' => $this->getOption('core.request.method'), |
528
|
|
|
'sCsrfMetaName' => $this->getOption('core.request.csrf_meta'), |
529
|
|
|
'bDebug' => $this->getOption('core.debug.on'), |
530
|
|
|
'bVerboseDebug' => $this->getOption('core.debug.verbose'), |
531
|
|
|
'sDebugOutputID' => $this->getOption('core.debug.output_id'), |
532
|
|
|
'nResponseQueueSize' => $this->getOption('js.lib.queue_size'), |
533
|
|
|
'sStatusMessages' => $this->getOption('js.lib.show_status') ? 'true' : 'false', |
534
|
|
|
'sWaitCursor' => $this->getOption('js.lib.show_cursor') ? 'true' : 'false', |
535
|
|
|
'sDefer' => $this->getOption('js.app.options'), |
536
|
|
|
); |
537
|
|
|
} |
538
|
|
|
|
539
|
|
|
/** |
540
|
|
|
* Get the javascript code for Jaxon client side configuration |
541
|
|
|
* |
542
|
|
|
* @return string |
543
|
|
|
*/ |
544
|
|
|
private function getConfigScript() |
545
|
|
|
{ |
546
|
|
|
$aVars = $this->getOptionVars(); |
547
|
|
|
$sYesScript = 'jaxon.ajax.response.process(command.response)'; |
548
|
|
|
$sNoScript = 'jaxon.confirm.skip(command);jaxon.ajax.response.process(command.response)'; |
549
|
|
|
$sConfirmScript = $this->getConfirm()->confirm('msg', $sYesScript, $sNoScript); |
550
|
|
|
$aVars['sConfirmScript'] = $this->render('jaxon::plugins/confirm.js', array('sConfirmScript' => $sConfirmScript)); |
551
|
|
|
|
552
|
|
|
return $this->render('jaxon::plugins/config.js', $aVars); |
553
|
|
|
} |
554
|
|
|
|
555
|
|
|
/** |
556
|
|
|
* Get the javascript code to be run after page load |
557
|
|
|
* |
558
|
|
|
* Also call each of the response plugins giving them the opportunity |
559
|
|
|
* to output some javascript to the page being generated. |
560
|
|
|
* |
561
|
|
|
* @return string |
562
|
|
|
*/ |
563
|
|
View Code Duplication |
private function getReadyScript() |
|
|
|
|
564
|
|
|
{ |
565
|
|
|
$sPluginScript = ''; |
566
|
|
|
foreach($this->aResponsePlugins as $xPlugin) |
567
|
|
|
{ |
568
|
|
|
if(($str = trim($xPlugin->getScript()))) |
569
|
|
|
{ |
570
|
|
|
$sPluginScript .= "\n" . trim($str, " \n"); |
571
|
|
|
} |
572
|
|
|
} |
573
|
|
|
foreach($this->aPackages as $sClass) |
574
|
|
|
{ |
575
|
|
|
$xPackage = jaxon()->di()->get($sClass); |
576
|
|
|
if(($str = trim($xPackage->ready()))) |
577
|
|
|
{ |
578
|
|
|
$sPluginScript .= "\n" . trim($str, " \n"); |
579
|
|
|
} |
580
|
|
|
} |
581
|
|
|
|
582
|
|
|
return $this->render('jaxon::plugins/ready.js', ['sPluginScript' => $sPluginScript]); |
583
|
|
|
} |
584
|
|
|
|
585
|
|
|
/** |
586
|
|
|
* Get the javascript code to be sent to the browser |
587
|
|
|
* |
588
|
|
|
* Also call each of the request plugins giving them the opportunity |
589
|
|
|
* to output some javascript to the page being generated. |
590
|
|
|
* This is called only when the page is being loaded initially. |
591
|
|
|
* This is not called when processing a request. |
592
|
|
|
* |
593
|
|
|
* @return string |
594
|
|
|
*/ |
595
|
|
|
private function getAllScripts() |
596
|
|
|
{ |
597
|
|
|
// Get the config and plugins scripts |
598
|
|
|
$sScript = $this->getConfigScript() . "\n" . $this->getReadyScript() . "\n"; |
599
|
|
|
foreach($this->aRequestPlugins as $xPlugin) |
600
|
|
|
{ |
601
|
|
|
$sScript .= "\n" . trim($xPlugin->getScript(), " \n"); |
602
|
|
|
} |
603
|
|
|
return $sScript; |
604
|
|
|
} |
605
|
|
|
|
606
|
|
|
/** |
607
|
|
|
* Get the javascript code to be sent to the browser |
608
|
|
|
* |
609
|
|
|
* Also call each of the request plugins giving them the opportunity |
610
|
|
|
* to output some javascript to the page being generated. |
611
|
|
|
* This is called only when the page is being loaded initially. |
612
|
|
|
* This is not called when processing a request. |
613
|
|
|
* |
614
|
|
|
* @return string |
615
|
|
|
*/ |
616
|
|
|
public function getScript() |
617
|
|
|
{ |
618
|
|
|
// Set the template engine cache dir |
619
|
|
|
$this->setTemplateCacheDir(); |
620
|
|
|
|
621
|
|
|
if($this->canExportJavascript()) |
622
|
|
|
{ |
623
|
|
|
$sJsAppURI = rtrim($this->getOption('js.app.uri'), '/') . '/'; |
624
|
|
|
$sJsAppDir = rtrim($this->getOption('js.app.dir'), '/') . '/'; |
625
|
|
|
|
626
|
|
|
// The plugins scripts are written into the javascript app dir |
627
|
|
|
$sHash = $this->generateHash(); |
628
|
|
|
$sOutFile = $sHash . '.js'; |
629
|
|
|
$sMinFile = $sHash . '.min.js'; |
630
|
|
|
if(!is_file($sJsAppDir . $sOutFile)) |
631
|
|
|
{ |
632
|
|
|
file_put_contents($sJsAppDir . $sOutFile, $this->getAllScripts()); |
633
|
|
|
} |
634
|
|
|
if(($this->getOption('js.app.minify')) && !is_file($sJsAppDir . $sMinFile)) |
635
|
|
|
{ |
636
|
|
|
if(($this->minify($sJsAppDir . $sOutFile, $sJsAppDir . $sMinFile))) |
637
|
|
|
{ |
638
|
|
|
$sOutFile = $sMinFile; |
639
|
|
|
} |
640
|
|
|
} |
641
|
|
|
|
642
|
|
|
// The returned code loads the generated javascript file |
643
|
|
|
$sScript = $this->render('jaxon::plugins/include.js', array( |
644
|
|
|
'sJsOptions' => $this->getOption('js.app.options'), |
645
|
|
|
'sUrl' => $sJsAppURI . $sOutFile, |
646
|
|
|
)); |
647
|
|
|
} |
648
|
|
|
else |
649
|
|
|
{ |
650
|
|
|
// The plugins scripts are wrapped with javascript tags |
651
|
|
|
$sScript = $this->render('jaxon::plugins/wrapper.js', array( |
652
|
|
|
'sJsOptions' => $this->getOption('js.app.options'), |
653
|
|
|
'sScript' => $this->getAllScripts(), |
654
|
|
|
)); |
655
|
|
|
} |
656
|
|
|
|
657
|
|
|
return $sScript; |
658
|
|
|
} |
659
|
|
|
|
660
|
|
|
/** |
661
|
|
|
* Find the specified response plugin by name and return a reference to it if one exists |
662
|
|
|
* |
663
|
|
|
* @param string $sName The name of the plugin |
664
|
|
|
* |
665
|
|
|
* @return \Jaxon\Plugin\Response |
666
|
|
|
*/ |
667
|
|
|
public function getResponsePlugin($sName) |
668
|
|
|
{ |
669
|
|
|
if(array_key_exists($sName, $this->aResponsePlugins)) |
670
|
|
|
{ |
671
|
|
|
return $this->aResponsePlugins[$sName]; |
672
|
|
|
} |
673
|
|
|
return null; |
674
|
|
|
} |
675
|
|
|
|
676
|
|
|
/** |
677
|
|
|
* Find the specified request plugin by name and return a reference to it if one exists |
678
|
|
|
* |
679
|
|
|
* @param string $sName The name of the plugin |
680
|
|
|
* |
681
|
|
|
* @return \Jaxon\Plugin\Request |
682
|
|
|
*/ |
683
|
|
|
public function getRequestPlugin($sName) |
684
|
|
|
{ |
685
|
|
|
if(array_key_exists($sName, $this->aRequestPlugins)) |
686
|
|
|
{ |
687
|
|
|
return $this->aRequestPlugins[$sName]; |
688
|
|
|
} |
689
|
|
|
return null; |
690
|
|
|
} |
691
|
|
|
} |
692
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.