/**
  * Execute the action
  */
 public function execute()
 {
     // get parameters
     $this->id = $this->getParameter('id', 'int');
     // does the item exist
     if ($this->id !== null && BackendExtensionsModel::existsTemplate($this->id)) {
         // call parent, this will probably add some general CSS/JS or other required files
         parent::execute();
         // init var
         $success = false;
         // get template (we need the title)
         $item = BackendExtensionsModel::getTemplate($this->id);
         // valid template?
         if (!empty($item)) {
             // delete the page
             $success = BackendExtensionsModel::deleteTemplate($this->id);
             // trigger event
             BackendModel::triggerEvent($this->getModule(), 'after_delete_template', array('id' => $this->id));
         }
         // page is deleted, so redirect to the overview
         if ($success) {
             $this->redirect(BackendModel::createURLForAction('theme_templates') . '&theme=' . $item['theme'] . '&report=deleted-template&var=' . urlencode($item['label']));
         } else {
             $this->redirect(BackendModel::createURLForAction('theme_templates') . '&error=non-existing');
         }
     } else {
         $this->redirect(BackendModel::createURLForAction('theme_templates') . '&error=non-existing');
     }
 }
 /**
  * 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);
     }
 }
 /**
  * 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);
     }
 }
 /**
  * Load the record
  */
 private function loadData()
 {
     // get data
     $this->selectedTheme = $this->getParameter('theme', 'string');
     // build available themes
     foreach (BackendExtensionsModel::getThemes() as $theme) {
         $this->availableThemes[$theme['value']] = $theme['label'];
     }
     // determine selected theme, based upon submitted form or default theme
     $this->selectedTheme = SpoonFilter::getValue($this->selectedTheme, array_keys($this->availableThemes), BackendModel::getModuleSetting('core', 'theme', 'core'));
 }
Exemple #5
0
 /**
  * Load the data for the 2 data grids.
  */
 private function loadData()
 {
     // get all managable modules
     $modules = BackendExtensionsModel::getModules();
     // split the modules in 2 seperate data grid sources
     foreach ($modules as $module) {
         if ($module['installed']) {
             $this->installedModules[] = $module;
         } else {
             $this->installableModules[] = $module;
         }
     }
 }
Exemple #6
0
 /**
  * Execute the action
  */
 public function execute()
 {
     parent::execute();
     // get some data
     $modulesThatRequireAkismet = BackendExtensionsModel::getModulesThatRequireAkismet();
     $modulesThatRequireGoogleMaps = BackendExtensionsModel::getModulesThatRequireGoogleMaps();
     // set properties
     $this->needsAkismet = !empty($modulesThatRequireAkismet);
     $this->needsGoogleMaps = !empty($modulesThatRequireGoogleMaps);
     $this->loadForm();
     $this->validateForm();
     $this->parse();
     $this->display();
 }
Exemple #7
0
 /**
  * Checks the settings and optionally returns an array with warnings
  *
  * @return array
  */
 public static function checkSettings()
 {
     $warnings = array();
     // check if debug-mode is active
     if (SPOON_DEBUG) {
         $warnings[] = array('message' => BL::err('DebugModeIsActive'));
     }
     // check if this action is allowed
     if (BackendAuthentication::isAllowedAction('index', 'settings')) {
         // check if the fork API keys are available
         if (self::getModuleSetting('core', 'fork_api_private_key') == '' || self::getModuleSetting('core', 'fork_api_public_key') == '') {
             $warnings[] = array('message' => sprintf(BL::err('ForkAPIKeys'), BackendModel::createURLForAction('index', 'settings')));
         }
     }
     // check for extensions warnings
     $warnings = array_merge($warnings, BackendExtensionsModel::checkSettings());
     return $warnings;
 }
