From 2983d823d1eef293ef11aac9e01336e23ed52b59 Mon Sep 17 00:00:00 2001 From: Loz Calver Date: Mon, 16 Nov 2015 15:36:52 +0000 Subject: [PATCH] FIX: Ensure VirtualPage forwards request/response data to virtual controllers (fixes #1329) --- code/model/VirtualPage.php | 15 ++++++++++----- tests/model/VirtualPageTest.php | 25 ++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/code/model/VirtualPage.php b/code/model/VirtualPage.php index ac9a9151..d456e738 100644 --- a/code/model/VirtualPage.php +++ b/code/model/VirtualPage.php @@ -563,12 +563,17 @@ class VirtualPage_Controller extends Page_Controller { } catch (Exception $e) { // Hack... detect exception type. We really should use exception subclasses. // if the exception isn't a 'no method' error, rethrow it - if ($e->getCode() !== 2175) throw $e; + if ($e->getCode() !== 2175) { + throw $e; + } + $original = $this->copyContentFrom(); - $originalClass = get_class($original); - if ($originalClass == 'SiteTree') $name = 'ContentController'; - else $name = $originalClass."_Controller"; - $controller = new $name($this->dataRecord->copyContentFrom()); + $controller = ModelAsController::controller_for($original); + + // 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 + return call_user_func_array(array($controller, $method), $args); } } diff --git a/tests/model/VirtualPageTest.php b/tests/model/VirtualPageTest.php index 1a764a84..6e8fafaa 100644 --- a/tests/model/VirtualPageTest.php +++ b/tests/model/VirtualPageTest.php @@ -1,7 +1,9 @@ logInWithPermission("ADMIN"); + $this->origInitiallyCopiedFields = VirtualPage::config()->initially_copied_fields; Config::inst()->remove('VirtualPage', 'initially_copied_fields'); VirtualPage::config()->initially_copied_fields = array_merge( @@ -644,6 +649,24 @@ class VirtualPageTest extends SapphireTest { if(!$isDetected) $this->fail("Shouldn't be allowed to write a VirtualPage that links to a disallowed child"); } + + public function testVirtualPagePointingToRedirectorPage() { + if (!class_exists('RedirectorPage')) { + $this->markTestSkipped('RedirectorPage required'); + } + + $rp = new RedirectorPage(array('ExternalURL' => 'http://google.com', 'RedirectionType' => 'External')); + $rp->write(); + $rp->doPublish(); + + $vp = new VirtualPage(array('URLSegment' => 'vptest', 'CopyContentFromID' => $rp->ID)); + $vp->write(); + $vp->doPublish(); + + $response = $this->get($vp->Link()); + $this->assertEquals(301, $response->getStatusCode()); + $this->assertEquals('http://google.com', $response->getHeader('Location')); + } } class VirtualPageTest_ClassA extends Page implements TestOnly {