/** * Execute the action * We will build the classname, require the class and call the execute method. */ public function execute() { $this->loadConfig(); // is the requested action possible? If not we throw an exception. We don't redirect because that could trigger a redirect loop if (!in_array($this->getAction(), $this->config->getPossibleActions())) { throw new BackendException('This is an invalid action (' . $this->getAction() . ').'); } // build action-class-name $actionClassName = SpoonFilter::toCamelCase('backend_' . $this->getModule() . '_' . $this->getAction()); // require the config file, we know it is there because we validated it before (possible actions are defined by existance off the file). require_once BACKEND_MODULE_PATH . '/actions/' . $this->getAction() . '.php'; // validate if class exists (aka has correct name) if (!class_exists($actionClassName)) { throw new BackendException('The actionfile is present, but the classname should be: ' . $actionClassName . '.'); } // get working languages $languages = BackendLanguage::getWorkingLanguages(); $workingLanguages = array(); // loop languages and build an array that we can assign foreach ($languages as $abbreviation => $label) { $workingLanguages[] = array('abbr' => $abbreviation, 'label' => $label, 'selected' => $abbreviation == BackendLanguage::getWorkingLanguage()); } // assign the languages $this->tpl->assign('workingLanguages', $workingLanguages); // create action-object $object = new $actionClassName(); $object->execute(); }
/** * Parse the JS-files */ public function parseJS() { $jsFiles = array(); $existingJSFiles = $this->getJSFiles(); // if there aren't any JS-files added we don't need to do something if (!empty($existingJSFiles)) { // some files should be cached, even if we don't want cached (mostly libraries) $ignoreCache = array('/backend/core/js/jquery/jquery.js', '/backend/core/js/jquery/jquery.ui.js', '/backend/core/js/ckeditor/jquery.ui.dialog.patch.js', '/backend/core/js/jquery/jquery.tools.js', '/backend/core/js/jquery/jquery.backend.js', '/backend/core/js/ckeditor/ckeditor.js', '/backend/core/js/ckeditor/adapters/jquery.js', '/backend/core/js/ckfinder/ckfinder.js'); foreach ($existingJSFiles as $file) { // some files shouldn't be uncachable if (in_array($file['file'], $ignoreCache) || $file['add_timestamp'] === false) { $file = array('file' => $file['file']); } else { // if the file is processed by PHP we don't want any caching if (substr($file['file'], 0, 11) == '/frontend/js') { $file = array('file' => $file['file'] . '&m=' . time()); } else { $modifiedTime = strpos($file['file'], '?') !== false ? '&m=' . LAST_MODIFIED_TIME : '?m=' . LAST_MODIFIED_TIME; $file = array('file' => $file['file'] . $modifiedTime); } } // add $jsFiles[] = $file; } } // assign JS-files $this->tpl->assign('jsFiles', $jsFiles); }
/** * Parse the JS, CSS files and meta-info into the head of the HTML-document */ public function parse() { $cssFiles = array(); $jsFiles = array(); // get last modified time for the header template $lastModifiedTime = @filemtime($this->tpl->getCompileDirectory() . '/' . md5(realpath(BACKEND_CORE_PATH . '/layout/templates/header.tpl')) . '_header.tpl.php'); // reset lastmodified time if needed (SPOON_DEBUG is enabled or we don't get a decent timestamp) if ($lastModifiedTime === false || SPOON_DEBUG) { $lastModifiedTime = time(); } // if there aren't any CSS-files added we don't need to do something if (!empty($this->cssFiles)) { // loop the CSS-files and add the modified-time foreach ($this->cssFiles as $file) { // add lastmodified time if ($file['add_timestamp'] !== false) { $file['path'] .= strpos($file['path'], '?') !== false ? '&m=' . $lastModifiedTime : '?m=' . $lastModifiedTime; } // add $cssFiles[] = array('path' => $file['path']); } } // assign CSS-files $this->tpl->assign('cssFiles', $cssFiles); // if there aren't any JS-files added we don't need to do something if (!empty($this->jsFiles)) { // some files should be cached, even if we don't want cached (mostly libraries) $ignoreCache = array('/backend/core/js/jquery/jquery.js', '/backend/core/js/jquery/jquery.ui.js', '/backend/core/js/ckeditor/jquery.ui.dialog.patch.js', '/backend/core/js/jquery/jquery.tools.js', '/backend/core/js/jquery/jquery.backend.js', '/backend/core/js/ckeditor/ckeditor.js', '/backend/core/js/ckeditor/adapters/jquery.js', '/backend/core/js/ckfinder/ckfinder.js'); foreach ($this->jsFiles as $file) { // some files shouldn't be uncachable if (in_array($file['path'], $ignoreCache) || $file['add_timestamp'] === false) { $jsFiles[] = array('path' => $file['path']); } else { // if the file is processed by PHP we don't want any caching if (substr($file['path'], 0, 11) == '/backend/js') { $jsFiles[] = array('path' => $file['path'] . '&m=' . time()); } else { if (strpos($file['path'], '?') !== false) { $path = $file['path'] . '&m=' . $lastModifiedTime; } else { $path = $file['path'] . '?m=' . $lastModifiedTime; } $jsFiles[] = array('path' => $path); } } } } // assign JS-files $this->tpl->assign('jsFiles', $jsFiles); }
/** * Parse to template */ protected function parse() { // build pathName $pathName = BACKEND_MODULES_PATH . '/' . $this->getModule(); // get actions $actions = (array) SpoonFile::getList($pathName . '/actions', '/(.*)\\.php/i'); $ajaxActions = (array) SpoonFile::getList($pathName . '/ajax', '/(.*)\\.php/i'); // loop through actions foreach ($actions as $action) { // get action name $actionName = str_replace('.php', '', $action); // check if allowed to perform this action $this->tpl->assign('show' . SpoonFilter::toCamelCase($actionName, '_'), BackendAuthentication::isAllowedAction($actionName, $this->getModule())); } // loop through ajax foreach ($ajaxActions as $action) { // get action name $actionName = str_replace('.php', '', $action); // check if allowed to perform this action $this->tpl->assign('show' . SpoonFilter::toCamelCase($actionName, '_'), BackendAuthentication::isAllowedAction($actionName, $this->getModule())); } }
/** * Execute the action * * @return void */ public function execute() { // if not in debug-mode we should include the minified versions if (!SPOON_DEBUG && SpoonFile::exists(BACKEND_CORE_PATH . '/js/minified.js')) { // include the minified JS-file $this->header->addJS('minified.js', 'core', false); } else { // add jquery, we will need this in every action, so add it globally $this->header->addJS('jquery/jquery.js', 'core'); $this->header->addJS('jquery/jquery.ui.js', 'core'); $this->header->addJS('jquery/jquery.tools.js', 'core'); $this->header->addJS('jquery/jquery.backend.js', 'core'); } // add items that always need to be loaded $this->header->addJS('utils.js', 'core', true); $this->header->addJS('backend.js', 'core', true); // add default js file (if the file exists) if (SpoonFile::exists(BACKEND_MODULE_PATH . '/js/' . $this->getModule() . '.js')) { $this->header->addJS($this->getModule() . '.js', null, true); } if (SpoonFile::exists(BACKEND_MODULE_PATH . '/js/' . $this->getAction() . '.js')) { $this->header->addJS($this->getAction() . '.js', null, true); } // if not in debug-mode we should include the minified version if (!SPOON_DEBUG && SpoonFile::exists(BACKEND_CORE_PATH . '/layout/css/minified.css')) { // include the minified CSS-file $this->header->addCSS('minified.css', 'core'); } else { // add css $this->header->addCSS('reset.css', 'core'); $this->header->addCSS('jquery_ui/fork/jquery_ui.css', 'core'); $this->header->addCSS('debug.css', 'core'); $this->header->addCSS('screen.css', 'core'); } // add module specific css if (SpoonFile::exists(BACKEND_MODULE_PATH . '/layout/css/' . $this->getModule() . '.css')) { $this->header->addCSS($this->getModule() . '.css', null); } // store var so we don't have to call this function twice $var = $this->getParameter('var', 'array'); // is there a report to show? if ($this->getParameter('report') !== null) { // show the report $this->tpl->assign('report', true); // camelcase the string $messageName = SpoonFilter::toCamelCase($this->getParameter('report'), '-'); // if we have data to use it will be passed as the var parameter if (!empty($var)) { $this->tpl->assign('reportMessage', vsprintf(BL::msg($messageName), $var)); } else { $this->tpl->assign('reportMessage', BL::msg($messageName)); } // highlight an element with the given id if needed if ($this->getParameter('highlight')) { $this->tpl->assign('highlight', $this->getParameter('highlight')); } } // is there an error to show? if ($this->getParameter('error') !== null) { // camelcase the string $errorName = SpoonFilter::toCamelCase($this->getParameter('error'), '-'); // if we have data to use it will be passed as the var parameter if (!empty($var)) { $this->tpl->assign('errorMessage', vsprintf(BL::err($errorName), $var)); } else { $this->tpl->assign('errorMessage', BL::err($errorName)); } } }
/** * Form for periodpicker * * @return void * @param BackendTemplate $tpl The template to parse the period picker in. * @param int $startTimestamp The start timestamp for the google call. * @param int $endTimestamp The end timestamp for the google call. * @param array[optional] $parameters The extra GET parameters to set on redirect. */ public static function parsePeriodPicker(BackendTemplate $tpl, $startTimestamp, $endTimestamp, $parameters = array()) { // redefine $startTimestamp = (int) $startTimestamp; $endTimestamp = (int) $endTimestamp; // assign $tpl->assign('startTimestamp', $startTimestamp); $tpl->assign('endTimestamp', $endTimestamp); // create form $frm = new BackendForm('periodPickerForm'); // create datepickers $frm->addDate('start_date', $startTimestamp, 'range', mktime(0, 0, 0, 1, 1, 2005), time(), 'noFocus'); $frm->addDate('end_date', $endTimestamp, 'range', mktime(0, 0, 0, 1, 1, 2005), time(), 'noFocus'); // submitted if ($frm->isSubmitted()) { // show the form $tpl->assign('showForm', true); // cleanup fields $frm->cleanupFields(); // shorten fields $txtStartDate = $frm->getField('start_date'); $txtEndDate = $frm->getField('end_date'); // required fields $txtStartDate->isFilled(BL::err('StartDateIsInvalid')); $txtEndDate->isFilled(BL::err('EndDateIsInvalid')); // dates within valid range if ($txtStartDate->isFilled() && $txtEndDate->isFilled()) { // valid dates if ($txtStartDate->isValid(BL::err('StartDateIsInvalid')) && $txtEndDate->isValid(BL::err('EndDateIsInvalid'))) { // get timestamps $newStartDate = BackendModel::getUTCTimestamp($txtStartDate); $newEndDate = BackendModel::getUTCTimestamp($txtEndDate); // init valid $valid = true; // startdate cannot be before 2005 (earliest valid google startdate) if ($newStartDate < mktime(0, 0, 0, 1, 1, 2005)) { $valid = false; } elseif ($newEndDate > time()) { $valid = false; } elseif ($newStartDate > $newEndDate) { $valid = false; } // invalid range if (!$valid) { $txtStartDate->setError(BL::err('DateRangeIsInvalid')); } } } // valid if ($frm->isCorrect()) { // parameters $parameters['start_timestamp'] = $newStartDate; $parameters['end_timestamp'] = $newEndDate; // build redirect string $redirect = html_entity_decode(BackendModel::createURLForAction(null, null, null, $parameters)); // redirect SpoonHTTP::redirect($redirect); } } // parse $frm->parse($tpl); // we only allow live data fetching when the end date is today, no point in fetching and older range because it will never change if ($endTimestamp == mktime(0, 0, 0, date('n'), date('j'), date('Y'))) { // url of current action $liveDataUrl = BackendModel::createURLForAction('loading') . '&redirect_action=' . Spoon::get('url')->getAction(); // page id set if (isset($_GET['page_id']) && $_GET['page_id'] != '') { $liveDataUrl .= '&page_id=' . (int) $_GET['page_id']; } // page path set if (isset($_GET['page_path']) && $_GET['page_path'] != '') { $liveDataUrl .= '&page_path=' . (string) $_GET['page_path']; } // assign $tpl->assign('liveDataURL', $liveDataUrl); } }
/** * Returns the content from a given template * * @param string $template The template to use. * @param array[optional] $variables The variabled to assign. * @return string */ private static function getTemplateContent($template, $variables = null) { // new template instance $tpl = new BackendTemplate(false); // set some options $tpl->setForceCompile(true); // variables were set if (!empty($variables)) { $tpl->assign($variables); } // grab the content $content = $tpl->getContent($template); // replace internal links/images $search = array('href="/', 'src="/'); $replace = array('href="' . SITE_URL . '/', 'src="' . SITE_URL . '/'); $content = str_replace($search, $replace, $content); // require CSSToInlineStyles require_once 'external/css_to_inline_styles.php'; // create instance $cssToInlineStyles = new CSSToInlineStyles(); // set some properties $cssToInlineStyles->setHTML($content); $cssToInlineStyles->setUseInlineStylesBlock(true); $cssToInlineStyles->setEncoding(SPOON_CHARSET); // return the content return (string) $cssToInlineStyles->convert(); }
/** * Execute the action */ public function execute() { // add jquery, we will need this in every action, so add it globally $this->header->addJS('jquery/jquery.js', 'core', false); $this->header->addJS('jquery/jquery.ui.js', 'core', false); $this->header->addJS('jquery/jquery.ui.dialog.patch.js', 'core'); $this->header->addJS('jquery/jquery.tools.js', 'core', false); $this->header->addJS('jquery/jquery.backend.js', 'core'); // add items that always need to be loaded $this->header->addJS('utils.js', 'core'); $this->header->addJS('backend.js', 'core', false, true); // add module js if (SpoonFile::exists(BACKEND_MODULE_PATH . '/js/' . $this->getModule() . '.js')) { $this->header->addJS($this->getModule() . '.js', null, false, true); } // add action js if (SpoonFile::exists(BACKEND_MODULE_PATH . '/js/' . $this->getAction() . '.js')) { $this->header->addJS($this->getAction() . '.js', null, false, true); } // add core css files $this->header->addCSS('reset.css', 'core'); $this->header->addCSS('jquery_ui/fork/jquery_ui.css', 'core', false, false); $this->header->addCSS('screen.css', 'core'); $this->header->addCSS('debug.css', 'core'); // add module specific css if (SpoonFile::exists(BACKEND_MODULE_PATH . '/layout/css/' . $this->getModule() . '.css')) { $this->header->addCSS($this->getModule() . '.css'); } // store var so we don't have to call this function twice $var = array_map('strip_tags', $this->getParameter('var', 'array', array())); // is there a report to show? if ($this->getParameter('report') !== null) { // show the report $this->tpl->assign('report', true); // camelcase the string $messageName = strip_tags(SpoonFilter::toCamelCase($this->getParameter('report'), '-')); // if we have data to use it will be passed as the var parameter if (!empty($var)) { $this->tpl->assign('reportMessage', vsprintf(BL::msg($messageName), $var)); } else { $this->tpl->assign('reportMessage', BL::msg($messageName)); } // highlight an element with the given id if needed if ($this->getParameter('highlight')) { $this->tpl->assign('highlight', strip_tags($this->getParameter('highlight'))); } } // is there an error to show? if ($this->getParameter('error') !== null) { // camelcase the string $errorName = strip_tags(SpoonFilter::toCamelCase($this->getParameter('error'), '-')); // if we have data to use it will be passed as the var parameter if (!empty($var)) { $this->tpl->assign('errorMessage', vsprintf(BL::err($errorName), $var)); } else { $this->tpl->assign('errorMessage', BL::err($errorName)); } } }