mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 06:05:56 +00:00
Merge pull request #1571 from open-sausages/pulls/4.0/virtualpage-controller
API Better behaviour for virtualised controller
This commit is contained in:
commit
25a8fb87da
@ -2,6 +2,7 @@
|
||||
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
use SilverStripe\Security\Member;
|
||||
|
||||
/**
|
||||
* Virtual Page creates an instance of a page, with the same fields that the original page had, but readonly.
|
||||
@ -9,6 +10,7 @@ use SilverStripe\ORM\Versioning\Versioned;
|
||||
* Note: This Only duplicates $db fields and not the $has_one etc..
|
||||
*
|
||||
* @method SiteTree CopyContentFrom()
|
||||
* @property int $CopyContentFromID
|
||||
*
|
||||
* @package cms
|
||||
*/
|
||||
@ -317,7 +319,7 @@ class VirtualPage extends Page {
|
||||
unset($this->components['CopyContentFrom']);
|
||||
|
||||
// Update ImageTracking
|
||||
$this->ImageTracking()->setByIdList($this->CopyContentFrom()->ImageTracking()->column('ID'));
|
||||
$this->ImageTracking()->setByIDList($this->CopyContentFrom()->ImageTracking()->column('ID'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -338,11 +340,14 @@ class VirtualPage extends Page {
|
||||
public function __get($field) {
|
||||
if(parent::hasMethod($funcName = "get$field")) {
|
||||
return $this->$funcName();
|
||||
} else if(parent::hasField($field) || ($field === 'ID' && !$this->exists())) {
|
||||
}
|
||||
if(parent::hasField($field) || ($field === 'ID' && !$this->exists())) {
|
||||
return $this->getField($field);
|
||||
} elseif(($copy = $this->CopyContentFrom()) && $copy->exists()) {
|
||||
}
|
||||
if(($copy = $this->CopyContentFrom()) && $copy->exists()) {
|
||||
return $copy->$field;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getField($field) {
|
||||
@ -386,7 +391,7 @@ class VirtualPage extends Page {
|
||||
if(parent::hasMethod($method)) {
|
||||
return parent::__call($method, $args);
|
||||
} else {
|
||||
return call_user_func_array(array($this->copyContentFrom(), $method), $args);
|
||||
return call_user_func_array(array($this->CopyContentFrom(), $method), $args);
|
||||
}
|
||||
}
|
||||
|
||||
@ -447,11 +452,38 @@ class VirtualPage_Controller extends Page_Controller {
|
||||
'loadcontentall' => 'ADMIN',
|
||||
);
|
||||
|
||||
/**
|
||||
* Backup of virtualised controller
|
||||
*
|
||||
* @var ContentController
|
||||
*/
|
||||
protected $virtualController = null;
|
||||
|
||||
/**
|
||||
* Get virtual controller
|
||||
*
|
||||
* @return ContentController
|
||||
*/
|
||||
protected function getVirtualisedController() {
|
||||
if($this->virtualController) {
|
||||
return $this->virtualController;
|
||||
}
|
||||
|
||||
// Validate virtualised model
|
||||
/** @var VirtualPage $page */
|
||||
$page = $this->data();
|
||||
$virtualisedPage = $page->CopyContentFrom();
|
||||
if (!$virtualisedPage || !$virtualisedPage->exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create controller using standard mechanism
|
||||
$this->virtualController = ModelAsController::controller_for($virtualisedPage);
|
||||
return $this->virtualController;
|
||||
}
|
||||
|
||||
public function getViewer($action) {
|
||||
$originalClass = get_class($this->CopyContentFrom());
|
||||
if ($originalClass == 'SiteTree') $name = 'Page_Controller';
|
||||
else $name = $originalClass."_Controller";
|
||||
$controller = new $name();
|
||||
$controller = $this->getVirtualisedController() ?: $this;
|
||||
return $controller->getViewer($action);
|
||||
}
|
||||
|
||||
@ -473,15 +505,13 @@ class VirtualPage_Controller extends Page_Controller {
|
||||
* @return bool
|
||||
*/
|
||||
public function hasMethod($method) {
|
||||
$haveIt = parent::hasMethod($method);
|
||||
if (!$haveIt) {
|
||||
$originalClass = get_class($this->CopyContentFrom());
|
||||
if ($originalClass == 'SiteTree') $name = 'ContentController';
|
||||
else $name = $originalClass."_Controller";
|
||||
$controller = new $name($this->dataRecord->copyContentFrom());
|
||||
$haveIt = $controller->hasMethod($method);
|
||||
}
|
||||
return $haveIt;
|
||||
if(parent::hasMethod($method)) {
|
||||
return true;
|
||||
};
|
||||
|
||||
// Fallback
|
||||
$controller = $this->getVirtualisedController();
|
||||
return $controller && $controller->hasMethod($method);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -493,23 +523,24 @@ class VirtualPage_Controller extends Page_Controller {
|
||||
*
|
||||
* @throws Exception Any error other than a 'no method' error.
|
||||
*/
|
||||
public function __call($method, $args) {
|
||||
public function __call($method, $args)
|
||||
{
|
||||
// Check if we can safely call this method before passing it back
|
||||
// to custom methods.
|
||||
if($this->getExtraMethodConfig($method)) {
|
||||
if ($this->getExtraMethodConfig($method)) {
|
||||
return parent::__call($method, $args);
|
||||
}
|
||||
|
||||
// Pass back to copied page
|
||||
$original = $this->copyContentFrom();
|
||||
$controller = ModelAsController::controller_for($original);
|
||||
$controller = $this->getVirtualisedController();
|
||||
if(!$controller) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ensure request/response data is available on virtual controller
|
||||
$controller->setRequest($this->getRequest());
|
||||
$controller->response = $this->response; // @todo - replace with getter/setter in 3.3
|
||||
$controller->setResponse($this->getResponse());
|
||||
|
||||
return call_user_func_array(array($controller, $method), $args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -601,6 +601,17 @@ class VirtualPageTest extends FunctionalTest {
|
||||
$this->assertEquals(301, $response->getStatusCode());
|
||||
$this->assertEquals('http://google.com', $response->getHeader('Location'));
|
||||
}
|
||||
|
||||
public function testMethod() {
|
||||
$virtualPage = $this->objFromFixture('VirtualPage', 'vp4');
|
||||
$controller = ModelAsController::controller_for($virtualPage);
|
||||
|
||||
$this->assertInstanceOf('VirtualPage_Controller', $controller);
|
||||
$this->assertTrue($controller->hasMethod('testMethod'));
|
||||
$this->assertEquals('hello', $controller->testMethod());
|
||||
$this->assertTrue($controller->hasMethod('modelMethod'));
|
||||
$this->assertEquals('hi there', $controller->modelMethod());
|
||||
}
|
||||
}
|
||||
|
||||
class VirtualPageTest_ClassA extends Page implements TestOnly {
|
||||
@ -613,6 +624,16 @@ class VirtualPageTest_ClassA extends Page implements TestOnly {
|
||||
);
|
||||
|
||||
private static $allowed_children = array('VirtualPageTest_ClassB');
|
||||
|
||||
public function modelMethod() {
|
||||
return 'hi there';
|
||||
}
|
||||
}
|
||||
|
||||
class VirtualPageTest_ClassA_Controller extends Page_Controller implements TestOnly {
|
||||
public function testMethod() {
|
||||
return 'hello';
|
||||
}
|
||||
}
|
||||
|
||||
class VirtualPageTest_ClassB extends Page implements TestOnly {
|
||||
|
@ -45,6 +45,10 @@ Page:
|
||||
CanEditType: OnlyTheseUsers
|
||||
CanViewType: Inherit
|
||||
EditorGroups: =>SilverStripe\Security\Group.bobgroup
|
||||
VirtualPageTest_ClassA:
|
||||
pagea:
|
||||
Title: 'Page A'
|
||||
Content: '<p>Content</p>'
|
||||
VirtualPage:
|
||||
vp1:
|
||||
Title: vp1
|
||||
@ -61,3 +65,6 @@ VirtualPage:
|
||||
CanViewType: OnlyTheseUsers
|
||||
EditorGroups: =>SilverStripe\Security\Group.andrewgroup
|
||||
ViewerGroups: =>SilverStripe\Security\Group.cindygroup
|
||||
vp4:
|
||||
CopyContentFrom: =>VirtualPageTest_ClassA.pagea
|
||||
Title: 'vp4'
|
||||
|
Loading…
x
Reference in New Issue
Block a user