예제 #1
0
 function run($requestParams)
 {
     if (isset($_GET['debug_profile'])) {
         Profiler::mark("Controller", "run");
     }
     $this->pushCurrent();
     $this->response = new HTTPResponse();
     $this->requestParams = $requestParams;
     $this->action = isset($this->urlParams['Action']) ? str_replace("-", "_", $this->urlParams['Action']) : "";
     if (!$this->action) {
         $this->action = 'index';
     }
     // Check security on the controller
     if (!$this->checkAccessAction($this->action)) {
         user_error("Disallowed action: '{$this->action}' on controller '{$this->class}'", E_USER_ERROR);
     }
     // Init
     $this->baseInitCalled = false;
     $this->init();
     if (!$this->baseInitCalled) {
         user_error("init() method on class '{$this->class}' doesn't call Controller::init().  Make sure that you have parent::init() included.", E_USER_WARNING);
     }
     // If we had a redirection or something, halt processing.
     if ($this->response->isFinished()) {
         $this->popCurrent();
         return $this->response;
     }
     // Look at the action variables for forms
     $funcName = null;
     foreach ($this->requestParams as $paramName => $paramVal) {
         if (substr($paramName, 0, 7) == 'action_') {
             // Cleanup action_, _x and _y from image fields
             $funcName = preg_replace(array('/^action_/', '/_x$|_y$/'), '', $paramName);
             break;
         }
     }
     // Form handler
     if (isset($this->requestParams['executeForm']) && is_string($this->requestParams['executeForm'])) {
         if (isset($funcName)) {
             Form::set_current_action($funcName);
         }
         // Get the appropraite ocntroller: sometimes we want to get a form from another controller
         if (isset($this->requestParams['formController'])) {
             $formController = Director::getControllerForURL($this->requestParams['formController']);
             while (is_a($formController, 'NestedController')) {
                 $formController = $formController->getNestedController();
             }
         } else {
             $formController = $this;
         }
         // Create the form object
         $form = $formController;
         $formObjParts = explode('.', $this->requestParams['executeForm']);
         foreach ($formObjParts as $formMethod) {
             if (isset($_GET['debug_profile'])) {
                 Profiler::mark("Calling {$formMethod}", "on {$form->class}");
             }
             $form = $form->{$formMethod}();
             if (isset($_GET['debug_profile'])) {
                 Profiler::unmark("Calling {$formMethod}", "on {$form->class}");
             }
             if (!$form) {
                 break;
             }
             //user_error("Form method '" . $this->requestParams['executeForm'] . "' returns null in controller class '$this->class' ($_SERVER[REQUEST_URI])", E_USER_ERROR);
         }
         // Populate the form
         if (isset($_GET['debug_profile'])) {
             Profiler::mark("Controller", "populate form");
         }
         if ($form) {
             $form->loadDataFrom($this->requestParams, true);
             // disregard validation if a single field is called
             if (!isset($_REQUEST['action_callfieldmethod'])) {
                 $valid = $form->beforeProcessing();
                 if (!$valid) {
                     $this->popCurrent();
                     return $this->response;
                 }
             } else {
                 $fieldcaller = $form->dataFieldByName($requestParams['fieldName']);
                 if (is_a($fieldcaller, "TableListField")) {
                     if ($fieldcaller->hasMethod('php')) {
                         $valid = $fieldcaller->php($requestParams);
                         if (!$valid) {
                             exit;
                         }
                     }
                 }
             }
             // If the action wasnt' set, choose the default on the form.
             if (!isset($funcName) && ($defaultAction = $form->defaultAction())) {
                 $funcName = $defaultAction->actionName();
             }
             if (isset($funcName)) {
                 $form->setButtonClicked($funcName);
             }
         } else {
             user_error("No form (" . Session::get('CMSMain.currentPage') . ") returned by {$formController->class}->{$_REQUEST['executeForm']}", E_USER_WARNING);
         }
         if (isset($_GET['debug_profile'])) {
             Profiler::unmark("Controller", "populate form");
         }
         if (!isset($funcName)) {
             user_error("No action button has been clicked in this form executon, and no default has been allowed", E_USER_ERROR);
         }
         // Protection against CSRF attacks
         if ($form->securityTokenEnabled()) {
             $securityID = Session::get('SecurityID');
             if (!$securityID || !isset($this->requestParams['SecurityID']) || $securityID != $this->requestParams['SecurityID']) {
                 // Don't show error on live sites, as spammers create a million of these
                 if (!Director::isLive()) {
                     trigger_error("Security ID doesn't match, possible CRSF attack.", E_USER_ERROR);
                 } else {
                     die;
                 }
             }
         }
         // First, try a handler method on the controller
         if ($this->hasMethod($funcName) || !$form) {
             if (isset($_GET['debug_controller'])) {
                 Debug::show("Found function {$funcName} on the controller");
             }
             if (isset($_GET['debug_profile'])) {
                 Profiler::mark("{$this->class}::{$funcName} (controller action)");
             }
             $result = $this->{$funcName}($this->requestParams, $form);
             if (isset($_GET['debug_profile'])) {
                 Profiler::unmark("{$this->class}::{$funcName} (controller action)");
             }
             // Otherwise, try a handler method on the form object
         } else {
             if (isset($_GET['debug_controller'])) {
                 Debug::show("Found function {$funcName} on the form object");
             }
             if (isset($_GET['debug_profile'])) {
                 Profiler::mark("{$form->class}::{$funcName} (form action)");
             }
             $result = $form->{$funcName}($this->requestParams, $form);
             if (isset($_GET['debug_profile'])) {
                 Profiler::unmark("{$form->class}::{$funcName} (form action)");
             }
         }
         // Normal action
     } else {
         if (!isset($funcName)) {
             $funcName = $this->action;
         }
         if ($this->hasMethod($funcName)) {
             if (isset($_GET['debug_controller'])) {
                 Debug::show("Found function {$funcName} on the {$this->class} controller");
             }
             if (isset($_GET['debug_profile'])) {
                 Profiler::mark("{$this->class}::{$funcName} (controller action)");
             }
             $result = $this->{$funcName}($this->urlParams);
             if (isset($_GET['debug_profile'])) {
                 Profiler::unmark("{$this->class}::{$funcName} (controller action)");
             }
         } else {
             if (isset($_GET['debug_controller'])) {
                 Debug::show("Running default action for {$funcName} on the {$this->class} controller");
             }
             if (isset($_GET['debug_profile'])) {
                 Profiler::mark("Controller::defaultAction({$funcName})");
             }
             $result = $this->defaultAction($funcName, $this->urlParams);
             if (isset($_GET['debug_profile'])) {
                 Profiler::unmark("Controller::defaultAction({$funcName})");
             }
         }
     }
     // If your controller function returns an array, then add that data to the
     // default template
     if (is_array($result)) {
         $extended = $this->customise($result);
         $viewer = $this->getViewer($funcName);
         $result = $viewer->process($extended);
     }
     $this->response->setBody($result);
     if ($result) {
         ContentNegotiator::process($this->response);
     }
     // Set up HTTP cache headers
     HTTP::add_cache_headers($this->response);
     if (isset($_GET['debug_profile'])) {
         Profiler::unmark("Controller", "run");
     }
     $this->popCurrent();
     return $this->response;
 }
