/** * Load the form */ protected function loadForm() { // create form $this->frm = new Form('edit'); $this->frm->addText('title', $this->record['title'], null, 'inputText title', 'inputTextError title'); $this->frm->addEditor('text', $this->record['text']); //$this->frm->addText('link', $this->record['link']); $this->frm->addText('linktext', $this->record['linktext']); $this->frm->addImage('image'); // build array with options for the hidden Radiobutton $RadiobuttonHiddenValues[] = array('label' => Language::lbl('Hidden'), 'value' => 'Y'); $RadiobuttonHiddenValues[] = array('label' => Language::lbl('Published'), 'value' => 'N'); $this->frm->addRadioButton('hidden', $RadiobuttonHiddenValues, $this->record['hidden']); // get categories $categories = BackendBlocksModel::getCategories(); $this->frm->addDropdown('category_id', $categories, $this->record['category_id']); // meta $this->meta = new Meta($this->frm, $this->record['meta_id'], 'title', true); $this->meta->setUrlCallBack('Backend\\Modules\\Blocks\\Engine\\Model', 'getUrl', array($this->record['id'])); // redirect $redirectValue = 'none'; if (isset($this->record['page_id'])) { $redirectValue = 'internal'; } if (isset($this->record['link'])) { $redirectValue = 'external'; } $redirectValues = array(array('value' => 'none', 'label' => \SpoonFilter::ucfirst(Language::lbl('None'))), array('value' => 'internal', 'label' => \SpoonFilter::ucfirst(Language::lbl('InternalLink')), 'variables' => array('isInternal' => true)), array('value' => 'external', 'label' => \SpoonFilter::ucfirst(Language::lbl('ExternalLink')), 'variables' => array('isExternal' => true))); $this->frm->addRadiobutton('redirect', $redirectValues, $redirectValue); $this->frm->addDropdown('internal_redirect', BackendPagesModel::getPagesForDropdown(), $redirectValue == 'internal' ? $this->record['page_id'] : null); $this->frm->addText('external_redirect', $redirectValue == 'external' ? $this->record['link'] : null, null, null, null, true); }
public function testUrlIsEncoded() { self::assertEquals('http://www.google.be/Quote', Model::getEncodedRedirectURL('http://www.google.be/Quote')); self::assertEquals('http://www.google.be/Quote%22HelloWorld%22', Model::getEncodedRedirectURL('http://www.google.be/Quote"HelloWorld"')); self::assertEquals('http://www.google.be/Quote%27HelloWorld%27', Model::getEncodedRedirectURL("http://www.google.be/Quote'HelloWorld'")); self::assertEquals('http://cédé.be/Quote%22HelloWorld%22', Model::getEncodedRedirectURL('http://cédé.be/Quote"HelloWorld"')); }
/** * @param KernelInterface $kernel */ public function __construct(KernelInterface $kernel) { parent::__construct($kernel); // store for later use throughout the application $this->getContainer()->set('navigation', $this); $this->URL = $this->getContainer()->get('url'); // check if navigation cache file exists if (!is_file(self::getCacheDirectory() . 'navigation.php')) { $this->buildCache(); } // check if editor_link_list_LANGUAGE.js cache file exists if (!is_file(FRONTEND_CACHE_PATH . '/Navigation/editor_link_list_' . BackendLanguage::getWorkingLanguage() . '.js')) { BackendPagesModel::buildCache(BackendLanguage::getWorkingLanguage()); } $navigation = array(); // require navigation-file require self::getCacheDirectory() . 'navigation.php'; // load it $this->navigation = (array) $navigation; $this->navigation = $this->addActiveStateToNavigation($this->navigation); // cleanup navigation (not needed for god user) if (!Authentication::getUser()->isGod()) { $this->navigation = $this->cleanup($this->navigation); } }
/** * Execute the action */ public function execute() { // call parent parent::execute(); // get parameters $id = \SpoonFilter::getPostValue('id', null, 0, 'int'); // validate if ($id === 0) { $this->output(self::BAD_REQUEST, null, 'no id provided'); } else { // get page $page = BackendPagesModel::get($id); // output $this->output(self::OK, $page); } }
/** * Fetches all data from the database * * @param string $language * @return array tupple containing keys and navigation */ protected function getData($language) { // get tree $levels = Model::getTree(array(0), null, 1, $language); $keys = array(); $navigation = array(); // loop levels foreach ($levels as $pages) { // loop all items on this level foreach ($pages as $pageId => $page) { $temp = $this->getPageData($keys, $page, $language); // add it $navigation[$page['type']][$page['parent_id']][$pageId] = $temp; } } // order by URL asort($keys); return array($keys, $navigation); }
/** * Execute the action */ public function execute() { // call parent, this will probably add some general CSS/JS or other required files parent::execute(); // get parameters $this->from = $this->getParameter('from'); $this->to = $this->getParameter('to'); // validate if ($this->from == '') { throw new BackendException('Specify a from-parameter.'); } if ($this->to == '') { throw new BackendException('Specify a to-parameter.'); } // copy pages BackendPagesModel::copy($this->from, $this->to); // redirect $this->redirect(BackendModel::createURLForAction('Index') . '&report=copy-added&var=' . urlencode($this->to)); }
/** * Execute the action */ public function execute() { // get parameters $this->id = $this->getParameter('id', 'int'); // does the item exist if ($this->id !== null && BackendPagesModel::exists($this->id)) { // call parent, this will probably add some general CSS/JS or other required files parent::execute(); // init var $success = false; // cannot have children if (BackendPagesModel::getFirstChildId($this->id) !== false) { $this->redirect(BackendModel::createURLForAction('Edit') . '&error=non-existing'); } $revisionId = $this->getParameter('revision_id', 'int'); if ($revisionId == 0) { $revisionId = null; } // get page (we need the title) $page = BackendPagesModel::get($this->id, $revisionId); // valid page? if (!empty($page)) { // delete the page $success = BackendPagesModel::delete($this->id, null, $revisionId); // trigger event BackendModel::triggerEvent($this->getModule(), 'after_delete', array('id' => $this->id)); // delete search indexes BackendSearchModel::removeIndex($this->getModule(), $this->id); // build cache BackendPagesModel::buildCache(BL::getWorkingLanguage()); } // page is deleted, so redirect to the overview if ($success) { $this->redirect(BackendModel::createURLForAction('Index') . '&id=' . $page['parent_id'] . '&report=deleted&var=' . rawurlencode($page['title'])); } else { $this->redirect(BackendModel::createURLForAction('Edit') . '&error=non-existing'); } } else { $this->redirect(BackendModel::createURLForAction('Edit') . '&error=non-existing'); } }
/** * Execute the action */ public function execute() { // call parent parent::execute(); // get parameters $id = \SpoonFilter::getPostValue('id', null, 0, 'int'); $droppedOn = \SpoonFilter::getPostValue('dropped_on', null, -1, 'int'); $typeOfDrop = \SpoonFilter::getPostValue('type', null, ''); $tree = \SpoonFilter::getPostValue('tree', array('main', 'meta', 'footer', 'root'), ''); // init validation $errors = array(); // validate if ($id === 0) { $errors[] = 'no id provided'; } if ($droppedOn === -1) { $errors[] = 'no dropped_on provided'; } if ($typeOfDrop == '') { $errors[] = 'no type provided'; } if ($tree == '') { $errors[] = 'no tree provided'; } // got errors if (!empty($errors)) { $this->output(self::BAD_REQUEST, array('errors' => $errors), 'not all fields were filled'); } else { // get page $success = BackendPagesModel::move($id, $droppedOn, $typeOfDrop, $tree); // build cache BackendPagesModel::buildCache(BL::getWorkingLanguage()); // output if ($success) { $this->output(self::OK, BackendPagesModel::get($id), 'page moved'); } else { $this->output(self::ERROR, null, 'page not moved'); } } }
/** * Load the form */ protected function loadForm() { $this->frm = new Form('add'); $this->frm->addText('title', null, null, 'inputText title', 'inputTextError title'); $this->frm->addEditor('text'); //$this->frm->addText('link'); $this->frm->addText('linktext'); $this->frm->addImage('image'); // build array with options for the hidden Radiobutton $RadiobuttonHiddenValues[] = array('label' => Language::lbl('Hidden'), 'value' => 'Y'); $RadiobuttonHiddenValues[] = array('label' => Language::lbl('Published'), 'value' => 'N'); $this->frm->addRadioButton('hidden', $RadiobuttonHiddenValues, 'N'); // get categories $categories = BackendBlocksModel::getCategories(); $this->frm->addDropdown('category_id', $categories); // redirect $redirectValue = 'none'; $redirectValues = array(array('value' => 'none', 'label' => \SpoonFilter::ucfirst(Language::lbl('None'))), array('value' => 'internal', 'label' => \SpoonFilter::ucfirst(Language::lbl('InternalLink')), 'variables' => array('isInternal' => true)), array('value' => 'external', 'label' => \SpoonFilter::ucfirst(Language::lbl('ExternalLink')), 'variables' => array('isExternal' => true))); $this->frm->addRadiobutton('redirect', $redirectValues, $redirectValue); $this->frm->addDropdown('internal_redirect', BackendPagesModel::getPagesForDropdown(), null); $this->frm->addText('external_redirect', null, null, null, null, true); // meta $this->meta = new Meta($this->frm, null, 'title', true); }
/** * Get the navigation-items * * @param string $language The language wherefore the keys should be loaded, * if not provided we will load the language that was provided in the URL. * @return array */ public static function getNavigation($language = null) { $language = $language !== null ? (string) $language : FRONTEND_LANGUAGE; return BackendPagesModel::getCacheBuilder()->getNavigation($language); }
/** * Validates the form. */ private function validateForm() { // is the form submitted? if ($this->frm->isSubmitted()) { // no errors? if ($this->frm->isCorrect()) { // determine themes $newTheme = $this->frm->getField('installedThemes')->getValue(); $oldTheme = $this->get('fork.settings')->get('Core', 'theme', 'core'); // check if we actually switched themes if ($newTheme != $oldTheme) { // fetch templates $oldTemplates = BackendExtensionsModel::getTemplates($oldTheme); $newTemplates = BackendExtensionsModel::getTemplates($newTheme); // check if templates already exist if (empty($newTemplates)) { // templates do not yet exist; don't switch $this->redirect(BackendModel::createURLForAction('Themes') . '&error=no-templates-available'); exit; } // fetch current default template $oldDefaultTemplatePath = $oldTemplates[$this->get('fork.settings')->get('Pages', 'default_template')]['path']; // loop new templates foreach ($newTemplates as $newTemplateId => $newTemplate) { // check if a a similar default template exists if ($newTemplate['path'] == $oldDefaultTemplatePath) { // set new default id $newDefaultTemplateId = (int) $newTemplateId; break; } } // no default template was found, set first template as default if (!isset($newDefaultTemplateId)) { $newDefaultTemplateId = array_keys($newTemplates); $newDefaultTemplateId = $newDefaultTemplateId[0]; } // update theme $this->get('fork.settings')->set('Core', 'theme', $newTheme); // save new default template $this->get('fork.settings')->set('Pages', 'default_template', $newDefaultTemplateId); // loop old templates foreach ($oldTemplates as $oldTemplateId => $oldTemplate) { // loop new templates foreach ($newTemplates as $newTemplateId => $newTemplate) { // if the templates don't match we can skip this one if ($oldTemplate['path'] != $newTemplate['path']) { continue; } // switch template BackendPagesModel::updatePagesTemplates($oldTemplateId, $newTemplateId); // break loop continue 2; } // getting here meant we found no matching template for the new theme; pick first theme's template as default BackendPagesModel::updatePagesTemplates($oldTemplateId, $newDefaultTemplateId); } // trigger event BackendModel::triggerEvent($this->getModule(), 'after_changed_theme'); } // assign report $this->tpl->assign('report', true); $this->tpl->assign('reportMessage', BL::msg('Saved')); } } }
/** * @return bool */ private function askToInstall() { if (array_key_exists($this->workingLocale, $this->installedLocale)) { $reinstallLocale = $this->formatter->confirm('The locale is already installed, would you like to reinstall and overwrite the current translations?', false); if (!$reinstallLocale) { return true; } $this->installWorkingLocale(true); return true; } $install = $this->formatter->confirm('Would you like to install this locale?'); if (!$install) { return false; } $this->formatter->writeln('<info>Before you can enable a new locale you need to authenticate to be able to create the pages</info>'); while (!Authentication::loginUser($this->formatter->ask('Login'), $this->formatter->askHidden('Password'))) { $this->formatter->error('Failed to login, please try again'); } if (!Authentication::isAllowedAction('Copy', 'Pages')) { $this->formatter->error('Your profile doesn\'t have the permission to execute the action Copy of the Pages module'); return false; } $this->installWorkingLocale(); $this->formatter->writeln('<info>Copying pages from the default locale to the current locale</info>'); BackendPagesModel::copy($this->defaultEnabledLocale, $this->workingLocale); return true; }
/** * Validate the form */ private function validateForm() { // is the form submitted? if ($this->frm->isSubmitted()) { // cleanup the submitted fields, ignore fields that were added by hackers $this->frm->cleanupFields(); // required fields $this->frm->getField('file')->isFilled(BL::err('FieldIsRequired')); $this->frm->getField('label')->isFilled(BL::err('FieldIsRequired')); $this->frm->getField('format')->isFilled(BL::err('FieldIsRequired')); // check if the template file exists if ($this->frm->getField('theme')->getValue() == 'Core') { $templateFile = PATH_WWW . '/src/Frontend/Core/Layout/Templates/' . $this->frm->getField('file')->getValue(); } else { $templateFile = PATH_WWW . '/src/Frontend/Themes/' . $this->frm->getField('theme')->getValue() . '/Core/Layout/Templates/' . $this->frm->getField('file')->getValue(); } if (!is_file($templateFile)) { $this->frm->getField('file')->addError(BL::err('TemplateFileNotFound')); } // validate syntax $syntax = trim(str_replace(array("\n", "\r", ' '), '', $this->frm->getField('format')->getValue())); // init var $table = BackendExtensionsModel::templateSyntaxToArray($syntax); // validate the syntax if ($table === false) { $this->frm->getField('format')->addError(BL::err('InvalidTemplateSyntax')); } else { $html = BackendExtensionsModel::buildTemplateHTML($syntax); $cellCount = 0; $first = true; $errors = array(); // loop rows foreach ($table as $row) { // first row defines the cellcount if ($first) { $cellCount = count($row); } // not same number of cells if (count($row) != $cellCount) { // add error $errors[] = BL::err('InvalidTemplateSyntax'); // stop break; } // double check position names foreach ($row as $cell) { // ignore unavailable space if ($cell != '/') { // not alphanumeric -> error if (!in_array($cell, $this->names)) { $errors[] = sprintf(BL::getError('NonExistingPositionName'), $cell); } elseif (substr_count($html, '"#position-' . $cell . '"') != 1) { // can't build proper html -> error $errors[] = BL::err('InvalidTemplateSyntax'); } } } // reset $first = false; } // add errors if ($errors) { $this->frm->getField('format')->addError(implode('<br />', array_unique($errors))); } } // no errors? if ($this->frm->isCorrect()) { // build array $item['id'] = $this->id; $item['theme'] = $this->frm->getField('theme')->getValue(); $item['label'] = $this->frm->getField('label')->getValue(); $item['path'] = 'Core/Layout/Templates/' . $this->frm->getField('file')->getValue(); $item['active'] = $this->frm->getField('active')->getChecked() ? 'Y' : 'N'; // copy data from previous version, otherwise default_extras from other languages are overwritten $item['data'] = $this->record['data']; $item['data']['format'] = trim(str_replace(array("\n", "\r", ' '), '', $this->frm->getField('format')->getValue())); $item['data']['names'] = $this->names; $item['data']['default_extras'] = $this->extras; $item['data']['default_extras_' . BL::getWorkingLanguage()] = $this->extras; // serialize $item['data'] = serialize($item['data']); // if this is the default template make the template active if ($this->get('fork.settings')->get('Pages', 'default_template') == $this->record['id']) { $item['active'] = 'Y'; } // if the template is in use we can't de-activate it if (BackendExtensionsModel::isTemplateInUse($item['id'])) { $item['active'] = 'Y'; } // insert the item BackendExtensionsModel::updateTemplate($item); // trigger event BackendModel::triggerEvent($this->getModule(), 'after_edit_template', array('item' => $item)); // set default template if ($this->frm->getField('default')->getChecked() && $item['theme'] == $this->get('fork.settings')->get('Core', 'theme', 'core')) { $this->get('fork.settings')->set('pages', 'default_template', $item['id']); } // update all existing pages using this template to add the newly inserted block(s) if (BackendExtensionsModel::isTemplateInUse($item['id'])) { BackendPagesModel::updatePagesTemplates($item['id'], $item['id'], $this->frm->getField('overwrite')->getChecked()); } // everything is saved, so redirect to the overview $this->redirect(BackendModel::createURLForAction('ThemeTemplates') . '&theme=' . $item['theme'] . '&report=edited-template&var=' . urlencode($item['label']) . '&highlight=row-' . $item['id']); } } }
/** * Validate the form */ private function validateForm() { // is the form submitted? if ($this->frm->isSubmitted()) { // get the status $status = \SpoonFilter::getPostValue('status', array('active', 'draft'), 'active'); // validate redirect $redirectValue = $this->frm->getField('redirect')->getValue(); if ($redirectValue == 'internal') { $this->frm->getField('internal_redirect')->isFilled(BL::err('FieldIsRequired')); } if ($redirectValue == 'external') { $this->frm->getField('external_redirect')->isURL(BL::err('InvalidURL')); } // set callback for generating an unique URL $this->meta->setURLCallback('Backend\\Modules\\Pages\\Engine\\Model', 'getURL', array($this->record['id'], $this->record['parent_id'], $this->frm->getField('is_action')->getChecked())); // cleanup the submitted fields, ignore fields that were added by hackers $this->frm->cleanupFields(); // validate fields $this->frm->getField('title')->isFilled(BL::err('TitleIsRequired')); // validate meta $this->meta->validate(); // no errors? if ($this->frm->isCorrect()) { // init var $data = null; // build data if ($this->frm->getField('is_action')->isChecked()) { $data['is_action'] = true; } if ($redirectValue == 'internal') { $data['internal_redirect'] = array('page_id' => $this->frm->getField('internal_redirect')->getValue(), 'code' => '301'); } if ($redirectValue == 'external') { $data['external_redirect'] = array('url' => BackendPagesModel::getEncodedRedirectURL($this->frm->getField('external_redirect')->getValue()), 'code' => '301'); } // build page record $page['id'] = $this->record['id']; $page['user_id'] = BackendAuthentication::getUser()->getUserId(); $page['parent_id'] = $this->record['parent_id']; $page['template_id'] = (int) $this->frm->getField('template_id')->getValue(); $page['meta_id'] = (int) $this->meta->save(); $page['language'] = BL::getWorkingLanguage(); $page['type'] = $this->record['type']; $page['title'] = $this->frm->getField('title')->getValue(); $page['navigation_title'] = $this->frm->getField('navigation_title')->getValue() != '' ? $this->frm->getField('navigation_title')->getValue() : $this->frm->getField('title')->getValue(); $page['navigation_title_overwrite'] = $this->frm->getField('navigation_title_overwrite')->getActualValue(); $page['hidden'] = $this->frm->getField('hidden')->getValue(); $page['status'] = $status; $page['publish_on'] = BackendModel::getUTCDate(null, $this->record['publish_on']); $page['created_on'] = BackendModel::getUTCDate(null, $this->record['created_on']); $page['edited_on'] = BackendModel::getUTCDate(); $page['allow_move'] = $this->record['allow_move']; $page['allow_children'] = $this->record['allow_children']; $page['allow_edit'] = $this->record['allow_edit']; $page['allow_delete'] = $this->record['allow_delete']; $page['sequence'] = $this->record['sequence']; $page['data'] = $data !== null ? serialize($data) : null; if ($this->isGod) { $page['allow_move'] = in_array('move', (array) $this->frm->getField('allow')->getValue()) ? 'Y' : 'N'; $page['allow_children'] = in_array('children', (array) $this->frm->getField('allow')->getValue()) ? 'Y' : 'N'; $page['allow_edit'] = in_array('edit', (array) $this->frm->getField('allow')->getValue()) ? 'Y' : 'N'; $page['allow_delete'] = in_array('delete', (array) $this->frm->getField('allow')->getValue()) ? 'Y' : 'N'; } // set navigation title if ($page['navigation_title'] == '') { $page['navigation_title'] = $page['title']; } // insert page, store the id, we need it when building the blocks $page['revision_id'] = BackendPagesModel::update($page); // loop blocks foreach ($this->blocksContent as $i => $block) { // add page revision id to blocks $this->blocksContent[$i]['revision_id'] = $page['revision_id']; // validate blocks, only save blocks for valid positions if (!in_array($block['position'], $this->templates[$this->frm->getField('template_id')->getValue()]['data']['names'])) { unset($this->blocksContent[$i]); } } // insert the blocks BackendPagesModel::insertBlocks($this->blocksContent); // trigger an event BackendModel::triggerEvent($this->getModule(), 'after_edit', array('item' => $page)); // save tags BackendTagsModel::saveTags($page['id'], $this->frm->getField('tags')->getValue(), $this->URL->getModule()); // build cache BackendPagesModel::buildCache(BL::getWorkingLanguage()); // active if ($page['status'] == 'active') { // init var $text = ''; // build search-text foreach ($this->blocksContent as $block) { $text .= ' ' . $block['html']; } // add to search index BackendSearchModel::saveIndex($this->getModule(), $page['id'], array('title' => $page['title'], 'text' => $text)); // everything is saved, so redirect to the overview $this->redirect(BackendModel::createURLForAction('Edit') . '&id=' . $page['id'] . '&report=edited&var=' . urlencode($page['title']) . '&highlight=row-' . $page['id']); } elseif ($page['status'] == 'draft') { // everything is saved, so redirect to the edit action $this->redirect(BackendModel::createURLForAction('Edit') . '&id=' . $page['id'] . '&report=saved-as-draft&var=' . urlencode($page['title']) . '&highlight=row-' . $page['id'] . '&draft=' . $page['revision_id']); } } } }
/** * Get the navigation-items * * @param string $language The language to use, if not provided we will use the working language. * @return array */ public static function getNavigation($language = null) { $language = $language !== null ? (string) $language : FRONTEND_LANGUAGE; // does the keys exists in the cache? if (!isset(self::$navigation[$language]) || empty(self::$navigation[$language])) { if (!is_file(FRONTEND_CACHE_PATH . '/Navigation/navigation_' . $language . '.php')) { BackendPagesModel::buildCache($language); } $navigation = array(); require FRONTEND_CACHE_PATH . '/Navigation/navigation_' . $language . '.php'; self::$navigation[$language] = $navigation; } return self::$navigation[$language]; }
/** * Get the page-keys * * @param string $language The language wherefore the navigation should be loaded, * if not provided we will load the language that was provided in the URL. * @return array */ public static function getKeys($language = null) { $language = $language !== null ? (string) $language : FRONTEND_LANGUAGE; // does the keys exists in the cache? if (!isset(self::$keys[$language]) || empty(self::$keys[$language])) { // validate file if (!is_file(FRONTEND_CACHE_PATH . '/Navigation/keys_' . $language . '.php')) { // generate the cache BackendPagesModel::buildCache($language); // recall return self::getKeys($language); } // init var $keys = array(); // require file require FRONTEND_CACHE_PATH . '/Navigation/keys_' . $language . '.php'; // validate keys if (empty($keys)) { throw new Exception('No pages for ' . $language . '.'); } // store self::$keys[$language] = $keys; } // return from cache return self::$keys[$language]; }
/** * Get the navigation-items * * @param string $language The language to use, if not provided we will use the working language. * @return array */ public static function getNavigation($language = null) { $language = $language !== null ? (string) $language : Language::getWorkingLanguage(); $cacheBuilder = BackendPagesModel::getCacheBuilder(); return $cacheBuilder->getNavigation($language); }
/** * Parse the datagrid and the reports */ protected function parse() { parent::parse(); // parse dgRecentlyEdited $this->tpl->assign('dgRecentlyEdited', $this->dgRecentlyEdited->getNumResults() != 0 ? $this->dgRecentlyEdited->getContent() : false); $this->tpl->assign('dgDrafts', $this->dgDrafts->getNumResults() != 0 ? $this->dgDrafts->getContent() : false); // parse the tree $this->tpl->assign('tree', BackendPagesModel::getTreeHTML()); // open the tree on a specific page if ($this->getParameter('id', 'int') !== null) { $this->tpl->assign('openedPageId', $this->getParameter('id', 'int')); } else { $this->tpl->assign('openedPageId', 1); } }