BUGFIX: Restore ability to pass injected variables right into SSViewer_DataPresenter

This commit is contained in:
Hamish Friedlander 2012-02-17 13:42:18 +13:00
parent f55c575f95
commit e4675d7172

View File

@ -295,20 +295,29 @@ class SSViewer_BasicIteratorSupport implements TemplateIteratorProvider {
*/ */
class SSViewer_DataPresenter extends SSViewer_Scope { class SSViewer_DataPresenter extends SSViewer_Scope {
private static $extras = array(); private static $globalProperties = null;
private static $iteratorSupport = array(); private static $iteratorProperties = null;
function __construct($item){ protected $extras;
function __construct($item, $extras = array()){
parent::__construct($item); parent::__construct($item);
if (count(self::$iteratorSupport) == 0) { //build up extras array only once per request // Build up global property providers array only once per request
$this->createCallableArray(self::$iteratorSupport, "TemplateIteratorProvider", true); //call non-statically if (self::$globalProperties === null) {
self::$globalProperties = array();
// Get all the exposed variables from all classes that implement the TemplateGlobalProvider interface
$this->createCallableArray(self::$globalProperties, "TemplateGlobalProvider");
} }
if (count(self::$extras) == 0) { //build up extras array only once per request // Build up iterator property providers array only once per request
//get all the exposed variables from all classes that implement the TemplateGlobalProvider interface if (self::$iteratorProperties === null) {
$this->createCallableArray(self::$extras, "TemplateGlobalProvider"); self::$iteratorProperties = array();
// Get all the exposed variables from all classes that implement the TemplateIteratorProvider interface
$this->createCallableArray(self::$iteratorProperties, "TemplateIteratorProvider", true); //call non-statically
} }
$this->extras = $extras;
} }
protected function createCallableArray(&$extraArray, $interfaceToQuery, $createObject = false) { protected function createCallableArray(&$extraArray, $interfaceToQuery, $createObject = false) {
@ -348,24 +357,36 @@ class SSViewer_DataPresenter extends SSViewer_Scope {
return parent::__call($name, $arguments); return parent::__call($name, $arguments);
} }
//attempt to call a "global" functions // We create a specific object instance, so that we can determine "unset" from "null" and "false"
if (array_key_exists($property, self::$extras) || array_key_exists($property, self::$iteratorSupport)) { static $nomatch = null;
$this->resetLocalScope(); //if we are inside a chain (e.g. $A.B.C.Up.E) break out to the beginning of it if ($nomatch === null) $nomatch = new stdClass();
//special case for the iterator, which need current index and total number of items // Start off with no match
if (array_key_exists($property, self::$iteratorSupport)) { $value = $nomatch;
$value = self::$iteratorSupport[$property];
if ($this->itemIterator) { // Check for a presenter-specific override
// Set the current iterator position and total (the object instance is the first item in the callable array) if (array_key_exists($property, $this->extras)) {
$value[0]->iteratorProperties($this->itemIterator->key(), $this->itemIteratorTotal); $value = $this->extras[$property];
} else { }
// If we don't actually have an iterator at the moment, act like a list of length 1 // Then for iterator-specific overrides
$value[0]->iteratorProperties(0, 1); else if (array_key_exists($property, self::$iteratorProperties)) {
} $value = self::$iteratorProperties[$property];
} else { //normal case of extras call
$value = self::$extras[$property]; //get the method call if ($this->itemIterator) {
// Set the current iterator position and total (the object instance is the first item in the callable array)
$value[0]->iteratorProperties($this->itemIterator->key(), $this->itemIteratorTotal);
} else {
// If we don't actually have an iterator at the moment, act like a list of length 1
$value[0]->iteratorProperties(0, 1);
} }
}
// And finally for global overrides
else if (array_key_exists($property, self::$globalProperties)) {
$value = self::$globalProperties[$property]; //get the method call
}
if ($value !== $nomatch) {
$this->resetLocalScope(); //if we are inside a chain (e.g. $A.B.C.Up.E) break out to the beginning of it
//only call callable functions //only call callable functions
if (is_callable($value)) { if (is_callable($value)) {