/**
  * Handle 404 errors gracefully as the normal 404 error pages are part
  * of the CMS module
  */
 public function handleAction($request, $action)
 {
     try {
         $response = parent::handleAction($request, $action);
         return $response;
     } catch (SS_HTTPResponse_Exception $e) {
         $response = $e->getResponse();
         $response->addHeader('Content-Type', 'text/html; charset=utf-8');
         $response->setBody($this->renderWith(array('Error', 'AppController')));
         return $response;
     }
 }
 /**
  * Overloaded to avoid "action doesnt exist" errors - all URL parts in this
  * controller are virtual and handled through handleRequest(), not controller methods.
  */
 public function handleAction($request)
 {
     try {
         $response = parent::handleAction($request);
     } catch (SS_HTTPResponse_Exception $e) {
         if (strpos($e->getMessage(), 'does not exist') !== FALSE) {
             return $this;
         } else {
             throw $e;
         }
     }
     return $response;
 }
 /**
  * Handle the Form Action
  * - FrontEndWorkflowForm contains the logic for this
  * 
  * @param SS_HTTPRequest $request
  * @todo - is this even required???
  */
 public function handleAction($request, $action)
 {
     return parent::handleAction($request, $action);
 }
 /**
  * 
  * @param SS_HTTPRequest $request
  * @param string $action
  * @return HTMLText
  */
 public function handleAction($request, $action)
 {
     parent::handleAction($request, $action);
     return $this->inspect();
 }
 protected function handleAction($request, $action)
 {
     $method = $request->httpMethod();
     // POST|GET|PUT…
     $allParams = $request->allParams();
     // from router
     $extension = $request->getExtension();
     // .html
     $requestVars = $request->requestVars();
     // POST + GET
     $getVars = $request->getVars();
     $postVars = $request->postVars();
     $body = $request->getBody();
     $headers = $request->getHeaders();
     $data = null;
     $contentType = isset($headers['Content-Type']) ? $headers['Content-Type'] : null;
     // parse json
     if (preg_match('/json$/', $contentType)) {
         $data = json_decode($body, true);
         if (!$data) {
             $msg = null;
             switch (json_last_error()) {
                 case JSON_ERROR_DEPTH:
                     $msg = 'reached max. stack depth';
                     break;
                 case JSON_ERROR_CTRL_CHAR:
                     $msg = 'unexpected control character';
                     break;
                 case JSON_ERROR_SYNTAX:
                     $msg = 'syntax error in JSON';
                     // break;
                     // case JSON_ERROR_NONE:
                     //  $msg = null;
                     break;
             }
             if ($msg) {
                 return $this->sendError(400, "JSON Parser Error ({$msg})");
             }
         }
     }
     $underscoreFields = $this->config()->get('underscoreFields');
     $errorType = null;
     $errorMessage = "";
     $parameters = array();
     $apiParameters = $this->stat('api_parameters');
     $alternateAction = $action . $method;
     // actionMETHOD, e.g. indexPOST()
     if ($this->hasAction($alternateAction)) {
         $actualAction = $alternateAction;
         // prefer this naming
     } else {
         $actualAction = $action;
     }
     if (!$this->hasAction($actualAction)) {
         return $this->sendError("Action `{$actualAction}` isn't available on API class `{$this->class}`", 404);
     }
     if (!$this->checkAccessAction($action) || in_array(strtolower($action), array('run', 'init'))) {
         return $this->sendError("No permission to access `{$action}` ({$actualAction}) on `{$this->class}`", 403);
     }
     $params = array();
     // check expected parameters against existing
     if (is_array($apiParameters)) {
         foreach ($apiParameters as $methodAndAction => $parameters) {
             if (preg_match("/^" . $method . ":" . $action . "\$/", $methodAndAction)) {
                 foreach ($parameters as $field => $type) {
                     $value = null;
                     // strip ?…! from field
                     $isRequired = $field[strlen($field) - 1] === '!' ? true : false;
                     $isQueryParameter = $field[0] === '?' ? true : false;
                     $isURLParameter = $field[0] === '$' ? true : false;
                     $field = preg_replace('/^(\\?|\\$)*(.*?)(\\!)*$/', "\$2", $field);
                     $camelCaseFieldName = null;
                     if ($isQueryParameter) {
                         if (isset($requestVars[$field])) {
                             $value = $requestVars[$field];
                         } else {
                             if ($field !== $camelCaseFieldName && isset($requestVars[$camelCaseFieldName])) {
                                 $value = $requestVars[$camelCaseFieldName];
                             }
                         }
                     } else {
                         if ($isURLParameter) {
                             // routing uses camelcase as default, this is why we do a check here again
                             if (isset($allParams[$field])) {
                                 $value = $allParams[$field];
                             } else {
                                 if ($field !== $camelCaseFieldName && isset($allParams[$camelCaseFieldName])) {
                                     $value = $allParams[$camelCaseFieldName];
                                 }
                             }
                         } else {
                             if (isset($data[$field])) {
                                 $value = $data[$field];
                             } else {
                                 if ($field !== $camelCaseFieldName && isset($data[$camelCaseFieldName])) {
                                     $value = $data[$camelCaseFieldName];
                                 }
                             }
                         }
                     }
                     $parameterType = "JSON property";
                     if ($isQueryParameter) {
                         $parameterType = "POST|GET parameter";
                     } else {
                         if ($isURLParameter) {
                             $parameterType = "URL parameter";
                         }
                     }
                     if ($isRequired && $value == null) {
                         $errorMessage .= "The {$parameterType} `{$field}` is required";
                         return $this->sendParameterError($errorMessage);
                     }
                     $valueType = strtolower($type);
                     if ($value === null) {
                         // null is always an accepted value if field is not required
                         // so if we have null, we skip the type check
                     } else {
                         if ($type[0] === '/' && $type[strlen($type) - 1] === '/') {
                             // regular pregmatch
                             if (!preg_match($type, $value)) {
                                 return $this->sendParameterError("The {$parameterType} `{$field}` has to match the following pattern: `{$type}`");
                             }
                         } else {
                             if ($valueType === 'int' || $valueType === 'integer') {
                                 // integer
                                 if (!preg_match("/^[\\+\\-]*\\d+\$/", $value)) {
                                     return $this->sendParameterError("The {$parameterType} `{$field}` has to be an integer");
                                 } else {
                                     $value = (int) $value;
                                 }
                             } else {
                                 if ($valueType === 'float' || $valueType === 'number') {
                                     // float
                                     if (!preg_match("/^[\\+\\-]*(\\d+(\\.\\d*)*|(\\d*\\.\\d+))+\$/", $value)) {
                                         return $this->sendParameterError("The {$parameterType} `{$field}` has to be a float");
                                     } else {
                                         $value = (double) $value;
                                     }
                                 } else {
                                     if ($valueType === 'boolean') {
                                         if (!is_bool($value) && !preg_match("/^(true|false|1|0)+\$/", $value)) {
                                             return $this->sendParameterError("The {$parameterType} `{$field}` has to be a boolean");
                                         } else {
                                             $value = (bool) $value;
                                         }
                                     }
                                 }
                             }
                         }
                     }
                     $params[$field] = $value;
                 }
             }
         }
     }
     $this->parameters = $params;
     return parent::handleAction($request, $actualAction);
 }
 /**
  * Overloaded to avoid "action doesn't exist" errors - all URL parts in
  * this controller are virtual and handled through handleRequest(), not
  * controller methods.
  *
  * @param $request
  * @param $action
  *
  * @return SS_HTTPResponse
  */
 public function handleAction($request, $action)
 {
     // if we submitted a form, let that pass
     if (!$request->isGET()) {
         return parent::handleAction($request, $action);
     }
     $url = $request->getURL();
     //
     // If the current request has an extension attached to it, strip that
     // off and redirect the user to the page without an extension.
     //
     if (DocumentationHelper::get_extension($url)) {
         $this->response = new SS_HTTPResponse();
         $this->response->redirect(DocumentationHelper::trim_extension_off($url) . '/', 301);
         $request->shift();
         $request->shift();
         return $this->response;
     }
     //
     // Strip off the base url
     //
     $base = ltrim(Config::inst()->get('DocumentationViewer', 'link_base'), '/');
     if ($base && strpos($url, $base) !== false) {
         $url = substr(ltrim($url, '/'), strlen($base));
     } else {
     }
     //
     // Handle any permanent redirections that the developer has defined.
     //
     if ($link = DocumentationPermalinks::map($url)) {
         // the first param is a shortcode for a page so redirect the user to
         // the short code.
         $this->response = new SS_HTTPResponse();
         $this->response->redirect($link, 301);
         $request->shift();
         $request->shift();
         return $this->response;
     }
     //
     // Validate the language provided. Language is a required URL parameter.
     // as we use it for generic interfaces and language selection. If
     // language is not set, redirects to 'en'
     //
     $languages = i18n::get_common_languages();
     if (!($lang = $request->param('Lang'))) {
         $lang = $request->param('Action');
         $action = $request->param('ID');
     } else {
         $action = $request->param('Action');
     }
     if (!$lang) {
         return $this->redirect($this->Link('en'));
     } else {
         if (!isset($languages[$lang])) {
             return $this->httpError(404);
         }
     }
     $request->shift(10);
     $allowed = $this->config()->allowed_actions;
     if (in_array($action, $allowed)) {
         //
         // if it's one of the allowed actions such as search or all then the
         // URL must be prefixed with one of the allowed languages.
         //
         return parent::handleAction($request, $action);
     } else {
         //
         // look up the manifest to see find the nearest match against the
         // list of the URL. If the URL exists then set that as the current
         // page to match against.
         // strip off any extensions.
         // if($cleaned !== $url) {
         // 	$redirect = new SS_HTTPResponse();
         // 	return $redirect->redirect($cleaned, 302);
         // }
         if ($record = $this->getManifest()->getPage($url)) {
             $this->record = $record;
             $this->init();
             $type = get_class($this->record);
             $body = $this->renderWith(array("DocumentationViewer_{$type}", "DocumentationViewer"));
             return new SS_HTTPResponse($body, 200);
         } else {
             if ($redirect = $this->getManifest()->getRedirect($url)) {
                 $response = new SS_HTTPResponse();
                 $to = Controller::join_links(Director::baseURL(), $base, $redirect);
                 return $response->redirect($to, 301);
             } else {
                 if (!$url || $url == $lang) {
                     $body = $this->renderWith(array("DocumentationViewer_DocumentationFolder", "DocumentationViewer"));
                     return new SS_HTTPResponse($body, 200);
                 }
             }
         }
     }
     return $this->httpError(404);
 }