Refactor VirtualPage, remove VirtualPage_Controller

This commit is contained in:
Loz Calver 2016-09-08 15:47:03 +01:00
parent 3d827543a8
commit 62816e1ff8
3 changed files with 35 additions and 141 deletions

View File

@ -414,24 +414,6 @@ class VirtualPage extends Page {
return $copy && $copy->exists() && $copy->hasField($field); return $copy && $copy->exists() && $copy->hasField($field);
} }
/**
* Overwrite to also check for method on the original data object
*
* @param string $method
* @return bool
*/
public function hasMethod($method) {
if(parent::hasMethod($method)) {
return true;
}
// Don't call property setters on copied page
if(stripos($method, 'set') === 0) {
return false;
}
$copy = $this->CopyContentFrom();
return $copy && $copy->exists() && $copy->hasMethod($method);
}
/** /**
* Return the "casting helper" (a piece of PHP code that when evaluated creates a casted value object) for a field * Return the "casting helper" (a piece of PHP code that when evaluated creates a casted value object) for a field
* on this object. * on this object.
@ -447,4 +429,28 @@ class VirtualPage extends Page {
return parent::castingHelper($field); return parent::castingHelper($field);
} }
/**
* {@inheritdoc}
*/
public function allMethodNames($custom = false) {
$methods = parent::allMethodNames($custom);
if ($copy = $this->CopyContentFrom()) {
$methods = array_merge($methods, $copy->allMethodNames($custom));
}
return $methods;
}
/**
* {@inheritdoc}
*/
public function getControllerName() {
if ($copy = $this->CopyContentFrom()) {
return $copy->getControllerName();
}
return parent::getControllerName();
}
} }

View File

@ -1,117 +0,0 @@
<?php
namespace SilverStripe\CMS\Model;
use SilverStripe\CMS\Controllers\ContentController;
use SilverStripe\CMS\Controllers\ModelAsController;
use Exception;
use Page_Controller;
/**
* Controller for the virtual page.
*/
class VirtualPage_Controller extends Page_Controller
{
private static $allowed_actions = array(
'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)
{
$controller = $this->getVirtualisedController();
if($controller) {
return $controller->getViewer($action);
}
return parent::getViewer($action);
}
/**
* When the virtualpage is loaded, check to see if the versions are the same
* if not, reload the content.
* NOTE: Virtual page must have a container object of subclass of sitetree.
* We can't load the content without an ID or record to copy it from.
*/
public function init()
{
parent::init();
$this->__call('init', array());
}
/**
* Also check the original object's original controller for the method
*
* @param string $method
* @return bool
*/
public function hasMethod($method)
{
if (parent::hasMethod($method)) {
return true;
};
// Fallback
$controller = $this->getVirtualisedController();
return $controller && $controller->hasMethod($method);
}
/**
* Pass unrecognized method calls on to the original controller
*
* @param string $method
* @param string $args
* @return mixed
*
* @throws Exception Any error other than a 'no method' error.
*/
public function __call($method, $args)
{
// Check if we can safely call this method before passing it back
// to custom methods.
if ($this->getExtraMethodConfig($method)) {
return parent::__call($method, $args);
}
// Pass back to copied page
$controller = $this->getVirtualisedController();
if (!$controller) {
return null;
}
// Ensure request/response data is available on virtual controller
$controller->setRequest($this->getRequest());
$controller->setResponse($this->getResponse());
return call_user_func_array(array($controller, $method), $args);
}
}

View File

@ -1,6 +1,5 @@
<?php <?php
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\Versioning\Versioned; use SilverStripe\ORM\Versioning\Versioned;
use SilverStripe\ORM\DB; use SilverStripe\ORM\DB;
@ -15,10 +14,6 @@ use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\FunctionalTest; use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Dev\TestOnly; use SilverStripe\Dev\TestOnly;
class VirtualPageTest extends FunctionalTest { class VirtualPageTest extends FunctionalTest {
protected static $fixture_file = 'VirtualPageTest.yml'; protected static $fixture_file = 'VirtualPageTest.yml';
protected static $use_draft_site = false; protected static $use_draft_site = false;
@ -616,12 +611,18 @@ class VirtualPageTest extends FunctionalTest {
$virtualPage = $this->objFromFixture('SilverStripe\\CMS\\Model\\VirtualPage', 'vp4'); $virtualPage = $this->objFromFixture('SilverStripe\\CMS\\Model\\VirtualPage', 'vp4');
$controller = ModelAsController::controller_for($virtualPage); $controller = ModelAsController::controller_for($virtualPage);
$this->assertInstanceOf('SilverStripe\\CMS\\Model\\VirtualPage_Controller', $controller); $this->assertInstanceOf('VirtualPageTest_ClassA_Controller', $controller);
$this->assertTrue($controller->hasMethod('testMethod')); $this->assertTrue($controller->hasMethod('testMethod'));
$this->assertEquals('hello', $controller->testMethod()); $this->assertEquals('hello', $controller->testMethod());
$this->assertTrue($controller->hasMethod('modelMethod')); $this->assertTrue($controller->hasMethod('modelMethod'));
$this->assertEquals('hi there', $controller->modelMethod()); $this->assertEquals('hi there', $controller->modelMethod());
} }
public function testAllowedActions() {
$virtualPage = $this->objFromFixture('SilverStripe\\CMS\\Model\\VirtualPage', 'vp4');
$controller = ModelAsController::controller_for($virtualPage);
$this->assertContains('testaction', $controller->allowedActions());
}
} }
class VirtualPageTest_ClassA extends Page implements TestOnly { class VirtualPageTest_ClassA extends Page implements TestOnly {
@ -641,6 +642,10 @@ class VirtualPageTest_ClassA extends Page implements TestOnly {
} }
class VirtualPageTest_ClassA_Controller extends Page_Controller implements TestOnly { class VirtualPageTest_ClassA_Controller extends Page_Controller implements TestOnly {
private static $allowed_actions = [
'testaction'
];
public function testMethod() { public function testMethod() {
return 'hello'; return 'hello';
} }