public function search(){ $view = $this->getView(); $request = $this->getPageRequest(); if(!$request->getParameter('q')){ // Simply redirect to the sitemap if no query was provided. \Core\redirect('/page/sitemap'); } $search = new \Core\Search\SearchResults(); $search->query = $request->getParameter('q'); $results = PageModel::Search($request->getParameter('q'), ['indexable = 1']); $isadmin = \Core\user()->checkAccess('g:admin'); foreach($results as $r){ /** @var Core\Search\ModelResult $r */ /** @var PageModel $model */ $model = $r->_model; if(!$model->isPublished() && !$isadmin){ // The page is not published and the user is not an admin, skip! continue; } // Skip the sitemap page iteself, as that will probably contain most of the keywords. if($model->get('baseurl') == '/page/sitemap'){ continue; } if(!\Core\user()->checkAccess($model->get('access'))){ // User does not have access to this page! continue; } if($r->relevancy < 10){ // Not a good enough of a match. continue; } // Otherwise. $search->addResult($r); } $search->sortResults(); HookHandler::DispatchHook('/core/page/search/results', $search); $view->title = 'Site Search'; $view->assign('query', $request->getParameter('q')); $view->assign('results', $search); }
/** * Set a JSON error message and optionally redirect if the page is not an ajax request. * * @param $code * @param $message * @param $redirect * * @return int */ public function sendJSONError($code, $message, $redirect){ $view = $this->getView(); $request = $this->getPageRequest(); if($request->isAjax()){ $view->mode = View::MODE_PAGEORAJAX; $view->jsondata = ['status' => $code, 'message' => $message]; $view->error = $code; } else{ \Core\set_message($message, 'error'); if($redirect){ \Core\redirect($redirect); } else{ \Core\go_back(); } } }
/** * Interface to "train" the system to learn spam keywords. * * A block of content can be submitted to this page, where the user has the options to score phrases and words. */ public function spam_train() { $view = $this->getView(); $request = $this->getPageRequest(); if (!\Core\user()->checkAccess('g:admin')) { return View::ERROR_ACCESSDENIED; } $view->title = 'Spam Training'; $view->mastertemplate = 'admin'; if ($request->isPost() && $request->getPost('keywords')) { foreach ($_POST['keywords'] as $w => $s) { if ($s == 0) { // Populating the database with a bunch of neutral scores is pointless. continue; } $k = SpamHamKeywordModel::Construct($w); $k->set('score', $s); $k->save(); } \Core\set_message('Trained keywords successfully!', 'success'); \Core\redirect('/security/spam/keywords'); } elseif (!$request->isPost() || !$request->getPost('content')) { // Step 1 for training with content, provide a text area to submit content! $view->templatename = 'pages/security/spam_train_1.tpl'; $form = new Form(); $form->addElement('textarea', ['name' => 'content', 'value' => '', 'title' => t('STRING_CONTENT'), 'description' => 'Paste in the content to parse for keywords. You will have the ability to fine-tune specific keywords on the next page.', 'rows' => 6]); $form->addElement('submit', ['value' => 'Next']); $view->assign('form', $form); } else { // Step 2, $view->templatename = 'pages/security/spam_train_2.tpl'; $check = new \SecuritySuite\SpamCan\SpamCheck($request->getPost('content')); $keywords = $check->getKeywords(); $form = new Form(); $form->set('orientation', 'grid'); foreach ($keywords as $dat) { if ($dat['score'] != 0) { // Skip keywords that are already weighted. continue; } if (preg_match_all('# #', $dat['keyword']) == 1) { // Skip keywords that only contain one space. // Here, we only want single words and 3-word phrases. continue; } $form->addElement('text', ['name' => 'keywords[' . $dat['keyword'] . ']', 'title' => $dat['keyword'], 'value' => 0]); } $form->addElement('submit', ['value' => 'Train!']); $view->assign('form', $form); } }
/** * Set a requested theme and template as default for the site. */ public function setdefault() { $request = $this->getPageRequest(); $view = $this->getView(); $themename = $this->getPageRequest()->getParameter(0); $template = $this->getPageRequest()->getParameter('template'); // If the browser prefers JSON data, send that. if ($request->prefersContentType(View::CTYPE_JSON)) { $view->contenttype = View::CTYPE_JSON; } // Validate the theme name if (!\Theme\validate_theme_name($themename)) { \Core\set_message('Invalid theme requested', 'error'); \Core\go_back(); } $theme = ThemeHandler::GetTheme($themename); if ($template) { // The template itself can be ignored. if (!\Theme\validate_template_name($themename, $template)) { \Core\set_message('Invalid template requested', 'error'); \Core\go_back(); } } else { // and the default one is used otherwise. $allskins = $theme->getSkins(); $template = $allskins[0]['file']; } if (Core::IsComponentAvailable('multisite') && MultiSiteHelper::GetCurrentSiteID()) { $config_default = ConfigHandler::GetConfig('/theme/default_template'); $config_selected = ConfigHandler::GetConfig('/theme/selected'); if ($config_default->get('overrideable') == 0) { // It's a child site and the admin never gave them permission to change default themes! \Core\set_message('Unable to set the default template on a child site, please ensure that the "/theme/default_template" config is set to be overrideable!', 'error'); \Core\go_back(); } if ($config_selected->get('overrideable') == 0) { // It's a child site and the admin never gave them permission to change default themes! \Core\set_message('Unable to set the selected theme on a child site, please ensure that the "/theme/selected" config is set to be overrideable!', 'error'); \Core\go_back(); } } if ($request->isPost()) { if ($themename != ConfigHandler::Get('/theme/selected')) { // The theme changed, change the admin skin too! ConfigHandler::Set('/theme/default_admin_template', $template); // And the email skin. ConfigHandler::Set('/theme/default_email_template', ''); } ConfigHandler::Set('/theme/default_template', $template); ConfigHandler::Set('/theme/selected', $themename); // reinstall theme and zee assets $t = ThemeHandler::GetTheme(); if (($change = $t->reinstall(0)) !== false) { SystemLogModel::LogInfoEvent('/updater/theme/reinstall', 'Theme ' . $t->getName() . ' reinstalled successfully', implode("\n", $change)); } \Core\set_message('Updated default theme', 'success'); \Core\redirect('/theme'); } $view->assign('theme', $themename); $view->assign('template', $template); }
/** * Redirect the user to another page via sending the Location header. * Prevents any POST data from being reloaded. * * @deprecated 2013.06.11 Please use the namespaced versions. * * @param string $page The page URL to redirect to * @param int $code The HTTP status code to send to the browser, MUST be 301 or 302. * * @throws \Exception * * @return bool|null False on failure, success will halt the script. */ static public function Redirect($page, $code = 302) { trigger_error('Core::Redirect is deprecated, please use \\Core\\redirect() instead.', E_USER_DEPRECATED); \Core\redirect($page, $code); }
public function widgetinstances_save(){ $view = $this->getView(); $request = $this->getPageRequest(); if(!\Core\user()->checkAccess('p:/core/widgets/manage')){ return View::ERROR_ACCESSDENIED; } if(!$request->isPost()){ return View::ERROR_BADREQUEST; } $counter = 0; $changes = ['created' => 0, 'updated' => 0, 'deleted' => 0]; $selected = $_POST['selected']; // For the incoming options, I want an explicit NULL if it's empty. $theme = $_POST['theme'] == '' ? null : $_POST['theme']; $skin = $_POST['skin'] == '' ? null : $_POST['skin']; $_POST['skin']; $template = $_POST['template'] == '' ? null : $_POST['template']; $baseurl = $_POST['page_baseurl'] == '' ? null : $_POST['page_baseurl']; foreach($_POST['widgetarea'] as $id => $dat){ // Merge in the global information for this request //$dat['theme'] = $theme; //$dat['skin'] = $skin; $dat['template'] = $template; $dat['page_baseurl'] = $baseurl; $dat['weight'] = ++$counter; $dat['access'] = $dat['widgetaccess']; $w = WidgetModel::Construct($dat['baseurl']); $dat['site'] = $w->get('site'); if(strpos($id, 'new') !== false){ $w = new WidgetInstanceModel(); $w->setFromArray($dat); $w->save(); $changes['created']++; } elseif(strpos($id, 'del-') !== false){ $w = new WidgetInstanceModel(substr($id, 4)); $w->delete(); // Reset the counter back down one notch since this was a deletion request. --$counter; $changes['deleted']++; } else{ $w = new WidgetInstanceModel($id); $w->setFromArray($dat); if($w->save()) $changes['updated']++; } } // foreach($_POST['widgetarea'] as $id => $dat) // Display some human friendly status message. if($changes['created'] || $changes['updated'] || $changes['deleted']){ $changetext = []; if($changes['created'] == 1) $changetext[] = 'One widget added'; elseif($changes['created'] > 1) $changetext[] = $changes['created'] . ' widgets added'; if($changes['updated'] == 1) $changetext[] = 'One widget updated'; elseif($changes['updated'] > 1) $changetext[] = $changes['updated'] . ' widgets updated'; if($changes['deleted'] == 1) $changetext[] = 'One widget deleted'; elseif($changes['deleted'] > 1) $changetext[] = $changes['deleted'] . ' widgets deleted'; \Core\set_message(implode('<br/>', $changetext), 'success'); } else{ \Core\set_message('t:MESSAGE_INFO_NO_CHANGES_PERFORMED'); } if($baseurl){ \Core\redirect($baseurl); } else{ \Core\redirect('/admin/widgets?selected=' . $selected); } }
/** * Execute the controller and method this page request points to. */ public function execute() { \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Starting PageRequest->execute()'); if($this->isCacheable()){ $uakey = \Core\UserAgent::Construct()->getPseudoIdentifier(); $urlkey = $this->host . $this->uri; $expires = $this->getPageModel()->get('expires'); $key = 'page-cache-' . md5($urlkey . '-' . $uakey); $cached = \Core\Cache::Get($key, $expires); if($cached && $cached instanceof View){ $this->_pageview = $cached; $this->_cached = true; return; } } // Anything that needs to fire off *before* the page is rendered. // This includes widgets, script addons, and anything else that needs a CurrentPage. HookHandler::DispatchHook('/core/page/preexecute'); // Load the underlying controller. $pagedat = $this->splitParts(); /** @var View $view The valid view object for this page */ $view = $this->getView(); // The controller must exist first! // (note, the SplitParts logic already takes care of the "Is this a valid controller" logic) if (!(isset($pagedat['controller']) && $pagedat['controller'])) { $view->error = View::ERROR_NOTFOUND; return; } $component = Core::GetComponentByController($pagedat['controller']); ////////////////////////////////////////////////////////////////////////////// /// In this block of logic, either the page is executed and a view returned, /// or a view is generated with an error. ////////////////////////////////////////////////////////////////////////////// if (!$component) { // Not found $view->error = View::ERROR_NOTFOUND; return; } elseif(!is_a($component, 'Component_2_1')) { $view->error = View::ERROR_NOTFOUND; return; } // Any method that starts with a "_" is an internal-only method! if ($pagedat['method']{0} == '_') { $view->error = View::ERROR_NOTFOUND; return; } // It also must be a part of the class... obviously if (!method_exists($pagedat['controller'], $pagedat['method'])) { $view->error = View::ERROR_NOTFOUND; return; } /** @var $controller Controller_2_1 This will be a Controller object. */ $controller = Controller_2_1::Factory($pagedat['controller']); $view->baseurl = $this->getBaseURL(); $controller->setView($view); // Make sure that the controller can access this object. $controller->setPageRequest($this); // The main page object. $page = $this->getPageModel(); // Check the access string first, (if there is one) if ($controller->accessstring !== null) { // Update the page's access string, (just in case it's saved at the end of execution) $page->set('access', $controller->accessstring); // And if the user doesn't have access to it... if (!\Core\user()->checkAccess($controller->accessstring)) { $view->error = View::ERROR_ACCESSDENIED; return; } } if($page->get('password_protected')) { if(\Core\Session::Get('page-password-protected/' . $page->get('baseurl')) !== $page->get('password_protected')){ $view->templatename = '/pages/page/passwordprotected.tpl'; $form = new Form(); $form->set('callsmethod', 'PageRequest::PasswordProtectHandler'); $form->addElement( 'system', [ 'name' => 'page', 'value' => $page ] ); $form->addElement( 'password', [ 'name' => 'passinput', 'title' => 'Password', 'required' => 'required', 'maxlength' => 128 ] ); $form->addElement( 'submit', [ 'value' => 'Submit' ] ); $view->assign('form', $form); return; } } // If the parent Controller object has a method named $pagedat['method'], assume it's a security error! // This is because if the parent Controller object has a method, it's most likely a utility method // that shouldn't be called from the public web! foreach(get_class_methods('Controller_2_1') as $parentmethod){ $parentmethod = strtolower($parentmethod); if($parentmethod == $pagedat['method']){ $view->error = View::ERROR_BADREQUEST; return; } } // Additional security logic for existing pages in multi-site mode. // If this exact URL is registered to another site, then // don't allow this site to display it. if(!$page->exists() && Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled()){ $site = MultiSiteHelper::GetCurrentSiteID(); $anypage = PageModel::Find(['baseurl = ' . $page->get('baseurl')], 1); if($anypage){ if($anypage->get('site') == -1){ // If this is a global page.... that's ok. // Just remap the page variable to this one! $page = $anypage; } elseif($anypage->get('site') == $site){ // Strange... it should have located this page... // Anyway, it's allowed, the site matches up. $page = $anypage; } else{ \Core\redirect($anypage->getResolvedURL()); } } } $return = call_user_func(array($controller, $pagedat['method'])); if (is_int($return)) { // A generic error code was returned. Create a View with that code and return that instead. $view->error = $return; //return; } elseif(is_a($return, 'View') && $return != $view){ // The controller method changed the view, (which is allowed), // but this needs to be remapped to this object so render knows about it. $this->_pageview = $view = $return; } elseif ($return === null) { // Hopefully it's setup! $return = $controller->getView(); if($return != $view){ $this->_pageview = $view = $return; } } elseif(!is_a($return, 'View')){ if(DEVELOPMENT_MODE){ var_dump('Controller method returned', $return); die('Sorry, but this controller did not return a valid object. Please ensure that your method returns either an integer, null, or a View object!'); } else{ $view->error = View::ERROR_SERVERERROR; return; } } // No else needed, else it's a valid object. // You may be asking why $view is one object, but $return is the return from page execution. // GREAT QUESTION, The $view is the original view object created from the page request. That is passed into // the controller and exposed via $this->getView(). The return can be a view, int, or other status indicator. // However since the controller can return a different view, that view should be used instead! ///** @var $return View */ // Allow the controller to assign controls via a shortcut function. if($view->error == View::ERROR_NOERROR){ $controls = $controller->getControls(); // This method may do absolutely nothing, add the controls to the view itself, or return an array of them. if(is_array($controls)){ foreach($controls as $control){ $view->addControl($control); } } } // For some of the options, there may be some that can be used for a fuzzy page, ie: a page's non-fuzzy template, // title, or meta information. if($view->error == View::ERROR_NOERROR){ if ($page->exists()) { $defaultpage = $page; } else { $defaultpage = null; $url = $view->baseurl; while ($url != '') { $url = substr($url, 0, strrpos($url, '/')); $p = PageModel::Find(array('baseurl' => $url, 'fuzzy' => 1), 1); if ($p === null) continue; if ($p->exists()) { $defaultpage = $p; break; } } if ($defaultpage === null) { // Fine.... $defaultpage = $page; } } $defaultmetas = $defaultpage->getLink('PageMeta'); // Make a list of the existing ones so I know which ones not to overwrite! // Just the key will suffice quite nicely. $currentmetas = array(); foreach($view->meta as $k => $meta){ $currentmetas[] = $k; } // Load some of the page information into the view now! foreach($defaultmetas as $meta){ /** @var $meta PageMetaModel */ $key = $meta->get('meta_key'); $viewmeta = $meta->getViewMetaObject(); // again, allow the executed controller have the final say on meta information. if ($meta->get('meta_value_title') && !in_array($key, $currentmetas)) { $view->meta[$key] = $viewmeta; } } // Since the controller already ran, do not overwrite the title. if ($view->title === null){ $view->title = $defaultpage->get('title'); } // Tracker to see if this page, (or a parent's page), is an admin-level page. // This is required because "admin" pages may have a different skin and should always have the dashboard as the top-level breadcrumb. /** @var boolean $isadmin */ $isadmin = ($page->get('admin') == '1'); $parents = array(); $parenttree = $page->getParentTree(); foreach ($parenttree as $parent) { /** @var PageModel $parent */ $parents[] = array( 'title' => $parent->get('title'), 'link' => $parent->getResolvedURL() ); // Since I'm here, check if this page is an admin page. if($parent->get('admin')){ $isadmin = true; } } $view->breadcrumbs = array_merge($parents, $view->breadcrumbs); if($isadmin && $view->baseurl != '/admin'){ // Make sure that admin is the top breadcrumb. // This block doesn't need to apply for the actual admin page itself, as that doesn't need its own breadcrumb :/ $adminlink = \Core\resolve_link('/admin'); if(!isset($view->breadcrumbs[0])){ // Nothing is even set! $view->breadcrumbs[] = ['title' => 'Administration', 'link' => $adminlink]; } elseif($view->breadcrumbs[0]['link'] != $adminlink){ // It's set, but not to admin. $view->breadcrumbs = array_merge([['title' => 'Administration', 'link' => $adminlink]], $view->breadcrumbs); } } } else{ $defaultpage = null; $isadmin = false; } if( $view->mode == View::MODE_PAGEORAJAX && $this->isAjax() && $view->jsondata !== null && $view->templatename === null ){ // Allow the content type to be overridden for ajax pages that have JSON data embedded in them. $view->contenttype = View::CTYPE_JSON; } if($view->mode == View::MODE_NOOUTPUT){ $view->mastertemplate = false; $view->templatename = null; } elseif( $view->error == View::ERROR_NOERROR && $view->contenttype == View::CTYPE_HTML && $view->templatename === null ){ // Try to guess the templatename if it wasn't set. // This $cnameshort = (strpos($pagedat['controller'], 'Controller') == strlen($pagedat['controller']) - 10) ? substr($pagedat['controller'], 0, -10) : $pagedat['controller']; $view->templatename = strtolower('/pages/' . $cnameshort . '/' . $pagedat['method'] . '.tpl'); } elseif( $view->error == View::ERROR_NOERROR && $view->contenttype == View::CTYPE_XML && $view->templatename === null ){ $cnameshort = (strpos($pagedat['controller'], 'Controller') == strlen($pagedat['controller']) - 10) ? substr($pagedat['controller'], 0, -10) : $pagedat['controller']; $view->templatename = Template::ResolveFile(strtolower('pages/' . $cnameshort . '/' . $pagedat['method'] . '.xml.tpl')); } // In addition to the autogeneration, also support the page_template from the datastore. if($defaultpage && $defaultpage->get('page_template')){ // Switch the template over to that custom one. // Some legacy data will have the fully resolved path for this template. // This has been switched to just the basename of the custom template, // but legacy data be legacy, 'yo. 0.o $base = substr($view->templatename, 0, -4); $override = $defaultpage->get('page_template'); if($base && strpos($override, $base) === 0){ $view->templatename = $override; } elseif($base){ $view->templatename = $base . '/' . $override; } } // Guess which theme skin (mastertemplate) should be used if one wasn't specified. if($view->mastertemplate == 'admin'){ // If the master template is set explictly to be the admin skin, then transpose that to the set admin skin. // This is useful for the pages that may not be under the "/admin" umbrella, but still rendered with the admin UI. $view->mastertemplate = ConfigHandler::Get('/theme/default_admin_template'); } elseif($view->mastertemplate){ // No change needed, just skip the below cases. } elseif($view->mastertemplate === false){ // If the master template is explictly set to false, the page wanted no master template! } elseif($isadmin){ // This page doesn't have a master template set, but it or a parent is set as an admin-level page. $view->mastertemplate = ConfigHandler::Get('/theme/default_admin_template'); } elseif ($defaultpage && $defaultpage->get('theme_template')) { // Master template set in the database? $view->mastertemplate = $defaultpage->get('theme_template'); } elseif($defaultpage && $defaultpage->exists() && $defaultpage->get('admin')){ // Or an admin level page? $view->mastertemplate = ConfigHandler::Get('/theme/default_admin_template'); } elseif(sizeof($view->breadcrumbs) && $view->breadcrumbs[0]['title'] == 'Administration'){ // Whatever, close e-damn-nough! // This happens for pages that don't actually exist, like "edit".... $view->mastertemplate = ConfigHandler::Get('/theme/default_admin_template'); } else{ $view->mastertemplate = ConfigHandler::Get('/theme/default_template'); } // First of all, if the current theme is not available, reset back to the first theme available! if(!($theme = ThemeHandler::GetTheme())){ /** @var \Theme\Theme $theme */ $theme = ThemeHandler::GetTheme('base-v2'); $view->mastertemplate = 'basic.tpl'; \Core\set_message('t:MESSAGE_ERROR_INVALID_THEME_SELECTED'); } // Make sure the selected mastertemplate actually exists! if($view->mastertemplate !== false){ $themeskins = $theme->getSkins(); $mastertplgood = false; foreach($themeskins as $skin){ if($skin['file'] == $view->mastertemplate){ // It's located! $mastertplgood =true; break; } } // A few special cases. if($view->mastertemplate == 'blank.tpl'){ // This is acceptable as a default one. $mastertplgood =true; } if(!$mastertplgood){ // Just use the first one instead! trigger_error('Invalid skin [' . $view->mastertemplate . '] selected for this page, skin is not located within the selected theme! Using first available instead.', E_USER_NOTICE); $view->mastertemplate = $themeskins[0]['file']; } } // Handle some of the new automatic meta data associated with Pages and the resulting View. if(\ConfigHandler::Get('/core/page/indexable') == 'deny'){ // Administratively set to noindex on all pages. $view->addMetaName('robots', 'noindex'); } elseif(!$page->get('indexable')){ // Bots have no business indexing user-action pages. $view->addMetaName('robots', 'noindex'); } if(!isset($view->meta['title'])){ $view->meta['title'] = $page->getSEOTitle(); } HookHandler::DispatchHook('/core/page/postexecute'); \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Completed PageRequest->execute()'); }
/** * Function that is fired off on page load. * This checks if a form was submitted and that form was present in the SESSION. * * @return null */ public static function CheckSavedSessionData() { // This needs to ignore the /form/savetemporary.ajax page! // This is a custom page that's meant to intercept all POST submissions. if(preg_match('#^/form/(.*)\.ajax$#', REL_REQUEST_PATH)) return; // There has to be data in the session. $forms = \Core\Session::Get('FormData/*'); $formid = (isset($_REQUEST['___formid'])) ? $_REQUEST['___formid'] : false; $form = false; foreach ($forms as $k => $v) { // If the object isn't a valid object after unserializing... if (!($el = unserialize($v))) { \Core\Session::UnsetKey('FormData/' . $k); continue; } // Check the expires time if ($el->get('expires') <= Time::GetCurrent()) { \Core\Session::UnsetKey('FormData/' . $k); continue; } if ($k == $formid) { // Remember this for after all the checks have finished. $form = $el; } } // No form found... simple enough if (!$form) return; // Otherwise /** @var $form Form */ // Ensure the submission types match up. if (strtoupper($form->get('method')) != $_SERVER['REQUEST_METHOD']) { \Core\set_message('t:MESSAGE_ERROR_FORM_SUBMISSION_TYPE_DOES_NOT_MATCH'); return; } // Ensure the REFERRER and original URL match up. if($_SERVER['HTTP_REFERER'] != $form->originalurl){ // @todo This is reported to be causing issues with production sites. // If found true, this check may need to be removed / refactored. //\Core\set_message('Form submission referrer does not match, please try your submission again.', 'error'); SystemLogModel::LogInfoEvent( 'Form Referrer Mismatch', 'Form referrer does not match! Submitted: [' . $_SERVER['HTTP_REFERER'] . '] Expected: [' . $form->originalurl . ']' ); //return; } // Run though each element submitted and try to validate it. if (strtoupper($form->get('method')) == 'POST') $src =& $_POST; else $src =& $_GET; $form->loadFrom($src); // Try to load the form from that form. That will call all of the model's validation logic // and will throw exceptions if it doesn't. try{ $form->getModel(); // Still good? if (!$form->hasError()){ $status = call_user_func($form->get('callsmethod'), $form); } else{ $status = false; } } catch(ModelValidationException $e){ \Core\set_message($e->getMessage(), 'error'); $status = false; } catch(GeneralValidationException $e){ \Core\set_message($e->getMessage(), 'error'); $status = false; } catch(Exception $e){ if(DEVELOPMENT_MODE){ // Developers get the full message \Core\set_message($e->getMessage(), 'error'); } else{ // While users of production-enabled sites get a friendlier message. \Core\set_message('t:MESSAGE_ERROR_FORM_SUBMISSION_UNHANDLED_EXCEPTION'); } Core\ErrorManagement\exception_handler($e); $status = false; } // The form was submitted. Set its persistent flag to true so that whatever may be listening for it can retrieve the user's values. $form->persistent = true; // Regardless, bundle this form back into the session so the controller can use it if needed. \Core\Session::Set('FormData/' . $formid, serialize($form)); // Fail statuses. if ($status === false) return; if ($status === null) return; // Guess it's not false and not null... must be good then. // @todo Handle an internal save procedure for "special" groups such as pageinsertables and what not. // Cleanup \Core\Session::UnsetKey('FormData/' . $formid); if ($status === 'die'){ // If it's set to die, simply exit the script without outputting anything. exit; } elseif($status === 'back'){ if($form->referrer && $form->referrer != REL_REQUEST_PATH){ // Go back to the original form's referrer. \Core\redirect($form->referrer); } else{ // Use Core to guess which page to redirect back to, (not as reliable). \Core\go_back(); } } elseif ($status === true){ // If the return code is boolean true, it's a reload. \Core\reload(); } elseif($status === REL_REQUEST_PATH || $status === CUR_CALL){ // If the page returned the same page as the current url, force a reload, (as redirect will ignore it) \Core\reload(); } else{ // Anything else gets sent to the redirect system. \core\redirect($status); } }
/** * Controller view to install 1 widget into one selected area, be that area a skin, or page template. * * @return int */ public function instance_install(){ $view = $this->getView(); $request = $this->getPageRequest(); if(!\Core\user()->checkAccess('p:/core/widgets/manage')){ return View::ERROR_ACCESSDENIED; } if(!$request->isPost()){ return View::ERROR_BADREQUEST; } // For the incoming options, I want an explicit NULL if it's empty. $template = (isset($_POST['template']) && $_POST['template'] != '') ? $_POST['template'] : null; $page_baseurl = (isset($_POST['page_baseurl']) && $_POST['page_baseurl'] != '') ? $_POST['page_baseurl'] : null; $widget_baseurl = (isset($_POST['widget_baseurl']) && $_POST['widget_baseurl'] != '') ? $_POST['widget_baseurl'] : null; $widgetarea = (isset($_POST['area']) && $_POST['area'] != '') ? $_POST['area'] : null; $wm = WidgetModel::Construct($widget_baseurl); $dat['site'] = $wm->get('site'); $dat['baseurl'] = $widget_baseurl; $dat['template'] = $template; $dat['page_baseurl'] = $page_baseurl; $dat['widgetarea'] = $widgetarea; if($template){ $counter = WidgetInstanceModel::Count(['template = ' . $template, 'widgetarea = ' . $widgetarea]); $w = new WidgetInstanceModel(); $w->setFromArray($dat); $w->set('weight', $counter + 1); $w->save(); \Core\set_message('Installed widget into requested template', 'success'); } elseif($page_baseurl){ $counter = WidgetInstanceModel::Count(['page_baseurl = ' . $page_baseurl, 'widgetarea = ' . $widgetarea]); $w = new WidgetInstanceModel(); $w->setFromArray($dat); $w->set('weight', $counter + 1); $w->save(); \Core\set_message('Installed widget into requested page', 'success'); } else{ \Core\set_message('Unknown request', 'error'); } if($page_baseurl){ \Core\redirect($page_baseurl); } else{ \Core\redirect('/widget/admin?template=' . $template); } }
/** * Page to enable Facebook logins for user accounts. * * @return int|null|string */ public function enable() { $request = $this->getPageRequest(); $auths = \Core\User\Helper::GetEnabledAuthDrivers(); if (!isset($auths['facebook'])) { // Facebook isn't enabled, simply redirect to the home page. \Core\redirect('/'); } if (!FACEBOOK_APP_ID) { \Core\redirect('/'); } if (!FACEBOOK_APP_SECRET) { \Core\redirect('/'); } // If it was a POST, then it should be the first page. if ($request->isPost()) { $facebook = new Facebook(['appId' => FACEBOOK_APP_ID, 'secret' => FACEBOOK_APP_SECRET]); // Did the user submit the facebook login request? if (isset($_POST['login-method']) && $_POST['login-method'] == 'facebook' && $_POST['access-token']) { try { $facebook->setAccessToken($_POST['access-token']); /** @var int $fbid The user ID from facebook */ $fbid = $facebook->getUser(); /** @var array $user_profile The array of user data from Facebook */ $user_profile = $facebook->api('/me'); } catch (Exception $e) { \Core\set_message($e->getMessage(), 'error'); \Core\go_back(); return null; } // If the user is logged in, then the verification logic is slightly different. if (\Core\user()->exists()) { // Logged in users, the email must match. if (\Core\user()->get('email') != $user_profile['email']) { \Core\set_message('Your Facebook email is ' . $user_profile['email'] . ', which does not match your account email! Unable to link accounts.', 'error'); \Core\go_back(); return null; } $user = \Core\user(); } else { /** @var \UserModel|null $user */ $user = UserModel::Find(['email' => $user_profile['email']], 1); if (!$user) { \Core\set_message('No local account found with the email ' . $user_profile['email'] . ', please <a href="' . \Core\resolve_link('/user/register') . '"create an account</a> instead.', 'error'); \Core\go_back(); return null; } } // Send an email with a nonce link that will do the actual activation. // This is a security feature so just anyone can't link another user's account. $nonce = NonceModel::Generate('20 minutes', null, ['user' => $user, 'access_token' => $_POST['access-token']]); $email = new Email(); $email->to($user->get('email')); $email->setSubject('Facebook Activation Request'); $email->templatename = 'emails/facebook/enable_confirmation.tpl'; $email->assign('link', \Core\resolve_link('/facebook/enable/' . $nonce)); if ($email->send()) { \Core\set_message('An email has been sent to your account with a link enclosed. Please click on that to complete activation within twenty minutes.', 'success'); \Core\go_back(); return null; } else { \Core\set_message('Unable to send a confirmation email, please try again later.', 'error'); \Core\go_back(); return null; } } } // If there is a nonce enclosed, then it should be the second confirmation page. // This is the one that actually performs the action. if ($request->getParameter(0)) { /** @var NonceModel $nonce */ $nonce = NonceModel::Construct($request->getParameter(0)); if (!$nonce->isValid()) { \Core\set_message('Invalid key requested.', 'error'); \Core\redirect('/'); return null; } $nonce->decryptData(); $data = $nonce->get('data'); /** @var UserModel $user */ $user = $data['user']; try { $facebook = new Facebook(['appId' => FACEBOOK_APP_ID, 'secret' => FACEBOOK_APP_SECRET]); $facebook->setAccessToken($data['access_token']); $facebook->getUser(); $facebook->api('/me'); } catch (Exception $e) { \Core\set_message($e->getMessage(), 'error'); \Core\redirect('/'); return null; } $user->enableAuthDriver('facebook'); /** @var \Facebook\UserAuth $auth */ $auth = $user->getAuthDriver('facebook'); $auth->syncUser($data['access_token']); \Core\set_message('Linked Facebook successfully!', 'success'); // And log the user in! if (!\Core\user()->exists()) { $user->set('last_login', \CoreDateTime::Now('U', \Time::TIMEZONE_GMT)); $user->save(); \Core\Session::SetUser($user); } \Core\redirect('/'); return null; } }
public function delete() { $view = $this->getView(); $request = $this->getPageRequest(); // This is a POST-only page. if (!$request->isPost()) { return View::ERROR_BADREQUEST; } if (!$this->setAccess('p:/content/manage_all')) { return View::ERROR_ACCESSDENIED; } $m = new ContentModel($request->getParameter(0)); $link = \Core\resolve_link($m->get('baseurl')); if (!$m->exists()) { return View::ERROR_NOTFOUND; } $m->delete(); \Core\set_message('Removed ' . $m->get('nickname') . ' successfully!', 'success'); $hist = $request->getReferrer(); if ($hist == $link) { \Core\redirect('/admin/pages'); } else { \Core\go_back(); } }
/** * View to sudo as another user. */ public function sudo(){ $view = $this->getView(); $req = $this->getPageRequest(); $id = $req->getParameter(0); if($id){ $model = UserModel::Construct($id); if(!\Core\user()->checkAccess('p:/user/users/sudo')){ return View::ERROR_ACCESSDENIED; } if(!$req->isPost()){ return View::ERROR_BADREQUEST; } if(!$model->exists()){ return View::ERROR_NOTFOUND; } \Core\Session::Set('user_sudo', $model); } elseif(\Core\Session::Get('user_sudo') !== null){ \Core\Session::UnsetKey('user_sudo'); } \Core\redirect('/'); }