Completed
Push — master ( 69716e...1c0988 )
by Fabio
10:12
created

TClientScriptManager::getStylePackageFolder()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
/**
3
 * TClientScriptManager and TClientSideOptions class file.
4
 *
5
 * @author Qiang Xue <[email protected]>
6
 * @author Gabor Berczi <[email protected]> (lazyload additions & progressive rendering)
7
 * @link https://github.com/pradosoft/prado4
8
 * @copyright Copyright &copy; 2005-2016 The PRADO Group
9
 * @license https://github.com/pradosoft/prado4/blob/master/LICENSE
10
 * @package Prado\Web\UI
11
 */
12
13
namespace Prado\Web\UI;
14
use Prado\Prado;
15
use Prado\TApplicationMode;
16
use Prado\Exceptions\TInvalidDataValueException;
17
use Prado\Exceptions\TInvalidOperationException;
18
use Prado\Web\Javascripts\TJavaScript;
19
use Prado\Web\UI\ActiveControls\ICallbackEventHandler;
20
use Prado\Web\THttpUtility;
21
22
/**
23
 * TClientScriptManager class.
24
 *
25
 * TClientScriptManager manages javascript and CSS stylesheets for a page.
26
 *
27
 * @author Qiang Xue <[email protected]>
28
 * @author Gabor Berczi <[email protected]> (lazyload additions & progressive rendering)
29
 * @package Prado\Web\UI
30
 * @since 3.0
31
 */
