Browse files

Merge pull request #466 from silverstripe-scienceninjas/feature/confi…

…g-enhancements

Feature/config enhancements
  • Loading branch information...
2 parents dd924f1 + 94f50f5 commit f348141cfda25a15fd8b545b4945342070e4df5c @sminnee sminnee committed May 20, 2012
View
16 _config.php
@@ -17,22 +17,6 @@
* @subpackage core
*/
-// Default director
-Director::addRules(10, array(
- 'Security//$Action/$ID/$OtherID' => 'Security',
- //'Security/$Action/$ID' => 'Security',
- '$Controller//$Action/$ID/$OtherID' => '*',
- 'api/v1/live' => 'VersionedRestfulServer',
- 'api/v1' => 'RestfulServer',
- 'soap/v1' => 'SOAPModelAccess',
- 'dev' => 'DevelopmentAdmin',
- 'interactive' => 'SapphireREPL',
-));
-// Add default routing unless 'cms' module is present (which overrules this with a CMSMain controller)
-Director::addRules(20, array(
- 'admin//$action/$ID/$OtherID' => '->admin/security'
-));
-
/**
* PHP 5.2 introduced a conflict with the Datetime field type, which was renamed to SSDatetime. This was later renamed
* to SS_Datetime to be consistent with other namespaced classes.
View
6 _config/RequestProcessor.yml
@@ -1,6 +0,0 @@
-name: RequestProcessor
----
-# Providing an empty config so it can be overridden at a later point
-Injector:
- RequestProcessor:
- 0:
View
3 _config/PasswordEncryptor.yml → _config/encryptors.yml
@@ -1,4 +1,5 @@
-name: PasswordEncryptor
+---
+name: coreencryptors
---
PasswordEncryptor:
encryptors:
View
3 _config/HTTP.yml → _config/mimetypes.yml
@@ -1,4 +1,5 @@
-name: HTTP
+---
+name: basicmimetypes
---
HTTP:
MimeTypes:
View
23 _config/routes.yml
@@ -0,0 +1,23 @@
+---
+Name: coreroutes
+After: cms/routes#modelascontrollerroutes
+Before: '*'
+---
+Director:
+ rules:
+ 'Security//$Action/$ID/$OtherID': 'Security'
+ '$Controller//$Action/$ID/$OtherID': '*'
+ 'api/v1/live': 'VersionedRestfulServer'
+ 'api/v1': 'RestfulServer'
+ 'soap/v1': 'SOAPModelAccess'
+ 'dev': 'DevelopmentAdmin'
+ 'interactive': 'SapphireREPL'
+---
+Name: adminroutes
+After: framework/routes#coreroutes
+---
+Director:
+ rules:
+ 'admin': 'AdminRootController'
+ '': 'RootURLController'
+ 'dev/buildcache/$Action': 'RebuildStaticCacheTask'
View
10 admin/_config.php
@@ -1,14 +1,4 @@
<?php
-Director::addRules(50, array(
- '' => 'RootURLController',
- 'processes//$Action/$ID/$Batch' => 'BatchProcess_Controller',
- 'admin/help//$Action/$ID' => 'CMSHelp',
- 'admin/bulkload//$Action/$ID/$OtherID' => 'BulkLoaderAdmin',
- 'dev/buildcache/$Action' => 'RebuildStaticCacheTask',
-));
-
-CMSMenu::add_director_rules();
-
// Default CMS HTMLEditorConfig
HtmlEditorConfig::get('cms')->setOptions(array(
'friendly_name' => 'Default CMS',
View
94 admin/code/AdminRootController.php
@@ -0,0 +1,94 @@
+<?php
+
+class AdminRootController extends Controller {
+
+ /**
+ * @var string
+ * @config
+ * The url base that all LeftAndMain derived panels will live under
+ * Won't automatically update the base route if you change this - that has to be done seperately
+ */
+ static $url_base = 'admin';
+
+ /**
+ * @var string
+ * @config
+ * The LeftAndMain child that will be used as the initial panel to display if none is selected (i.e. if you visit /admin)
+ */
+ static $default_panel = 'SecurityAdmin';
+
+ /**
+ * @var array
+ * Holds an array of url_pattern => controller k/v pairs, the same as Director::rules. However this is built
+ * dynamically from introspecting on all the classes that derive from LeftAndMain.
+ *
+ * Don't access this directly - always access via the rules() accessor below, which will build this array
+ * the first time it's accessed
+ */
+ private static $_rules = null;
+
+ /**
+ * Gets a list of url_pattern => controller k/v pairs for each LeftAndMain derived controller
+ */
+ public static function rules() {
+ if (self::$_rules === null) {
+ self::$_rules = array();
+
+ // Build an array of class => url_priority k/v pairs
+ $classes = array();
+ foreach (CMSMenu::get_cms_classes() as $class) {
+ $classes[$class] = Config::inst()->get($class, 'url_priority', Config::FIRST_SET);
+ }
+
+ // Sort them so highest priority item is first
+ arsort($classes, SORT_NUMERIC);
+
+ // Map over the array calling add_rule_for_controller on each
+ array_map(array(__CLASS__, 'add_rule_for_controller'), array_keys($classes));
+ }
+
+ return self::$_rules;
+ }
+
+ /**
+ * Add the appropriate k/v pair to self::$rules for the given controller.
+ */
+ protected static function add_rule_for_controller($controllerClass) {
+ $urlSegment = Config::inst()->get($controllerClass, 'url_segment', Config::FIRST_SET);
+ $urlRule = Config::inst()->get($controllerClass, 'url_rule', Config::FIRST_SET);
+
+ if($urlSegment || $controllerClass == 'CMSMain') {
+ // Make director rule
+ if($urlRule[0] == '/') $urlRule = substr($urlRule,1);
+ $rule = $urlSegment . '//' . $urlRule;
+
+ self::$_rules[$rule] = $controllerClass;
+ }
+ }
+
+ function handleRequest(SS_HTTPRequest $request, DataModel $model) {
+ // If this is the final portion of the request (i.e. the URL is just /admin), direct to the default panel
+ if ($request->allParsed()) {
+ $base = $this->config()->url_base;
+ $segment = Config::inst()->get($this->config()->default_panel, 'url_segment');
+
+ $this->response = new SS_HTTPResponse();
+ $this->redirect(Controller::join_links($base, $segment));
+ return $this->response;
+ }
+
+ // Otherwise
+ else {
+ $rules = self::rules();
+
+ foreach($rules as $pattern => $controller) {
+ if(($arguments = $request->match($pattern, true)) !== false) {
+ $controllerObj = Injector::inst()->create($controller);
+ $controllerObj->setSession($this->session);
+
+ return $controllerObj->handleRequest($request, $model);
+ }
+ }
+ }
+ }
+}
View
27 admin/code/CMSMenu.php
@@ -35,13 +35,6 @@ public static function populate_menu() {
}
/**
- * Add Director rules for all of the CMS controllers.
- */
- public static function add_director_rules() {
- array_map(array('self','add_director_rule_for_controller'), self::get_cms_classes());
- }
-
- /**
* Add a LeftAndMain controller to the CMS menu.
*
* @param string $controllerClass The class name of the controller
@@ -76,27 +69,7 @@ protected static function menuitem_for_controller($controllerClass) {
return new CMSMenuItem($menuTitle, $link, $controllerClass, $menuPriority);
}
-
- /**
- * Add the appropriate Director rules for the given controller.
- */
- protected static function add_director_rule_for_controller($controllerClass) {
- $urlBase = Config::inst()->get($controllerClass, 'url_base', Config::FIRST_SET);
- $urlSegment = Config::inst()->get($controllerClass, 'url_segment', Config::FIRST_SET);
- $urlRule = Config::inst()->get($controllerClass, 'url_rule', Config::FIRST_SET);
- $urlPriority = Config::inst()->get($controllerClass, 'url_priority', Config::FIRST_SET);
- if($urlSegment || $controllerClass == 'CMSMain') {
- $link = Controller::join_links($urlBase, $urlSegment) . '/';
-
- // Make director rule
- if($urlRule[0] == '/') $urlRule = substr($urlRule,1);
- $rule = $link . '/' . $urlRule; // the / will combine with the / on the end of $link to make a //
- Director::addRules($urlPriority, array(
- $rule => $controllerClass
- ));
- }
- }
/**
* Add an arbitrary URL to the CMS menu.
View
82 control/Director.php
@@ -41,7 +41,11 @@ class Director implements TemplateGlobalProvider {
* We recommend priority 100 for your site's rules. The built-in rules are priority 10, standard modules are priority 50.
*/
static function addRules($priority, $rules) {
- Director::$rules[$priority] = isset(Director::$rules[$priority]) ? array_merge($rules, (array)Director::$rules[$priority]) : $rules;
+ if ($priority != 100) {
+ Deprecation::notice('3.0', 'Priority argument is now ignored - use the default of 100. You should really be setting routes via _config yaml fragments though.');
+ }
+
+ Config::inst()->update('Director', 'rules', $rules);
}
/**
@@ -242,48 +246,46 @@ static function test($url, $postVars = null, $session = null, $httpMethod = null
* @return SS_HTTPResponse|string
*/
protected static function handleRequest(SS_HTTPRequest $request, Session $session, DataModel $model) {
- krsort(Director::$rules);
-
- if(isset($_REQUEST['debug'])) Debug::show(Director::$rules);
- foreach(Director::$rules as $priority => $rules) {
- foreach($rules as $pattern => $controllerOptions) {
- if(is_string($controllerOptions)) {
- if(substr($controllerOptions,0,2) == '->') $controllerOptions = array('Redirect' => substr($controllerOptions,2));
- else $controllerOptions = array('Controller' => $controllerOptions);
+ $rules = Config::inst()->get('Director', 'rules');
+
+ if(isset($_REQUEST['debug'])) Debug::show($rules);
+
+ foreach($rules as $pattern => $controllerOptions) {
+ if(is_string($controllerOptions)) {
+ if(substr($controllerOptions,0,2) == '->') $controllerOptions = array('Redirect' => substr($controllerOptions,2));
+ else $controllerOptions = array('Controller' => $controllerOptions);
+ }
+
+ if(($arguments = $request->match($pattern, true)) !== false) {
+ // controllerOptions provide some default arguments
+ $arguments = array_merge($controllerOptions, $arguments);
+
+ // Find the controller name
+ if(isset($arguments['Controller'])) $controller = $arguments['Controller'];
+
+ // Pop additional tokens from the tokeniser if necessary
+ if(isset($controllerOptions['_PopTokeniser'])) {
+ $request->shift($controllerOptions['_PopTokeniser']);
}
-
- if(($arguments = $request->match($pattern, true)) !== false) {
- // controllerOptions provide some default arguments
- $arguments = array_merge($controllerOptions, $arguments);
-
- // Find the controller name
- if(isset($arguments['Controller'])) $controller = $arguments['Controller'];
-
- // Pop additional tokens from the tokeniser if necessary
- if(isset($controllerOptions['_PopTokeniser'])) {
- $request->shift($controllerOptions['_PopTokeniser']);
- }
- // Handle redirections
- if(isset($arguments['Redirect'])) {
- return "redirect:" . Director::absoluteURL($arguments['Redirect'], true);
-
- } else {
- Director::$urlParams = $arguments;
- $controllerObj = Injector::inst()->create($controller);
- $controllerObj->setSession($session);
-
- try {
- $result = $controllerObj->handleRequest($request, $model);
- } catch(SS_HTTPResponse_Exception $responseException) {
- $result = $responseException->getResponse();
- }
- if(!is_object($result) || $result instanceof SS_HTTPResponse) return $result;
-
- user_error("Bad result from url " . $request->getURL() . " handled by " .
- get_class($controllerObj)." controller: ".get_class($result), E_USER_WARNING);
-
+ // Handle redirections
+ if(isset($arguments['Redirect'])) {
+ return "redirect:" . Director::absoluteURL($arguments['Redirect'], true);
+
+ } else {
+ Director::$urlParams = $arguments;
+ $controllerObj = Injector::inst()->create($controller);
+ $controllerObj->setSession($session);
+
+ try {
+ $result = $controllerObj->handleRequest($request, $model);
+ } catch(SS_HTTPResponse_Exception $responseException) {
+ $result = $responseException->getResponse();
}
+ if(!is_object($result) || $result instanceof SS_HTTPResponse) return $result;
+
+ user_error("Bad result from url " . $request->getURL() . " handled by " .
+ get_class($controllerObj)." controller: ".get_class($result), E_USER_WARNING);
}
}
}
View
7 core/manifest/ConfigManifest.php
@@ -485,12 +485,7 @@ function matchesVariantRules($rules) {
*/
function mergeInYamlFragment(&$into, $fragment) {
foreach ($fragment as $k => $v) {
- if (is_array($v) || is_object($v)) {
- if (isset($into[$k])) { $sub = $into[$k]; $this->mergeInYamlFragment($sub, $v); $into[$k] = $sub; }
- else $into[$k] = $v;
- }
- else if (is_numeric($k)) $into[] = $v;
- else $into[$k] = $v;
+ Config::merge_high_into_low($into[$k], $v);
}
}

0 comments on commit f348141

Please sign in to comment.