mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge branch '3.1' into 3.2
This commit is contained in:
commit
3fe8d30c2c
@ -220,19 +220,23 @@ abstract class Object {
|
||||
// Keep track of the current bucket that we're putting data into
|
||||
$bucket = &$args;
|
||||
$bucketStack = array();
|
||||
$had_ns = false;
|
||||
$hadNamespace = false;
|
||||
$currentKey = null;
|
||||
|
||||
foreach($tokens as $token) {
|
||||
$tName = is_array($token) ? $token[0] : $token;
|
||||
// Get the class naem
|
||||
if($class == null && is_array($token) && $token[0] == T_STRING) {
|
||||
// $forceResult used to allow null result to be detected
|
||||
$result = $forceResult = null;
|
||||
$tokenName = is_array($token) ? $token[0] : $token;
|
||||
|
||||
// Get the class name
|
||||
if($class === null && is_array($token) && $token[0] === T_STRING) {
|
||||
$class = $token[1];
|
||||
} elseif(is_array($token) && $token[0] == T_NS_SEPARATOR) {
|
||||
} elseif(is_array($token) && $token[0] === T_NS_SEPARATOR) {
|
||||
$class .= $token[1];
|
||||
$had_ns = true;
|
||||
} elseif ($had_ns && is_array($token) && $token[0] == T_STRING) {
|
||||
$hadNamespace = true;
|
||||
} elseif($hadNamespace && is_array($token) && $token[0] === T_STRING) {
|
||||
$class .= $token[1];
|
||||
$had_ns = false;
|
||||
$hadNamespace = false;
|
||||
// Get arguments
|
||||
} else if(is_array($token)) {
|
||||
switch($token[0]) {
|
||||
@ -240,52 +244,85 @@ abstract class Object {
|
||||
$argString = $token[1];
|
||||
switch($argString[0]) {
|
||||
case '"':
|
||||
$argString = stripcslashes(substr($argString,1,-1));
|
||||
$result = stripcslashes(substr($argString,1,-1));
|
||||
break;
|
||||
case "'":
|
||||
$argString = str_replace(array("\\\\", "\\'"),array("\\", "'"), substr($argString,1,-1));
|
||||
$result = str_replace(array("\\\\", "\\'"),array("\\", "'"), substr($argString,1,-1));
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Bad T_CONSTANT_ENCAPSED_STRING arg $argString");
|
||||
}
|
||||
$bucket[] = $argString;
|
||||
|
||||
break;
|
||||
|
||||
case T_DNUMBER:
|
||||
$bucket[] = (double)$token[1];
|
||||
$result = (double)$token[1];
|
||||
break;
|
||||
|
||||
case T_LNUMBER:
|
||||
$bucket[] = (int)$token[1];
|
||||
$result = (int)$token[1];
|
||||
break;
|
||||
|
||||
case T_DOUBLE_ARROW:
|
||||
// We've encountered an associative array (the array itself has already been
|
||||
// added to the bucket), so the previous item added to the bucket is the key
|
||||
end($bucket);
|
||||
$currentKey = current($bucket);
|
||||
array_pop($bucket);
|
||||
break;
|
||||
|
||||
case T_STRING:
|
||||
switch($token[1]) {
|
||||
case 'true': $bucket[] = true; break;
|
||||
case 'false': $bucket[] = false; break;
|
||||
case 'null': $bucket[] = null; break;
|
||||
case 'true': $result = true; break;
|
||||
case 'false': $result = false; break;
|
||||
case 'null': $result = null; $forceResult = true; break;
|
||||
default: throw new Exception("Bad T_STRING arg '{$token[1]}'");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case T_ARRAY:
|
||||
// Add an empty array to the bucket
|
||||
$bucket[] = array();
|
||||
$bucketStack[] = &$bucket;
|
||||
$bucket = &$bucket[sizeof($bucket)-1];
|
||||
$result = array();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if($tokenName === '[') {
|
||||
$result = array();
|
||||
} elseif(($tokenName === ')' || $tokenName === ']') && ! empty($bucketStack)) {
|
||||
// Store the bucket we're currently working on
|
||||
$oldBucket = $bucket;
|
||||
// Fetch the key for the bucket at the top of the stack
|
||||
end($bucketStack);
|
||||
$key = key($bucketStack);
|
||||
reset($bucketStack);
|
||||
// Re-instate the bucket from the top of the stack
|
||||
$bucket = &$bucketStack[$key];
|
||||
// Add our saved, "nested" bucket to the bucket we just popped off the stack
|
||||
$bucket[$key] = $oldBucket;
|
||||
// Remove the bucket we just popped off the stack
|
||||
array_pop($bucketStack);
|
||||
}
|
||||
}
|
||||
|
||||
// If we've got something to add to the bucket, add it
|
||||
if($result !== null || $forceResult) {
|
||||
if($currentKey) {
|
||||
$bucket[$currentKey] = $result;
|
||||
$currentKey = null;
|
||||
} else {
|
||||
$bucket[] = $result;
|
||||
}
|
||||
|
||||
} else {
|
||||
if($tName == '[') {
|
||||
// Add an empty array to the bucket
|
||||
$bucket[] = array();
|
||||
$bucketStack[] = &$bucket;
|
||||
$bucket = &$bucket[sizeof($bucket)-1];
|
||||
} elseif($tName == ')' || $tName == ']') {
|
||||
// Pop-by-reference
|
||||
$bucket = &$bucketStack[sizeof($bucketStack)-1];
|
||||
array_pop($bucketStack);
|
||||
// If we've just pushed an array, that becomes our new bucket
|
||||
if($result === array()) {
|
||||
// Fetch the key that the array was pushed to
|
||||
end($bucket);
|
||||
$key = key($bucket);
|
||||
reset($bucket);
|
||||
// Store reference to "old" bucket in the stack
|
||||
$bucketStack[$key] = &$bucket;
|
||||
// Set the active bucket to be our newly-pushed, empty array
|
||||
$bucket = &$bucket[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ class ObjectTest extends SapphireTest {
|
||||
// 5.4 Shorthand Array
|
||||
$this->assertEquals(
|
||||
array('Enum',array(array('Accepted', 'Pending', 'Declined', 'Unsubmitted'), 'Unsubmitted')),
|
||||
Object::parse_class_spec("Enum(['Accepted', 'Pending', 'Declined', 'Unsubmitted'), 'Unsubmitted']")
|
||||
Object::parse_class_spec("Enum(['Accepted', 'Pending', 'Declined', 'Unsubmitted'], 'Unsubmitted')")
|
||||
);
|
||||
// 5.4 Nested shorthand array
|
||||
$this->assertEquals(
|
||||
@ -436,6 +436,28 @@ class ObjectTest extends SapphireTest {
|
||||
Object::parse_class_spec(
|
||||
"Enum(['Accepted', 'Pending', 'Declined', ['UnsubmittedA','UnsubmittedB']], 'Unsubmitted')")
|
||||
);
|
||||
|
||||
// Associative array
|
||||
$this->assertEquals(
|
||||
array('Varchar', array(255, array('nullifyEmpty' => false))),
|
||||
Object::parse_class_spec("Varchar(255, array('nullifyEmpty' => false))")
|
||||
);
|
||||
// Nested associative array
|
||||
$this->assertEquals(
|
||||
array('Test', array('string', array('nested' => array('foo' => 'bar')))),
|
||||
Object::parse_class_spec("Test('string', array('nested' => array('foo' => 'bar')))")
|
||||
);
|
||||
// 5.4 shorthand associative array
|
||||
$this->assertEquals(
|
||||
array('Varchar', array(255, array('nullifyEmpty' => false))),
|
||||
Object::parse_class_spec("Varchar(255, ['nullifyEmpty' => false])")
|
||||
);
|
||||
// 5.4 shorthand nested associative array
|
||||
$this->assertEquals(
|
||||
array('Test', array('string', array('nested' => array('foo' => 'bar')))),
|
||||
Object::parse_class_spec("Test('string', ['nested' => ['foo' => 'bar']])")
|
||||
);
|
||||
|
||||
// Namespaced class
|
||||
$this->assertEquals(
|
||||
array('Test\MyClass', array()),
|
||||
|
Loading…
Reference in New Issue
Block a user