예제 #2
0
	/**
	 * Return the object that is going to own a form that's being processed, and handle its execution.
	 * Note that the result needn't be an actual controller object.
	 */
	function getFormOwner() {
		// Get the appropraite ocntroller: sometimes we want to get a form from another controller
		if(isset($this->requestParams['formController'])) {
			$formController = Director::getControllerForURL($this->requestParams['formController']);

			while(is_a($formController, 'NestedController')) {
				$formController = $formController->getNestedController();
			}
			return $formController;

		} else {
			return $this;
		}
	}
예제 #3
0
 /**
  * Test a URL request, returning a response object.
  * 
  * This method is the counterpart of Director::direct() that is used in functional testing.  It will execute the URL given,
  * 
  * @param $url The URL to visit
  * @param $post The $_POST & $_FILES variables
  * @param $session The {@link Session} object representing the current session.  By passing the same object to multiple
  * calls of Director::test(), you can simulate a peristed session.
  * 
  * @uses getControllerForURL() The rule-lookup logic is handled by this.
  * @uses Controller::run() Controller::run() handles the page logic for a Director::direct() call.
  */
 function test($url, $post = null, $session = null)
 {
     $getVars = array();
     if (strpos($url, '?') !== false) {
         list($url, $getVarsEncoded) = explode('?', $url, 2);
         parse_str($getVarsEncoded, $getVars);
     }
     $controllerObj = Director::getControllerForURL($url);
     // Load the session into the controller
     $controllerObj->setSession($session ? $session : new Session(null));
     if (is_string($controllerObj) && substr($controllerObj, 0, 9) == 'redirect:') {
         user_error("Redirection not implemented in Director::test", E_USER_ERROR);
     } else {
         if ($controllerObj) {
             $response = $controllerObj->run(array_merge($getVars, (array) $post));
             return $response;
         }
     }
 }