mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-19 02:56:15 +00:00
Refactored JavascriptHelper::object(), improved JSON spec compliance, added sport for native json extension, improved tests
git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6379 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
parent
14122fd1e6
commit
1e4549679a
2 changed files with 93 additions and 45 deletions
|
@ -44,10 +44,16 @@ class JavascriptHelper extends AppHelper {
|
|||
var $_cacheToFile = false;
|
||||
var $_cacheAll = false;
|
||||
var $_rules = array();
|
||||
/**
|
||||
* Determines whether native JSON extension is used for encoding. Set by object constructor.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
var $useNative = false;
|
||||
var $enabled = true;
|
||||
var $safe = false;
|
||||
/**
|
||||
* html tags used by this helper.
|
||||
* HTML tags used by this helper.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
|
@ -57,7 +63,15 @@ class JavascriptHelper extends AppHelper {
|
|||
'javascriptlink' => '<script type="text/javascript" src="%s"></script>',
|
||||
'javascriptend' => '</script>',
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor. Checks for presence of native PHP JSON extension to use for object encoding
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function __construct() {
|
||||
$this->useNative = function_exists('json_encode');
|
||||
return parent::__construct();
|
||||
}
|
||||
/**
|
||||
* Returns a JavaScript script tag.
|
||||
*
|
||||
|
@ -384,26 +398,22 @@ class JavascriptHelper extends AppHelper {
|
|||
}
|
||||
|
||||
$defaultOptions = array('block' => false, 'prefix' => '', 'postfix' => '', 'stringKeys' => array(), 'quoteKeys' => true, 'q' => '"');
|
||||
$options = array_merge($defaultOptions, $options);
|
||||
|
||||
foreach($defaultOptions as $option => $value) {
|
||||
if (isset($$option) && $$option !== null) {
|
||||
$options[$option] = $$option;
|
||||
}
|
||||
}
|
||||
$options = array_merge($defaultOptions, $options, array_filter(compact(array_keys($defaultOptions))));
|
||||
|
||||
if (is_object($data)) {
|
||||
$data = get_object_vars($data);
|
||||
}
|
||||
|
||||
$out = array();
|
||||
$keys = array();
|
||||
$out = $keys = array();
|
||||
$numeric = true;
|
||||
|
||||
if ($this->useNative) {
|
||||
$rt = json_encode($data);
|
||||
} else {
|
||||
if (is_array($data)) {
|
||||
$keys = array_keys($data);
|
||||
}
|
||||
|
||||
$numeric = true;
|
||||
if (!empty($keys)) {
|
||||
$numeric = (array_values($keys) === array_keys(array_values($keys)));
|
||||
}
|
||||
|
@ -412,21 +422,11 @@ class JavascriptHelper extends AppHelper {
|
|||
if (is_array($val) || is_object($val)) {
|
||||
$val = $this->object($val, $options);
|
||||
} else {
|
||||
if ((!count($options['stringKeys']) && !is_numeric($val) && !is_bool($val)) || ($options['quoteKeys'] && in_array($key, $options['stringKeys'], true)) || (!$options['quoteKeys'] && !in_array($key, $options['stringKeys'], true))) {
|
||||
$val = $options['q'] . $this->escapeString($val) . $options['q'];
|
||||
$val = $this->value($val, (!count($options['stringKeys']) || ($options['quoteKeys'] && in_array($key, $options['stringKeys'], true)) || (!$options['quoteKeys'] && !in_array($key, $options['stringKeys'], true))));
|
||||
}
|
||||
if ($val === null) {
|
||||
$val = 'null';
|
||||
}
|
||||
if (is_bool($val)) {
|
||||
$val = ife($val, 'true', 'false');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$numeric) {
|
||||
$val = $options['q'] . $key . $options['q'] . ':' . $val;
|
||||
$val = $options['q'] . $this->value($key, false) . $options['q'] . ':' . $val;
|
||||
}
|
||||
|
||||
$out[] = $val;
|
||||
}
|
||||
|
||||
|
@ -435,6 +435,7 @@ class JavascriptHelper extends AppHelper {
|
|||
} else {
|
||||
$rt = '[' . join(',', $out) . ']';
|
||||
}
|
||||
}
|
||||
$rt = $options['prefix'] . $rt . $options['postfix'];
|
||||
|
||||
if ($options['block']) {
|
||||
|
@ -443,6 +444,39 @@ class JavascriptHelper extends AppHelper {
|
|||
|
||||
return $rt;
|
||||
}
|
||||
/**
|
||||
* Converts a PHP-native variable of any type to a JSON-equivalent representation
|
||||
*
|
||||
* @param mixed $val A PHP variable to be converted to JSON
|
||||
* @param boolean $quoteStrings If false, leaves string values unquoted
|
||||
* @return string a JavaScript-safe/JSON representation of $val
|
||||
*/
|
||||
function value($val, $quoteStrings = true) {
|
||||
switch (true) {
|
||||
case (is_array($val) || is_object($val)):
|
||||
$val = $this->object($val);
|
||||
break;
|
||||
case ($val === null):
|
||||
$val = 'null';
|
||||
break;
|
||||
case (is_bool($val)):
|
||||
$val = ife($val, 'true', 'false');
|
||||
break;
|
||||
case (is_int($val)):
|
||||
$val = $val;
|
||||
break;
|
||||
case (is_float($val)):
|
||||
$val = sprintf("%.11f", $val);
|
||||
break;
|
||||
default:
|
||||
$val = $this->escapeString($val);
|
||||
if ($quoteStrings) {
|
||||
$val = '"' . $val . '"';
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
/**
|
||||
* AfterRender callback. Writes any cached events to the view, or to a temp file.
|
||||
*
|
||||
|
|
|
@ -99,15 +99,29 @@ class JavascriptTest extends UnitTestCase {
|
|||
|
||||
$result = $this->Javascript->object(array(
|
||||
'2007' => array(
|
||||
'Spring' => array('1' => array('id' => '1', 'name' => 'Josh'), '2' => array('id' => '2', 'name' => 'Becky')),
|
||||
'Fall' => array('1' => array('id' => '1', 'name' => 'Josh'), '2' => array('id' => '2', 'name' => 'Becky'))
|
||||
'Spring' => array('1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')),
|
||||
'Fall' => array('1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky'))
|
||||
), '2006' => array(
|
||||
'Spring' => array('1' => array('id' => '1', 'name' => 'Josh'), '2' => array('id' => '2', 'name' => 'Becky')),
|
||||
'Fall' => array('1' => array('id' => '1', 'name' => 'Josh'), '2' => array('id' => '2', 'name' => 'Becky')
|
||||
'Spring' => array('1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')),
|
||||
'Fall' => array('1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
|
||||
))
|
||||
));
|
||||
$expected = '{"2007":{"Spring":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}},"Fall":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}}},"2006":{"Spring":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}},"Fall":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}}}}';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$result = $this->Javascript->object(array('Object' => array(true, false, 1, '02101', 0, -1, 3.141592653589, "1")));
|
||||
$expected = '{"Object":[true,false,1,"02101",0,-1,3.14159265359,"1"]}';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$result = $this->Javascript->object(array('Object' => array(true => true, false, -3.141592653589, -10)));
|
||||
$expected = '{"Object":{"1":true,"2":false,"3":-3.14159265359,"4":-10}}';
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
if ($this->Javascript->useNative) {
|
||||
$this->Javascript->useNative = false;
|
||||
$this->testObjectGeneration();
|
||||
$this->Javascript->useNative = true;
|
||||
}
|
||||
}
|
||||
|
||||
function testScriptBlock() {
|
||||
|
|
Loading…
Add table
Reference in a new issue