mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
FIX: Parameters passed to includes overwrite all scopes (fixes #2617)
This commit is contained in:
parent
e091bb8474
commit
24660afabd
@ -0,0 +1 @@
|
||||
$Title - <% loop $Items %>$Title<% if not Last %> - <% else %> - {$Top.Title}<% end_if %><% end_loop %>
|
@ -0,0 +1 @@
|
||||
$Top.Title - <% with $Item %>$Title - <% with $NestedItem %>{$Title} - {$Up.Title} - {$Top.Title}<% end_with %><% end_with %>
|
@ -0,0 +1 @@
|
||||
$Title - <% with $Item %>$Title - {$Up.Title}<% end_with %>
|
@ -701,6 +701,31 @@ after')
|
||||
'<p>A</p><p>Bar</p>'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$this->render('<% include SSViewerTestIncludeScopeInheritanceWithArgsInLoop Title="SomeArg" %>',
|
||||
new ArrayData(array('Items' => new ArrayList(array(
|
||||
new ArrayData(array('Title' => 'Foo')),
|
||||
new ArrayData(array('Title' => 'Bar'))
|
||||
))))),
|
||||
'SomeArg - Foo - Bar - SomeArg'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$this->render('<% include SSViewerTestIncludeScopeInheritanceWithArgsInWith Title="A" %>',
|
||||
new ArrayData(array('Item' => new ArrayData(array('Title' =>'B'))))),
|
||||
'A - B - A'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$this->render('<% include SSViewerTestIncludeScopeInheritanceWithArgsInNestedWith Title="A" %>',
|
||||
new ArrayData(array(
|
||||
'Item' => new ArrayData(array(
|
||||
'Title' =>'B', 'NestedItem' => new ArrayData(array('Title' => 'C'))
|
||||
)))
|
||||
)),
|
||||
'A - B - C - B - A'
|
||||
);
|
||||
|
||||
$data = new ArrayData(array(
|
||||
'Nested' => new ArrayData(array(
|
||||
'Object' => new ArrayData(array('Key' => 'A'))
|
||||
|
@ -25,7 +25,7 @@
|
||||
class SSViewer_Scope {
|
||||
|
||||
// The stack of previous "global" items
|
||||
// And array of item, itemIterator, itemIteratorTotal, pop_index, up_index, current_index
|
||||
// And array of item, itemIterator, itemIteratorTotal, pop_index, up_index, current_index, parent_overlay
|
||||
private $itemStack = array();
|
||||
|
||||
// The current "global" item (the one any lookup starts from)
|
||||
@ -181,6 +181,27 @@ class SSViewer_Scope {
|
||||
$this->resetLocalScope();
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getItemStack() {
|
||||
return $this->itemStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array
|
||||
*/
|
||||
protected function setItemStack(array $stack) {
|
||||
$this->itemStack = $stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
protected function getUpIndex() {
|
||||
return $this->upIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -519,6 +540,70 @@ class SSViewer_DataPresenter extends SSViewer_Scope {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the current overlay (as it doesn't directly apply to the new scope
|
||||
* that's being pushed). We want to store the overlay against the next item
|
||||
* "up" in the stack (hence upIndex), rather than the current item, because
|
||||
* SSViewer_Scope::obj() has already been called and pushed the new item to
|
||||
* the stack by this point
|
||||
* @return SSViewer_Scope
|
||||
*/
|
||||
public function pushScope() {
|
||||
$scope = parent::pushScope();
|
||||
|
||||
$itemStack = $this->getItemStack();
|
||||
$itemStack[$this->getUpIndex()][6] = $this->overlay;
|
||||
|
||||
$this->setItemStack($itemStack);
|
||||
$this->overlay = array();
|
||||
|
||||
return $scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Now that we're going to jump up an item in the item stack, we need to
|
||||
* restore the overlay that was previously stored against the next item "up"
|
||||
* in the stack from the current one
|
||||
* @return SSViewer_Scope
|
||||
*/
|
||||
public function popScope() {
|
||||
$itemStack = $this->getItemStack();
|
||||
$this->overlay = $itemStack[$this->getUpIndex()][6];
|
||||
|
||||
return parent::popScope();
|
||||
}
|
||||
|
||||
/**
|
||||
* $Up and $Top need to restore the overlay from the parent and top-level
|
||||
* scope respectively.
|
||||
*/
|
||||
public function obj($name, $arguments = null, $forceReturnedObject = true, $cache = false, $cacheName = null) {
|
||||
$overlayIndex = false;
|
||||
|
||||
switch($name) {
|
||||
case 'Up':
|
||||
$upIndex = $this->getUpIndex();
|
||||
if ($upIndex === null) {
|
||||
user_error('Up called when we\'re already at the top of the scope', E_USER_ERROR);
|
||||
}
|
||||
|
||||
$overlayIndex = $upIndex; // Parent scope
|
||||
break;
|
||||
case 'Top':
|
||||
$overlayIndex = 0; // Top-level scope
|
||||
break;
|
||||
}
|
||||
|
||||
if ($overlayIndex !== false) {
|
||||
$itemStack = $this->getItemStack();
|
||||
if (!$this->overlay && isset($itemStack[$overlayIndex][6])) {
|
||||
$this->overlay = $itemStack[$overlayIndex][6];
|
||||
}
|
||||
}
|
||||
|
||||
return parent::obj($name, $arguments, $forceReturnedObject, $cache, $cacheName);
|
||||
}
|
||||
|
||||
public function getObj($name, $arguments = null, $forceReturnedObject = true, $cache = false, $cacheName = null) {
|
||||
$result = $this->getInjectedValue($name, (array)$arguments);
|
||||
if($result) return $result['obj'];
|
||||
|
Loading…
Reference in New Issue
Block a user