32
class TClientScriptManager extends \Prado\TApplicationComponent
33
{
34
	/**
35
	 * file containing javascript packages and their cross dependencies
36
	 */
37
	const PACKAGES_FILE='Web/Javascripts/packages.php';
38
	/**
39
	 * file containing css packages and their cross dependencies
40
	 */
41
	const CSS_PACKAGES_FILE='Web/Javascripts/css-packages.php';
42
	/**
43
	 * @var TPage page who owns this manager
44
	 */
45
	private $_page;
46
	/**
47
	 * @var array registered hidden fields, indexed by hidden field names
48
	 */
49
	private $_hiddenFields=array();
50
	/**
51
	 * @var array javascript blocks to be rendered at the beginning of the form
52
	 */
53
	private $_beginScripts=array();
54
	/**
55
	 * @var array javascript blocks to be rendered at the end of the form
56
	 */
57
	private $_endScripts=array();
58
	/**
59
	 * @var array javascript files to be rendered in the form
60
	 */
61
	private $_scriptFiles=array();
62
	/**
63
	 * @var array javascript files to be rendered in page head section
64
	 */
65
	private $_headScriptFiles=array();
66
	/**
67
	 * @var array javascript blocks to be rendered in page head section
68
	 */
69
	private $_headScripts=array();
70
	/**
71
	 * @var array CSS files
72
	 */
73
	private $_styleSheetFiles=array();
74
	/**
75
	 * @var array CSS declarations
76
	 */
77
	private $_styleSheets=array();
78
	/**
79
	 * @var array registered PRADO script libraries
80
	 */
81
	private $_registeredScripts=array();
82
	/**
83
	 * Client-side javascript library dependencies, loads from PACKAGES_FILE;
84
	 * @var array
85
	 */
86
	private static $_scripts;
87
	/**
88
	 * Client-side javascript library packages, loads from PACKAGES_FILE;
89
	 * @var array
90
	 */
91
	private static $_scriptsPackages;
92
	/**
93
	 * Client-side javascript library source folders, loads from PACKAGES_FILE;
94
	 * @var array
95
	 */
96
	private static $_scriptsFolders;
97
	/**
98
	 * @var array registered PRADO style libraries
99
	 */
100
	private $_registeredStyles=array();
101
	/**
102
	 * Client-side style library dependencies, loads from CSS_PACKAGES_FILE;
103
	 * @var array
104
	 */
105
	private static $_styles;
106
	/**
107
	 * Client-side style library packages, loads from CSS_PACKAGES_FILE;
108
	 * @var array
109
	 */
110
	private static $_stylesPackages;
111
	/**
112
	 * Client-side style library folders, loads from CSS_PACKAGES_FILE;
113
	 * @var array
114
	 */
115
	private static $_stylesFolders;
116
117
	private $_renderedHiddenFields;
118
119
	private $_renderedScriptFiles=array();
120
121
	private $_expandedScripts;
122
	private $_expandedStyles;
123
124
	/**
125
	 * Constructor.
126
	 * @param TPage page that owns this client script manager
127
	 */
128
	public function __construct(TPage $owner)
129
	{
130
		$this->_page=$owner;
131
	}
132
133
	/**
134
	 * @return boolean whether THead is required in order to render CSS and js within head
135
	 * @since 3.1.1
136
	 */
137
	public function getRequiresHead()
138
	{
139
		return count($this->_styleSheetFiles) || count($this->_styleSheets)
140
			|| count($this->_headScriptFiles) || count($this->_headScripts);
141
	}
142
143
	public static function getPradoPackages()
144
	{
145
		return self::$_scriptsPackages;
146
	}
147
148
	public static function getPradoScripts()
149
	{
150
		return self::$_scripts;
151
	}
152
153
	/**
154
	 * Registers Prado javascript by library name. See "Web/Javascripts/packages.php"
155
	 * for library names.
156
	 * @param string script library name.
157
	 */
158
	public function registerPradoScript($name)
159
	{
160
		$this->registerPradoScriptInternal($name);
161
		$params=func_get_args();
162
		$this->_page->registerCachingAction('Page.ClientScript','registerPradoScript',$params);
163
	}
164
165
	/**
166
	 * Registers a Prado javascript library to be loaded.
167
	 */
168
	protected function registerPradoScriptInternal($name)
169
	{
170
		// $this->checkIfNotInRender();
171
		if(!isset($this->_registeredScripts[$name]))
172
		{
173
			if(self::$_scripts === null)
174
			{
175
				$packageFile = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::PACKAGES_FILE;
176
				list($folders, $packages, $deps)= include($packageFile);
177
				self::$_scriptsFolders = $folders;
178
				self::$_scripts = $deps;
179
				self::$_scriptsPackages = $packages;
180
			}
181
182
			if (isset(self::$_scripts[$name]))
183
				$this->_registeredScripts[$name]=true;
184
			else
185
				throw new TInvalidOperationException('csmanager_pradoscript_invalid',$name);
186
187
			if(($packages=array_keys($this->_registeredScripts))!==array())
188
			{
189
				$packagesUrl=array();
190
				$isDebug=$this->getApplication()->getMode()===TApplicationMode::Debug;
191
				foreach ($packages as $p)
192
				{
193
					foreach (self::$_scripts[$p] as $dep)
194
					{
195
						foreach (self::$_scriptsPackages[$dep] as $script)
196
						{
197
							if (!isset($this->_expandedScripts[$script]))
198
							{
199
								list($base, $subPath) = $this->getScriptPackageFolder($script);
200
								list($path, $baseUrl) = $this->getPackagePathUrl($base);
201
202
								$this->_expandedScripts[$script] = true;
203
								if($isDebug)
204
								{
205
									if (!in_array($url=$baseUrl.'/'.$subPath, $packagesUrl))
206
										$packagesUrl[]=$url;
207
								} else {
208
									if (!in_array($url=$baseUrl.'/min/'.$subPath, $packagesUrl))
209
									{
210
										if(!is_file($filePath=$path.'/min/'.$subPath))
211
										{
212
											$dirPath=dirname($filePath);
213
											if(!is_dir($dirPath))
214
												mkdir($dirPath, PRADO_CHMOD, true);
215
											file_put_contents($filePath, TJavaScript::JSMin(file_get_contents($base.'/'.$subPath)));
216
											chmod($filePath, PRADO_CHMOD);
217
										}
218
										$packagesUrl[]=$url;
219
									}
220
								}
221
							}
222
						}
223
					}
224
				}
225
				foreach($packagesUrl as $url)
226
					$this->registerScriptFile($url,$url);
227
			}
228
		}
229
	}
230
231
	/**
232
	 * @return string Prado javascript library base asset url.
233
	 */
234
	public function getPradoScriptAssetUrl($script='prado')
235
	{
236
		if(!array_key_exists($script, self::$_scriptsFolders))
237
			throw new TInvalidOperationException('csmanager_pradostyle_invalid',$script);
238
		
239
		$base = Prado::getPathOfNameSpace(self::$_scriptsFolders[$script]);
240
		$assets = Prado::getApplication()->getAssetManager();
241
		return $assets->publishFilePath($base);
242
	}
243
244
	/**
245
	 * Returns the URLs of all script files referenced on the page
246
	 * @return array Combined list of all script urls used in the page
247
	 */
248
	public function getScriptUrls()
249
	{
250
		$scripts = array_values($this->_headScriptFiles);
251
		$scripts = array_merge($scripts, array_values($this->_scriptFiles));
252
		$scripts = array_unique($scripts);
253
254
		return $scripts;
255
	}
256
257
	/**
258
	 * @param string javascript or css package path.
259
	 * @return array tuple($path,$url).
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use string[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
260
	 */
261
	protected function getPackagePathUrl($base)
262
	{
263
		$assets = Prado::getApplication()->getAssetManager();
264
		if(strpos($base, $assets->getBaseUrl())===false)
265
		{
266
			if(($dir = Prado::getPathOfNameSpace($base)) !== null) {
267
				$base = $dir;
268
			}
269
			return array($assets->getPublishedPath($base), $assets->publishFilePath($base));
270
		}
271
		else
272
		{
273
			return array($assets->getBasePath().str_replace($assets->getBaseUrl(),'',$base), $base);
274
		}
275
	}
276
277
	/**
278
	 * @param string javascript package source folder path.
279
	 * @return array tuple($basepath,$subpath).
280
	 */
281
	protected function getScriptPackageFolder($script)
282
	{
283
		list($base, $subPath) = explode("/", $script, 2);
284
285
		if(!array_key_exists($base, self::$_scriptsFolders))
286
			throw new TInvalidOperationException('csmanager_pradostyle_invalid',$base);
287
		
288
		return array(self::$_scriptsFolders[$base], $subPath);
289
	}
290
291
	/**
292
	 * @param string css package source folder path.
293
	 * @return array tuple($basepath,$subpath).
294
	 */
295
	protected function getStylePackageFolder($script)
296
	{
297
		list($base, $subPath) = explode("/", $script, 2);
298
299
		if(!array_key_exists($base, self::$_stylesFolders))
300
			throw new TInvalidOperationException('csmanager_pradostyle_invalid',$base);
301
		
302
		return array(self::$_stylesFolders[$base], $subPath);
303
	}
304
305
	/**
306
	 * Returns javascript statement that create a new callback request object.
307
	 * @param ICallbackEventHandler callback response handler
308
	 * @param array additional callback options
309
	 * @return string javascript statement that creates a new callback request.
310
	 */
311
	public function getCallbackReference(ICallbackEventHandler $callbackHandler, $options=null)
312
	{
313
		$options = !is_array($options) ? array() : $options;
314
		$class = new \ReflectionClass($callbackHandler);
0 ignored issues
show
Unused Code introduced by
$class 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...
315
		$clientSide = $callbackHandler->getActiveControl()->getClientSide();
316
		$options = array_merge($options, $clientSide->getOptions()->toArray());
317
		$optionString = TJavaScript::encode($options);
318
		$this->registerPradoScriptInternal('ajax');
319
		$id = $callbackHandler->getUniqueID();
320
		return "new Prado.CallbackRequest('{$id}',{$optionString})";
321
	}
322
323
	/**
324
	 * Registers callback javascript for a control.
325
	 * @param string javascript class responsible for the control being registered for callback
326
	 * @param array callback options
327
	 */
328
	public function registerCallbackControl($class, $options)
329
	{
330
		$optionString=TJavaScript::encode($options);
331
		$code="new {$class}({$optionString});";
332
		$this->_endScripts[sprintf('%08X', crc32($code))]=$code;
333
		$this->registerPradoScriptInternal('ajax');
334
335
		$params=func_get_args();
336
		$this->_page->registerCachingAction('Page.ClientScript','registerCallbackControl',$params);
337
	}
338
339
	/**
340
	 * Registers postback javascript for a control. A null class parameter will prevent
341
	 * the javascript code registration.
342
	 * @param string javascript class responsible for the control being registered for postback
343
	 * @param array postback options
344
	 */
345
	public function registerPostBackControl($class,$options)
346
	{
347
		if($class === null) {
348
			return;
349
		}
350
		if(!isset($options['FormID']) && ($form=$this->_page->getForm())!==null)
351
			$options['FormID']=$form->getClientID();
352
		$optionString=TJavaScript::encode($options);
353
		$code="new {$class}({$optionString});";
354
355
		$this->_endScripts[sprintf('%08X', crc32($code))]=$code;
356
		$this->registerPradoScriptInternal('prado');
357
358
		$params=func_get_args();
359
		$this->_page->registerCachingAction('Page.ClientScript','registerPostBackControl',$params);
360
	}
361
362
	/**
363
	 * Register a default button to panel. When the $panel is in focus and
364
	 * the 'enter' key is pressed, the $button will be clicked.
365
	 * @param TControl|string panel (or its unique ID) to register the default button action
366
	 * @param TControl|string button (or its unique ID) to trigger a postback
367
	 */
368
	public function registerDefaultButton($panel, $button)
369
	{
370
		$panelID=is_string($panel)?$panel:$panel->getUniqueID();
371
372
		if(is_string($button))
373
			$buttonID=$button;
374
		else
375
		{
376
			$button->setIsDefaultButton(true);
377
			$buttonID=$button->getUniqueID();
378
		}
379
		$options = TJavaScript::encode($this->getDefaultButtonOptions($panelID, $buttonID));
380
		$code = "new Prado.WebUI.DefaultButton($options);";
381
382
		$this->_endScripts['prado:'.$panelID]=$code;
383
		$this->registerPradoScriptInternal('prado');
384
385
		$params=array($panelID,$buttonID);
386
		$this->_page->registerCachingAction('Page.ClientScript','registerDefaultButton',$params);
387
	}
388
389
	/**
390
	 * @param string the unique ID of the container control
391
	 * @param string the unique ID of the button control
392
	 * @return array default button options.
393
	 */
394
	protected function getDefaultButtonOptions($panelID, $buttonID)
395
	{
396
		$options['ID'] = TControl::convertUniqueIdToClientId($panelID);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$options was never initialized. Although not strictly required by PHP, it is generally a good practice to add $options = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
397
		$options['Panel'] = TControl::convertUniqueIdToClientId($panelID);
398
		$options['Target'] = TControl::convertUniqueIdToClientId($buttonID);
399
		$options['EventTarget'] = $buttonID;
400
		$options['Event'] = 'click';
401
		return $options;
402
	}
403
404
	/**
405
	 * Registers the control to receive default focus.
406
	 * @param string the client ID of the control to receive default focus
407
	 */
408
	public function registerFocusControl($target)
409
	{
410
		$this->registerPradoScriptInternal('jquery');
411
		if($target instanceof TControl)
412
			$target=$target->getClientID();
413
		$this->_endScripts['prado:focus'] = 'jQuery(\'#'.$target.'\').focus();';
414
415
		$params=func_get_args();
416
		$this->_page->registerCachingAction('Page.ClientScript','registerFocusControl',$params);
417
	}
418
419
	/**
420
	 * Registers Prado style by library name. See "Web/Javascripts/packages.php"
421
	 * for library names.
422
	 * @param string style library name.
423
	 */
424
	public function registerPradoStyle($name)
425
	{
426
		$this->registerPradoStyleInternal($name);
427
		$params=func_get_args();
428
		$this->_page->registerCachingAction('Page.ClientScript','registerPradoStyle',$params);
429
	}
430
431
	/**
432
	 * Registers a Prado style library to be loaded.
433
	 */
434
	protected function registerPradoStyleInternal($name)
435
	{
436
		// $this->checkIfNotInRender();
437
		if(!isset($this->_registeredStyles[$name]))
438
		{
439
			$base = $this->getPradoScriptAssetUrl();
440
441
			if(self::$_styles === null)
442
			{
443
				$packageFile = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::CSS_PACKAGES_FILE;
444
				list($folders, $packages,$deps)= include($packageFile);
445
				self::$_stylesFolders = $folders;
446
				self::$_styles = $deps;
447
				self::$_stylesPackages = $packages;
448
			}
449
450
			if (isset(self::$_styles[$name]))
451
				$this->_registeredStyles[$name]=true;
452
			else
453
				throw new TInvalidOperationException('csmanager_pradostyle_invalid',$name);
454
455
			if(($packages=array_keys($this->_registeredStyles))!==array())
456
			{
457
				$packagesUrl=array();
458
				$isDebug=$this->getApplication()->getMode()===TApplicationMode::Debug;
0 ignored issues
show
Unused Code introduced by
$isDebug 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...
459
				foreach ($packages as $p)
460
				{
461
					foreach (self::$_styles[$p] as $dep)
462
					{
463
						foreach (self::$_stylesPackages[$dep] as $style)
464
						{
465
							if (!isset($this->_expandedStyles[$style]))
466
							{
467
								list($base, $subPath) = $this->getStylePackageFolder($style);
468
								list($path, $baseUrl) = $this->getPackagePathUrl($base);
0 ignored issues
show
Unused Code introduced by
The assignment to $path is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
469
470
								$this->_expandedStyles[$style] = true;
471
								// TODO minify css?
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
472
								if (!in_array($url=$baseUrl.'/'.$subPath, $packagesUrl))
473
									$packagesUrl[]=$url;
474
							}
475
						}
476
					}
477
				}
478
				foreach($packagesUrl as $url)
479
					$this->registerStyleSheetFile($url,$url);
480
			}
481
		}
482
	}
483
484
	/**
485
	 * Registers a CSS file to be rendered in the page head
486
	 *
487
	 * The CSS files in themes are registered in {@link OnPreRenderComplete onPreRenderComplete} if you want to override
488
	 * CSS styles in themes you need to register it after this event is completed.
489
	 *
490
	 * Example:
491
	 * <code>
492
	 * <?php
493
	 * class BasePage extends TPage {
494
	 *   public function onPreRenderComplete($param) {
495
	 *     parent::onPreRenderComplete($param);
496
	 *     $url = 'path/to/your/stylesheet.css';
497
	 *     $this->Page->ClientScript->registerStyleSheetFile($url, $url);
498
	 *   }
499
	 * }
500
	 * </code>
501
	 *
502
	 * @param string a unique key identifying the file
503
	 * @param string URL to the CSS file
504
	 * @param string media type of the CSS (such as 'print', 'screen', etc.). Defaults to empty, meaning the CSS applies to all media types.
505
	 */
506
	public function registerStyleSheetFile($key,$url,$media='')
507
	{
508
		if($media==='')
509
			$this->_styleSheetFiles[$key]=$url;
510
		else
511
			$this->_styleSheetFiles[$key]=array($url,$media);
512
513
		$params=func_get_args();
514
		$this->_page->registerCachingAction('Page.ClientScript','registerStyleSheetFile',$params);
515
	}
516
517
	/**
518
	 * Registers a CSS block to be rendered in the page head
519
	 * @param string a unique key identifying the CSS block
520
	 * @param string CSS block
521
	 */
522
	public function registerStyleSheet($key,$css,$media='')
523
	{
524
		$this->_styleSheets[$key]=$css;
525
526
		$params=func_get_args();
527
		$this->_page->registerCachingAction('Page.ClientScript','registerStyleSheet',$params);
528
	}
529
530
	/**
531
	 * Returns the URLs of all stylesheet files referenced on the page
532
	 * @return array List of all stylesheet urls used in the page
533
	 */
534
	public function getStyleSheetUrls()
535
	{
536
		$stylesheets = array_values(
537
			array_map(function($e) {
538
				return is_array($e) ? $e[0] : $e;
539
			}, $this->_styleSheetFiles)
540
		);
541
542
		foreach(Prado::getApplication()->getAssetManager()->getPublished() as $path=>$url)
543
			if (substr($url,strlen($url)-4)=='.css')
544
				$stylesheets[] = $url;
545
546
		$stylesheets = array_unique($stylesheets);
547
548
		return $stylesheets;
549
	}
550
551
	/**
552
	 * Returns all the stylesheet code snippets referenced on the page
553
	 * @return array List of all stylesheet snippets used in the page
554
	 */
555
	public function getStyleSheetCodes()
556
	{
557
		return array_unique(array_values($this->_styleSheets));
558
	}
559
560
	/**
561
	 * Registers a javascript file in the page head
562
	 * @param string a unique key identifying the file
563
	 * @param string URL to the javascript file
564
	 */
565
	public function registerHeadScriptFile($key,$url)
566
	{
567
		$this->checkIfNotInRender();
568
		$this->_headScriptFiles[$key]=$url;
569
570
		$params=func_get_args();
571
		$this->_page->registerCachingAction('Page.ClientScript','registerHeadScriptFile',$params);
572
	}
573
574
	/**
575
	 * Registers a javascript block in the page head.
576
	 * @param string a unique key identifying the script block
577
	 * @param string javascript block
578
	 */
579
	public function registerHeadScript($key,$script)
580
	{
581
		$this->checkIfNotInRender();
582
		$this->_headScripts[$key]=$script;
583
584
		$params=func_get_args();
585
		$this->_page->registerCachingAction('Page.ClientScript','registerHeadScript',$params);
586
	}
587
588
	/**
589
	 * Registers a javascript file to be rendered within the form
590
	 * @param string a unique key identifying the file
591
	 * @param string URL to the javascript file to be rendered
592
	 */
593
	public function registerScriptFile($key, $url)
594
	{
595
		$this->_scriptFiles[$key]=$url;
596
597
		$params=func_get_args();
598
		$this->_page->registerCachingAction('Page.ClientScript','registerScriptFile',$params);
599
	}
600
601
	/**
602
	 * Registers a javascript script block at the beginning of the form
603
	 * @param string a unique key identifying the script block
604
	 * @param string javascript block
605
	 */
606
	public function registerBeginScript($key,$script)
607
	{
608
		$this->checkIfNotInRender();
609
		$this->_beginScripts[$key]=$script;
610
611
		$params=func_get_args();
612
		$this->_page->registerCachingAction('Page.ClientScript','registerBeginScript',$params);
613
	}
614
615
	/**
616
	 * Registers a javascript script block at the end of the form
617
	 * @param string a unique key identifying the script block
618
	 * @param string javascript block
619
	 */
620
	public function registerEndScript($key,$script)
621
	{
622
		$this->_endScripts[$key]=$script;
623
624
		$params=func_get_args();
625
		$this->_page->registerCachingAction('Page.ClientScript','registerEndScript',$params);
626
	}
627
628
	/**
629
	 * Registers a hidden field to be rendered in the form.
630
	 * @param string a unique key identifying the hidden field
631
	 * @param string|array hidden field value, if the value is an array, every element
632
	 * in the array will be rendered as a hidden field value.
633
	 */
634
	public function registerHiddenField($name,$value)
635
	{
636
		$this->_hiddenFields[$name]=$value;
637
638
		$params=func_get_args();
639
		$this->_page->registerCachingAction('Page.ClientScript','registerHiddenField',$params);
640
	}
641
642
	/**
643
	 * @param string a unique key
644
	 * @return boolean whether there is a CSS file registered with the specified key
645
	 */
646
	public function isStyleSheetFileRegistered($key)
647
	{
648
		return isset($this->_styleSheetFiles[$key]);
649
	}
650
651
	/**
652
	 * @param string a unique key
653
	 * @return boolean whether there is a CSS block registered with the specified key
654
	 */
655
	public function isStyleSheetRegistered($key)
656
	{
657
		return isset($this->_styleSheets[$key]);
658
	}
659
660
	/**
661
	 * @param string a unique key
662
	 * @return boolean whether there is a head javascript file registered with the specified key
663
	 */
664
	public function isHeadScriptFileRegistered($key)
665
	{
666
		return isset($this->_headScriptFiles[$key]);
667
	}
668
669
	/**
670
	 * @param string a unique key
671
	 * @return boolean whether there is a head javascript block registered with the specified key
672
	 */
673
	public function isHeadScriptRegistered($key)
674
	{
675
		return isset($this->_headScripts[$key]);
676
	}
677
678
	/**
679
	 * @param string a unique key
680
	 * @return boolean whether there is a javascript file registered with the specified key
681
	 */
682
	public function isScriptFileRegistered($key)
683
	{
684
		return isset($this->_scriptFiles[$key]);
685
	}
686
687
	/**
688
	 * @param string a unique key
689
	 * @return boolean whether there is a beginning javascript block registered with the specified key
690
	 */
691
	public function isBeginScriptRegistered($key)
692
	{
693
		return isset($this->_beginScripts[$key]);
694
	}
695
696
	/**
697
	 * @param string a unique key
698
	 * @return boolean whether there is an ending javascript block registered with the specified key
699
	 */
700
	public function isEndScriptRegistered($key)
701
	{
702
		return isset($this->_endScripts[$key]);
703
	}
704
705
	/**
706
	 * @return boolean true if any end scripts are registered.
707
	 */
708
	public function hasEndScripts()
709
	{
710
		return count($this->_endScripts) > 0;
711
	}
712
713
	/**
714
	 * @return boolean true if any begin scripts are registered.
715
	 */
716
	public function hasBeginScripts()
717
	{
718
		return count($this->_beginScripts) > 0;
719
	}
720
721
	/**
722
	 * @param string a unique key
723
	 * @return boolean whether there is a hidden field registered with the specified key
724
	 */
725
	public function isHiddenFieldRegistered($key)
726
	{
727
		return isset($this->_hiddenFields[$key]);
728
	}
729
730
	/**
731
	 * @param THtmlWriter writer for the rendering purpose
732
	 */
733
	public function renderStyleSheetFiles($writer)
734
	{
735
		$str='';
736
		foreach($this->_styleSheetFiles as $url)
737
		{
738
			if(is_array($url))
739
				$str.="<link rel=\"stylesheet\" type=\"text/css\" media=\"{$url[1]}\" href=\"".THttpUtility::htmlEncode($url[0])."\" />\n";
740
			else
741
				$str.="<link rel=\"stylesheet\" type=\"text/css\" href=\"".THttpUtility::htmlEncode($url)."\" />\n";
742
		}
743
		$writer->write($str);
744
	}
745
746
	/**
747
	 * @param THtmlWriter writer for the rendering purpose
748
	 */
749
	public function renderStyleSheets($writer)
750
	{
751
		if(count($this->_styleSheets))
752
			$writer->write("<style type=\"text/css\">\n/*<![CDATA[*/\n".implode("\n",$this->_styleSheets)."\n/*]]>*/\n</style>\n");
753
	}
754
755
	/**
756
	 * @param THtmlWriter writer for the rendering purpose
757
	 */
758
	public function renderHeadScriptFiles($writer)
759
	{
760
		$this->renderScriptFiles($writer,$this->_headScriptFiles);
761
	}
762
763
	/**
764
	 * @param THtmlWriter writer for the rendering purpose
765
	 */
766
	public function renderHeadScripts($writer)
767
	{
768
		$writer->write(TJavaScript::renderScriptBlocks($this->_headScripts));
769
	}
770
771
	public function renderScriptFilesBegin($writer)
772
	{
773
		$this->renderAllPendingScriptFiles($writer);
774
	}
775
776
	public function renderScriptFilesEnd($writer)
777
	{
778
		$this->renderAllPendingScriptFiles($writer);
779
	}
780
781
	public function markScriptFileAsRendered($url)
782
	{
783
		$this->_renderedScriptFiles[$url] = $url;
784
		$params=func_get_args();
785
		$this->_page->registerCachingAction('Page.ClientScript','markScriptFileAsRendered',$params);
786
	}
787
788
	protected function renderScriptFiles($writer, Array $scripts)
789
	{
790
		foreach($scripts as $script)
791
		{
792
			$writer->write(TJavaScript::renderScriptFile($script));
793
			$this->markScriptFileAsRendered($script);
794
		}
795
	}
796
797
	protected function getRenderedScriptFiles()
798
	{
799
		return $this->_renderedScriptFiles;
800
	}
801
802
	/**
803
	 * @param THtmlWriter writer for the rendering purpose
804
	 */
805
	public function renderAllPendingScriptFiles($writer)
806
	{
807
		if(!empty($this->_scriptFiles))
808
		{
809
			$addedScripts = array_diff($this->_scriptFiles,$this->getRenderedScriptFiles());
810
			$this->renderScriptFiles($writer,$addedScripts);
811
		}
812
	}
813
814
	/**
815
	 * @param THtmlWriter writer for the rendering purpose
816
	 */
817
	public function renderBeginScripts($writer)
818
	{
819
		$writer->write(TJavaScript::renderScriptBlocks($this->_beginScripts));
820
	}
821
822
	/**
823
	 * @param THtmlWriter writer for the rendering purpose
824
	 */
825
	public function renderEndScripts($writer)
826
	{
827
		$writer->write(TJavaScript::renderScriptBlocks($this->_endScripts));
828
	}
829
830
	/**
831
	 * @param THtmlWriter writer for the rendering purpose
832
	 */
833
	public function renderBeginScriptsCallback($writer)
834
	{
835
		$writer->write(TJavaScript::renderScriptBlocksCallback($this->_beginScripts));
836
	}
837
838
	/**
839
	 * @param THtmlWriter writer for the rendering purpose
840
	 */
841
	public function renderEndScriptsCallback($writer)
842
	{
843
		$writer->write(TJavaScript::renderScriptBlocksCallback($this->_endScripts));
844
	}
845
846
	public function renderHiddenFieldsBegin($writer)
847
	{
848
		$this->renderHiddenFieldsInt($writer,true);
849
	}
850
851
	public function renderHiddenFieldsEnd($writer)
852
	{
853
		$this->renderHiddenFieldsInt($writer,false);
854
	}
855
856
	/**
857
	 * Flushes all pending script registrations
858
	 * @param THtmlWriter writer for the rendering purpose
859
	 * @param TControl the control forcing the flush (used only in error messages)
860
	 */
861
	public function flushScriptFiles($writer, $control=null)
862
	{
863
		if(!$this->_page->getIsCallback())
864
		{
865
			$this->_page->ensureRenderInForm($control);
866
			$this->renderAllPendingScriptFiles($writer);
867
		}
868
	}
869
870
	/**
871
	 * @param THtmlWriter writer for the rendering purpose
872
	 */
873
	protected function renderHiddenFieldsInt($writer, $initial)
874
 	{
875
		if ($initial) $this->_renderedHiddenFields = array();
876
		$str='';
877
		foreach($this->_hiddenFields as $name=>$value)
878
		{
879
			if (in_array($name,$this->_renderedHiddenFields)) continue;
880
			$id=strtr($name,':','_');
881
			if(is_array($value))
882
			{
883
				foreach($value as $v)
884
					$str.='<input type="hidden" name="'.$name.'[]" id="'.$id.'" value="'.THttpUtility::htmlEncode($value)."\" />\n";
885
			}
886
			else
887
			{
888
				$str.='<input type="hidden" name="'.$name.'" id="'.$id.'" value="'.THttpUtility::htmlEncode($value)."\" />\n";
889
			}
890
			$this->_renderedHiddenFields[] = $name;
891
		}
892
		if($str!=='')
893
			$writer->write("<div style=\"visibility:hidden;\">\n".$str."</div>\n");
894
	}
895
896
	public function getHiddenFields()
897
	{
898
		return $this->_hiddenFields;
899
	}
900
901
	/**
902
	 * Checks whether page rendering has not begun yet
903
	 */
904
	protected function checkIfNotInRender()
905
	{
906
		if ($form = $this->_page->InFormRender)
0 ignored issues
show
Bug introduced by
The property InFormRender does not seem to exist. Did you mean _inFormRender?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Unused Code introduced by
$form 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...
907
			throw new \Exception('Operation invalid when page is already rendering');
908
	}
909
}
910