/** * Magic method allowing for shorter URLs. This attempts * to install the provided module name. * * @param string $name * @param array $args * @return string */ public function __call($name, array $args) { $this->setTitle(t('Module installation')); $this->setOutputType(self::_OT_CONFIG); // Get correct module name to install try { $name = substr($name, 0, -7); $module = new Module($name); $result = $module->install(); if ($result === true) { $this->_event->success(sprintf('Module "%s" installed successfully, please check permissions', $module->name)); return zula_redirect($this->_router->makeUrl('module_manager', 'permission', $module->name)); } else { if ($result === false) { $this->_event->error(sprintf('Module "%s" is not installable', $module->name)); } else { // Some dependency checks failed $this->setTitle(t('Module dependencies not satisfied')); $view = $this->loadView('install/failed.html'); $result['module_name'] = $module->name; $view->assign($result); return $view->getOutput(); } } } catch (Router_ArgNoExist $e) { $this->_event->error(t('Please provide a module name to install')); } catch (Module_NoExist $e) { $this->_event->error(sprintf(t('Module "%1$s" does not exist'), $name)); } return zula_redirect($this->_router->makeUrl('module_manager', 'install')); }
/** * Places a vote on a poll if the user has permission * * @return bool */ public function indexSection() { try { $oid = $this->_input->post('poll/oid'); $option = $this->_model()->getOption($oid); $poll = $this->_model()->getPoll($option['poll_id']); // Check user has permission $aclResource = 'poll-' . $poll['id']; if (!$this->_acl->resourceExists($aclResource) || !$this->_acl->check($aclResource)) { throw new Module_NoPermission(); } else { if ($this->isClosed($poll)) { $this->_event->error(t('Sorry, the poll is now closed')); } else { if ($this->hasUserVoted($this->_model()->getPollVotes($poll['id']))) { $this->_event->error(t('Sorry, you have already voted')); } else { $this->_model()->vote($option['id']); $this->_event->success(t('Your vote has been placed!')); } } } return zula_redirect($this->_router->makeUrl('poll', 'view', $poll['id'])); } catch (Input_KeyNoExist $e) { $this->_event->error(t('No option selected')); } catch (Poll_OptionNoExist $e) { $this->_event->error(t('Invalid option selected')); } catch (Poll_NoExist $e) { $this->_event->error(t('Poll does not exist')); } return zula_redirect($_SESSION['previous_url']); }
/** * Display some RSS options, and a list of the current feeds * * @return string */ public function indexSection() { if (!$this->_acl->check('rss_edit')) { throw new Module_NoPermission(); } $this->setTitle(t('RSS configuration')); $this->setOutputType(self::_OT_CONFIG); /** * Prepare form validation */ $form = new View_Form('config/main.html', 'rss'); $form->addElement('rss/global', (bool) $this->_config->get('rss/global_agg_enable'), t('Global aggregation'), new Validator_Bool()); $form->addElement('rss/default', $this->_config->get('rss/default_feed'), t('Default feed'), new Validator_Alphanumeric('_-')); $form->addElement('rss/items', $this->_config->get('rss/items_per_feed'), t('Number of items'), new Validator_Numeric()); if ($form->hasInput() && $form->isValid()) { $fd = $form->getValues('rss'); // Check default feed given is valid if ($fd['default'] != 0 && !in_array($fd['default'], array_keys($this->feeds))) { $this->_event->error(t('Please select a valid default RSS feed.')); } else { $this->_config_sql->update(array('rss/global_agg_enable', 'rss/items_per_feed', 'rss/default_feed'), array($fd['global'], $fd['items'], $fd['default'])); $this->_event->success(t('Updated RSS configuration')); return zula_redirect($this->_router->makeUrl('rss', 'config')); } } // Add additional data $form->assign(array('RSS_FEEDS' => $this->feeds)); return $form->getOutput(); }
/** * Security check to ensure only those authorized can perform * the upgrade. This is skiped when using CLI * * @return string */ public function indexSection() { $this->setTitle(t('Security check')); if ($this->_zula->getMode() == 'cli') { return zula_redirect($this->_router->makeUrl('upgrade', 'checks')); } else { if (!isset($_SESSION['upgradeStage']) || $_SESSION['upgradeStage'] !== 2) { return zula_redirect($this->_router->makeUrl('upgrade', 'version')); } } if (!empty($_SESSION['securityCode'])) { // We've got a security code, see if the file exists $file = $this->_zula->getDir('setup') . '/' . $_SESSION['securityCode'] . '.txt'; if (file_exists($file)) { unset($_SESSION['securityCode']); ++$_SESSION['upgradeStage']; return zula_redirect($this->_router->makeUrl('upgrade', 'checks')); } else { $this->_event->error(sprintf(t('Verification file "%s" does not exist'), $file)); } } if (!isset($_SESSION['securityCode'])) { $_SESSION['securityCode'] = uniqid('zula_verify_'); } $view = $this->loadView('security.html'); $view->assign(array('code' => $_SESSION['securityCode'])); return $view->getOutput(); }
/** * Shows a list of enabled and disabled sites * * @return string */ public function indexSection() { if (!$this->_acl->check('shareable_manage')) { throw new Module_NoPermission(); } $this->setTitle(t('Shareable configuration')); $this->setOutputType(self::_OT_CONFIG); // Get sites $sites = $this->_model()->getSites(); $siteCount = count($sites); // Build form with validation $form = new View_form('config/manage.html', 'shareable'); $form->addElement('shareable/order', null, t('Order'), new Validator_Length($siteCount)); $form->addElement('shareable/enabled', null, t('Enabled'), new Validator_Length(0, $siteCount), false); if ($form->hasInput() && $form->isValid()) { try { $enabledSites = $form->getValues('shareable/enabled'); } catch (View_FormValueNoExist $e) { $enabledSites = array(); } $editData = array(); foreach ($form->getValues('shareable/order') as $key => $val) { $editData[$key] = array('order' => abs($val), 'disabled' => !in_array($key, $enabledSites)); } $this->_model()->edit($editData); $this->_event->success(t('Updated config')); return zula_redirect($this->_router->makeUrl('shareable', 'config')); } $this->_theme->addJsFile('jQuery/plugins/dnd.js'); $this->addAsset('js/dnd_order.js'); $form->assign(array('sites' => $sites)); return $form->getOutput(); }
/** * Posts a new comment for a given request path, if it * is valid. Once done it will return back to the URL * * @return bool|string */ public function indexSection() { $this->setTitle(t('Post comment')); if (!$this->_acl->check('comments_post')) { throw new Module_NoPermission(); } // Check request path hash try { $hashPath = $this->_input->post('comments/hash'); if (isset($_SESSION['mod']['comments'][$hashPath])) { $requestPath = $_SESSION['mod']['comments'][$hashPath]['path']; $siteType = $_SESSION['mod']['comments'][$hashPath]['siteType']; } else { throw new Exception(); } } catch (Exception $e) { if (empty($_SESSION['previous_url'])) { $_SESSION['previous_url'] = $this->_router->getBaseUrl(); } $this->_event->error(t('Unable to post comment')); return zula_redirect($_SESSION['previous_url']); } // Build and validate form $isGuest = $this->_session->isLoggedIn() == false; $form = new View_form('form.html', 'comments'); $form->antispam(true); $form->addElement('comments/hash', $hashPath, 'hash path', new Validator_Alphanumeric()); $form->addElement('comments/name', null, t('Name'), new Validator_Length(0, 255), $isGuest); $form->addElement('comments/website', null, t('Website'), new Validator_Url(false), false); $form->addElement('comments/body', null, t('Message'), new Validator_Length(10, 4096)); if ($form->hasInput() && $form->isValid()) { $fd = $form->getValues('comments'); if ($isGuest == false) { $fd['name'] = ''; # Registered users will have their own details used } try { $commentId = $this->_model()->add($requestPath, $fd['body'], $fd['name'], $fd['website']); // Redirect back to correct place if ($siteType != $this->_router->getDefaultSiteType()) { $requestPath = $siteType . '/' . $requestPath; } $url = $this->_router->makeUrl($requestPath); if ($this->_config->get('comments/moderate')) { $this->_event->success(t('Comment is now in the moderation queue')); } else { $this->_event->success(t('Added new comment')); $url->fragment('comment-' . $commentId); } return zula_redirect($url); } catch (Exception $e) { $this->_event->error($e->getMessage()); } } $this->_session->storePrevious(false); # Don't store this URL as previous return $form->getOutput(); }
/** * Displays the upgrade successful message * * @return string */ public function indexSection() { $this->setTitle(t('Upgrade complete!')); if (!isset($_SESSION['upgradeStage']) || $_SESSION['upgradeStage'] !== 5) { return zula_redirect($this->_router->makeUrl('upgrade', 'version')); } else { $view = $this->loadView('complete.html'); $view->assign(array('project_version' => $_SESSION['project_version'])); return $view->getOutput(); } }
/** * Shows form for editing an existing comment * * @param int $commentId * @return bool|string */ public function indexSection($commentId = null) { $this->setTitle(t('Edit comment')); // Check if we are editing 'inline' or via the main config cntrlr if ($this->_router->hasArgument('inline') || $this->_input->has('post', 'comments_inline')) { $editInline = true; } else { $editInline = false; $this->setPageLinks(array(t('Manage comments') => $this->_router->makeUrl('comments', 'config'), t('Settings') => $this->_router->makeUrl('comments', 'config', 'settings'))); } try { if ($commentId === null) { $commentId = $this->_input->post('comments/id'); } $comment = $this->_model()->getDetails($commentId); } catch (Comments_NoExist $e) { $this->_event->error(t('Unable to edit comment as it does not exist')); $url = $editInline ? $this->_router->getBaseUrl() : $this->_router->makeUrl('comments', 'config'); return zula_redirect($url); } if (($comment['user_id'] == Ugmanager::_GUEST_ID || $comment['user_id'] != $this->_session->getUserId()) && !$this->_acl->check('comments_manage')) { throw new Module_NoPermission(); } // Build form and validation $form = new View_form('edit.html', 'comments', false); $form->addElement('comments/id', $comment['id'], 'ID', new Validator_Int()); $form->addElement('comments/website', $comment['website'], t('Website'), new Validator_Url(false), false); $form->addElement('comments/body', $comment['body'], t('Message'), new Validator_Length(10, 4096)); if ($form->hasInput() && $form->isValid()) { $fd = $form->getValues('comments'); unset($fd['id']); try { $commentId = $this->_model()->edit($comment['id'], $fd); $this->_event->success(sprintf(t('Edited comment #%1$d'), $comment['id'])); if ($editInline === false) { return zula_redirect($this->_router->makeUrl('comments', 'config')); } else { if ($this->_router->getSiteType() != $this->_router->getDefaultSiteType()) { $comment['url'] = $this->_router->getSiteType() . '/' . $comment['url']; } return zula_redirect($this->_router->makeUrl($comment['url'])->fragment('comment-' . $comment['id'])); } } catch (Exception $e) { $this->_event->error($e->getMessage()); } } $form->assign(array('edit_inline' => $editInline)); return $form->getOutput(); }
/** * Displays a simple message saying the installation is complete * * @return string */ public function indexSection() { $this->setTitle(t('Installation complete!')); if ($this->_zula->getMode() == 'cli') { $this->_event->success(t('Installation complete')); return true; } else { if (!isset($_SESSION['installStage']) || $_SESSION['installStage'] !== 6) { return zula_redirect($this->_router->makeUrl('install', 'checks')); } else { $view = $this->loadView('complete.html'); return $view->getOutput(); } } }
/** * Installs all available modules * * @return bool */ public function indexSection() { $this->setTitle(t('Module installation')); if ($this->_zula->getMode() != 'cli' && (!isset($_SESSION['installStage']) || $_SESSION['installStage'] !== 4)) { return zula_redirect($this->_router->makeUrl('install', 'checks')); } Module::setDirectory(_REAL_MODULE_DIR); foreach (Module::getModules(Module::_INSTALLABLE) as $modname) { $module = new Module($modname); $module->install(); } $this->setProjectDefaults(); Module::setDirectory($this->_zula->getDir('modules')); if (isset($_SESSION['installStage'])) { ++$_SESSION['installStage']; } $this->_event->success(t('Installed all available modules')); return zula_redirect($this->_router->makeUrl('install', 'settings')); }
/** * Check the environment the installer is running in to * ensure all required PHP extensions exist and the needed * files/directories are writable * * @return bool|string */ public function indexSection() { $this->setTitle(t('Pre-installation checks')); $checks = array('exts' => array('title' => t('Required PHP extensions'), 'passed' => false, 'values' => array('ctype', 'date', 'dom', 'filter', 'hash', 'pdo', 'pdo_mysql', 'pcre', 'session', 'json')), 'optExts' => array('title' => t('Optional PHP extensions'), 'passed' => true, 'values' => array('gd', 'FileInfo')), 'files' => array('title' => t('Writable files'), 'passed' => false, 'values' => array($this->_zula->getDir('config') . '/config.ini.php', $this->_zula->getDir('config') . '/layouts/admin-default.xml', $this->_zula->getDir('config') . '/layouts/main-default.xml', $this->_zula->getDir('config') . '/layouts/fpsc-admin.xml', $this->_zula->getDir('config') . '/layouts/fpsc-main.xml')), 'dirs' => array('title' => t('Writable directories'), 'passed' => false, 'values' => array($this->_zula->getDir('config') . '/layouts', $this->_zula->getDir('logs'), $this->_zula->getDir('tmp'), $this->_zula->getDir('uploads'), $this->_zula->getDir('locale')))); // Run the various checks $passed = true; foreach ($checks as $name => $details) { $results = array(); foreach ($details['values'] as $val) { switch ($name) { case 'exts': case 'optExts': $results[$val] = extension_loaded($val); break; case 'files': case 'dirs': $results[$val] = zula_is_writable($val); } } if ($name != 'optExts' && in_array(false, $results, true)) { $passed = false; $checks[$name]['passed'] = false; } else { $checks[$name]['passed'] = true; } $checks[$name]['values'] = $results; } if ($passed) { if ($this->_zula->getMode() !== 'cli') { $_SESSION['installStage'] = 2; } $this->_event->success(t('Pre-installation checks were successful')); return zula_redirect($this->_router->makeUrl('install', 'sql')); } else { if ($this->_zula->getMode() == 'cli') { $this->_zula->setExitCode(3); } $this->_event->error(t('Sorry, your server environment does not meet our requirements')); $view = $this->loadView('checks' . ($this->_zula->getMode() == 'cli' ? '-cli.txt' : '.html')); $view->assign(array('checks' => $checks, 'passed' => $passed)); return $view->getOutput(); } }
/** * Check if the currently installed version is supported * by this upgrader * * @return bool|string */ public function indexSection() { $_SESSION['upgradeStage'] = 1; if (Registry::has('sql') && in_array(_PROJECT_VERSION, $this->supportedVersions)) { if (isset($_SESSION['upgradeStage'])) { ++$_SESSION['upgradeStage']; } $_SESSION['project_version'] = _PROJECT_VERSION; // Set the event and redirect to next stage $langStr = t('Found version "%1$s" and will upgrade to "%2$s"'); $this->_event->success(sprintf($langStr, _PROJECT_VERSION, _PROJECT_LATEST_VERSION)); return zula_redirect($this->_router->makeUrl('upgrade', 'security')); } $langStr = t('Version %s is not supported by this upgrader'); $this->_event->error(sprintf($langStr, _PROJECT_VERSION)); if ($this->_zula->getMode() == 'cli') { $this->_zula->setExitCode(3); return false; } else { return zula_redirect($this->_router->makeUrl('index')); } }
/** * Displays form for attaching a module to the provied * layout name. * * @param string $name * @param array $args * @return mixed */ public function __call($name, $args) { $this->setTitle(t('Attach new module')); $this->setOutputType(self::_OT_CONFIG); if (!$this->_acl->check('content_layout_attach_module')) { throw new Module_NoPermission(); } /** * Create the layout object and get all sectors from the theme of * the site type of this layout */ $layout = new Layout(substr($name, 0, -7)); $siteType = substr($layout->getName(), 0, strpos($layout->getName(), '-')); $theme = new Theme($this->_config->get('theme/' . $siteType . '_default')); // Build the form with validation $form = new View_form('attach/attach.html', 'content_layout'); $form->action($this->_router->makeUrl('content_layout', 'attach', $layout->getName())); $form->addElement('content_layout/module', null, t('Module'), new Validator_InArray(Module::getModules())); $form->addElement('content_layout/sector', null, t('Sector'), new Validator_InArray(array_keys($theme->getSectors()))); if ($form->hasInput() && $form->isValid()) { $fd = $form->getValues('content_layout'); // Attach the new module to the correct sector try { $cntrlrId = $layout->addController($fd['sector'], array('mod' => $fd['module'])); if ($layout->save()) { $this->_event->success(t('Successfully added module')); return zula_redirect($this->_router->makeUrl('content_layout', 'edit', $layout->getName(), null, array('id' => $cntrlrId))); } else { $this->_event->error(t('Unable to save content layout file')); } } catch (Theme_SectorNoExist $e) { $this->_event->error(sprintf(t('Unable to attach module. Sector "%s" does not exist'), $fd['sector'])); } } // Assign additional data $form->assign(array('SECTORS' => $theme->getSectors(), 'LAYOUT' => $layout->getName())); return $form->getOutput(); }
/** * Update common basic settings so a user doesn't forget * to change them after installation. * * @return bool|string */ public function indexSection() { $this->setTitle(t('Basic configuration')); if ($this->_zula->getMode() != 'cli' && (!isset($_SESSION['installStage']) || $_SESSION['installStage'] !== 5)) { return zula_redirect($this->_router->makeUrl('install', 'checks')); } // Get data from either a form or CLI arguments if ($this->_zula->getMode() == 'cli') { $title = $this->_input->cli('t'); $email = $this->_input->cli('e'); $data = array('config' => array('title' => $title), 'mail' => array('outgoing' => $email, 'incoming' => $email)); } else { $form = new View_form('settings.html', 'install'); $form->addElement('settings/config/title', null, t('Site title'), new Validator_Length(0, 255)); $form->addElement('settings/meta/description', null, t('Meta description'), new Validator_Length(0, 255)); $form->addElement('settings/mail/outgoing', null, t('Outgoing email'), new Validator_Email()); $form->addElement('settings/mail/incoming', null, t('Incoming email'), new Validator_Email()); $form->addElement('settings/mail/subject_prefix', true, t('Email prefix'), new Validator_Bool()); if ($form->hasInput() && $form->isValid()) { $data = $form->getValues('settings'); } else { return $form->getOutput(); } } foreach ($data as $confRealm => $confValues) { foreach ($confValues as $key => $val) { $this->_config_sql->update($confRealm . '/' . $key, $val); } } // Update scheme/protocol that is being used $this->_config_sql->add('config/protocol', $this->_router->getScheme()); if (isset($_SESSION['installStage'])) { ++$_SESSION['installStage']; } $this->_event->success(t('Basic configuration updated')); return zula_redirect($this->_router->makeUrl('install', 'complete')); }
/** * Magic method allows for shorter URL by providing the * contact form ID * * @param string $name * @param array $args * @return string|bool */ public function __call($name, array $args) { if (!$this->inSector('SC')) { return false; } $id = substr($name, 0, -7); if ($id == 'index') { // Select the latest contact form and display that $pdoSt = $this->_sql->query('SELECT identifier FROM {PREFIX}mod_contact ORDER BY id LIMIT 1'); } else { // Change the ID into the identifier $pdoSt = $this->_sql->prepare('SELECT identifier FROM {PREFIX}mod_contact WHERE id = :id'); $pdoSt->bindValue(':id', $id, PDO::PARAM_INT); $pdoSt->execute(); } $identifier = $pdoSt->fetch(PDO::FETCH_COLUMN); $pdoSt->closeCursor(); if ($identifier == false) { throw new Module_ControllerNoExist(); } return zula_redirect($this->_router->makeUrl('contact', 'form', $identifier)); }
/** * Add the first user which will be created in the special * 'root' group. * * @return bool|string */ public function indexSection() { $this->setTitle(t('First user')); if ($this->_zula->getMode() != 'cli' && (!isset($_SESSION['installStage']) || $_SESSION['installStage'] !== 3)) { return zula_redirect($this->_router->makeUrl('install', 'checks')); } // Get data from either a form or CLI arguments if ($this->_zula->getMode() == 'cli') { $data = array('username' => $this->_input->cli('u'), 'password' => $this->_input->cli('p'), 'email' => $this->_input->cli('e')); } else { $form = new View_Form('user.html', 'install'); $form->addElement('username', null, t('Username'), array(new Validator_Alphanumeric('_-'), new Validator_Length(2, 32))); $form->addElement('password', null, t('Password'), array(new Validator_Length(4, 32), new Validator_Confirm('password2', Validator_Confirm::_POST))); $form->addElement('email', null, t('Email'), array(new Validator_Email(), new Validator_Confirm('email2', Validator_Confirm::_POST))); if ($form->hasInput() && $form->isValid()) { $data = $form->getValues(); } else { return $form->getOutput(); } } if (strcasecmp($data['username'], 'guest') === 0) { $this->_event->error(t('Username of "guest" is invalid')); if (isset($form)) { return $form->getOutput(); } else { $this->_zula->setExitCode(3); return false; } } $this->_ugmanager->editUser(2, $data); if (isset($_SESSION['installStage'])) { ++$_SESSION['installStage']; } $this->_event->success(t('First user has been created')); return zula_redirect($this->_router->makeUrl('install', 'modules')); }
/** * Pre-upgrade checks to ensure the environment is how we * require it. * * @return bool|string */ public function indexSection() { $this->setTitle(t('Pre-upgrade checks')); if ($this->_zula->getMode() != 'cli' && (!isset($_SESSION['upgradeStage']) || $_SESSION['upgradeStage'] !== 3)) { return zula_redirect($this->_router->makeUrl('upgrade', 'version')); } /** * All the checks that need to be run, and then actualy run the needed checks */ $tests = array('files' => array($this->_zula->getConfigPath() => ''), 'dirs' => array($this->_zula->getDir('config') => '')); $passed = true; foreach ($tests as $type => &$items) { foreach ($items as $itemName => $status) { $writable = zula_is_writable($itemName); $items[$itemName] = $writable; if ($writable === false) { $passed = false; } } } if ($passed) { if (isset($_SESSION['upgradeStage'])) { ++$_SESSION['upgradeStage']; } $this->_event->success(t('Pre-upgrade checks were successful')); return zula_redirect($this->_router->makeUrl('upgrade', 'migrate')); } else { if ($this->_zula->getMode() == 'cli') { $this->_zula->setExitCode(3); } $this->_event->error(t('Sorry, your server environment does not meet our requirements')); $view = $this->loadView('checks' . ($this->_zula->getMode() == 'cli' ? '-cli.txt' : '.html')); $view->assign(array('file_results' => $tests['files'], 'dir_results' => $tests['dirs'], 'passed' => $passed)); return $view->getOutput(); } }
/** * 'router_pre_parse' Hook * * @param string $url * @return string */ public function hookRouterPreParse($url) { $resolvedUrl = trim($url, '/ '); do { $break = false; if (isset($this->aliases[$resolvedUrl])) { $redirect = $this->aliases[$resolvedUrl]['redirect']; $resolvedUrl = $this->aliases[$resolvedUrl]['url']; } else { $break = true; } } while ($break === false && $url !== $resolvedUrl); if (!empty($redirect) && $url != $resolvedUrl) { if (zula_url_has_scheme($resolvedUrl)) { $url = $resolvedUrl; } else { // Don't use makeFullUrl since that will re-alias this URL! $url = $this->_router->getBaseUrl(); if ($this->_router->getType() == 'standard') { $url .= 'index.php?url='; } $url .= $resolvedUrl; } zula_redirect($url); die; # Eww, but needed. } return $resolvedUrl; }
/** * Logs the user out and then will zula_redirect back to the * appropiate page (normally the previous URL) or the * session index controller * * @return void */ public function logoutSection() { if (empty($_SESSION['previous_url'])) { $url = $this->_router->makeFullUrl('/'); } else { $url = $_SESSION['previous_url']; } $this->_session->destroy(); return zula_redirect($url); }
/** * Change settings regarding themeing and style * * @return string */ public function settingsSection() { $this->setTitle(t('Theme settings')); $this->setOutputType(self::_OT_CONFIG); // Prepare form validation $form = new View_Form('settings.html', 'theme'); $form->addElement('theme/allow_user_override', $this->_config->get('theme/allow_user_override'), t('Allow user override'), new Validator_Bool()); if ($form->hasInput() && $form->isValid()) { $allowOverride = $form->getValues('theme/allow_user_override'); try { $this->_config_sql->update('theme/allow_user_override', $allowOverride); } catch (Config_KeyNoExist $e) { $this->_config_sql->add('theme/allow_user_override', $allowOverride); } $this->_event->success(t('Updated theme settings')); return zula_redirect($this->_router->makeUrl('theme', 'index', 'settings')); } return $form->getOutput(); }
/** * Allows the user to change an expired password, however it can not be * the same as the current password! * * @return string|bool */ public function expireSection() { if (empty($_SESSION['mod']['session']['changePw'])) { throw new Module_ControllerNoExist(); } $this->setTitle(t('Your password has expired')); $form = new View_form('pwd/expire.html', 'session'); $form->addElement('session/password', null, 'Password', array(new Validator_Length(4, 32), new Validator_Confirm('session/password_confirm', Validator_Confirm::_POST), array($this, 'validatePreviousPw'))); if ($form->hasInput() && $form->isValid()) { $this->_ugmanager->editUser($this->_session->getUserId(), $form->getValues('session')); $this->_event->success(t('Your password has been successfully changed')); unset($_SESSION['mod']['session']['changePw']); return zula_redirect($this->_router->getCurrentUrl()); } return $form->getOutput(); }
/** * Handles adding a new media item to a category, either uploaded or from * external media such as a YouTube video. * * @param string $name * @param array $args * @return mixed */ public function __call($name, $args) { $type = substr($name, 0, -7); if ($type != 'external' && $type != 'upload') { throw new Module_ControllerNoExist(); } $this->setTitle(t('Add/upload new media item')); // Prepare the form validation $form = new View_form('add/form.html', 'media'); $form->addElement('media/cid', null, 'CID', new Validator_Int()); if ($type == 'external') { // Specific for external YouTube $form->addElement('media/external/service', null, t('External service'), new Validator_Length(1, 32)); $form->addElement('media/external/youtube_url', null, t('YouTube URL'), new Validator_Url()); } if ($form->hasInput() && $form->isValid()) { /** * Ensure the category exists and user has permission */ try { $category = $this->_model()->getCategory($form->getValues('media/cid')); if (!$this->_acl->check('media-cat_upload_' . $category['id'])) { throw new Module_NoPermission(); } } catch (Media_CategoryNoExist $e) { $this->_event->error(t('Media category does not exist')); return zula_redirect($this->_router->makeUrl('media')); } try { if ($type == 'upload') { $uploadedFiles = $this->handleUpload($form->getValues('media')); } else { if ($type == 'external') { $uploadedFiles = $this->handleExternal($form->getValues('media')); } } $fileCount = count($uploadedFiles); foreach ($uploadedFiles as $file) { if (!isset($file['external'])) { $file['external'] = array('service' => '', 'id' => ''); } $lastItem = $this->_model()->addItem($category['id'], $file['title'], $file['desc'], $file['type'], $file['file'], $file['thumbnail'], $file['external']['service'], $file['external']['id']); } if ($fileCount == 1) { $this->_event->success(t('Added new media item')); } else { $this->_event->success(sprintf('Added %1$d new media items', $fileCount)); } return zula_redirect($this->_router->makeUrl('media', 'manage', 'outstanding')->queryArgs(array('cid' => $category['id']))); } catch (Media_Exception $e) { $this->_event->error($e->getMessage()); } } // Redirect back to correct location $url = $this->_router->makeUrl('media', 'add'); try { $url->queryArgs(array('cid' => $this->_input->post('media/cid'))); } catch (Input_KeyNoExist $e) { } return zula_redirect($url); }
/** * Deletes all selected poll options * * @return string */ public function delOptSection() { $this->setOutputType(self::_OT_CONFIG); if (!$this->_acl->check('poll_delete')) { throw new Module_NoPermission(); } else { if (!$this->_input->checkToken()) { $this->_event->error(Input::csrfMsg()); } else { try { $poll = $this->_model()->getPoll($this->_router->getArgument('id')); // Check user has permission $resource = 'poll-' . $poll['id']; if ($this->_acl->resourceExists($resource) && $this->_acl->check($resource)) { $optionIds = $this->_input->post('option_ids'); foreach ((array) $optionIds as $oid) { try { $this->_model()->deleteOption($oid); } catch (Poll_OptionNoExist $e) { } } $this->_event->success(t('Deleted selected options')); } else { throw new Module_NoPermission(); } } catch (Input_KeyNoExist $e) { $this->_event->error(t('No options selected')); } } } if (isset($poll['id'])) { return zula_redirect($this->_router->makeUrl('poll', 'config', 'edit', null, array('id' => $poll['id']))); } else { return zula_redirect($this->_router->makeUrl('poll', 'config')); } }
/** * Update the settings based on the post-data provided * * @param string $name * @param array $args * @return string */ public function __call($name, $args) { $name = substr($name, 0, -7); if (!$this->_acl->check('settings_update')) { throw new Module_NoPermission(); } else { if (!in_array($name, $this->categories)) { throw new Module_ControllerNoExist(); } else { if (!$this->_input->checkToken()) { $this->_event->error(Input::csrfMsg()); return zula_redirect($this->_router->makeUrl('settings', $name)); } } } $this->setTitle(t('Update settings')); // Update all of the provided settings, or insert if they don't exist foreach ($this->_input->post('setting') as $key => $val) { if (strpos($key, 'cache') !== 0) { if (substr($key, 8, 9) == 'mail/smtp' && !$this->_acl->check('settings_access_smtp')) { continue; } try { $this->_config_sql->update($key, $val); } catch (Config_KeyNoExist $e) { $this->_sql->insert('config', array('name' => $key, 'value' => $val)); } } } /** * Category specific things to do when updating * the settings or other things (ACL forms etc). */ switch ($name) { case 'general': $this->_cache->delete('view_default_tags'); break; case 'cache': try { $this->_config_ini->update('cache/type', $this->_input->post('setting/cache\\/type')); $this->_config_ini->update('cache/ttl', $this->_input->post('setting/cache\\/ttl')); $this->_config_ini->update('cache/js_aggregate', $this->_input->post('setting/cache\\/js_aggregate')); $this->_config_ini->update('cache/google_cdn', $this->_input->post('setting/cache\\/google_cdn')); $this->_config_ini->writeIni(); // Clear cache if needbe if ($this->_input->post('cache_purge')) { $this->_cache->purge(); } } catch (Exception $e) { $this->_event->error($e->getMessage()); $this->_log->message($e->getMessage(), Log::L_WARNING); } break; case 'locale': try { $this->_config_ini->update('locale/default', $this->_input->post('setting/locale\\/default')); $this->_config_ini->writeIni(); } catch (Exception $e) { $this->_event->error($e->getMessage()); $this->_log->message($e->getMessage(), Log::L_WARNING); } if (($pkg = $this->_input->post('lang_pkg')) !== 'none') { // Download and install a new locale if (!zula_supports('zipExtraction')) { $this->_event->error(t('Cannot install locale, server does not support zip extraction')); } else { if (!preg_match('#^[a-z]{2}_[A-Z]{2}$#', $pkg)) { $this->_event->error(t('Provided locale is invalid, unable to install')); } else { if (!zula_is_writable($this->_zula->getDir('locale'))) { $this->_event->error(t('Locale directory is not writable, unable to install')); } else { $version = str_replace('-', '/', zula_version_map(_PROJECT_VERSION)); $zipDest = $this->_zula->getDir('tmp') . '/i18n-' . $pkg . '.zip'; $copyResult = @copy('http://releases.tangocms.org/' . $version . '/i18n/' . $pkg . '.zip', $zipDest); if ($copyResult) { // Extract the archive to the locale dir $zip = new ZipArchive(); if ($zip->open($zipDest)) { $zip->extractTo($this->_zula->getDir('locale')); $zip->close(); $this->_event->success(t('Locale successfully installed')); } else { $this->_event->error(t('Could not install locale, zip extraction failed')); } unlink($zipDest); } else { $this->_event->error(t('Failed to get remote language archive')); } } } } } break; } $this->_event->success(t('Updated settings')); return zula_redirect($this->_router->makeUrl('settings', $name)); }
/** * Creates a bridge between the Delete Selected and Update Order * functionaility, as there can only be one form with one action * * @return mixed */ public function bridgeSection() { $this->setOutputType(self::_OT_CONFIG); if (!$this->_input->checkToken()) { $this->_event->error(Input::csrfMsg()); } else { if ($this->_input->has('post', 'menu_delete')) { // Delete all selected menu items if (!$this->_acl->check('menu_delete_item')) { throw new Module_NoPermission(); } try { $delCount = 0; foreach ($this->_input->post('menu_ids') as $item) { try { $resource = 'menu-item-' . $item; if ($this->_acl->resourceExists($resource) && $this->_acl->check($resource)) { $this->_model()->deleteItem($item); ++$delCount; } } catch (Menu_ItemNoExist $e) { } } if ($delCount > 0) { $this->_event->success(t('Deleted menu items')); } } catch (Input_KeyNoExist $e) { $this->_event->error(t('No menu items selected')); } } else { if ($this->_input->has('post', 'menu_updateorder')) { // Update order of all of the menu items if (!$this->_acl->check('menu_edit_item')) { throw new Module_NoPermission(); } $execData = array(); $sqlMiddle = null; foreach ($this->_input->post('menu_order') as $item => $order) { try { $item = $this->_model()->getItem($item); $resource = 'menu-item-' . $item['id']; if ($this->_acl->resourceExists($resource) && $this->_acl->check($resource)) { // Clear cache for this menu item! $this->_cache->delete(array('menu_items_' . $item['cat_id'], 'menu_child_items_' . $item['id'])); $execData[] = $item['id']; $execData[] = abs($order); $sqlMiddle .= 'WHEN id = ? THEN ? '; } } catch (Menu_ItemNoExist $e) { } } if ($sqlMiddle !== null) { $pdoSt = $this->_sql->prepare('UPDATE {PREFIX}mod_menu SET `order` = CASE ' . $sqlMiddle . 'ELSE `order` END'); $pdoSt->execute($execData); } $this->_event->success(t('Menu order updated')); } } } try { $url = $this->_router->makeUrl('menu', 'config', 'editcat', null, array('id' => $this->_input->post('menu/cid'))); } catch (Router_ArgNoExist $e) { $url = $this->_router->makeUrl('menu', 'config'); } return zula_redirect($url); }
/** * Attempts to delete all selected users * * @return string */ public function deleteSection() { $this->setOutputType(self::_OT_CONFIG); if (!$this->_acl->check('users_delete')) { throw new Module_NoPermission(); } else { if (!$this->_input->checkToken()) { $this->_event->error(Input::csrfMsg()); } else { try { $delCount = 0; foreach ($this->_input->post('user_ids') as $uid) { try { $this->_ugmanager->deleteUser($uid); ++$delCount; } catch (Ugmanager_InvalidUser $e) { $this->_event->error(t('You can not delete the root or guest user')); } catch (Ugmanager_UserNoExist $e) { } } if ($delCount > 0) { $this->_event->success(t('Deleted Selected Users')); } } catch (Input_KeyNoExist $e) { $this->_event->error(t('No users selected')); } } } return zula_redirect($this->_router->makeUrl('users', 'config')); }
/** * Displays all users awaiting validation, these can either be accepted * or declined. * * @return string */ public function validationsSection() { $this->setTitle(t('Manage validations')); $this->setOutputType(self::_OT_CONFIG); if (!$this->_acl->check('session_manage')) { throw new Module_NoPermission(); } // Build form validation $form = new View_form('config/validation.html', 'session'); $form->addElement('session/action', null, t('Action'), new Validator_InArray(array('accept', 'decline'))); $form->addElement('session/uids', null, t('Users'), new Validator_Is('array')); if ($form->hasInput() && $form->isValid()) { // Activate or Decline/Remove all selected users foreach ($form->getValues('session/uids') as $user) { try { $user = $this->_ugmanager->getUser($user, true, true); if ($user['activate_code']) { if ($form->getValues('session/action') == 'accept') { $this->_ugmanager->editUser($user['id'], array('status' => 'active', 'activate_code' => null)); $viewFile = 'config/validation_accepted.txt'; $eventMsg = t('Selected users are now active'); } else { $this->_ugmanager->deleteUser($user['id']); $viewFile = 'config/validation_declined.txt'; $eventMsg = t('Selected users have been declined'); } $msgView = $this->loadView($viewFile); $msgView->assign(array('USERNAME' => $user['username'])); // Send off the correct email to the user, to notify them. $message = new Email_Message(t('Account Status'), $msgView->getOutput()); $message->setTo($user['email']); $email = new Email(); $email->send($message); } } catch (Ugmanager_UserNoExist $e) { // We don't really care if it does not exist, do nothing. } catch (Email_Exception $e) { $this->_event->error(t('An error occurred when sending the validation email')); $this->_log->message('Unable to send validation email: ' . $e->getMessage(), Log::L_WARNING); } } $this->_event->success($eventMsg); return zula_redirect($this->_router->makeUrl('session', 'config', 'validations')); } $form->assign(array('VALIDATIONS' => $this->_model()->getAwaitingValidation())); return $form->getOutput(); }
/** * Magic method, allows for shorter URLs. Display the specified * contact form to the user. * * @param string $name * @param array $args * @return mixed */ public function __call($name, array $args) { $this->setTitle(t('Contact')); $this->setOutputType(self::_OT_COLLECTIVE); // Get the correct form identifier to display try { $contact = $this->_model()->getForm(substr($name, 0, -7), false); } catch (Contact_NoExist $e) { throw new Module_ControllerNoExist(); } if (!$this->_acl->check('contact-form-' . $contact['id'])) { throw new Module_NoPermission(); } $this->setTitle($contact['name']); /** * Prepare form validation, if needed */ $fields = $this->_model()->getFormFields($contact['id']); if ($fields) { $form = new View_form('contact.html', 'contact'); $form->caseSensitive()->antispam(true); $form->addElement('contact/email', $this->_session->getUser('email'), t('Email address'), new Validator_Email()); foreach ($fields as &$tmpField) { $tmpField['options'] = zula_split_config($tmpField['options']); // Use correct validation for the given types. switch ($tmpField['type']) { case 'textbox': case 'password': $validator = new Validator_Length(1, 300); break; case 'textarea': $validator = new Validator_Length(1, 3000); break; case 'radio': case 'select': case 'checkbox': $validator = new Validator_InArray(array_values($tmpField['options'])); break; default: $validator = null; } $form->addElement('contact/fields/' . $tmpField['id'], null, $tmpField['name'], $validator, (bool) $tmpField['required']); } if ($form->hasInput() && $form->isValid()) { /** * Send out the contact form email */ $mailBody = $this->loadView('email_body.txt'); $mailBody->assign(array('form' => $contact, 'fields' => $fields, 'email' => $form->getValues('contact/email'))); $mailBody->assignHtml(array('contact' => $form->getValues('contact'))); try { $message = new Email_message(sprintf(t('Contact form "%s"'), $contact['name']), $mailBody->getOutput(), 'text/plain'); $message->setTo($contact['email']); $message->setReplyTo($form->getValues('contact/email')); $email = new Email(); $email->send($message); $this->_event->success(t('Contact form sent successfully')); } catch (Email_Exception $e) { $this->_event->error(t('Sorry, there was a technical error while sending the contact form')); $this->_log->message($e->getMessage(), Log::L_WARNING); } return zula_redirect($this->_router->getParsedUrl()); } } else { $form = $this->loadView('contact.html'); } // Parse the body $editor = new Editor($contact['body']); unset($contact['body']); $form->assignHtml(array('body' => $editor->parse())); $form->assign(array('details' => $contact, 'fields' => $fields)); return $form->getOutput(); }
/** * Manages the Module (Hook) Load Order * * @return string|bool */ public function loadorderSection() { $this->setTitle(t('Module load order')); $this->setOutputType(self::_OT_CONFIG); // Build form validation $form = new View_form('config/loadorder.html', 'module_manager'); $form->action($this->_router->makeUrl('module_manager', 'config', 'loadorder')); $form->addElement('module_manager/modules', null, t('Modules'), new Validator_Between(0, 1000)); if ($form->hasInput() && $form->isValid()) { foreach ($form->getValues('module_manager/modules') as $tmpModule => $order) { try { $module = new Module($tmpModule); $module->setLoadOrder($order); } catch (Module_NoExist $e) { } } $this->_event->success(t('Updated module load order')); return zula_redirect($this->_router->makeUrl('module_manager', 'config', 'loadorder')); } $this->_theme->addJsFile('jQuery/plugins/dnd.js'); $this->addAsset('js/dnd_order.js'); $form->assign(array('MODULES' => Hooks::getLoadedModules())); return $form->getOutput(); }
/** * Manages settings for comments * * @return string|bool */ public function settingsSection() { $this->setTitle(t('Comments settings')); $this->setOutputType(self::_OT_CONFIG); if (!$this->_acl->check('comments_manage')) { throw new Module_NoPermission(); } // Build form and validation $form = new View_form('config/settings.html', 'comments'); $form->action($this->_router->makeUrl('comments', 'config', 'settings')); $form->addElement('comments/moderate', $this->_config->get('comments/moderate'), t('Moderate comments'), new Validator_Bool()); if ($form->hasInput() && $form->isValid()) { foreach ($form->getValues('comments') as $key => $val) { $this->_config_sql->update('comments/' . $key, $val); } $this->_event->success(t('Updated comment settings')); return zula_redirect($this->_router->makeUrl('comments', 'config', 'settings')); } return $form->getOutput(); }