Exemple #8
0
 /**
  * Parse
  */
 protected function parse()
 {
     parent::parse();
     // set
     $this->record['url'] = $this->meta->getURL();
     if ($this->id == 1) {
         $this->record['url'] = '';
     }
     // parse some variables
     $this->tpl->assign('item', $this->record);
     $this->tpl->assign('isGod', $this->isGod);
     $this->tpl->assign('templates', $this->templates);
     $this->tpl->assign('positions', $this->positions);
     $this->tpl->assign('extrasData', json_encode(BackendExtensionsModel::getExtrasData()));
     $this->tpl->assign('extrasById', json_encode(BackendExtensionsModel::getExtras()));
     $this->tpl->assign('prefixURL', rtrim(BackendPagesModel::getFullURL($this->record['parent_id']), '/'));
     $this->tpl->assign('formErrors', (string) $this->frm->getErrors());
     // init var
     $showDelete = true;
     // has children?
     if (BackendPagesModel::getFirstChildId($this->record['id']) !== false) {
         $showDelete = false;
     }
     if (!$this->record['delete_allowed']) {
         $showDelete = false;
     }
     // allowed?
     if (!BackendAuthentication::isAllowedAction('delete', $this->getModule())) {
         $showDelete = false;
     }
     // show delete button
     $this->tpl->assign('showPagesDelete', $showDelete);
     // assign template
     $this->tpl->assignArray($this->templates[$this->record['template_id']], 'template');
     // parse datagrids
     $this->tpl->assign('revisions', $this->dgRevisions->getNumResults() != 0 ? $this->dgRevisions->getContent() : false);
     $this->tpl->assign('drafts', $this->dgDrafts->getNumResults() != 0 ? $this->dgDrafts->getContent() : false);
     // parse the tree
     $this->tpl->assign('tree', BackendPagesModel::getTreeHTML());
 }
 /**
  * Do we have write rights to the modules folders?
  *
  * @return bool
  */
 private function isWritable()
 {
     // check if writable
     if (!BackendExtensionsModel::isWritable(FRONTEND_MODULES_PATH)) {
         return false;
     }
     if (!BackendExtensionsModel::isWritable(BACKEND_MODULES_PATH)) {
         return false;
     }
     // everything is writeable
     return true;
 }
 /**
  * Parse.
  */
 protected function parse()
 {
     parent::parse();
     // assign theme data
     $this->tpl->assign('name', $this->currentTheme);
     $this->tpl->assign('warnings', $this->warnings);
     $this->tpl->assign('information', $this->information);
     $this->tpl->assign('showExtensionsInstallTheme', !BackendExtensionsModel::isThemeInstalled($this->currentTheme) && BackendAuthentication::isAllowedAction('install_theme'));
     // data grids
     $this->tpl->assign('dataGridTemplates', isset($this->dataGridTemplates) && $this->dataGridTemplates->getNumResults() > 0 ? $this->dataGridTemplates->getContent() : false);
 }
 /**
  * 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'));
         // 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;
                 }
                 // doublecheck 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) {
                             $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';
             $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_' . BackendLanguage::getWorkingLanguage()] = $this->extras;
             // serialize
             $item['data'] = serialize($item['data']);
             // if this is the default template make the template active
             if (BackendModel::getModuleSetting('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'] == BackendModel::getModuleSetting('core', 'theme', 'core')) {
                 BackendModel::setModuleSetting('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('theme_templates') . '&theme=' . $item['theme'] . '&report=edited-template&var=' . urlencode($item['label']) . '&highlight=row-' . $item['id']);
         }
     }
 }
Exemple #12
0
    /**
     * Install a theme.
     *
     * @param string $theme The name of the theme to be installed.
     */
    public static function installTheme($theme)
    {
        // set path to info.xml
        $pathInfoXml = FRONTEND_PATH . '/themes/' . $theme . '/info.xml';
        // load info.xml
        $infoXml = @new SimpleXMLElement($pathInfoXml, LIBXML_NOCDATA, true);
        // convert xml to useful array
        $information = BackendExtensionsModel::processThemeXml($infoXml);
        if (!$information) {
            throw new BackendException('Invalid info.xml');
        }
        // loop templates
        foreach ($information['templates'] as $template) {
            // init var
            $item = array();
            // build array
            $item['theme'] = $information['name'];
            $item['label'] = $template['label'];
            $item['path'] = $template['path'];
            $item['active'] = 'Y';
            // set format
            $item['data']['format'] = $template['format'];
            // build positions
            $item['data']['names'] = array();
            $item['data']['default_extras'] = array();
            foreach ($template['positions'] as $position) {
                // init position
                $item['data']['names'][] = $position['name'];
                $item['data']['default_extras'][$position['name']] = array();
                // add default widgets
                foreach ($position['widgets'] as $widget) {
                    // fetch extra_id for this extra
                    $extraId = (int) BackendModel::getDB()->getVar('SELECT i.id
						 FROM modules_extras AS i
						 WHERE type = ? AND module = ? AND action = ? AND data IS NULL AND hidden = ?', array('widget', $widget['module'], $widget['action'], 'N'));
                    // add extra to defaults
                    if ($extraId) {
                        $item['data']['default_extras'][$position['name']][] = $extraId;
                    }
                }
                // add default editors
                foreach ($position['editors'] as $editor) {
                    $item['data']['default_extras'][$position['name']][] = 0;
                }
            }
            // serialize the data
            $item['data'] = serialize($item['data']);
            // insert the item
            $item['id'] = self::insertTemplate($item);
        }
    }
 /**
  * Validate a submitted form and process it.
  */
 private function validateForm()
 {
     // the form is submitted
     if ($this->frm->isSubmitted()) {
         // shorten field variables
         $fileFile = $this->frm->getField('file');
         // validate the file
         if ($fileFile->isFilled(BL::err('FieldIsRequired'))) {
             // only zip files allowed
             if ($fileFile->isAllowedExtension(array('zip'), sprintf(BL::getError('ExtensionNotAllowed'), 'zip'))) {
                 // create ziparchive instance
                 $zip = new ZipArchive();
                 // try and open it
                 if ($zip->open($fileFile->getTempFileName()) === true) {
                     // zip file needs to contain some files
                     if ($zip->numFiles > 0) {
                         // get first entry (= the theme folder)
                         $file = $zip->statIndex(0);
                         // name of the module we are trying to upload
                         $themeName = trim($file['name'], '/');
                         // find info.xml
                         $infoXml = $zip->getFromName($themeName . '/info.xml');
                         // add error if info.xml is not found
                         if ($infoXml === false) {
                             $fileFile->addError(sprintf(BL::getError('NoInformationFile'), $themeName));
                         } else {
                             // parse xml
                             try {
                                 // load info.xml
                                 $infoXml = @new SimpleXMLElement($infoXml, LIBXML_NOCDATA, false);
                                 // convert xml to useful array
                                 $this->information = BackendExtensionsModel::processThemeXml($infoXml);
                                 // empty data (nothing useful)
                                 if (empty($this->information)) {
                                     $fileFile->addError(BL::getMessage('InformationFileIsEmpty'));
                                 }
                                 // check if theme name in info.xml matches folder name
                                 if ($this->information['name'] != $themeName) {
                                     $fileFile->addError(BL::err('ThemeNameDoesntMatch'));
                                 }
                             } catch (Exception $e) {
                                 $fileFile->addError(BL::getMessage('InformationFileCouldNotBeLoaded'));
                             }
                         }
                         // wow wow, you are trying to upload an already existing theme
                         if (BackendExtensionsModel::existsTheme($themeName)) {
                             $fileFile->addError(sprintf(BL::getError('ThemeAlreadyExists'), $themeName));
                         }
                         // list of validated files (these files will actually be unpacked)
                         $files = array();
                         // check every file in the zip
                         for ($i = 0; $i < $zip->numFiles; $i++) {
                             // get the file name
                             $file = $zip->statIndex($i);
                             $fileName = $file['name'];
                             // yay, in a valid directory
                             if (stripos($fileName, $themeName . '/') === 0) {
                                 // valid file, add to extraction-list
                                 $files[] = $fileName;
                             }
                         }
                     } else {
                         $fileFile->addError(BL::getError('FileIsEmpty'));
                     }
                 } else {
                     $fileFile->addError(BL::getError('CorruptedFile'));
                 }
             }
         }
         // passed all validation
         if ($this->frm->isCorrect()) {
             // unpack module files
             $zip->extractTo(FRONTEND_PATH . '/themes', $files);
             // run installer
             BackendExtensionsModel::installTheme($themeName);
             // redirect with fireworks
             $this->redirect(BackendModel::createURLForAction('themes') . '&report=theme-installed&var=' . $themeName);
         }
     }
 }
Exemple #14
0
    /**
     * Switch templates for all existing pages
     *
     * @param int $oldTemplateId The id of the new template to replace.
     * @param int $newTemplateId The id of the new template to use.
     * @param bool[optional] $overwrite Overwrite all pages with default blocks.
     */
    public static function updatePagesTemplates($oldTemplateId, $newTemplateId, $overwrite = false)
    {
        $newTemplateId = (int) $newTemplateId;
        $oldTemplateId = (int) $oldTemplateId;
        $overwrite = (bool) $overwrite;
        // fetch new template data
        $newTemplate = BackendExtensionsModel::getTemplate($newTemplateId);
        $newTemplate['data'] = @unserialize($newTemplate['data']);
        // fetch all pages
        $pages = (array) BackendModel::getDB()->getRecords('SELECT *
			 FROM pages
			 WHERE template_id = ? AND status IN (?, ?)', array($oldTemplateId, 'active', 'draft'));
        // there is no active/draft page with the old template id
        if (empty($pages)) {
            return;
        }
        // loop pages
        foreach ($pages as $page) {
            // fetch blocks
            $blocksContent = BackendPagesModel::getBlocks($page['id'], $page['revision_id'], $page['language']);
            // unset revision id
            unset($page['revision_id']);
            // change template
            $page['template_id'] = $newTemplateId;
            // save new page revision
            $page['revision_id'] = BackendPagesModel::update($page);
            // overwrite all blocks with current defaults
            if ($overwrite) {
                // init var
                $blocksContent = array();
                // fetch default blocks for this page
                $defaultBlocks = array();
                if (isset($newTemplate['data']['default_extras_' . $page['language']])) {
                    $defaultBlocks = $newTemplate['data']['default_extras_' . $page['language']];
                } elseif (isset($newTemplate['data']['default_extras'])) {
                    $defaultBlocks = $newTemplate['data']['default_extras'];
                }
                // loop positions
                foreach ($defaultBlocks as $position => $blocks) {
                    // loop blocks
                    foreach ($blocks as $extraId) {
                        // build block
                        $block = array();
                        $block['revision_id'] = $page['revision_id'];
                        $block['position'] = $position;
                        $block['extra_id'] = $extraId;
                        $block['html'] = '';
                        $block['created_on'] = BackendModel::getUTCDate();
                        $block['edited_on'] = $block['created_on'];
                        $block['visible'] = 'Y';
                        $block['sequence'] = count($defaultBlocks[$position]) - 1;
                        // add to the list
                        $blocksContent[] = $block;
                    }
                }
            } else {
                // set new page revision id
                foreach ($blocksContent as &$block) {
                    $block['revision_id'] = $page['revision_id'];
                }
            }
            // insert the blocks
            BackendPagesModel::insertBlocks($blocksContent);
        }
    }
Exemple #15
0
 /**
  * Parse
  */
 protected function parse()
 {
     parent::parse();
     // parse some variables
     $this->tpl->assign('templates', $this->templates);
     $this->tpl->assign('isGod', $this->isGod);
     $this->tpl->assign('positions', $this->positions);
     $this->tpl->assign('extrasData', json_encode(BackendExtensionsModel::getExtrasData()));
     $this->tpl->assign('extrasById', json_encode(BackendExtensionsModel::getExtras()));
     $this->tpl->assign('prefixURL', rtrim(BackendPagesModel::getFullURL(1), '/'));
     $this->tpl->assign('formErrors', (string) $this->frm->getErrors());
     // get default template id
     $defaultTemplateId = BackendModel::getModuleSetting($this->getModule(), 'default_template', 1);
     // assign template
     $this->tpl->assignArray($this->templates[$defaultTemplateId], 'template');
     // parse the form
     $this->frm->parse($this->tpl);
     // parse the tree
     $this->tpl->assign('tree', BackendPagesModel::getTreeHTML());
 }
Exemple #16
0
    /**
     * Delete a template.
     *
     * @param int $id The id of the template to delete.
     * @return bool
     */
    public static function deleteTemplate($id)
    {
        $id = (int) $id;
        // get all templates
        $templates = self::getTemplates();
        // we can't delete a template that doesn't exist
        if (!isset($templates[$id])) {
            return false;
        }
        // we can't delete the last template
        if (count($templates) == 1) {
            return false;
        }
        // we can't delete the default template
        if ($id == BackendModel::getModuleSetting('pages', 'default_template')) {
            return false;
        }
        if (BackendExtensionsModel::isTemplateInUse($id)) {
            return false;
        }
        // get db
        $db = BackendModel::getDB(true);
        // delete
        $db->delete('themes_templates', 'id = ?', $id);
        // get all non-active pages that use this template
        $ids = (array) $db->getColumn('SELECT i.revision_id
			 FROM pages AS i
			 WHERE i.template_id = ? AND i.status != ?', array($id, 'active'));
        // any items
        if (!empty($ids)) {
            // delete those pages and the linked blocks
            $db->delete('pages', 'revision_id IN(' . implode(',', $ids) . ')');
            $db->delete('pages_blocks', 'revision_id IN(' . implode(',', $ids) . ')');
        }
        return true;
    }
 /**
  * Parse.
  */
 protected function parse()
 {
     parent::parse();
     // assign module data
     $this->tpl->assign('name', $this->currentModule);
     $this->tpl->assign('warnings', $this->warnings);
     $this->tpl->assign('information', $this->information);
     $this->tpl->assign('showExtensionsInstallModule', !BackendExtensionsModel::isModuleInstalled($this->currentModule) && BackendAuthentication::isAllowedAction('install_module'));
     // data grids
     $this->tpl->assign('dataGridEvents', isset($this->dataGridEvents) && $this->dataGridEvents->getNumResults() > 0 ? $this->dataGridEvents->getContent() : false);
     $this->tpl->assign('dataGridCronjobs', isset($this->dataGridCronjobs) && $this->dataGridCronjobs->getNumResults() > 0 ? $this->dataGridCronjobs->getContent() : false);
 }