public static function fetchPrototypes() { $prototypes = PageManager::fetchPageByType('prototype'); // Make sure to return an array of pages if (!is_array(current($prototypes))) { $prototypes = array($prototypes); } return $prototypes; }
public static function getPageList($page_id = 0) { $pagesData = PageManager::fetchPageByType(extension_RestEngine::pageType()); if (!is_array($pagesData[0])) { $pagesArray[0] = $pagesData; } else { $pagesArray = $pagesData; } $exclude = RestResourceManager::getExistingRestPages(); $pageOptions = array(); foreach ($pagesArray as $page) { $selectedPage = $page_id == $page['id'] ? true : false; //Disable select options for pages that already are set, allowing the current page and any pages that aren't already set up to still be selected. $attr = is_numeric(array_search($page['id'], $exclude)) && $page_id != $page['id'] ? array('disabled' => 'disabled') : null; $pageOptions[] = array($page['id'], $selectedPage, $page['title'], null, null, $attr); } return $pageOptions; }
/** * This function attempts to resolve the given page in to it's Symphony page. If no * page is given, it is assumed the 'index' is being requested. Before a page row is * returned, it is checked to see that if it has the 'admin' type, that the requesting * user is authenticated as a Symphony author. If they are not, the Symphony 403 * page is returned (whether that be set as a user defined page using the page type * of 403, or just returning the Default Symphony 403 error page). Any URL parameters * set on the page are added to the `$env` variable before the function returns an * associative array of page details such as Title, Content Type etc. * * @uses FrontendPrePageResolve * @see __isSchemaValid() * @param string $page * The URL of the current page that is being Rendered as returned by `getCurrentPage()`. * If no URL is provided, Symphony assumes the Page with the type 'index' is being * requested. * @return array * An associative array of page details */ public function resolvePage($page = null) { if ($page) { $this->_page = $page; } $row = null; /** * Before page resolve. Allows manipulation of page without redirection * @delegate FrontendPrePageResolve * @param string $context * '/frontend/' * @param mixed $row * @param FrontendPage $page * An instance of this FrontendPage */ Symphony::ExtensionManager()->notifyMembers('FrontendPrePageResolve', '/frontend/', array('row' => &$row, 'page' => &$this->_page)); // Default to the index page if no page has been specified if ((!$this->_page || $this->_page == '//') && is_null($row)) { $row = PageManager::fetchPageByType('index'); } else { if (is_null($row)) { $page_extra_bits = array(); $pathArr = preg_split('/\\//', trim($this->_page, '/'), -1, PREG_SPLIT_NO_EMPTY); $handle = array_pop($pathArr); do { $path = implode('/', $pathArr); if ($row = PageManager::resolvePageByPath($handle, $path)) { $pathArr[] = $handle; break 1; } else { $page_extra_bits[] = $handle; } } while ($handle = array_pop($pathArr)); if (empty($pathArr)) { return false; } if (!$this->__isSchemaValid($row['params'], $page_extra_bits)) { return false; } } } // Process the extra URL params $url_params = preg_split('/\\//', $row['params'], -1, PREG_SPLIT_NO_EMPTY); foreach ($url_params as $var) { $this->_env['url'][$var] = NULL; } if (isset($page_extra_bits)) { if (!empty($page_extra_bits)) { $page_extra_bits = array_reverse($page_extra_bits); } for ($i = 0, $ii = count($page_extra_bits); $i < $ii; $i++) { $this->_env['url'][$url_params[$i]] = str_replace(' ', '+', $page_extra_bits[$i]); } } if (!is_array($row) || empty($row)) { return false; } $row['type'] = PageManager::fetchPageTypes($row['id']); // Make sure the user has permission to access this page if (!$this->is_logged_in && in_array('admin', $row['type'])) { $row = PageManager::fetchPageByType('403'); if (empty($row)) { GenericExceptionHandler::$enabled = true; throw new SymphonyErrorPage(__('Please login to view this page.') . ' <a href="' . SYMPHONY_URL . '/login/">' . __('Take me to the login page') . '</a>.', __('Forbidden'), 'generic', array('header' => 'HTTP/1.0 403 Forbidden')); } $row['type'] = PageManager::fetchPageTypes($row['id']); } $row['filelocation'] = PageManager::resolvePageFileLocation($row['path'], $row['handle']); return $row; }
/** * This function attempts to resolve the given page in to it's Symphony page. If no * page is given, it is assumed the 'index' is being requested. Before a page row is * returned, it is checked to see that if it has the 'admin' type, that the requesting * user is authenticated as a Symphony author. If they are not, the Symphony 403 * page is returned (whether that be set as a user defined page using the page type * of 403, or just returning the Default Symphony 403 error page). Any URL parameters * set on the page are added to the `$env` variable before the function returns an * associative array of page details such as Title, Content Type etc. * * @uses FrontendPrePageResolve * @see __isSchemaValid() * @param string $page * The URL of the current page that is being Rendered as returned by `getCurrentPage()`. * If no URL is provided, Symphony assumes the Page with the type 'index' is being * requested. * @return array * An associative array of page details */ public function resolvePage($page = null) { if ($page) { $this->_page = $page; } $row = null; /** * Before page resolve. Allows manipulation of page without redirection * @delegate FrontendPrePageResolve * @param string $context * '/frontend/' * @param mixed $row * @param FrontendPage $page * An instance of this FrontendPage */ Symphony::ExtensionManager()->notifyMembers('FrontendPrePageResolve', '/frontend/', array('row' => &$row, 'page' => &$this->_page)); // Default to the index page if no page has been specified if ((!$this->_page || $this->_page == '//') && is_null($row)) { $row = PageManager::fetchPageByType('index'); } else { if (is_null($row)) { $page_extra_bits = array(); $pathArr = preg_split('/\\//', trim($this->_page, '/'), -1, PREG_SPLIT_NO_EMPTY); $handle = array_pop($pathArr); do { $path = implode('/', $pathArr); if ($row = PageManager::resolvePageByPath($handle, $path)) { $pathArr[] = $handle; break 1; } else { $page_extra_bits[] = $handle; } } while ($handle = array_pop($pathArr)); // If the `$pathArr` is empty, that means a page hasn't resolved for // the given `$page`, however in some cases the index page may allow // parameters, so we'll check. if (empty($pathArr)) { // If the index page does not handle parameters, then return false // (which will give up the 404), otherwise treat the `$page` as // parameters of the index. RE: #1351 $index = PageManager::fetchPageByType('index'); if (!$this->__isSchemaValid($index['params'], $page_extra_bits)) { return false; } else { $row = $index; } } else { if (!$this->__isSchemaValid($row['params'], $page_extra_bits)) { return false; } } } } // Process the extra URL params $url_params = preg_split('/\\//', $row['params'], -1, PREG_SPLIT_NO_EMPTY); foreach ($url_params as $var) { $this->_env['url'][$var] = NULL; } if (isset($page_extra_bits)) { if (!empty($page_extra_bits)) { $page_extra_bits = array_reverse($page_extra_bits); } for ($i = 0, $ii = count($page_extra_bits); $i < $ii; $i++) { $this->_env['url'][$url_params[$i]] = str_replace(' ', '+', $page_extra_bits[$i]); } } if (!is_array($row) || empty($row)) { return false; } $row['type'] = PageManager::fetchPageTypes($row['id']); // Make sure the user has permission to access this page if (!$this->is_logged_in && in_array('admin', $row['type'])) { $row = PageManager::fetchPageByType('403'); if (empty($row)) { Frontend::instance()->throwCustomError(__('Please login to view this page.') . ' <a href="' . SYMPHONY_URL . '/login/">' . __('Take me to the login page') . '</a>.', __('Forbidden'), Page::HTTP_STATUS_FORBIDDEN); } $row['type'] = PageManager::fetchPageTypes($row['id']); } $row['filelocation'] = PageManager::resolvePageFileLocation($row['path'], $row['handle']); return $row; }
/** * Redirect to maintenance page, if site is in maintenance and the user is not logged in * * @param array $context * delegate context */ public function __checkForMaintenanceMode($context) { if (!Symphony::Engine()->isLoggedIn() && Symphony::Configuration()->get('enabled', 'maintenance_mode') === 'yes') { // Check the IP white list $whitelist = Symphony::Configuration()->get('ip_whitelist', 'maintenance_mode'); if (strlen(trim($whitelist)) > 0) { $whitelist = explode(' ', $whitelist); if (in_array($_SERVER['REMOTE_ADDR'], $whitelist)) { return; } } // Check if useragent is allowed $useragent = Symphony::Configuration()->get('useragent_whitelist', 'maintenance_mode'); if (strlen(trim($useragent)) > 0) { $useragent = json_decode($useragent); if (in_array($_SERVER['HTTP_USER_AGENT'], $useragent)) { return; } } // Find custom maintenance page $row = PageManager::fetchPageByType('maintenance'); if (is_array($row) && isset($row[0])) { // There's more than a `maintenance` page $row = $row[0]; } $context['row'] = $row; // Default maintenance message if (empty($context['row'])) { Symphony::Engine()->throwCustomError(__('Website Offline'), __('This site is currently in maintenance. Please check back at a later date.')); } } }
public function checkFrontendPagePermissions($context) { $isLoggedIn = false; $errors = array(); $action = null; // Checks $_REQUEST to see if a Member Action has been requested, // member-action['login'] and member-action['logout']/?member-action=logout // are the only two supported at this stage. if (isset($_REQUEST['member-action']) && is_array($_REQUEST['member-action'])) { list($action) = array_keys($_REQUEST['member-action']); } else { if (isset($_REQUEST['member-action'])) { $action = $_REQUEST['member-action']; } } // Check to see a Member is already logged in. $isLoggedIn = $this->getMemberDriver()->isLoggedIn($errors); // Logout if (trim($action) == 'logout') { /** * Fired just before a member is logged out (and page redirection), * this delegate provides the current Member ID * * @delegate MembersPreLogout * @param string $context * '/frontend/' * @param integer $member_id * The Member ID of the member who is about to logged out */ Symphony::ExtensionManager()->notifyMembers('MembersPreLogout', '/frontend/', array('member_id' => $this->getMemberDriver()->getMemberID())); $this->getMemberDriver()->logout(); // If a redirect is provided, redirect to that, otherwise return the user // to the index of the site. Issue #51 & #121 if (isset($_REQUEST['redirect'])) { redirect($_REQUEST['redirect']); } redirect(URL); } else { if (trim($action) == 'login' && !is_null($_POST['fields'])) { // If a Member is already logged in and another Login attempt is requested // log the Member out first before trying to login with new details. if ($isLoggedIn) { $this->getMemberDriver()->logout(); } if ($this->getMemberDriver()->login($_POST['fields'])) { /** * Fired just after a Member has successfully logged in, this delegate * provides the current Member ID. This delegate is fired just before * the page redirection (if it is provided) * * @delegate MembersPostLogin * @param string $context * '/frontend/' * @param integer $member_id * The Member ID of the member who just logged in. * @param Entry $member * The Entry object of the logged in Member. */ Symphony::ExtensionManager()->notifyMembers('MembersPostLogin', '/frontend/', array('member_id' => $this->getMemberDriver()->getMemberID(), 'member' => $this->getMemberDriver()->getMember())); if (isset($_POST['redirect'])) { redirect($_POST['redirect']); } } else { self::$_failed_login_attempt = true; /** * A failed Member login attempt * * @delegate MembersLoginFailure * @param string $context * '/frontend/' * @param string $username * The username of the Member who attempted to login. */ Symphony::ExtensionManager()->notifyMembers('MembersLoginFailure', '/frontend/', array('username' => Symphony::Database()->cleanValue($_POST['fields'][extension_Members::getFieldHandle('identity')]))); } } } $this->Member->initialiseMemberObject(); $hasRoles = FieldManager::isFieldUsed(extension_Members::getFieldType('role')); if ($isLoggedIn && $this->getMemberDriver()->getMember() instanceof Entry) { $this->getMemberDriver()->updateSystemTimezoneOffset(); if ($hasRoles) { $role_field = extension_Members::getField('role'); if ($role_field) { $role_data = $this->getMemberDriver()->getMember()->getData($role_field->get('id')); } } } // If there is no role field, or a Developer is logged in, return, as Developers // should be able to access every page. Handles Symphony 2.4 or Symphony 2.5 $isDeveloper = method_exists(Symphony::Engine(), 'Author') ? Symphony::Engine()->Author() instanceof Author && Symphony::Engine()->Author()->isDeveloper() : Symphony::Engine()->Author instanceof Author && Symphony::Engine()->Author->isDeveloper(); if (!$hasRoles || $isDeveloper) { return; } $role_id = $isLoggedIn ? $role_data['role_id'] : Role::PUBLIC_ROLE; $role = RoleManager::fetch($role_id); if ($role instanceof Role && !$role->canAccessPage((int) $context['page_data']['id'])) { // User has no access to this page, so look for a custom 403 page if ($row = PageManager::fetchPageByType('403')) { $row['type'] = PageManager::fetchPageTypes($row['id']); $row['filelocation'] = PageManager::resolvePageFileLocation($row['path'], $row['handle']); $context['page_data'] = $row; return; } else { // No custom 403, just throw default 403 GenericExceptionHandler::$enabled = true; Frontend::instance()->throwCustomError(__('The page you have requested has restricted access permissions.'), __('Forbidden'), Page::HTTP_STATUS_FORBIDDEN); } } }
/** * Redirect to maintenance page, if site is in maintenance and the user is not logged in * * @param array $context * delegate context */ public function __checkForMaintenanceMode($context) { if (!Symphony::Engine()->isLoggedIn() && Symphony::Configuration()->get('enabled', 'maintenance_mode') == 'yes') { // Find custom maintenance page $row = PageManager::fetchPageByType('maintenance'); if (is_array($row) && isset($row[0])) { // There's more than a `maintenance` page $row = $row[0]; } $context['row'] = $row; // Default maintenance message if (empty($context['row'])) { Symphony::Engine()->customError(__('Website Offline'), __('This site is currently in maintenance. Please check back at a later date.')); } } }
public function frontendPageResolved($context) { if (!(int) ($page_id = $context['page_data']['id'])) { return; } // Don't show prototype pages to normal visitors if (!Frontend::instance()->isLoggedIn() && PagePrototypes::isPagePrototype($page_id)) { $forbidden = PageManager::fetchPageByType('403'); // User has no access to this page, so look for a custom 403 page if (!empty($forbidden)) { $forbidden['type'] = FrontendPage::fetchPageTypes($forbidden['id']); $forbidden['filelocation'] = FrontendPage::resolvePageFileLocation($forbidden['path'], $forbidden['handle']); $context['page_data'] = $forbidden; return; } else { GenericExceptionHandler::$enabled = true; throw new SymphonyErrorPage(__('The page you have requested has restricted access permissions.'), __('Forbidden'), 'generic', array('header' => 'HTTP/1.0 403 Forbidden')); } } // Override context if the page is connected to a prototype. // This is not really necesary because when a prototype gets changed in the backend, the referenced pages get changed as well. $prototype = PagePrototypes::fetchPrototypeOfPage($page_id); if (!empty($prototype)) { $context['page_data']['params'] = $prototype['params']; $context['page_data']['data_sources'] = $prototype['data_sources']; $context['page_data']['events'] = $prototype['events']; $context['page_data']['type'] = $prototype['type']; $context['page_data']['filelocation'] = PageManager::resolvePageFileLocation($prototype['path'], $prototype['handle']); } }
/** * The render function will take a `FrontendPageNotFoundException` Exception and * output a HTML page. This function first checks to see if their is a page in Symphony * that has been given the '404' page type, otherwise it will just use the default * Symphony error page template to output the exception * * @param FrontendPageNotFoundException $e * The Exception object * @return string * An HTML string */ public static function render(Exception $e) { $page = PageManager::fetchPageByType('404'); if (is_null($page['id'])) { parent::render(new SymphonyErrorPage($e->getMessage(), __('Page Not Found'), 'generic', array('header' => 'HTTP/1.0 404 Not Found'))); } else { $url = '/' . PageManager::resolvePagePath($page['id']) . '/'; $output = Frontend::instance()->display($url); header(sprintf('Content-Length: %d', strlen($output))); echo $output; exit; } }
/** * The render function will take a `FrontendPageNotFoundException` Exception and * output a HTML page. This function first checks to see if their is a page in Symphony * that has been given the '404' page type, otherwise it will just use the default * Symphony error page template to output the exception * * @param Exception $e * The Exception object * @throws FrontendPageNotFoundException * @throws SymphonyErrorPage * @return string * An HTML string */ public static function render(Exception $e) { $page = PageManager::fetchPageByType('404'); $previous_exception = Frontend::instance()->getException(); // No 404 detected, throw default Symphony error page if (is_null($page['id'])) { parent::render(new SymphonyErrorPage($e->getMessage(), __('Page Not Found'), 'generic', array(), Page::HTTP_STATUS_NOT_FOUND)); // Recursive 404 } elseif (isset($previous_exception)) { parent::render(new SymphonyErrorPage(__('This error occurred whilst attempting to resolve the 404 page for the original request.') . ' ' . $e->getMessage(), __('Page Not Found'), 'generic', array(), Page::HTTP_STATUS_NOT_FOUND)); // Handle 404 page } else { $url = '/' . PageManager::resolvePagePath($page['id']) . '/'; Frontend::instance()->setException($e); $output = Frontend::instance()->display($url); echo $output; exit; } }