/** * 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); }