add config var for namespace mapping page->control, add test to confirm

This commit is contained in:
Andrew Aitken-Fincham 2019-10-15 12:29:05 +01:00 committed by Andrew Paxley
parent 3b980c40c6
commit 863ed24920
4 changed files with 70 additions and 4 deletions

View File

@ -215,6 +215,22 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
*/
private static $controller_name = null;
/**
* You can define the a map of Page namespaces to Controller namespaces here
* This will apply after the magic of appending Controller, and in order
* Must be applied to SiteTree config e.g.
*
* SilverStripe\CMS\Model\SiteTree:
* namespace_map:
* "App\Pages": "App\Control"
*
* Will map App\Pages\MyPage to App\Control\MyPageController
*
* @config
* @var string
*/
private static $namespace_map = null;
private static $db = [
"URLSegment" => "Varchar(255)",
"Title" => "Varchar(255)",
@ -2989,6 +3005,8 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
return $controller;
}
$namespaceMap = Config::inst()->get(SiteTree::class, 'namespace_mapping');
//default controller for SiteTree objects
$controller = ContentController::class;
@ -3002,8 +3020,7 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
}
// If we have a class of "{$ClassName}Controller" then we found our controller
if (class_exists($candidate = sprintf('%sController', $class))) {
$controller = $candidate;
break;
return $candidate;
} elseif (class_exists($candidate = sprintf('%s_Controller', $class))) {
// Support the legacy underscored filename, but raise a deprecation notice
Deprecation::notice(
@ -3011,8 +3028,20 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi
'Underscored controller class names are deprecated. Use "MyController" instead of "My_Controller".',
Deprecation::SCOPE_GLOBAL
);
$controller = $candidate;
break;
return $candidate;
} elseif (is_array($namespaceMap)) {
foreach ($namespaceMap as $pageNamespace => $controllerNamespace) {
if (strpos($class, $pageNamespace) !== 0) {
continue;
}
$candidate = sprintf(
'%sController',
str_replace($pageNamespace, $controllerNamespace, $class)
);
if (class_exists($candidate)) {
return $candidate;
}
}
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace SilverStripe\CMS\Tests\Controllers;
use SilverStripe\CMS\Controllers\ContentController;
use SilverStripe\Dev\TestOnly;
class SiteTreeTest_NamespaceMapTestController extends ContentController implements TestOnly
{
}

View File

@ -9,6 +9,8 @@ use ReflectionMethod;
use SilverStripe\CMS\Model\RedirectorPage;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\CMS\Model\VirtualPage;
use SilverStripe\CMS\Tests\Controllers\SiteTreeTest_NamespaceMapTestController;
use SilverStripe\CMS\Tests\Page\SiteTreeTest_NamespaceMapTest;
use SilverStripe\Control\ContentNegotiator;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
@ -1651,6 +1653,19 @@ class SiteTreeTest extends SapphireTest
$this->assertSame('This\\Is\\A\\New\\Controller', $class->getControllerName());
}
/**
* Test that the controller name for a Namespaced SiteTree instance can be gathered when set via namespace map
*/
public function testGetControllerNameFromNamespaceMappingConfig()
{
Config::inst()->update(SiteTree::class, 'namespace_mapping', [
'SilverStripe\\CMS\\Tests\\Page' => 'SilverStripe\\CMS\\Tests\\Controllers',
]);
$namespacedSiteTree = new SiteTreeTest_NamespaceMapTest();
$this->assertSame(SiteTreeTest_NamespaceMapTestController::class, $namespacedSiteTree->getControllerName());
}
/**
* Test that underscored class names (legacy) are still supported (deprecation notice is issued though).
*/

View File

@ -0,0 +1,11 @@
<?php
namespace SilverStripe\CMS\Tests\Page;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Dev\TestOnly;
class SiteTreeTest_NamespaceMapTest extends SiteTree implements TestOnly
{
private static $table_name = 'SiteTreeTest_NamespaceMapTestNode';
}