Mercurial > hg > Members > shoshi > webvirt
comparison cake/libs/view/helpers/javascript.php @ 0:261e66bd5a0c
hg init
author | Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 24 Jul 2011 21:08:31 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:261e66bd5a0c |
---|---|
1 <?php | |
2 /** | |
3 * Javascript Helper class file. | |
4 * | |
5 * PHP versions 4 and 5 | |
6 * | |
7 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | |
8 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
9 * | |
10 * Licensed under The MIT License | |
11 * Redistributions of files must retain the above copyright notice. | |
12 * | |
13 * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
14 * @link http://cakephp.org CakePHP(tm) Project | |
15 * @package cake | |
16 * @subpackage cake.cake.libs.view.helpers | |
17 * @since CakePHP(tm) v 0.10.0.1076 | |
18 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) | |
19 */ | |
20 | |
21 /** | |
22 * Javascript Helper class for easy use of JavaScript. | |
23 * | |
24 * JavascriptHelper encloses all methods needed while working with JavaScript. | |
25 * | |
26 * @package cake | |
27 * @subpackage cake.cake.libs.view.helpers | |
28 * @link http://book.cakephp.org/view/1450/Javascript | |
29 */ | |
30 class JavascriptHelper extends AppHelper { | |
31 | |
32 /** | |
33 * Determines whether native JSON extension is used for encoding. Set by object constructor. | |
34 * | |
35 * @var boolean | |
36 * @access public | |
37 */ | |
38 var $useNative = false; | |
39 | |
40 /** | |
41 * If true, automatically writes events to the end of a script or to an external JavaScript file | |
42 * at the end of page execution | |
43 * | |
44 * @var boolean | |
45 * @access public | |
46 */ | |
47 var $enabled = true; | |
48 | |
49 /** | |
50 * Indicates whether <script /> blocks should be written 'safely,' i.e. wrapped in CDATA blocks | |
51 * | |
52 * @var boolean | |
53 * @access public | |
54 */ | |
55 var $safe = false; | |
56 | |
57 /** | |
58 * HTML tags used by this helper. | |
59 * | |
60 * @var array | |
61 * @access public | |
62 */ | |
63 var $tags = array( | |
64 'javascriptstart' => '<script type="text/javascript">', | |
65 'javascriptend' => '</script>', | |
66 'javascriptblock' => '<script type="text/javascript">%s</script>', | |
67 'javascriptlink' => '<script type="text/javascript" src="%s"></script>' | |
68 ); | |
69 | |
70 /** | |
71 * Holds options passed to codeBlock(), saved for when block is dumped to output | |
72 * | |
73 * @var array | |
74 * @access protected | |
75 * @see JavascriptHelper::codeBlock() | |
76 */ | |
77 var $_blockOptions = array(); | |
78 | |
79 /** | |
80 * Caches events written by event() for output at the end of page execution | |
81 * | |
82 * @var array | |
83 * @access protected | |
84 * @see JavascriptHelper::event() | |
85 */ | |
86 var $_cachedEvents = array(); | |
87 | |
88 /** | |
89 * Indicates whether generated events should be cached for later output (can be written at the | |
90 * end of the page, in the <head />, or to an external file). | |
91 * | |
92 * @var boolean | |
93 * @access protected | |
94 * @see JavascriptHelper::event() | |
95 * @see JavascriptHelper::writeEvents() | |
96 */ | |
97 var $_cacheEvents = false; | |
98 | |
99 /** | |
100 * Indicates whether cached events should be written to an external file | |
101 * | |
102 * @var boolean | |
103 * @access protected | |
104 * @see JavascriptHelper::event() | |
105 * @see JavascriptHelper::writeEvents() | |
106 */ | |
107 var $_cacheToFile = false; | |
108 | |
109 /** | |
110 * Indicates whether *all* generated JavaScript should be cached for later output | |
111 * | |
112 * @var boolean | |
113 * @access protected | |
114 * @see JavascriptHelper::codeBlock() | |
115 * @see JavascriptHelper::blockEnd() | |
116 */ | |
117 var $_cacheAll = false; | |
118 | |
119 /** | |
120 * Contains event rules attached with CSS selectors. Used with the event:Selectors JavaScript | |
121 * library. | |
122 * | |
123 * @var array | |
124 * @access protected | |
125 * @see JavascriptHelper::event() | |
126 * @link http://alternateidea.com/event-selectors/ | |
127 */ | |
128 var $_rules = array(); | |
129 | |
130 /** | |
131 * @var string | |
132 * @access private | |
133 */ | |
134 var $__scriptBuffer = null; | |
135 | |
136 /** | |
137 * Constructor. Checks for presence of native PHP JSON extension to use for object encoding | |
138 * | |
139 * @access public | |
140 */ | |
141 function __construct($options = array()) { | |
142 if (!empty($options)) { | |
143 foreach ($options as $key => $val) { | |
144 if (is_numeric($key)) { | |
145 $key = $val; | |
146 $val = true; | |
147 } | |
148 switch ($key) { | |
149 case 'cache': | |
150 | |
151 break; | |
152 case 'safe': | |
153 $this->safe = $val; | |
154 break; | |
155 } | |
156 } | |
157 } | |
158 $this->useNative = function_exists('json_encode'); | |
159 return parent::__construct($options); | |
160 } | |
161 | |
162 /** | |
163 * Returns a JavaScript script tag. | |
164 * | |
165 * Options: | |
166 * | |
167 * - allowCache: boolean, designates whether this block is cacheable using the | |
168 * current cache settings. | |
169 * - safe: boolean, whether this block should be wrapped in CDATA tags. Defaults | |
170 * to helper's object configuration. | |
171 * - inline: whether the block should be printed inline, or written | |
172 * to cached for later output (i.e. $scripts_for_layout). | |
173 * | |
174 * @param string $script The JavaScript to be wrapped in SCRIPT tags. | |
175 * @param array $options Set of options: | |
176 * @return string The full SCRIPT element, with the JavaScript inside it, or null, | |
177 * if 'inline' is set to false. | |
178 */ | |
179 function codeBlock($script = null, $options = array()) { | |
180 if (!empty($options) && !is_array($options)) { | |
181 $options = array('allowCache' => $options); | |
182 } elseif (empty($options)) { | |
183 $options = array(); | |
184 } | |
185 $defaultOptions = array('allowCache' => true, 'safe' => true, 'inline' => true); | |
186 $options = array_merge($defaultOptions, $options); | |
187 | |
188 if (empty($script)) { | |
189 $this->__scriptBuffer = @ob_get_contents(); | |
190 $this->_blockOptions = $options; | |
191 $this->inBlock = true; | |
192 @ob_end_clean(); | |
193 ob_start(); | |
194 return null; | |
195 } | |
196 if ($this->_cacheEvents && $this->_cacheAll && $options['allowCache']) { | |
197 $this->_cachedEvents[] = $script; | |
198 return null; | |
199 } | |
200 if ($options['safe'] || $this->safe) { | |
201 $script = "\n" . '//<![CDATA[' . "\n" . $script . "\n" . '//]]>' . "\n"; | |
202 } | |
203 if ($options['inline']) { | |
204 return sprintf($this->tags['javascriptblock'], $script); | |
205 } else { | |
206 $view =& ClassRegistry::getObject('view'); | |
207 $view->addScript(sprintf($this->tags['javascriptblock'], $script)); | |
208 } | |
209 } | |
210 | |
211 /** | |
212 * Ends a block of cached JavaScript code | |
213 * | |
214 * @return mixed | |
215 */ | |
216 function blockEnd() { | |
217 if (!isset($this->inBlock) || !$this->inBlock) { | |
218 return; | |
219 } | |
220 $script = @ob_get_contents(); | |
221 @ob_end_clean(); | |
222 ob_start(); | |
223 echo $this->__scriptBuffer; | |
224 $this->__scriptBuffer = null; | |
225 $options = $this->_blockOptions; | |
226 $this->_blockOptions = array(); | |
227 $this->inBlock = false; | |
228 | |
229 if (empty($script)) { | |
230 return null; | |
231 } | |
232 | |
233 return $this->codeBlock($script, $options); | |
234 } | |
235 | |
236 /** | |
237 * Returns a JavaScript include tag (SCRIPT element). If the filename is prefixed with "/", | |
238 * the path will be relative to the base path of your application. Otherwise, the path will | |
239 * be relative to your JavaScript path, usually webroot/js. | |
240 * | |
241 * @param mixed $url String URL to JavaScript file, or an array of URLs. | |
242 * @param boolean $inline If true, the <script /> tag will be printed inline, | |
243 * otherwise it will be printed in the <head />, using $scripts_for_layout | |
244 * @see JS_URL | |
245 * @return string | |
246 */ | |
247 function link($url, $inline = true) { | |
248 if (is_array($url)) { | |
249 $out = ''; | |
250 foreach ($url as $i) { | |
251 $out .= "\n\t" . $this->link($i, $inline); | |
252 } | |
253 if ($inline) { | |
254 return $out . "\n"; | |
255 } | |
256 return; | |
257 } | |
258 | |
259 if (strpos($url, '://') === false) { | |
260 if ($url[0] !== '/') { | |
261 $url = JS_URL . $url; | |
262 } | |
263 if (strpos($url, '?') === false) { | |
264 if (substr($url, -3) !== '.js') { | |
265 $url .= '.js'; | |
266 } | |
267 } | |
268 $url = $this->assetTimestamp($this->webroot($url)); | |
269 | |
270 if (Configure::read('Asset.filter.js')) { | |
271 $pos = strpos($url, JS_URL); | |
272 if ($pos !== false) { | |
273 $url = substr($url, 0, $pos) . 'cjs/' . substr($url, $pos + strlen(JS_URL)); | |
274 } | |
275 } | |
276 } | |
277 $out = sprintf($this->tags['javascriptlink'], $url); | |
278 | |
279 if ($inline) { | |
280 return $out; | |
281 } else { | |
282 $view =& ClassRegistry::getObject('view'); | |
283 $view->addScript($out); | |
284 } | |
285 } | |
286 | |
287 /** | |
288 * Escape carriage returns and single and double quotes for JavaScript segments. | |
289 * | |
290 * @param string $script string that might have javascript elements | |
291 * @return string escaped string | |
292 */ | |
293 function escapeScript($script) { | |
294 $script = str_replace(array("\r\n", "\n", "\r"), '\n', $script); | |
295 $script = str_replace(array('"', "'"), array('\"', "\\'"), $script); | |
296 return $script; | |
297 } | |
298 | |
299 /** | |
300 * Escape a string to be JavaScript friendly. | |
301 * | |
302 * List of escaped ellements: | |
303 * + "\r\n" => '\n' | |
304 * + "\r" => '\n' | |
305 * + "\n" => '\n' | |
306 * + '"' => '\"' | |
307 * + "'" => "\\'" | |
308 * | |
309 * @param string $script String that needs to get escaped. | |
310 * @return string Escaped string. | |
311 */ | |
312 function escapeString($string) { | |
313 App::import('Core', 'Multibyte'); | |
314 $escape = array("\r\n" => "\n", "\r" => "\n"); | |
315 $string = str_replace(array_keys($escape), array_values($escape), $string); | |
316 return $this->_utf8ToHex($string); | |
317 } | |
318 | |
319 /** | |
320 * Encode a string into JSON. Converts and escapes necessary characters. | |
321 * | |
322 * @return void | |
323 */ | |
324 function _utf8ToHex($string) { | |
325 $length = strlen($string); | |
326 $return = ''; | |
327 for ($i = 0; $i < $length; ++$i) { | |
328 $ord = ord($string{$i}); | |
329 switch (true) { | |
330 case $ord == 0x08: | |
331 $return .= '\b'; | |
332 break; | |
333 case $ord == 0x09: | |
334 $return .= '\t'; | |
335 break; | |
336 case $ord == 0x0A: | |
337 $return .= '\n'; | |
338 break; | |
339 case $ord == 0x0C: | |
340 $return .= '\f'; | |
341 break; | |
342 case $ord == 0x0D: | |
343 $return .= '\r'; | |
344 break; | |
345 case $ord == 0x22: | |
346 case $ord == 0x2F: | |
347 case $ord == 0x5C: | |
348 case $ord == 0x27: | |
349 $return .= '\\' . $string{$i}; | |
350 break; | |
351 case (($ord >= 0x20) && ($ord <= 0x7F)): | |
352 $return .= $string{$i}; | |
353 break; | |
354 case (($ord & 0xE0) == 0xC0): | |
355 if ($i + 1 >= $length) { | |
356 $i += 1; | |
357 $return .= '?'; | |
358 break; | |
359 } | |
360 $charbits = $string{$i} . $string{$i + 1}; | |
361 $char = Multibyte::utf8($charbits); | |
362 $return .= sprintf('\u%04s', dechex($char[0])); | |
363 $i += 1; | |
364 break; | |
365 case (($ord & 0xF0) == 0xE0): | |
366 if ($i + 2 >= $length) { | |
367 $i += 2; | |
368 $return .= '?'; | |
369 break; | |
370 } | |
371 $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2}; | |
372 $char = Multibyte::utf8($charbits); | |
373 $return .= sprintf('\u%04s', dechex($char[0])); | |
374 $i += 2; | |
375 break; | |
376 case (($ord & 0xF8) == 0xF0): | |
377 if ($i + 3 >= $length) { | |
378 $i += 3; | |
379 $return .= '?'; | |
380 break; | |
381 } | |
382 $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3}; | |
383 $char = Multibyte::utf8($charbits); | |
384 $return .= sprintf('\u%04s', dechex($char[0])); | |
385 $i += 3; | |
386 break; | |
387 case (($ord & 0xFC) == 0xF8): | |
388 if ($i + 4 >= $length) { | |
389 $i += 4; | |
390 $return .= '?'; | |
391 break; | |
392 } | |
393 $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4}; | |
394 $char = Multibyte::utf8($charbits); | |
395 $return .= sprintf('\u%04s', dechex($char[0])); | |
396 $i += 4; | |
397 break; | |
398 case (($ord & 0xFE) == 0xFC): | |
399 if ($i + 5 >= $length) { | |
400 $i += 5; | |
401 $return .= '?'; | |
402 break; | |
403 } | |
404 $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4} . $string{$i + 5}; | |
405 $char = Multibyte::utf8($charbits); | |
406 $return .= sprintf('\u%04s', dechex($char[0])); | |
407 $i += 5; | |
408 break; | |
409 } | |
410 } | |
411 return $return; | |
412 } | |
413 | |
414 /** | |
415 * Attach an event to an element. Used with the Prototype library. | |
416 * | |
417 * @param string $object Object to be observed | |
418 * @param string $event event to observe | |
419 * @param string $observer function to call | |
420 * @param array $options Set options: useCapture, allowCache, safe | |
421 * @return boolean true on success | |
422 */ | |
423 function event($object, $event, $observer = null, $options = array()) { | |
424 if (!empty($options) && !is_array($options)) { | |
425 $options = array('useCapture' => $options); | |
426 } else if (empty($options)) { | |
427 $options = array(); | |
428 } | |
429 | |
430 $defaultOptions = array('useCapture' => false); | |
431 $options = array_merge($defaultOptions, $options); | |
432 | |
433 if ($options['useCapture'] == true) { | |
434 $options['useCapture'] = 'true'; | |
435 } else { | |
436 $options['useCapture'] = 'false'; | |
437 } | |
438 $isObject = ( | |
439 strpos($object, 'window') !== false || strpos($object, 'document') !== false || | |
440 strpos($object, '$(') !== false || strpos($object, '"') !== false || | |
441 strpos($object, '\'') !== false | |
442 ); | |
443 | |
444 if ($isObject) { | |
445 $b = "Event.observe({$object}, '{$event}', function(event) { {$observer} }, "; | |
446 $b .= "{$options['useCapture']});"; | |
447 } elseif ($object[0] == '\'') { | |
448 $b = "Event.observe(" . substr($object, 1) . ", '{$event}', function(event) { "; | |
449 $b .= "{$observer} }, {$options['useCapture']});"; | |
450 } else { | |
451 $chars = array('#', ' ', ', ', '.', ':'); | |
452 $found = false; | |
453 foreach ($chars as $char) { | |
454 if (strpos($object, $char) !== false) { | |
455 $found = true; | |
456 break; | |
457 } | |
458 } | |
459 if ($found) { | |
460 $this->_rules[$object] = $event; | |
461 } else { | |
462 $b = "Event.observe(\$('{$object}'), '{$event}', function(event) { "; | |
463 $b .= "{$observer} }, {$options['useCapture']});"; | |
464 } | |
465 } | |
466 | |
467 if (isset($b) && !empty($b)) { | |
468 if ($this->_cacheEvents === true) { | |
469 $this->_cachedEvents[] = $b; | |
470 return; | |
471 } else { | |
472 return $this->codeBlock($b, array_diff_key($options, $defaultOptions)); | |
473 } | |
474 } | |
475 } | |
476 | |
477 /** | |
478 * Cache JavaScript events created with event() | |
479 * | |
480 * @param boolean $file If true, code will be written to a file | |
481 * @param boolean $all If true, all code written with JavascriptHelper will be sent to a file | |
482 * @return null | |
483 */ | |
484 function cacheEvents($file = false, $all = false) { | |
485 $this->_cacheEvents = true; | |
486 $this->_cacheToFile = $file; | |
487 $this->_cacheAll = $all; | |
488 } | |
489 | |
490 /** | |
491 * Gets (and clears) the current JavaScript event cache | |
492 * | |
493 * @param boolean $clear | |
494 * @return string | |
495 */ | |
496 function getCache($clear = true) { | |
497 $out = ''; | |
498 $rules = array(); | |
499 | |
500 if (!empty($this->_rules)) { | |
501 foreach ($this->_rules as $sel => $event) { | |
502 $rules[] = "\t'{$sel}': function(element, event) {\n\t\t{$event}\n\t}"; | |
503 } | |
504 } | |
505 $data = implode("\n", $this->_cachedEvents); | |
506 | |
507 if (!empty($rules)) { | |
508 $data .= "\nvar Rules = {\n" . implode(",\n\n", $rules) . "\n}"; | |
509 $data .= "\nEventSelectors.start(Rules);\n"; | |
510 } | |
511 if ($clear) { | |
512 $this->_rules = array(); | |
513 $this->_cacheEvents = false; | |
514 $this->_cachedEvents = array(); | |
515 } | |
516 return $data; | |
517 } | |
518 | |
519 /** | |
520 * Write cached JavaScript events | |
521 * | |
522 * @param boolean $inline If true, returns JavaScript event code. Otherwise it is added to the | |
523 * output of $scripts_for_layout in the layout. | |
524 * @param array $options Set options for codeBlock | |
525 * @return string | |
526 */ | |
527 function writeEvents($inline = true, $options = array()) { | |
528 $out = ''; | |
529 $rules = array(); | |
530 | |
531 if (!$this->_cacheEvents) { | |
532 return; | |
533 } | |
534 $data = $this->getCache(); | |
535 | |
536 if (empty($data)) { | |
537 return; | |
538 } | |
539 | |
540 if ($this->_cacheToFile) { | |
541 $filename = md5($data); | |
542 if (!file_exists(JS . $filename . '.js')) { | |
543 cache(str_replace(WWW_ROOT, '', JS) . $filename . '.js', $data, '+999 days', 'public'); | |
544 } | |
545 $out = $this->link($filename); | |
546 } else { | |
547 $out = $this->codeBlock("\n" . $data . "\n", $options); | |
548 } | |
549 | |
550 if ($inline) { | |
551 return $out; | |
552 } else { | |
553 $view =& ClassRegistry::getObject('view'); | |
554 $view->addScript($out); | |
555 } | |
556 } | |
557 | |
558 /** | |
559 * Includes the Prototype Javascript library (and anything else) inside a single script tag. | |
560 * | |
561 * Note: The recommended approach is to copy the contents of | |
562 * javascripts into your application's | |
563 * public/javascripts/ directory, and use @see javascriptIncludeTag() to | |
564 * create remote script links. | |
565 * | |
566 * @param string $script Script file to include | |
567 * @param array $options Set options for codeBlock | |
568 * @return string script with all javascript in/javascripts folder | |
569 */ | |
570 function includeScript($script = "", $options = array()) { | |
571 if ($script == "") { | |
572 $files = scandir(JS); | |
573 $javascript = ''; | |
574 | |
575 foreach ($files as $file) { | |
576 if (substr($file, -3) == '.js') { | |
577 $javascript .= file_get_contents(JS . "{$file}") . "\n\n"; | |
578 } | |
579 } | |
580 } else { | |
581 $javascript = file_get_contents(JS . "$script.js") . "\n\n"; | |
582 } | |
583 return $this->codeBlock("\n\n" . $javascript, $options); | |
584 } | |
585 | |
586 /** | |
587 * Generates a JavaScript object in JavaScript Object Notation (JSON) | |
588 * from an array | |
589 * | |
590 * ### Options | |
591 * | |
592 * - block - Wraps the return value in a script tag if true. Default is false | |
593 * - prefix - Prepends the string to the returned data. Default is '' | |
594 * - postfix - Appends the string to the returned data. Default is '' | |
595 * - stringKeys - A list of array keys to be treated as a string. | |
596 * - quoteKeys - If false treats $stringKeys as a list of keys **not** to be quoted. Default is true. | |
597 * - q - The type of quote to use. Default is '"'. This option only affects the keys, not the values. | |
598 * | |
599 * @param array $data Data to be converted | |
600 * @param array $options Set of options: block, prefix, postfix, stringKeys, quoteKeys, q | |
601 * @return string A JSON code block | |
602 */ | |
603 function object($data = array(), $options = array()) { | |
604 if (!empty($options) && !is_array($options)) { | |
605 $options = array('block' => $options); | |
606 } else if (empty($options)) { | |
607 $options = array(); | |
608 } | |
609 | |
610 $defaultOptions = array( | |
611 'block' => false, 'prefix' => '', 'postfix' => '', | |
612 'stringKeys' => array(), 'quoteKeys' => true, 'q' => '"' | |
613 ); | |
614 $options = array_merge($defaultOptions, $options, array_filter(compact(array_keys($defaultOptions)))); | |
615 | |
616 if (is_object($data)) { | |
617 $data = get_object_vars($data); | |
618 } | |
619 | |
620 $out = $keys = array(); | |
621 $numeric = true; | |
622 | |
623 if ($this->useNative) { | |
624 $rt = json_encode($data); | |
625 } else { | |
626 if (is_null($data)) { | |
627 return 'null'; | |
628 } | |
629 if (is_bool($data)) { | |
630 return $data ? 'true' : 'false'; | |
631 } | |
632 | |
633 if (is_array($data)) { | |
634 $keys = array_keys($data); | |
635 } | |
636 | |
637 if (!empty($keys)) { | |
638 $numeric = (array_values($keys) === array_keys(array_values($keys))); | |
639 } | |
640 | |
641 foreach ($data as $key => $val) { | |
642 if (is_array($val) || is_object($val)) { | |
643 $val = $this->object( | |
644 $val, | |
645 array_merge($options, array('block' => false, 'prefix' => '', 'postfix' => '')) | |
646 ); | |
647 } else { | |
648 $quoteStrings = ( | |
649 !count($options['stringKeys']) || | |
650 ($options['quoteKeys'] && in_array($key, $options['stringKeys'], true)) || | |
651 (!$options['quoteKeys'] && !in_array($key, $options['stringKeys'], true)) | |
652 ); | |
653 $val = $this->value($val, $quoteStrings); | |
654 } | |
655 if (!$numeric) { | |
656 $val = $options['q'] . $this->value($key, false) . $options['q'] . ':' . $val; | |
657 } | |
658 $out[] = $val; | |
659 } | |
660 | |
661 if (!$numeric) { | |
662 $rt = '{' . implode(',', $out) . '}'; | |
663 } else { | |
664 $rt = '[' . implode(',', $out) . ']'; | |
665 } | |
666 } | |
667 $rt = $options['prefix'] . $rt . $options['postfix']; | |
668 | |
669 if ($options['block']) { | |
670 $rt = $this->codeBlock($rt, array_diff_key($options, $defaultOptions)); | |
671 } | |
672 | |
673 return $rt; | |
674 } | |
675 | |
676 /** | |
677 * Converts a PHP-native variable of any type to a JSON-equivalent representation | |
678 * | |
679 * @param mixed $val A PHP variable to be converted to JSON | |
680 * @param boolean $quoteStrings If false, leaves string values unquoted | |
681 * @return string a JavaScript-safe/JSON representation of $val | |
682 */ | |
683 function value($val, $quoteStrings = true) { | |
684 switch (true) { | |
685 case (is_array($val) || is_object($val)): | |
686 $val = $this->object($val); | |
687 break; | |
688 case ($val === null): | |
689 $val = 'null'; | |
690 break; | |
691 case (is_bool($val)): | |
692 $val = !empty($val) ? 'true' : 'false'; | |
693 break; | |
694 case (is_int($val)): | |
695 $val = $val; | |
696 break; | |
697 case (is_float($val)): | |
698 $val = sprintf("%.11f", $val); | |
699 break; | |
700 default: | |
701 $val = $this->escapeString($val); | |
702 if ($quoteStrings) { | |
703 $val = '"' . $val . '"'; | |
704 } | |
705 break; | |
706 } | |
707 return $val; | |
708 } | |
709 | |
710 /** | |
711 * AfterRender callback. Writes any cached events to the view, or to a temp file. | |
712 * | |
713 * @return null | |
714 */ | |
715 function afterRender() { | |
716 if (!$this->enabled) { | |
717 return; | |
718 } | |
719 echo $this->writeEvents(true); | |
720 } | |
721 } |