diff --git a/core/Object.php b/core/Object.php index ba543ed76..a9ab5adce 100755 --- a/core/Object.php +++ b/core/Object.php @@ -150,6 +150,11 @@ abstract class Object { $class = null; $args = array(); $passedBracket = false; + + // Keep track of the current bucket that we're putting data into + $bucket = &$args; + $bucketStack = array(); + foreach($tokens as $token) { $tName = is_array($token) ? $token[0] : $token; // Get the class naem @@ -165,15 +170,15 @@ abstract class Object { case "'": $argString = str_replace(array("\\\\", "\\'"),array("\\", "'"), substr($argString,1,-1)); break; default: throw new Exception("Bad T_CONSTANT_ENCAPSED_STRING arg $argString"); } - $args[] = $argString; + $bucket[] = $argString; break; case T_DNUMBER: - $args[] = (double)$token[1]; + $bucket[] = (double)$token[1]; break; case T_LNUMBER: - $args[] = (int)$token[1]; + $bucket[] = (int)$token[1]; break; case T_STRING: @@ -182,8 +187,21 @@ abstract class Object { case 'false': $args[] = false; break; default: throw new Exception("Bad T_STRING arg '{$token[1]}'"); } + + case T_ARRAY: + // Add an empty array to the bucket + $bucket[] = array(); + $bucketStack[] = &$bucket; + $bucket = &$bucket[sizeof($bucket)-1]; + } + } else { + if($tName == ')') { + // Pop-by-reference + $bucket = &$bucketStack[sizeof($bucketStack)-1]; + array_pop($bucketStack); + } } } diff --git a/tests/ObjectTest.php b/tests/ObjectTest.php index bace066db..6c2c1e271 100755 --- a/tests/ObjectTest.php +++ b/tests/ObjectTest.php @@ -337,18 +337,31 @@ class ObjectTest extends SapphireTest { } public function testParseClassSpec() { + // Simple case $this->assertEquals( array('Versioned',array('Stage', 'Live')), Object::parse_class_spec("Versioned('Stage','Live')") ); + // String with commas $this->assertEquals( array('Versioned',array('Stage,Live', 'Stage')), Object::parse_class_spec("Versioned('Stage,Live','Stage')") ); + // String with quotes $this->assertEquals( array('Versioned',array('Stage\'Stage,Live\'Live', 'Live')), Object::parse_class_spec("Versioned('Stage\'Stage,Live\'Live','Live')") ); + // Array + $this->assertEquals( + array('Enum',array(array('Accepted', 'Pending', 'Declined', 'Unsubmitted'), 'Unsubmitted')), + Object::parse_class_spec("Enum(array('Accepted', 'Pending', 'Declined', 'Unsubmitted'), 'Unsubmitted')") + ); + // Nested array + $this->assertEquals( + array('Enum',array(array('Accepted', 'Pending', 'Declined', array('UnsubmittedA','UnsubmittedB')), 'Unsubmitted')), + Object::parse_class_spec("Enum(array('Accepted', 'Pending', 'Declined', array('UnsubmittedA','UnsubmittedB')), 'Unsubmitted')") + ); } }