diff --git a/_config/dev.yml b/_config/dev.yml
new file mode 100644
index 000000000..a3aa0b604
--- /dev/null
+++ b/_config/dev.yml
@@ -0,0 +1,23 @@
+---
+Name: DevelopmentAdmin
+---
+DevelopmentAdmin:
+ registered_controllers:
+ build:
+ controller: 'DevBuildController'
+ links:
+ build: 'Build/rebuild this environment. Call this whenever you have updated your project sources'
+ tests:
+ controller: 'TestRunner'
+ links:
+ tests: 'See a list of unit tests to run'
+ 'tests/all': 'Run all tests'
+ jstests:
+ controller: 'JSTestRunner'
+ links:
+ jstests: 'See a list of JavaScript tests to run'
+ 'jstests/all': 'Run all JavaScript tests'
+ tasks:
+ controller: 'TaskRunner'
+ links:
+ tasks: 'See a list of build tasks to run'
\ No newline at end of file
diff --git a/dev/DevBuildController.php b/dev/DevBuildController.php
new file mode 100644
index 000000000..02ffbaa52
--- /dev/null
+++ b/dev/DevBuildController.php
@@ -0,0 +1,32 @@
+ 'build'
+ );
+
+ private static $allowed_actions = array(
+ 'build'
+ );
+
+
+ public function build($request) {
+ if(Director::is_cli()) {
+ $da = DatabaseAdmin::create();
+ return $da->handleRequest($request, $this->model);
+ } else {
+ $renderer = DebugView::create();
+ $renderer->writeHeader();
+ $renderer->writeInfo("Environment Builder", Director::absoluteBaseURL());
+ echo "
";
+
+ $da = DatabaseAdmin::create();
+ return $da->handleRequest($request, $this->model);
+
+ echo "
";
+ $renderer->writeFooter();
+ }
+ }
+
+}
diff --git a/dev/DevelopmentAdmin.php b/dev/DevelopmentAdmin.php
index 6533aea10..d68d941f7 100644
--- a/dev/DevelopmentAdmin.php
+++ b/dev/DevelopmentAdmin.php
@@ -1,10 +1,15 @@
'index',
'build/defaults' => 'buildDefaults',
- '$Action' => '$Action',
- '$Action//$Action/$ID' => 'handleAction',
+ 'generatesecuretoken' => 'generatesecuretoken',
+ '$Action' => 'runRegisteredController',
);
private static $allowed_actions = array(
'index',
- 'tests',
- 'jstests',
- 'tasks',
- 'viewmodel',
- 'build',
- 'reset',
- 'viewcode',
- 'generatesecuretoken',
'buildDefaults',
+ 'runRegisteredController',
+ 'generatesecuretoken',
);
+
public function init() {
parent::init();
@@ -80,20 +80,8 @@ class DevelopmentAdmin extends Controller {
}
public function index() {
- $actions = array(
- "build" => "Build/rebuild this environment. Call this whenever you have updated your project sources",
- "tests" => "See a list of unit tests to run",
- "tests/all" => "Run all tests",
- "jstests" => "See a list of JavaScript tests to run",
- "jstests/all" => "Run all JavaScript tests",
- "tasks" => "See a list of build tasks to run"
- );
-
// Web mode
if(!Director::is_cli()) {
- // This action is sake-only right now.
- unset($actions["modules/add"]);
-
$renderer = DebugView::create();
$renderer->writeHeader();
$renderer->writeInfo("SilverStripe Development Tools", Director::absoluteBaseURL());
@@ -101,7 +89,7 @@ class DevelopmentAdmin extends Controller {
echo '';
$evenOdd = "odd";
- foreach($actions as $action => $description) {
+ foreach(self::get_links() as $action => $description) {
echo "- /dev/$action:"
. " $description
\n";
$evenOdd = ($evenOdd == "odd") ? "even" : "odd";
@@ -113,42 +101,74 @@ class DevelopmentAdmin extends Controller {
} else {
echo "SILVERSTRIPE DEVELOPMENT TOOLS\n--------------------------\n\n";
echo "You can execute any of the following commands:\n\n";
- foreach($actions as $action => $description) {
+ foreach(self::get_links() as $action => $description) {
echo " sake dev/$action: $description\n";
}
echo "\n\n";
}
}
- public function tests($request) {
- return TestRunner::create();
- }
-
- public function jstests($request) {
- return JSTestRunner::create();
- }
-
- public function tasks() {
- return TaskRunner::create();
- }
-
- public function build($request) {
- if(Director::is_cli()) {
- $da = DatabaseAdmin::create();
- return $da->handleRequest($request, $this->model);
- } else {
- $renderer = DebugView::create();
- $renderer->writeHeader();
- $renderer->writeInfo("Environment Builder", Director::absoluteBaseURL());
- echo "";
-
- $da = DatabaseAdmin::create();
- return $da->handleRequest($request, $this->model);
-
- echo "
";
- $renderer->writeFooter();
+ public function runRegisteredController(SS_HTTPRequest $request){
+ $controllerClass = null;
+
+ $baseUrlPart = $request->param('Action');
+ $reg = Config::inst()->get(__CLASS__, 'registered_controllers');
+ if(isset($reg[$baseUrlPart])){
+ $controllerClass = $reg[$baseUrlPart]['controller'];
+ }
+
+ if($controllerClass && class_exists($controllerClass)){
+ return $controllerClass::create();
+ }
+
+ $msg = 'Error: no controller registered in '.__CLASS__.' for: '.$request->param('Action');
+ if(Director::is_cli()){
+ // in CLI we cant use httpError because of a bug with stuff being in the output already, see DevAdminControllerTest
+ throw new Exception($msg);
+ }else{
+ $this->httpError(500, $msg);
}
}
+
+
+
+
+ /*
+ * Internal methods
+ */
+
+ /**
+ * @return array of url => description
+ */
+ protected static function get_links(){
+ $links = array();
+
+ $reg = Config::inst()->get(__CLASS__, 'registered_controllers');
+ foreach($reg as $registeredController){
+ foreach($registeredController['links'] as $url => $desc){
+ $links[$url] = $desc;
+ }
+ }
+ return $links;
+ }
+
+ protected function getRegisteredController($baseUrlPart){
+ $reg = Config::inst()->get(__CLASS__, 'registered_controllers');
+
+ if(isset($reg[$baseUrlPart])){
+ $controllerClass = $reg[$baseUrlPart]['controller'];
+ return $controllerClass;
+ }
+
+ return null;
+ }
+
+
+
+
+ /*
+ * Unregistered (hidden) actions
+ */
/**
* Build the default data, calling requireDefaultRecords on all
diff --git a/tests/dev/DevAdminControllerTest.php b/tests/dev/DevAdminControllerTest.php
new file mode 100644
index 000000000..c09b14684
--- /dev/null
+++ b/tests/dev/DevAdminControllerTest.php
@@ -0,0 +1,116 @@
+update('DevelopmentAdmin', 'registered_controllers', array(
+ 'x1' => array(
+ 'controller' => 'DevAdminControllerTest_Controller1',
+ 'links' => array(
+ 'x1' => 'x1 link description',
+ 'x1/y1' => 'x1/y1 link description'
+ )
+ ),
+ 'x2' => array(
+ 'controller' => 'DevAdminControllerTest_Controller2', // intentionally not a class that exists
+ 'links' => array(
+ 'x2' => 'x2 link description'
+ )
+ )
+ ));
+ }
+
+ public function tearDown(){
+ parent::tearDown();
+ Config::unnest();
+ }
+
+
+ public function testGoodRegisteredControllerOutput(){
+ // Check for the controller running from the registered url above
+ // (we use contains rather than equals because sometimes you get Warning: You probably want to define an entry in $_FILE_TO_URL_MAPPING)
+ $this->assertContains(DevAdminControllerTest_Controller1::OK_MSG, $this->getCapture('/dev/x1'));
+ $this->assertContains(DevAdminControllerTest_Controller1::OK_MSG, $this->getCapture('/dev/x1/y1'));
+ }
+
+ public function testGoodRegisteredControllerStatus(){
+ // Check response code is 200/OK
+ $this->assertEquals(false, $this->getAndCheckForError('/dev/x1'));
+ $this->assertEquals(false, $this->getAndCheckForError('/dev/x1/y1'));
+
+ // Check response code is 500/ some sort of error
+ $this->assertEquals(true, $this->getAndCheckForError('/dev/x2'));
+ }
+
+
+
+ protected function getCapture($url){
+ $this->logInWithPermission('ADMIN');
+
+ ob_start();
+ $this->get($url);
+ $r = ob_get_contents();
+ ob_end_clean();
+
+ return $r;
+ }
+
+ protected function getAndCheckForError($url){
+ $this->logInWithPermission('ADMIN');
+
+ if(Director::is_cli()){
+ // when in CLI the admin controller throws exceptions
+ ob_start();
+ try{
+ $this->get($url);
+ }catch(Exception $e){
+ ob_end_clean();
+ return true;
+ }
+
+ ob_end_clean();
+ return false;
+
+ }else{
+ // when in http the admin controller sets a response header
+ ob_start();
+ $resp = $this->get($url);
+ ob_end_clean();
+ return $resp->isError();
+ }
+ }
+
+}
+
+class DevAdminControllerTest_Controller1 extends Controller {
+
+ const OK_MSG = 'DevAdminControllerTest_Controller1 TEST OK';
+
+ private static $url_handlers = array(
+ '' => 'index',
+ 'y1' => 'y1Action'
+ );
+
+ private static $allowed_actions = array(
+ 'index',
+ 'y1Action',
+ );
+
+
+ public function index(){
+ echo self::OK_MSG;
+ }
+
+ public function y1Action(){
+ echo self::OK_MSG;
+ }
+
+}
\ No newline at end of file