/** * Parse the correct messages into the template */ protected function parse() { parent::parse(); // grab the error-type from the parameters $errorType = $this->getParameter('type'); // set correct headers switch ($errorType) { case 'module-not-allowed': case 'action-not-allowed': SpoonHTTP::setHeadersByCode(403); break; case 'not-found': SpoonHTTP::setHeadersByCode(404); break; } // querystring provided? if ($this->getParameter('querystring') !== null) { // split into file and parameters $chunks = explode('?', $this->getParameter('querystring')); // get extension $extension = SpoonFile::getExtension($chunks[0]); // if the file has an extension it is a non-existing-file if ($extension != '' && $extension != $chunks[0]) { // set correct headers SpoonHTTP::setHeadersByCode(404); // give a nice error, so we can detect which file is missing echo 'Requested file (' . htmlspecialchars($this->getParameter('querystring')) . ') not found.'; // stop script execution exit; } } // assign the correct message into the template $this->tpl->assign('message', BL::err(SpoonFilter::toCamelCase(htmlspecialchars($errorType), '-'))); }
/** * You have to specify the action and module so we know what to do with this instance * * @param string $action The action to load. * @param string $module The module to load. */ public function __construct($action, $module) { $this->setModule($module); $this->setAction($action); $this->loadConfig(); $allowed = false; // is this an allowed action if (BackendAuthentication::isAllowedAction($action, $this->getModule())) { $allowed = true; } // is this an allowed AJAX-action? if (!$allowed) { // set correct headers SpoonHTTP::setHeadersByCode(403); // output $fakeAction = new BackendBaseAJAXAction('', ''); $fakeAction->output(BackendBaseAJAXAction::FORBIDDEN, null, 'Not logged in.'); } }
/** * Set the module * * We can't rely on the parent setModule function, because a cronjob requires no login * * @param string $module The module to load. */ public function setModule($module) { // does this module exist? $modules = SpoonDirectory::getList(BACKEND_MODULES_PATH); $modules[] = 'core'; if (!in_array($module, $modules)) { // set correct headers SpoonHTTP::setHeadersByCode(403); // throw exception throw new BackendException('Module not allowed.'); } // set property $this->module = $module; }
/** * Set the module * * We can't rely on the parent setModule function, because a cronjob requires no login * * @param string $module The module to load. */ public function setModule($module) { // does this module exist? $modules = BackendModel::getModulesOnFilesystem(); if (!in_array($module, $modules)) { // set correct headers \SpoonHTTP::setHeadersByCode(403); // throw exception throw new Exception('Module not allowed.'); } // set property $this->module = $module; }
/** * Output as XML * * @return void * @param int $statusCode The status code. * @param array[optional] $data The data to return. */ private static function outputXML($statusCode, array $data = null) { // redefine $statusCode = (int) $statusCode; // init vars $pathChunks = explode('/', trim(dirname(__FILE__), '/')); $version = $pathChunks[count($pathChunks) - 2]; // init XML $XML = new DOMDocument('1.0', 'utf-8'); // set some properties $XML->preserveWhiteSpace = false; $XML->formatOutput = true; // create root element $root = $XML->createElement('fork'); // add attributes $root->setAttribute('status_code', $statusCode); $root->setAttribute('status', $statusCode == 200 ? 'ok' : 'error'); $root->setAttribute('version', FORK_VERSION); $root->setAttribute('endpoint', SITE_URL . '/api/' . $version); // append $XML->appendChild($root); // build XML array_walk($data, array('API', 'arrayToXML'), $root); // set correct headers SpoonHTTP::setHeadersByCode($statusCode); SpoonHTTP::setHeaders('content-type: text/xml;charset=utf-8'); // output XML echo $XML->saveXML(); // stop script execution exit; }
/** * Output an answer to the browser * * @return void * @param int $statusCode The status code for the response, use the available constants. (self::OK, self::BAD_REQUEST, self::FORBIDDEN, self::ERROR). * @param mixed[optional] $data The data to output. * @param string[optional] $message The text-message to send. */ public function output($statusCode, $data = null, $message = null) { // redefine $statusCode = (int) $statusCode; if ($message !== null) { $message = (string) $message; } // create response array $response = array('code' => $statusCode, 'data' => $data, 'message' => $message); // set correct headers SpoonHTTP::setHeadersByCode($statusCode); SpoonHTTP::setHeaders('content-type: application/json'); // output JSON to the browser echo json_encode($response); // stop script execution exit; }
/** * Set module * * @param string $value The module to use. */ private function setModule($value) { // set property $this->module = (string) $value; // core is a module that contains general stuff, so it has to be allowed if ($this->module !== 'core') { // is this module allowed? if (!BackendAuthentication::isAllowedModule($this->module)) { // set correct headers SpoonHTTP::setHeadersByCode(403); // stop script execution exit; } } // create URL instance, the templatemodifiers need this object $URL = new BackendURL(); // set the module $URL->setModule($this->module); }
/** * Display the page */ public function display() { // parse header $this->header->parse(); // parse breadcrumb $this->breadcrumb->parse(); // parse languages $this->parseLanguages(); // parse footer $this->footer->parse(); // assign the id so we can use it as an option $this->tpl->assign('isPage' . $this->pageId, true); // fetch variables from main template $mainVariables = $this->tpl->getAssignedVariables(); // loop all positions foreach ($this->record['positions'] as $position => &$blocks) { // loop all blocks in this position foreach ($blocks as &$block) { // check for extra's that need to be reparsed if (isset($block['extra'])) { // fetch extra-specific variables $extraVariables = $block['extra']->getTemplate()->getAssignedVariables(); // assign all main variables $block['extra']->getTemplate()->assignArray($mainVariables); // overwrite with all specific variables $block['extra']->getTemplate()->assignArray($extraVariables); // parse extra $block = array('blockIsHTML' => false, 'blockContent' => $block['extra']->getContent()); } } // assign position to template $this->tpl->assign('position' . SpoonFilter::ucfirst($position), $blocks); } // assign empty positions $unusedPositions = array_diff($this->record['template_data']['names'], array_keys($this->record['positions'])); foreach ($unusedPositions as $position) { $this->tpl->assign('position' . SpoonFilter::ucfirst($position), array()); } // only overwrite when status code is 404 if ($this->statusCode == 404) { SpoonHTTP::setHeadersByCode(404); } // output $this->tpl->display($this->templatePath, false, true); }
/** * Display the page */ public function display() { // parse header $this->header->parse(); // parse breadcrumb $this->breadcrumb->parse(); // parse languages $this->parseLanguages(); // parse footer $this->footer->parse(); // assign the id so we can use it as an option $this->tpl->assign('isPage' . $this->pageId, true); // the the positions to the template $this->parsePositions(); // assign empty positions $unusedPositions = array_diff($this->record['template_data']['names'], array_keys($this->record['positions'])); foreach ($unusedPositions as $position) { $this->tpl->assign('position' . SpoonFilter::ucfirst($position), array()); } // only overwrite when status code is 404 if ($this->statusCode == 404) { SpoonHTTP::setHeadersByCode(404); } // output $this->tpl->display($this->templatePath, false, true); }
/** * Do authentication stuff * This method could end the script by throwing an exception * * @return void */ private function validateLogin() { // check if the user is logged on, if not he shouldn't load any JS-file if (!BackendAuthentication::isLoggedIn()) { // set the correct header SpoonHTTP::setHeadersByCode(403); // output $fakeAction = new BackendBaseAJAXAction('', ''); $fakeAction->output(BackendBaseAJAXAction::FORBIDDEN, null, 'Not logged in.'); } // set interface language BackendLanguage::setLocale(BackendAuthentication::getUser()->getSetting('interface_language')); }
/** * Execute the action * We will build the classname, require the class and call the execute method. * * @return void */ public function execute() { // build action-class-name $actionClassName = 'Backend' . SpoonFilter::toCamelCase($this->getModule() . '_cronjob_' . $this->getAction()); if ($this->getModule() == 'core') { // check if the file is present? If it isn't present there is a huge problem, so we will stop our code by throwing an error if (!SpoonFile::exists(BACKEND_CORE_PATH . '/cronjobs/' . $this->getAction() . '.php')) { // set correct headers SpoonHTTP::setHeadersByCode(500); // throw exception throw new BackendException('The cronjobfile for the module (' . $this->getAction() . '.php) can\'t be found.'); } // require the config file, we know it is there because we validated it before (possible actions are defined by existance of the file). require_once BACKEND_CORE_PATH . '/cronjobs/' . $this->getAction() . '.php'; } else { // check if the file is present? If it isn't present there is a huge problem, so we will stop our code by throwing an error if (!SpoonFile::exists(BACKEND_MODULES_PATH . '/' . $this->getModule() . '/cronjobs/' . $this->getAction() . '.php')) { // set correct headers SpoonHTTP::setHeadersByCode(500); // throw exception throw new BackendException('The cronjobfile for the module (' . $this->getAction() . '.php) can\'t be found.'); } // require the config file, we know it is there because we validated it before (possible actions are defined by existance of the file). require_once BACKEND_MODULES_PATH . '/' . $this->getModule() . '/cronjobs/' . $this->getAction() . '.php'; } // validate if class exists (aka has correct name) if (!class_exists($actionClassName)) { // set correct headers SpoonHTTP::setHeadersByCode(500); // throw exception throw new BackendException('The cronjobfile is present, but the classname should be: ' . $actionClassName . '.'); } // create action-object $object = new $actionClassName($this->getAction(), $this->getModule()); // call the execute method of the real action (defined in the module) $object->execute(); }
/** * Set file * * @param string $value The file to load. */ private function setFile($value) { // set property $this->filename = (string) $value; // validate if (substr_count($this->filename, '../') > 0) { // set correct headers SpoonHTTP::setHeadersByCode(400); // when debug is on throw an exception if (SPOON_DEBUG) { throw new FrontendException('Invalid file.'); } else { exit(SPOON_DEBUG_MESSAGE); } } // init var $valid = true; // core is a special module if ($this->module == 'core') { // build path $path = realpath(FRONTEND_CORE_PATH . '/js/' . $this->filename); // validate if path is allowed if (substr($path, 0, strlen(realpath(FRONTEND_CORE_PATH . '/js/'))) != realpath(FRONTEND_CORE_PATH . '/js/')) { $valid = false; } } else { // build path $path = realpath(FRONTEND_MODULES_PATH . '/' . $this->getModule() . '/js/' . $this->filename); // validate if path is allowed if (substr($path, 0, strlen(realpath(FRONTEND_MODULES_PATH . '/' . $this->getModule() . '/js/'))) != realpath(FRONTEND_MODULES_PATH . '/' . $this->getModule() . '/js/')) { $valid = false; } } // invalid file? if (!$valid) { // set correct headers SpoonHTTP::setHeadersByCode(400); // when debug is on throw an exception if (SPOON_DEBUG) { throw new FrontendException('Invalid file.'); } else { exit(SPOON_DEBUG_MESSAGE); } } // check if the path exists, if not whe should given an error if (!SpoonFile::exists($path)) { // set correct headers SpoonHTTP::setHeadersByCode(404); // when debug is on throw an exception if (SPOON_DEBUG) { throw new FrontendException('File not present.'); } else { exit(SPOON_DEBUG_MESSAGE); } } }
/** * Display the page * * @return void */ public function display() { // parse header $this->header->parse(); // parse breadcrumb $this->breadcrumb->parse(); // parse languages $this->parseLanguages(); // parse footer $this->footer->parse(); // assign the id so we can use it as an option $this->tpl->assign('page' . $this->pageId, true); // fetch variables from main template $mainVariables = $this->tpl->getAssignedVariables(); // loop all extras foreach ((array) $this->extras as $templateVariable => $extra) { // fetch extra-specific variables $extraVariables = $extra->getTemplate()->getAssignedVariables(); // assign all main variables $extra->getTemplate()->assignArray($mainVariables); // overwrite with all specific variables $extra->getTemplate()->assignArray($extraVariables); // parse extra and assign to main template $this->tpl->assign($templateVariable, $extra->getContent()); } // only overwrite when status code is 404 if ($this->statusCode == 404) { SpoonHTTP::setHeadersByCode(404); } // output $this->tpl->display($this->templatePath, false, true); }
/** * Set the module * * @param string $module The module to load. * @throws Exception If module is not allowed */ public function setModule($module) { // is this module allowed? if (!Authentication::isAllowedModule($module)) { // set correct headers \SpoonHTTP::setHeadersByCode(403); // throw exception throw new Exception('Module not allowed.'); } // set property $this->module = $module; }
/** * Output as XML * * @param int $statusCode The status code. * @param array $data The data to return. */ private static function outputXML($statusCode, array $data = null) { // redefine $statusCode = (int) $statusCode; // init vars $charset = BackendModel::getContainer()->getParameter('kernel.charset'); $pathChunks = explode(DIRECTORY_SEPARATOR, trim(dirname(__FILE__), DIRECTORY_SEPARATOR)); $version = $pathChunks[count($pathChunks) - 2]; $version = strtolower($version); // init XML $XML = new \DOMDocument('1.0', $charset); // set some properties $XML->preserveWhiteSpace = false; $XML->formatOutput = true; // create root element $root = $XML->createElement('fork'); // add attributes $root->setAttribute('status_code', $statusCode); $root->setAttribute('status', $statusCode == 200 ? 'ok' : 'error'); $root->setAttribute('version', FORK_VERSION); $root->setAttribute('endpoint', SITE_URL . '/api/' . $version); // append $XML->appendChild($root); // build XML array_walk($data, array(__CLASS__, 'arrayToXML'), $root); // set correct headers \SpoonHTTP::setHeadersByCode($statusCode); \SpoonHTTP::setHeaders('content-type: text/xml;charset=' . $charset); // output XML self::$content = $XML->saveXML(); }