From 1dd57b18dee8e94ba13d570418256c25b423afd1 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Thu, 24 May 2012 11:59:15 -0400 Subject: [PATCH] Add list of blacklisted array functions, add more tests --- JSObject.php | 31 ++++++++++++++++++++++++++++--- README.md | 20 ++++++++++++++++++-- tests.php | 28 ++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/JSObject.php b/JSObject.php index cc0a893..ae59ca9 100644 --- a/JSObject.php +++ b/JSObject.php @@ -30,6 +30,8 @@ class JSObject extends ArrayObject { foreach($params as $name => &$val) { + if (empty($val)) continue; + // Bind '$this' for closures if ($val instanceof Closure) { @@ -52,11 +54,34 @@ class JSObject extends ArrayObject { */ public function __call($name, $params = []) { + $function_blacklist = [ + 'array_change_key_case', + 'array_combine', + 'array_count_values', + 'array_fill_keys', + 'array_fill', + 'array_key_exists', + 'array_map', + 'array_merge', + 'array_merge_recursive', + 'array_search', + 'array_unshift', + ]; + // Allow array operations on the object - if (substr($name, 0, 6) === 'array_' && is_callable($name)) + if (substr($name, 0, 6) === 'array_' && is_callable($name) && ! in_array($name, $function_blacklist)) { - $args = array_merge($this->getArrayCopy(), $params); - return call_user_func_array($name, [$args]); + $args = ( ! empty($params)) + ? array_merge($this->getArrayCopy(), $params) + : $this->getArrayCopy(); + + // Make sure the array items in the array parameter aren't used as function parameters + if (count($args === 1)) + { + $args = [$args]; + } + + return call_user_func_array($name, $args); } // Call closures attached to the object diff --git a/README.md b/README.md index 9410d0d..110be9e 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,25 @@ JSObject A PHP 5.4 class to emulate Javascript object literals. -Also, can use ``array_`` functions to operate on the object's properties and values. (Only works for functions that start with ``array_`` and have the array as the first parameter) +Also, can use ``array_`` functions to operate on the object's properties and values. (Only works for functions that start with ``array_`` and have the array as the first parameter.) -Examples: +The following array functions are blacklisted because of their parameter ordering, or unpredictable behavior: + + * array_change_key_case + * array_count_values + * array_combine + * array_fill_keys + * array_fill + * array_key_exists + * array_map + * array_merge + * array_merge_recursive + * array_search + * array_unshift + + + +##Examples: * Basic Usage diff --git a/tests.php b/tests.php index eb2e223..04c0dc8 100644 --- a/tests.php +++ b/tests.php @@ -15,6 +15,8 @@ require_once('simpletest/autorun.php'); // Include JSObject require_once('JSObject.php'); + + class JSObjectTests extends UnitTestCase { function TestIsA() @@ -41,6 +43,22 @@ class JSObjectTests extends UnitTestCase { $this->assertEqual($obj->x(), 50); } + // List of blacklisted array functions +/* + 'array_change_key_case', + 'array_count_values', + 'array_combine', + 'array_fill_keys', + 'array_fill', + 'array_key_exists', + 'array_map', + 'array_merge', + 'array_merge_recursive', + 'array_search', + 'array_unshift', +*/ + + function TestArrayFlip() { $obj = new JSObject([ @@ -60,5 +78,15 @@ class JSObjectTests extends UnitTestCase { $this->assertEqual($obj->array_keys(), ['x','y']); } + + function TestArrayValues() + { + $obj = new JSObject([ + 'x' => 'foo', + 'y' => 'bar' + ]); + + $this->assertEqual($obj->array_values(), ['foo','bar']); + } } \ No newline at end of file