/** * Build navigation cache file. * * @return void */ public function buildCache() { // init $navigationTree = ''; // build tree starting with the root $this->buildNavigation(0, $navigationTree); // start generating PHP $value = '<?php' . "\n"; $value .= '/**' . "\n"; $value .= ' *' . "\n"; $value .= ' * This file is generated by the Backend, it contains' . "\n"; $value .= ' * more information about the navigation in the backend. Do NOT edit.' . "\n"; $value .= ' * ' . "\n"; $value .= ' * @author Backend' . "\n"; $value .= ' * @generated ' . date('Y-m-d H:i:s') . "\n"; $value .= ' */' . "\n"; $value .= "\n"; $value .= "\$navigation = array(\n"; // add navigation tree $value .= $navigationTree; // close php $value .= ");\n"; $value .= "\n"; $value .= '?>'; // store SpoonFile::setContent(BACKEND_CACHE_PATH . '/navigation/navigation.php', $value); }
/** * Load the config file for the requested module. * In the config file we have to find disabled actions, the constructor will read the folder * and set possible actions. Other configurations will also be stored in it. */ public function loadConfig() { // check if module path is not yet defined if (!defined('BACKEND_MODULE_PATH')) { // build path for core if ($this->getModule() == 'core') { define('BACKEND_MODULE_PATH', BACKEND_PATH . '/' . $this->getModule()); } else { define('BACKEND_MODULE_PATH', BACKEND_MODULES_PATH . '/' . $this->getModule()); } } // check if the config 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_MODULE_PATH . '/config.php')) { throw new BackendException('The configfile for the module (' . $this->getModule() . ') can\'t be found.'); } // build config-object-name $configClassName = 'Backend' . SpoonFilter::toCamelCase($this->getModule() . '_config'); // require the config file, we validated before for existence. require_once BACKEND_MODULE_PATH . '/config.php'; // validate if class exists (aka has correct name) if (!class_exists($configClassName)) { throw new BackendException('The config file is present, but the classname should be: ' . $configClassName . '.'); } // create config-object, the constructor will do some magic $this->config = new $configClassName($this->getModule()); }
/** * Get warnings for active modules * * @return array */ public static function getWarnings() { // init vars $warnings = array(); $activeModules = BackendModel::getModules(true); // add warnings $warnings = array_merge($warnings, BackendModel::checkSettings()); // loop active modules foreach ($activeModules as $module) { // model class $class = 'Backend' . SpoonFilter::toCamelCase($module) . 'Model'; // model file exists if (SpoonFile::exists(BACKEND_MODULES_PATH . '/' . $module . '/engine/model.php')) { // require class require_once BACKEND_MODULES_PATH . '/' . $module . '/engine/model.php'; } // method exists if (is_callable(array($class, 'checkSettings'))) { // add possible warnings $warnings = array_merge($warnings, call_user_func(array($class, 'checkSettings'))); } } // return return (array) $warnings; }
/** * Load the data. * This will also set some warnings if needed. */ private function loadData() { // inform that the module is not installed yet if (!BackendExtensionsModel::isModuleInstalled($this->currentModule)) { $this->warnings[] = array('message' => BL::getMessage('InformationModuleIsNotInstalled')); } // path to information file $pathInfoXml = BACKEND_MODULES_PATH . '/' . $this->currentModule . '/info.xml'; // information needs to exists if (SpoonFile::exists($pathInfoXml)) { try { // load info.xml $infoXml = @new SimpleXMLElement($pathInfoXml, LIBXML_NOCDATA, true); // convert xml to useful array $this->information = BackendExtensionsModel::processModuleXml($infoXml); // empty data (nothing useful) if (empty($this->information)) { $this->warnings[] = array('message' => BL::getMessage('InformationFileIsEmpty')); } // check if cronjobs are installed already if (isset($this->information['cronjobs'])) { foreach ($this->information['cronjobs'] as $cronjob) { if (!$cronjob['active']) { $this->warnings[] = array('message' => BL::getError('CronjobsNotSet')); } break; } } } catch (Exception $e) { $this->warnings[] = array('message' => BL::getMessage('InformationFileCouldNotBeLoaded')); } } else { $this->warnings[] = array('message' => BL::getMessage('InformationFileIsMissing')); } }
/** * Returns the CampaignMonitor object * * @param int[optional] $listId The default list id to use. * @return CampaignMonitor */ public static function getCM($listId = null) { // campaignmonitor reference exists if (!Spoon::exists('campaignmonitor')) { // check if the CampaignMonitor class exists if (!SpoonFile::exists(PATH_LIBRARY . '/external/campaignmonitor.php')) { // the class doesn't exist, so throw an exception throw new SpoonFileException('The CampaignMonitor wrapper class is not found. Please locate and place it in /library/external'); } // require CampaignMonitor class require_once 'external/campaignmonitor.php'; // set login data $url = FrontendModel::getModuleSetting('mailmotor', 'cm_url'); $username = FrontendModel::getModuleSetting('mailmotor', 'cm_username'); $password = FrontendModel::getModuleSetting('mailmotor', 'cm_password'); // init CampaignMonitor object $cm = new CampaignMonitor($url, $username, $password, 5, self::getClientId()); // set CampaignMonitor object reference Spoon::set('campaignmonitor', $cm); // get the default list ID $listId = !empty($listId) ? $listId : self::getDefaultListID(); // set the default list ID $cm->setListId($listId); } // return the CampaignMonitor object return Spoon::get('campaignmonitor'); }
/** * Get the file path based on the theme. * If it does not exist in the theme it will return $file. * * @return string Path to the (theme) file. * @param string $file Path to the file. */ public static function getPath($file) { // redefine $file = (string) $file; // theme name $theme = self::getTheme(); // theme in use if (FrontendModel::getModuleSetting('core', 'theme', 'core') != 'core') { // theme not yet specified if (strpos($file, 'frontend/themes/' . $theme) === false) { // add theme location $themeTemplate = str_replace(array('frontend/'), array('frontend/themes/' . $theme . '/'), $file); // check if this template exists if (SpoonFile::exists(PATH_WWW . str_replace(PATH_WWW, '', $themeTemplate))) { $file = $themeTemplate; } } } // check if the file exists if (!SpoonFile::exists(PATH_WWW . str_replace(PATH_WWW, '', $file))) { throw new FrontendException('The template (' . $file . ') doesn\'t exists.'); } // return template path return $file; }
/** * Load the data. * This will also set some warnings if needed. */ private function loadData() { // inform that the theme is not installed yet if (!BackendExtensionsModel::isThemeInstalled($this->currentTheme)) { $this->warnings[] = array('message' => BL::getMessage('InformationThemeIsNotInstalled')); } // path to information file $pathInfoXml = FRONTEND_PATH . '/themes/' . $this->currentTheme . '/info.xml'; // information needs to exists if (SpoonFile::exists($pathInfoXml)) { try { // load info.xml $infoXml = @new SimpleXMLElement($pathInfoXml, LIBXML_NOCDATA, true); // convert xml to useful array $this->information = BackendExtensionsModel::processThemeXml($infoXml); // empty data (nothing useful) if (empty($this->information)) { $this->warnings[] = array('message' => BL::getMessage('InformationFileIsEmpty')); } } catch (Exception $e) { $this->warnings[] = array('message' => BL::getMessage('InformationFileCouldNotBeLoaded')); } } else { $this->warnings[] = array('message' => BL::getMessage('InformationFileIsMissing')); } }
/** * 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), '-'))); }
/** * Validate if the module can be installed. */ private function validateInstall() { // already installed if (BackendExtensionsModel::isModuleInstalled($this->currentModule)) { $this->redirect(BackendModel::createURLForAction('modules') . '&error=already-installed&var=' . $this->currentModule); } // no installer class present if (!SpoonFile::exists(BACKEND_MODULES_PATH . '/' . $this->currentModule . '/installer/installer.php')) { $this->redirect(BackendModel::createURLForAction('modules') . '&error=no-installer-file&var=' . $this->currentModule); } }
/** * Validate if the theme can be installed. */ private function validateInstall() { // already installed if (BackendExtensionsModel::isThemeInstalled($this->currentTheme)) { $this->redirect(BackendModel::createURLForAction('themes') . '&error=already-installed&var=' . $this->currentTheme); } // no information file present if (!SpoonFile::exists(FRONTEND_PATH . '/themes/' . $this->currentTheme . '/info.xml')) { $this->redirect(BackendModel::createURLForAction('themes') . '&error=no-information-file&var=' . $this->currentTheme); } }
/** * Execute the action */ public function execute() { parent::execute(); // get parameters $url = SpoonFilter::getPostValue('url', null, ''); $username = SpoonFilter::getPostValue('username', null, ''); $password = SpoonFilter::getPostValue('password', null, ''); // filter out the 'http://' from the URL if (strpos($url, 'http://') !== false) { $url = str_replace('http://', '', $url); } if (strpos($url, 'https://') !== false) { $url = str_replace('https://', '', $url); } // check input if (empty($url)) { $this->output(self::BAD_REQUEST, array('field' => 'url'), BL::err('NoCMAccountCredentials')); } if (empty($username)) { $this->output(self::BAD_REQUEST, array('field' => 'username'), BL::err('NoCMAccountCredentials')); } if (empty($password)) { $this->output(self::BAD_REQUEST, array('field' => 'password'), BL::err('NoCMAccountCredentials')); } try { // check if the CampaignMonitor class exists if (!SpoonFile::exists(PATH_LIBRARY . '/external/campaignmonitor.php')) { // the class doesn't exist, so stop here $this->output(self::BAD_REQUEST, null, BL::err('ClassDoesNotExist', $this->getModule())); } // require CampaignMonitor class require_once 'external/campaignmonitor.php'; // init CampaignMonitor object new CampaignMonitor($url, $username, $password, 10); // save the new data BackendModel::setModuleSetting($this->getModule(), 'cm_url', $url); BackendModel::setModuleSetting($this->getModule(), 'cm_username', $username); BackendModel::setModuleSetting($this->getModule(), 'cm_password', $password); // account was linked BackendModel::setModuleSetting($this->getModule(), 'cm_account', true); } catch (Exception $e) { // timeout occured if ($e->getMessage() == 'Error Fetching http headers') { $this->output(self::BAD_REQUEST, null, BL::err('CmTimeout', $this->getModule())); } // other error $this->output(self::ERROR, array('field' => 'url'), sprintf(BL::err('CampaignMonitorError', $this->getModule()), $e->getMessage())); } // trigger event BackendModel::triggerEvent($this->getModule(), 'after_account_linked'); // CM was successfully initialized $this->output(self::OK, array('message' => 'account-linked'), BL::msg('AccountLinked', $this->getModule())); }
/** * Add a GOD-user */ private function addUser() { // no god user already exists // @todo refactor this nasty if statement... if (!(bool) $this->getDB()->getVar('SELECT 1 FROM users WHERE is_god = ? AND deleted = ? AND active = ? LIMIT 1', array('Y', 'N', 'Y'))) { // secret files $avatar124x124 = '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'; $avatar64x64 = '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'; $avatar32x32 = '/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBAQFBAYFBQYJBgUGCQsIBgYICwwKCgsKCgwQDAwMDAwMEAwODxAPDgwTExQUExMcGxsbHCAgICAgICAgICD/2wBDAQcHBw0MDRgQEBgaFREVGiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICD/wAARCAAgACADAREAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABwYIBf/EACsQAAICAQIFBAEEAwAAAAAAAAECAwQFBhEABxIhMRMiI0EUMkJRYjNxsf/EABkBAAMBAQEAAAAAAAAAAAAAAAMEBQIGAP/EACcRAAEDBAIBAgcAAAAAAAAAAAEAAgMEERIhMUEFIlETMkNhYqGx/9oADAMBAAIRAxEAPwBd1Bm1xmDzV+Svt+BUllsM/T6khrwGWIORsQC3j7HHNwRZWB1/U05yxbe5081Ll6S42pr8Mkm/x15mhiUH9qxpsoA4viBgFraS2S1Fye5jZXWOlMdmZ7rS5DDQvTyVLZfnn7BbMkh9wYxDwPvfhCqFiiN91eQx5OxkJQd54W96vI3tA3I6Ytu/b+3HqSLM5FYlJGlj7W/OPm1ee9pjJl8dFKHr28U9dRMVYbFXZ19TwPrbhmOnYPVz91oZHQU7hOXmTyVCC4sRaNmPXGp6JNlOzfqBA8cDkr2tdiqcPiHPYHXtfpNPK/HZ3GtJiNKYWrSW2yPYzF+zLO3WnYdEaxhSR32UrtvxhlQ2XraHW0PwBzdO2D6sLh5IL99rFwyrHJb+wG3YHuz+Bue7H/g4ZpiP2pkiMuYNXEZ2pm1BE+o5HEWIlkhTrgesAy2I32L+mxU9R+h54lxEg/imC/E3HKOMflreJ3qWBFHLY91doyWg3bb1CjDfdQd+FpI966XYRS5NBPe0kcrxaTHZC8bnVEfhrtGpQI0fySfqALbp+76/3wSL0hSfLG9gqGjmFs5RKNf5UqL+Shk3d36wAqEnzsfP3xuNxCiH2WcNYc58jdpCpg3kgntwSQ5O6B0hhZ2M0MCHqIDEDqlJ63/qO3FaOmtyg5KpwFFtQ6arXHhia56MT+kjArJ6a+mZFU90l9vu2Pu+u/lOuhsch2rfiq76b+BwqPR0WZ01pzJay3rtiJJoqn4lpmWKaMSrBMP4j7vv1n+O443Rw32UPzE+8Grsya+0lj9RVYI6k+IztpDUmh6W/wAtdDtH0AyKrk+xl7HurKWB4bkomO+XSiNkIX//2Q=='; // store files SpoonFile::setContent(PATH_WWW . '/frontend/files/backend_users/avatars/source/god.jpg', base64_decode($avatar124x124)); SpoonFile::setContent(PATH_WWW . '/frontend/files/backend_users/avatars/128x128/god.jpg', base64_decode($avatar124x124)); SpoonFile::setContent(PATH_WWW . '/frontend/files/backend_users/avatars/64x64/god.jpg', base64_decode($avatar64x64)); SpoonFile::setContent(PATH_WWW . '/frontend/files/backend_users/avatars/32x32/god.jpg', base64_decode($avatar32x32)); // get the password strength $passwordStrength = $this->checkPassword(); // build settings $settings['nickname'] = serialize('Fork CMS'); $settings['name'] = serialize('Fork'); $settings['surname'] = serialize('CMS'); $settings['interface_language'] = serialize($this->getVariable('default_interface_language')); $settings['date_format'] = serialize('j F Y'); $settings['time_format'] = serialize('H:i'); $settings['datetime_format'] = serialize(unserialize($settings['date_format']) . ' ' . unserialize($settings['time_format'])); $settings['number_format'] = serialize('dot_nothing'); $settings['password_key'] = serialize(uniqid()); $settings['password_strength'] = serialize($passwordStrength); $settings['current_password_change'] = serialize(time()); $settings['avatar'] = serialize('god.jpg'); // build user $user['email'] = $this->getVariable('email'); $user['password'] = sha1(md5(unserialize($settings['password_key'])) . md5($this->getVariable('password'))); $user['active'] = 'Y'; $user['deleted'] = 'N'; $user['is_god'] = 'Y'; // insert user $user['id'] = $this->getDB()->insert('users', $user); // build group $group['group_id'] = $this->getSetting('users', 'default_group'); $group['user_id'] = $user['id']; // insert group $this->getDB()->insert('users_groups', $group); // loop settings foreach ($settings as $name => $value) { // insert user settings $this->getDB()->insert('users_settings', array('user_id' => $user['id'], 'name' => $name, 'value' => $value)); } } }
/** * Write an error/custom message to the log. * * @return void * @param string $message The messages that should be logged. * @param string[optional] $type The type of message you want to log, possible values are: error, custom. */ public static function write($message, $type = 'error') { // milliseconds list($milliseconds) = explode(' ', microtime()); $milliseconds = round($milliseconds * 1000, 0); // redefine var $message = date('Y-m-d H:i:s') . ' ' . $milliseconds . 'ms | ' . $message . "\n"; $type = SpoonFilter::getValue($type, array('error', 'custom'), 'error'); // file $file = self::getPath() . '/' . $type . '.log'; // rename if needed if ((int) @filesize($file) >= self::MAX_FILE_SIZE * 1024) { // start new log file SpoonDirectory::move($file, $file . '.' . date('Ymdhis')); } // write content SpoonFile::setContent($file, $message, true, true); }
/** * Execute the action */ public function execute() { $this->id = $this->getParameter('id', 'int'); // does the item exist if ($this->id !== null && BackendAddressesModel::exists($this->id)) { parent::execute(); $this->record = (array) BackendAddressesModel::get($this->id); BackendAddressesModel::delete($this->id); BackendAddressesModel::deleteGroupsFromAddress($this->id); // delete the image \SpoonFile::delete(FRONTEND_FILES_PATH . '/Addresses/Images/Source/' . $this->record['image']); BackendSearchModel::removeIndex($this->getModule(), $this->id); BackendModel::triggerEvent($this->getModule(), 'after_delete', array('id' => $this->id)); $this->redirect(BackendModel::createURLForAction('index') . '&report=deleted&var=' . urlencode($this->record['id'])); } else { $this->redirect(BackendModel::createURLForAction('index') . '&error=non-existing'); } }
/** * Process the content of the file. * * @param string $file The file to process. * @return boolean|array */ private function processFile($file) { // if the files doesn't exists we can stop here and just return an empty string if (!SpoonFile::exists($file)) { return array(); } // fetch content from file $content = SpoonFile::getContent($file); $json = @json_decode($content, true); // skip invalid JSON if ($json === false || $json === null) { return array(); } $return = array(); // loop templates foreach ($json as $template) { // skip items without a title if (!isset($template['title'])) { continue; } if (isset($template['file'])) { if (SpoonFile::exists(PATH_WWW . $template['file'])) { $template['html'] = SpoonFile::getContent(PATH_WWW . $template['file']); } } // skip items without HTML if (!isset($template['html'])) { continue; } $image = ''; if (isset($template['image'])) { // we have to remove the first slash, because that is set in the wrapper. Otherwise the images don't work $image = ltrim($template['image'], '/'); } $temp['title'] = $template['title']; $temp['description'] = isset($template['description']) ? $template['description'] : ''; $temp['image'] = $image; $temp['html'] = $template['html']; // add the template $return[] = $temp; } return $return; }
/** * Load the datagrid * * @return void */ private function loadDataGrid() { // init var $items = array(); // get active modules $modules = BackendModel::getModules(); // loop active modules foreach ($modules as $module) { // check if their is a model-file if (SpoonFile::exists(BACKEND_MODULES_PATH . '/' . $module . '/engine/model.php')) { // require the model-file require_once BACKEND_MODULES_PATH . '/' . $module . '/engine/model.php'; // build class name $className = SpoonFilter::toCamelCase('backend_' . $module . '_model'); // check if the getByTag-method is available if (is_callable(array($className, 'getByTag'))) { // make the call and get the item $moduleItems = (array) call_user_func(array($className, 'getByTag'), $this->id); // loop items foreach ($moduleItems as $row) { // check if needed fields are available if (isset($row['url'], $row['name'], $row['module'])) { // add $items[] = array('module' => ucfirst(BL::lbl(SpoonFilter::toCamelCase($row['module']))), 'name' => $row['name'], 'url' => $row['url']); } } } } } // create datagrid $this->dgUsage = new BackendDataGridArray($items); // disable paging $this->dgUsage->setPaging(false); // hide columns $this->dgUsage->setColumnsHidden(array('url')); // set headers $this->dgUsage->setHeaderLabels(array('name' => ucfirst(BL::lbl('Title')), 'url' => '')); // set url $this->dgUsage->setColumnURL('name', '[url]', ucfirst(BL::lbl('Edit'))); // add use column $this->dgUsage->addColumn('edit', null, ucfirst(BL::lbl('Edit')), '[url]', BL::lbl('Edit')); }
/** * Sets the headers so we may download the CSV file in question * * @param string $path The full path to the CSV file you wish to download. * @return array */ private function downloadCSV($path) { // check if the file exists if (!SpoonFile::exists($path)) { throw new SpoonFileException('The file ' . $path . ' doesn\'t exist.'); } // fetch the filename from the path string $explodedFilename = explode('/', $path); $filename = end($explodedFilename); // set headers for download $headers[] = 'Content-type: application/csv; charset=' . SPOON_CHARSET; $headers[] = 'Content-Disposition: attachment; filename="' . $filename . '"'; $headers[] = 'Pragma: no-cache'; // overwrite the headers SpoonHTTP::setHeaders($headers); // get the file contents $content = SpoonFile::getContent($path); // output the file contents echo $content; exit; }
/** * Execute the action */ public function execute() { parent::execute(); // add js $this->header->addJS('jstree/jquery.tree.js', null, false, false, false); $this->header->addJS('jstree/lib/jquery.cookie.js', null, false, false, false); $this->header->addJS('jstree/plugins/jquery.tree.cookie.js', null, false, false, false); // add css $this->header->addCSS('/backend/modules/pages/js/jstree/themes/fork/style.css', null, true); // check if the cached files exists if (!SpoonFile::exists(PATH_WWW . '/frontend/cache/navigation/keys_' . BackendLanguage::getWorkingLanguage() . '.php')) { BackendPagesModel::buildCache(BL::getWorkingLanguage()); } if (!SpoonFile::exists(PATH_WWW . '/frontend/cache/navigation/navigation_' . BackendLanguage::getWorkingLanguage() . '.php')) { BackendPagesModel::buildCache(BL::getWorkingLanguage()); } // load the dgRecentlyEdited $this->loadDataGrids(); // parse $this->parse(); // display the page $this->display(); }
/** * The default constructor * * @return void * @param string $title The title off the feed. * @param string $link The link of the feed. * @param string $description The description of the feed. * @param array[optional] $items An array with SpoonRSSItems. */ public function __construct($title, $link, $description, array $items = array()) { // decode $title = SpoonFilter::htmlspecialcharsDecode($title); $description = SpoonFilter::htmlspecialcharsDecode($description); // call the parent parent::__construct($title, FrontendModel::addURLParameters($link, array('utm_source' => 'feed', 'utm_medium' => 'rss', 'utm_campaign' => SpoonFilter::urlise($title))), $description, $items); // set feed properties $this->setLanguage(FRONTEND_LANGUAGE); $this->setCopyright(SpoonDate::getDate('Y') . ' ' . SpoonFilter::htmlspecialcharsDecode(FrontendModel::getModuleSetting('core', 'site_title_' . FRONTEND_LANGUAGE))); $this->setGenerator(SITE_RSS_GENERATOR); $this->setImage(SITE_URL . FRONTEND_CORE_URL . '/layout/images/rss_image.png', $title, $link); // theme was set if (FrontendModel::getModuleSetting('core', 'theme', null) != null) { // theme name $theme = FrontendModel::getModuleSetting('core', 'theme', null); // theme rss image exists if (SpoonFile::exists(PATH_WWW . '/frontend/themes/' . $theme . '/core/images/rss_image.png')) { // set rss image $this->setImage(SITE_URL . '/frontend/themes/' . $theme . '/core/images/rss_image.png', $title, $link); } } }
/** * Execute the action */ public function execute() { // get parameters $this->id = $this->getParameter('id', 'int'); // does the item exist if ($this->id !== null && BackendBlogModel::exists($this->id)) { // call parent, this will probably add some general CSS/JS or other required files parent::execute(); // set category id $this->categoryId = SpoonFilter::getGetValue('category', null, null, 'int'); if ($this->categoryId == 0) { $this->categoryId = null; } // get data $this->record = (array) BackendBlogModel::get($this->id); // delete item BackendBlogModel::delete($this->id); // delete the image SpoonFile::delete(FRONTEND_FILES_PATH . '/blog/images/source/' . $this->record['image']); // trigger event BackendModel::triggerEvent($this->getModule(), 'after_delete', array('id' => $this->id)); // delete search indexes if (is_callable(array('BackendSearchModel', 'removeIndex'))) { BackendSearchModel::removeIndex($this->getModule(), $this->id); } // build redirect URL $redirectUrl = BackendModel::createURLForAction('index') . '&report=deleted&var=' . urlencode($this->record['title']); // append to redirect URL if ($this->categoryId != null) { $redirectUrl .= '&category=' . $this->categoryId; } // item was deleted, so redirect $this->redirect($redirectUrl); } else { $this->redirect(BackendModel::createURLForAction('index') . '&error=non-existing'); } }
/** * Returns the mailchimp object. * * @return mailchimp */ public static function getMC() { // mailchimp reference exists if (!\Spoon::exists('mailchimp')) { // check if the mailchimp class exists if (!\SpoonFile::exists(PATH_LIBRARY . '/external/mcapi.php')) { // the class doesn't exist, so throw an exception throw new \SpoonFileException(sprintf(FL::err('ClassDoesNotExist'), 'mailchimp')); } // require mailchimp class require_once PATH_LIBRARY . '/external/mcapi.php'; // set login data $key = FrontendModel::getModuleSetting('MailMotor', 'api_key'); if (empty($key)) { throw new \Exception('Mailmotor api_key is required.'); } // init mailchimp object $mc = new \MCAPI($key); // set mailchimp object reference \Spoon::set('mailchimp', $mc); } // return the CampaignMonitor object return \Spoon::get('mailchimp'); }
/** * Get templates. * * @return array */ public static function getTemplates() { // fetch templates available in core $templates = SpoonFile::getList(FRONTEND_MODULES_PATH . '/content_blocks/layout/widgets', '/.*?\\.tpl/'); // fetch current active theme $theme = BackendModel::getModuleSetting('core', 'theme', 'core'); // fetch theme templates if a theme is selected if ($theme != 'core') { $templates = array_merge($templates, SpoonFile::getList(FRONTEND_PATH . '/themes/' . $theme . '/modules/content_blocks/layout/widgets', '/.*?\\.tpl/')); } // no duplicates (core templates will be overridden by theme templates) and sort alphabetically $templates = array_unique($templates); sort($templates); return $templates; }
/** * Installs the required and optional modules */ private function installModules() { // The default extras to add to every page after installation of all modules and to add to the default templates. $defaultExtras = array(); // init var $warnings = array(); /** * First we need to install the core. All the linked modules, settings and sql tables are * being installed. */ require_once PATH_WWW . '/backend/core/installer/installer.php'; // create the core installer $installer = new CoreInstaller($this->db, SpoonSession::get('languages'), SpoonSession::get('interface_languages'), SpoonSession::get('example_data'), array('default_language' => SpoonSession::get('default_language'), 'default_interface_language' => SpoonSession::get('default_interface_language'), 'spoon_debug_email' => SpoonSession::get('email'), 'api_email' => SpoonSession::get('email'), 'site_domain' => isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'fork.local', 'site_title' => 'Fork CMS', 'smtp_server' => '', 'smtp_port' => '', 'smtp_username' => '', 'smtp_password' => '')); // install the core $installer->install(); // add the warnings $moduleWarnings = $installer->getWarnings(); if (!empty($moduleWarnings)) { $warnings[] = array('module' => 'core', 'warnings' => $moduleWarnings); } // add the default extras $moduleDefaultExtras = $installer->getDefaultExtras(); if (!empty($moduleDefaultExtras)) { array_merge($defaultExtras, $moduleDefaultExtras); } // variables passed to module installers $variables = array(); $variables['email'] = SpoonSession::get('email'); $variables['default_interface_language'] = SpoonSession::get('default_interface_language'); // modules to install (required + selected) $modules = array_unique(array_merge($this->modules['required'], SpoonSession::get('modules'))); // loop required modules foreach ($modules as $module) { // install exists if (SpoonFile::exists(PATH_WWW . '/backend/modules/' . $module . '/installer/installer.php')) { // users module needs custom variables if ($module == 'users') { $variables['password'] = SpoonSession::get('password'); } // load installer file require_once PATH_WWW . '/backend/modules/' . $module . '/installer/installer.php'; // build installer class name $class = SpoonFilter::toCamelCase($module) . 'Installer'; // create installer $installer = new $class($this->db, SpoonSession::get('languages'), SpoonSession::get('interface_languages'), SpoonSession::get('example_data'), $variables); // install the module $installer->install(); // add the warnings $moduleWarnings = $installer->getWarnings(); if (!empty($moduleWarnings)) { $warnings[] = array('module' => $module, 'warnings' => $moduleWarnings); } // add the default extras $moduleDefaultExtras = $installer->getDefaultExtras(); if (!empty($moduleDefaultExtras)) { $defaultExtras = array_merge($defaultExtras, $moduleDefaultExtras); } } } // loop default extras foreach ($defaultExtras as $extra) { // get pages without this extra $revisionIds = $this->db->getColumn('SELECT i.revision_id FROM pages AS i WHERE i.revision_id NOT IN ( SELECT DISTINCT b.revision_id FROM pages_blocks AS b WHERE b.extra_id = ? GROUP BY b.revision_id )', array($extra['id'])); // build insert array for this extra $insertExtras = array(); foreach ($revisionIds as $revisionId) { $insertExtras[] = array('revision_id' => $revisionId, 'position' => $extra['position'], 'extra_id' => $extra['id'], 'created_on' => gmdate('Y-m-d H:i:s'), 'edited_on' => gmdate('Y-m-d H:i:s'), 'visible' => 'Y'); } // insert block $this->db->insert('pages_blocks', $insertExtras); } // parse the warnings $this->tpl->assign('warnings', $warnings); }
/** * Set the action * * We can't rely on the parent setModule function, because a cronjob requires no login * * @param string $action The action to load. * @param string[optional] $module The module to load. */ public function setAction($action, $module = null) { // set module if ($module !== null) { $this->setModule($module); } // check if module is set if ($this->getModule() === null) { throw new BackendException('Module has not yet been set.'); } // path to look for actions based on the module if ($this->getModule() == 'core') { $path = BACKEND_CORE_PATH . '/cronjobs'; } else { $path = BACKEND_MODULES_PATH . '/' . $this->getModule() . '/cronjobs'; } // does this module exist? $actions = SpoonFile::getList($path); if (!in_array($action . '.php', $actions)) { // set correct headers SpoonHTTP::setHeadersByCode(403); // throw exception throw new BackendException('Action not allowed.'); } // set property $this->action = (string) $action; }
/** * Display the output. * * @param string $template The filename of the template that you want to display. */ public function display($template) { // redefine $template = (string) $template; // validate name if (trim($template) == '' || !SpoonFile::exists($template)) { throw new SpoonTemplateException('Please provide an existing template.'); } // compiled name $compileName = $this->getCompileName((string) $template); // compiled if needed if ($this->forceCompile || !SpoonFile::exists($this->compileDirectory . '/' . $compileName)) { // create compiler $compiler = new SpoonTemplateCompiler((string) $template, $this->variables); // set some options $compiler->setCacheDirectory($this->cacheDirectory); $compiler->setCompileDirectory($this->compileDirectory); $compiler->setForceCompile($this->forceCompile); $compiler->setForms($this->forms); // compile & save $compiler->parseToFile(); } // load template require $this->compileDirectory . '/' . $compileName; }
/** * Autoloader for the frontend * * @return void * @param string $className The name of the class to require. */ public static function autoLoader($className) { // redefine $className = strtolower((string) $className); // init var $pathToLoad = ''; // exceptions $exceptions = array(); $exceptions['frontend'] = FRONTEND_CORE_PATH . '/engine/frontend.php'; $exceptions['frontendbaseajaxaction'] = FRONTEND_CORE_PATH . '/engine/base.php'; $exceptions['frontendbaseconfig'] = FRONTEND_CORE_PATH . '/engine/base.php'; $exceptions['frontendbaseobject'] = FRONTEND_CORE_PATH . '/engine/base.php'; $exceptions['frontendblockextra'] = FRONTEND_CORE_PATH . '/engine/block.php'; $exceptions['frontendblockwidget'] = FRONTEND_CORE_PATH . '/engine/block.php'; $exceptions['frontendtemplatecompiler'] = FRONTEND_CORE_PATH . '/engine/template_compiler.php'; // is it an exception if (isset($exceptions[$className])) { $pathToLoad = $exceptions[$className]; } elseif (substr($className, 0, 8) == 'frontend') { $pathToLoad = FRONTEND_CORE_PATH . '/engine/' . str_replace('frontend', '', $className) . '.php'; } // file check in core if ($pathToLoad != '' && SpoonFile::exists($pathToLoad)) { require_once $pathToLoad; } else { // we'll need the original class name again, with the uppercases $className = func_get_arg(0); // split in parts if (preg_match_all('/[A-Z][a-z0-9]*/', $className, $parts)) { // the real matches $parts = $parts[0]; // doublecheck that we are looking for a frontend class $root = array_shift($parts); if (strtolower($root) == 'frontend') { foreach ($parts as $i => $part) { // skip the first if ($i == 0) { continue; } // action $action = strtolower(implode('_', $parts)); // module $module = ''; for ($j = 0; $j < $i; $j++) { $module .= strtolower($parts[$j]) . '_'; } // fix action & module $action = substr($action, strlen($module)); $module = substr($module, 0, -1); // check the actions, engine & widgets directories foreach (array('actions', 'engine', 'widgets') as $dir) { // file to be loaded $pathToLoad = FRONTEND_PATH . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . $action . '.php'; // if it exists, load it! if ($pathToLoad != '' && SpoonFile::exists($pathToLoad)) { require_once $pathToLoad; break; } } } } } } }
/** * Write data to cache file * * @return void * @param array $data The data to write to the cache file. * @param int $startTimestamp The start timestamp for the cache file. * @param int $endTimestamp The end timestamp for the cache file. */ public static function writeCacheFile(array $data, $startTimestamp, $endTimestamp) { // build xml string from data $xml = "<?xml version='1.0' encoding='UTF-8'?>\n"; $xml .= "<analytics start_timestamp=\"" . $startTimestamp . "\" end_timestamp=\"" . $endTimestamp . "\">\n"; // loop data foreach ($data as $type => $records) { // init vars $attributes = array(); // there are some attributes if (isset($records['attributes']) && !empty($records['attributes'])) { // loop em foreach ($records['attributes'] as $key => $value) { // add to the attributes string $attributes[] = $key . '="' . $value . '"'; } } // build xml $xml .= "\t<" . $type . (!empty($attributes) ? ' ' . implode(' ', $attributes) : '') . ">\n"; // we're not dealing with a page detail if (strpos($type, 'page_') === false) { // get items $items = isset($records['entries']) ? $records['entries'] : $records; // loop data foreach ($items as $key => $value) { // skip empty items if (is_array($value) && empty($value) || trim((string) $value) === '') { continue; } // value contains an array if (is_array($value)) { // there are values if (!empty($value)) { // build xml $xml .= "\t\t<entry>\n"; // loop data foreach ($value as $entryKey => $entryValue) { // build xml $xml .= "\t\t\t<" . $entryKey . "><![CDATA[" . $entryValue . "]]></" . $entryKey . ">\n"; } // end xml element $xml .= "\t\t</entry>\n"; } } else { $xml .= "\t\t<" . $key . ">" . $value . "</" . $key . ">\n"; } } } else { // loop data foreach ($records as $subkey => $subitems) { // build xml $xml .= "\t\t<" . $subkey . ">\n"; // subitems is an array if (is_array($subitems)) { // loop data foreach ($subitems as $key => $value) { // skip empty items if (is_array($value) && empty($value) || trim((string) $value) === '') { continue; } // value contains an array if (is_array($value)) { // there are values if (!empty($value)) { // build xml $xml .= "\t\t\t<entry>\n"; // loop data foreach ($value as $entryKey => $entryValue) { // build xml $xml .= "\t\t\t\t<" . $entryKey . "><![CDATA[" . $entryValue . "]]></" . $entryKey . ">\n"; } // end xml element $xml .= "\t\t\t</entry>\n"; } } else { $xml .= "\t\t<" . $key . ">" . $value . "</" . $key . ">\n"; } } } else { $xml .= "<![CDATA[" . (string) $subitems . "]]>"; } // end xml element $xml .= "\t\t</" . $subkey . ">\n"; } } // end xml element $xml .= "\t</" . $type . ">\n"; } // end xml string $xml .= "</analytics>"; // perform checks for valid xml and throw exception if needed $simpleXml = @simplexml_load_string($xml); if ($simpleXml === false) { throw new BackendException('The xml of the cache file is invalid.'); } // get filename $filename = $startTimestamp . '_' . $endTimestamp . '.xml'; // all is well SpoonFile::setContent(BACKEND_CACHE_PATH . '/analytics/' . $filename, $xml); }
/** * Parse the template to a file. */ public function parseToFile() { SpoonFile::setContent($this->compileDirectory . '/' . $this->getCompileName($this->template), $this->getContent()); }
/** * Default constructor * * @return void */ public function __construct() { // simulate $_REQUEST $parameters = array_merge($_GET, $_POST); // validate parameters if (!isset($parameters['method'])) { self::output(self::BAD_REQUEST, array('message' => 'No method-parameter provided.')); } // check GET $method = SpoonFilter::getValue($parameters['method'], null, ''); // validate if ($method == '') { self::output(self::BAD_REQUEST, array('message' => 'No method-parameter provided.')); } // process method $chunks = (array) explode('.', $method, 2); // validate method if (!isset($chunks[1])) { self::output(self::BAD_REQUEST, array('message' => 'Invalid method.')); } // build the path to the backend API file if ($chunks[0] == 'core') { $path = BACKEND_CORE_PATH . '/engine/api.php'; } else { $path = BACKEND_MODULES_PATH . '/' . $chunks[0] . '/engine/api.php'; } // check if the fille is present? If it isn't present there is a problem if (!SpoonFile::exists($path)) { self::output(self::BAD_REQUEST, array('message' => 'Invalid method.')); } // build config-object-name $className = 'Backend' . SpoonFilter::toCamelCase($chunks[0]) . 'API'; $methodName = SpoonFilter::toCamelCase($chunks[1], '.', true); // require the class require_once $path; // validate if the method exists if (!is_callable(array($className, $methodName))) { self::output(self::BAD_REQUEST, array('message' => 'Invalid method.')); } // call the method try { // init var $arguments = null; // create reflection method $reflectionMethod = new ReflectionMethod($className, $methodName); $parameterDocumentation = array(); // get data from docs $matches = array(); preg_match_all('/@param[\\s\\t]+(.*)[\\s\\t]+\\$(.*)[\\s\\t]+(.*)$/Um', $reflectionMethod->getDocComment(), $matches); // documentation found if (!empty($matches[0])) { // loop matches foreach ($matches[0] as $i => $row) { // set documentation $parameterDocumentation[$matches[2][$i]] = array('type' => str_replace('[optional]', '', $matches[1][$i]), 'optional' => substr_count($matches[1][$i], '[optional]') > 0, 'description' => $matches[3][$i]); } } // loop parameters foreach ($reflectionMethod->getParameters() as $parameter) { // init var $name = $parameter->getName(); // check if the parameter is available if (!$parameter->isOptional() && !isset($parameters[$name])) { self::output(self::BAD_REQUEST, array('message' => 'No ' . $name . '-parameter provided.')); } // add not-passed arguments if ($parameter->isOptional() && !isset($parameters[$name])) { $arguments[] = $parameter->getDefaultValue(); } elseif (isset($parameterDocumentation[$name]['type'])) { // get default value $defaultValue = null; if ($parameter->isOptional()) { $defaultValue = $parameter->getDefaultValue(); } // add argument $arguments[] = SpoonFilter::getValue($parameters[$name], null, $defaultValue, $parameterDocumentation[$name]['type']); } else { $arguments[] = $parameters[$name]; } } // get the return $data = (array) call_user_func_array(array($className, $methodName), (array) $arguments); // output self::output(self::OK, $data); } catch (Exception $e) { // if we are debugging we should see the exceptions if (SPOON_DEBUG) { if (isset($parameters['debug']) && $parameters['debug'] == 'false') { // do nothing } else { throw $e; } } // output self::output(500, array('message' => $e->getMessage())); } }
/** * Get the widgets * * @return void */ private function getWidgets() { // get all active modules $modules = BackendModel::getModules(true); // loop all modules foreach ($modules as $module) { // you have sufficient rights? if (BackendAuthentication::isAllowedModule($module)) { // build pathName $pathName = BACKEND_MODULES_PATH . '/' . $module; // check if the folder exists if (SpoonDirectory::exists($pathName . '/widgets')) { // get widgets $widgets = (array) SpoonFile::getList($pathName . '/widgets', '/(.*)\\.php/i'); // loop through widgets foreach ($widgets as $widget) { // require the classes require_once $pathName . '/widgets/' . $widget; // init var $widgetName = str_replace('.php', '', $widget); // build classname $className = 'Backend' . SpoonFilter::toCamelCase($module) . 'Widget' . SpoonFilter::toCamelCase($widgetName); // validate if the class exists if (!class_exists($className)) { // throw exception throw new BackendException('The widgetfile is present, but the classname should be: ' . $className . '.'); } else { // add to array $this->widgetInstances[] = array('module' => $module, 'widget' => $widgetName, 'className' => $className); // create reflection class $reflection = new ReflectionClass('Backend' . SpoonFilter::toCamelCase($module) . 'Widget' . SpoonFilter::toCamelCase($widgetName)); // get the offset $offset = strpos($reflection->getDocComment(), '*', 7); // get the first sentence $description = substr($reflection->getDocComment(), 0, $offset); // replacements $description = str_replace('*', '', $description); $description = trim(str_replace('/', '', $description)); } // check if model file exists if (SpoonFile::exists($pathName . '/engine/model.php')) { // require model require_once $pathName . '/engine/model.php'; } // add to array $this->widgets[] = array('label' => SpoonFilter::toCamelCase($widgetName), 'value' => $widgetName, 'description' => $description); } } } } }