public function __construct(){ // This system now has a combined primary key. // HOWEVER, construction of the model should still be allowed to be performed with simply the baseurl. // The first part of the key can be assumed. if(func_num_args() == 2){ if(Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled()){ $site = MultiSiteHelper::GetCurrentSiteID(); } else{ $site = 0; } $baseurl = func_get_arg(0); $name = func_get_arg(1); parent::__construct($site, $baseurl, $name); } elseif(func_num_args() == 3){ $site = func_get_arg(0); $baseurl = func_get_arg(1); $name = func_get_arg(2); parent::__construct($site, $baseurl, $name); } else{ parent::__construct(); } }
public function __construct() { $this->_linked = array( 'Page' => array( 'link' => Model::LINK_BELONGSTOONE, 'on' => 'baseurl', ), ); // This system now has a combined primary key. // HOWEVER, construction of the model should still be allowed to be performed with simply the baseurl. // The first part of the key can be assumed. if(func_num_args() == 3){ if(Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled()){ $site = MultiSiteHelper::GetCurrentSiteID(); } else{ $site = null; } $key1 = func_get_arg(0); $key2 = func_get_arg(1); $key3 = func_get_arg(2); parent::__construct($site, $key1, $key2, $key3); $this->load(); } elseif(func_num_args() == 4){ $site = func_get_arg(0); $key1 = func_get_arg(1); $key2 = func_get_arg(2); $key3 = func_get_arg(3); parent::__construct($site, $key1, $key2, $key3); } else{ parent::__construct(); } }
/** * Get the value appropriate for INSERT statements. * * @return string */ public function getInsertValue(){ if($this->value === null || $this->value === false){ if(\Core::IsComponentAvailable('multisite') && \MultiSiteHelper::IsEnabled()){ $this->setValueFromApp(\MultiSiteHelper::GetCurrentSiteID()); } else{ $this->setValueFromApp(0); } } return $this->value; }
<?php /** * Upgrade file to update the page insertables on 2.6.0 * * @package Core */ // Give me the page system! if(!class_exists('PageModel')) require_once(ROOT_PDIR . 'core/models/PageModel.class.php'); if(!class_exists('PageMetaModel')) require_once(ROOT_PDIR . 'core/models/PageMetaModel.class.php'); // If this site was not in multisite mode.... the insertables and metadata may not have matched up 1-to-1 with the page's site. // In 2.6.0, this relationship is a little more strictly enforced. if(!(Core::IsComponentAvailable('enterprise') && MultiSiteHelper::IsEnabled())){ // Get every page that currently exists $pages = PageModel::FindRaw(); foreach($pages as $page){ // Find the insertables that belong to this page and update their site id. $insertables = InsertableModel::Find(['baseurl = ' . $page['baseurl']]); foreach($insertables as $ins){ /** @var $ins InsertableModel */ $ins->set('site', $page['site']); $ins->save(); } } }
/** * @param \UserModel|null $user * * @return \Form */ public static function GetForm($user = null){ $form = new \Form(); if($user === null) $user = new \UserModel(); $type = ($user->exists()) ? 'edit' : 'registration'; $usermanager = \Core\user()->checkAccess('p:/user/users/manage'); $groupmanager = \Core\user()->checkAccess('p:/user/groups/manage'); $allowemailchanging = \ConfigHandler::Get('/user/email/allowchanging'); if($type == 'registration'){ $form->set('callsmethod', 'Core\\User\\Helper::RegisterHandler'); } else{ $form->set('callsmethod', 'Core\\User\\Helper::UpdateHandler'); } $form->addElement('system', ['name' => 'user', 'value' => $user]); // Because the user system may not use a traditional Model for the backend, (think LDAP), // I cannot simply do a setModel() call here. // Only enable email changes if the current user is an admin or it's new. // (Unless the admin allows it via the site config) if($type != 'registration' && ( $usermanager || $allowemailchanging)){ $form->addElement('text', array('name' => 'email', 'title' => 'Email', 'required' => true, 'value' => $user->get('email'))); } // Tack on the active option if the current user is an admin. if($usermanager){ $form->addElement( 'checkbox', array( 'name' => 'active', 'title' => 'Active', 'checked' => ($user->get('active') == 1), ) ); $form->addElement( 'checkbox', array( 'name' => 'admin', 'title' => 'System Admin', 'checked' => $user->get('admin'), 'description' => 'The system admin, (or root user), has complete control over the site and all systems.', ) ); } if($usermanager){ $elements = array_keys($user->getKeySchemas()); } elseif($type == 'registration'){ $elements = explode('|', \ConfigHandler::Get('/user/register/form_elements')); } else{ $elements = explode('|', \ConfigHandler::Get('/user/edit/form_elements')); } // If avatars are disabled globally, remove that from the list if it's set. if(!\ConfigHandler::Get('/user/enableavatar') && in_array('avatar', $elements)){ array_splice($elements, array_search('avatar', $elements), 1); } foreach($elements as $k){ if($k){ // Skip blank elements that can be caused by string|param|foo| or empty strings. $el = $user->getColumn($k)->getAsFormElement(); if($el){ $form->addElement($el); } } } // Tack on the group registration if the current user is an admin. if($groupmanager){ // Find all the groups currently on the site. $where = new DatasetWhereClause(); $where->addWhere('context = '); if(\Core::IsComponentAvailable('multisite') && \MultiSiteHelper::IsEnabled()){ $where->addWhereSub('OR', ['site = ' . \MultiSiteHelper::GetCurrentSiteID(), 'site = -1']); } $groups = \UserGroupModel::Find($where, null, 'name'); if(sizeof($groups)){ $groupopts = array(); foreach($groups as $g){ $groupopts[$g->get('id')] = $g->get('name'); } $form->addElement( 'checkboxes', array( 'name' => 'groups[]', 'title' => 'Group Membership', 'options' => $groupopts, 'value' => $user->getGroups() ) ); } $where = new DatasetWhereClause(); $where->addWhere('context != '); if(\Core::IsComponentAvailable('multisite') && \MultiSiteHelper::IsEnabled()){ $w = new DatasetWhereClause(); $w->setSeparator('or'); $w->addWhere('site = ' . \MultiSiteHelper::GetCurrentSiteID()); $w->addWhere('site = -1'); $where->addWhere($w); } $contextgroups = \UserGroupModel::Count($where); if($contextgroups > 0){ // If this is a non-global context. // Good enough to stop here! $form->addElement( new \FormGroup( [ 'name' => 'context-groups', 'id' => 'context-groups', 'title' => 'Context Group Membership', ] ) ); // So that these elements will be registered on the form object... $form->addElement('hidden', ['name' => 'contextgroup[]', 'persistent' => false]); $form->addElement('hidden', ['name' => 'contextgroupcontext[]', 'persistent' => false]); } } // If the config is enabled and the current user is guest... if($type == 'registration' && \ConfigHandler::Get('/user/register/requirecaptcha') && !\Core\user()->exists()){ $form->addElement('captcha'); } $form->addElement( 'submit', [ 'value' => (($type == 'registration') ? 'Register' : 'Update'), 'name' => 'submit', ] ); return $form; }
/** * Internal function to do the multisite check on the model. * If the model supports a site attribute and none requested, then set it to the current site. */ private function _performMultisiteCheck(){ $m = $this->_model; $ref = new ReflectionClass($m); $schema = $ref->getMethod('GetSchema')->invoke(null); $index = $ref->getMethod('GetIndexes')->invoke(null); //$schema = $m::GetSchema(); //$index = $m:: // Is there a site property? If not I don't even care. if( isset($schema['site']) && $schema['site']['type'] == Model::ATT_TYPE_SITE && Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled() ){ // I want to look it up because if the script actually set the site, then // it evidently wants it for a reason. $siteexact = (sizeof($this->_dataset->getWhereClause()->findByField('site')) > 0); $idexact = false; // The primary check will allow a model to be instantiated with the exact primary key string. $pri = isset($index['primary']) ? $index['primary'] : null; if($pri && !is_array($pri)) $pri = [$pri]; if($pri){ $allids = true; foreach($pri as $k){ if(sizeof($this->_dataset->getWhereClause()->findByField($k)) == 0){ $allids = false; break; } } if($allids) $idexact = true; } if(!($siteexact || $idexact)){ $w = new \Core\Datamodel\DatasetWhereClause(); $w->setSeparator('or'); $w->addWhere('site = ' . MultiSiteHelper::GetCurrentSiteID()); $w->addWhere('site = -1'); $this->_dataset->where($w); //$this->_dataset->where('site = ' . MultiSiteHelper::GetCurrentSiteID()); } } }
public function delete(){ $view = $this->getView(); $req = $this->getPageRequest(); $id = $req->getParameter(0); $model = new UserGroupModel($id); if(!$req->isPost()){ return View::ERROR_BADREQUEST; } if(Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled()){ $where['site'] = MultiSiteHelper::GetCurrentSiteID(); } $model->delete(); \Core\set_message('Removed group successfully', 'success'); \core\redirect('/usergroupadmin'); }
/** * Page to display the currently installed themes and shortcuts to various operations therein. */ public function index() { $view = $this->getView(); $selected = ConfigHandler::Get('/theme/selected'); $themes = ThemeHandler::GetAllThemes(); $current = ThemeHandler::GetTheme($selected); // Set to true if multisite is enabled AND the page is currently on a child site. $multisite = Core::IsLibraryAvailable('multisite') && MultiSiteHelper::IsEnabled() && MultiSiteHelper::GetCurrentSiteID() != 0; $configDefault = ConfigHandler::GetConfig('/theme/default_template'); $configSelected = ConfigHandler::GetConfig('/theme/selected'); $configEmailDefault = ConfigHandler::GetConfig('/theme/default_email_template'); // Only allow changing the theme if it's on the root site OR both config options are overrideable. $themeSelectionEnabled = !$multisite || $configDefault->get('overrideable') && $configSelected->get('overrideable'); $emailSelectionEnabled = !$multisite || $configEmailDefault->get('overrideable'); $configOptions = $current->getConfigs(); if (!sizeof($configOptions)) { $optionForm = null; } else { $optionForm = new Form(); $optionForm->set('callsmethod', 'AdminController::_ConfigSubmit'); foreach ($configOptions as $c) { /** @var $c ConfigModel */ if ($multisite) { // Only pull the config options that are enabled for this specific site. if ($c->get('overrideable')) { $optionForm->addElement($c->getAsFormElement()); } } else { // Sites that either // do NOT have multisite installed // nor have multisite enabled // or on the root site, get all options. $optionForm->addElement($c->getAsFormElement()); } } if (sizeof($optionForm->getElements()) > 0) { // There is at least one element in the option forms! $optionForm->addElement('submit', ['value' => 'Save Configurable Options']); } else { // Reset the form back to null so that the section doesn't display. $optionForm = null; } } // The source objects to look for assets in. // Set initially to all the installed components. $assetsources = Core::GetComponents(); // And add on the current theme. $assetsources[] = $current; // Load in all asset files available from the installed components and current theme. // these are assembled into a virtual directory listing. $assets = array(); // Give me the current theme! foreach ($assetsources as $source) { /** @var Component_2_1 $source */ $dir = $source->getAssetDir(); if (!$dir) { continue; } $dirlen = strlen($dir); $name = $source->getName(); $dh = \Core\Filestore\Factory::Directory($dir); $ls = $dh->ls(null, true); foreach ($ls as $obj) { // Skip directories. if (!$obj instanceof \Core\Filestore\File) { continue; } /** @var $obj \Core\Filestore\File */ $file = 'assets/' . substr($obj->getFilename(), $dirlen); // Since this is a template, it may actually be in a different location than where the package maintainer put it. // ie: user template user/templates/pages/user/view.tpl may be installed to themes/myawesometheme/pages/user/view.tpl instead. $newobj = \Core\Filestore\Factory::File($file); $assets[$file] = array('file' => $file, 'obj' => $newobj, 'component' => $name); } } // Now that the asset files have been loaded into a flat array, I need to convert that to the properly nested version. ksort($assets); $nestedassets = array(); foreach ($assets as $k => $obj) { $parts = explode('/', $k); $lastkey = sizeof($parts) - 1; $thistarget =& $nestedassets; foreach ($parts as $i => $bit) { if ($i == $lastkey) { $thistarget[$bit] = $obj; } else { if (!isset($thistarget[$bit])) { $thistarget[$bit] = []; } $thistarget =& $thistarget[$bit]; } } } // Get the templates throughout the site. These can include pages, emails, form elements, etc. $components = Core::GetComponents(); $templates = array(); foreach ($components as $c) { /** @var $c Component_2_1 */ $dir = $c->getViewSearchDir(); if (!$dir) { continue; } $dirlen = strlen($dir); $component = $c->getName(); $dh = \Core\Filestore\Factory::Directory($dir); //$pagetplfiles = $dh->ls('tpl', true); $pagetplfiles = $dh->ls(null, true); // not sure why getFilename(path) isn't working as expected, but this works too. foreach ($pagetplfiles as $obj) { // I don't want directories. if ($obj instanceof \Core\Filestore\Directory) { continue; } /** @var $obj \Core\Filestore\File */ $file = substr($obj->getFilename(), $dirlen); // Since this is a template, it may actually be in a different location than where the package maintainer put it. // ie: user template user/templates/pages/user/view.tpl may be installed to themes/myawesometheme/pages/user/view.tpl instead. $tpl = Core\Templates\Template::Factory($file); $resolved = Core\Templates\Template::ResolveFile($file); $newobj = \Core\Filestore\Factory::File($resolved); $templates[$file] = array('file' => $file, 'resolved' => $resolved, 'obj' => $newobj, 'haswidgets' => $tpl->hasWidgetAreas(), 'component' => $component, 'has_stylesheets' => $tpl->hasOptionalStylesheets()); } } // Now that the template files have been loaded into a flat array, I need to convert that to the properly nested version. ksort($templates); $nestedtemplates = array(); foreach ($templates as $k => $obj) { $parts = explode('/', $k); $lastkey = sizeof($parts) - 1; $thistarget =& $nestedtemplates; foreach ($parts as $i => $bit) { if ($i == $lastkey) { $thistarget[$bit] = $obj; } else { if (!isset($thistarget[$bit])) { $thistarget[$bit] = []; } $thistarget =& $thistarget[$bit]; } } } $siteskinform = new Form(); $siteskinform->set('callsmethod', 'ThemeController::SaveSiteSkins'); $opts = ['' => '-- Public Default --']; foreach ($current->getSkins() as $skin) { $opts[$skin['file']] = $skin['title']; } foreach (ConfigHandler::FindConfigs('/theme/siteskin/') as $k => $config) { $siteskinform->addElement('select', ['name' => 'config[' . $k . ']', 'title' => $config->get('description'), 'value' => $config->getValue(), 'options' => $opts]); } $siteskinform->addElement('submit', ['value' => t('STRING_SAVE')]); $customdest = \Core\directory('themes/custom'); $cssform = false; $cssprintform = false; if ($customdest->isWritable()) { $sets = [['file' => 'css/custom.css', 'form' => null], ['file' => 'css/custom_print.css', 'form' => null]]; foreach ($sets as $k => $set) { // Load the editor for the custom CSS file, as this is a very common thing to do! $file = $set['file']; // And try to look up and find this damn file... $srcdirs = array(); $srcdirs[] = ROOT_PDIR . 'themes/custom/assets/'; $srcdirs[] = ROOT_PDIR . 'themes/' . ConfigHandler::Get('/theme/selected') . '/assets/'; foreach (Core::GetComponents() as $c) { if ($c->getAssetDir()) { $srcdirs[] = $c->getAssetDir(); } } foreach ($srcdirs as $dir) { if (file_exists($dir . $file)) { $file = $dir . $file; break; } } $fh = \Core\Filestore\Factory::File($file); $content = $fh->getContents(); $m = new ThemeTemplateChangeModel(); $m->set('content', $content); $m->set('filename', 'assets/css/custom.css'); $form = Form::BuildFromModel($m); $form->set('callsmethod', 'ThemeController::_SaveEditorHandler'); // I need to add the file as a system element so core doesn't try to reuse the same forms on concurrent edits. //$form->addElement('system', array('name' => 'revision', 'value' => $revision)); $form->addElement('system', array('name' => 'file', 'value' => 'assets/' . $set['file'])); $form->addElement('system', array('name' => 'filetype', 'value' => 'file')); // No one uses this anyways! $form->switchElementType('model[comment]', 'hidden'); $form->getElement('model[content]')->set('id', 'custom_content_' . $k); $form->addElement('submit', array('value' => 'Save Custom CSS')); // Save it back down to the original array $sets[$k]['form'] = $form; } $cssform = $sets[0]['form']; $cssprintform = $sets[1]['form']; } $view->title = 'Theme Manager'; $view->assign('themes', $themes); $view->assign('current', $current); $view->assign('options_form', $optionForm); $view->assign('assets', $nestedassets); $view->assign('templates', $nestedtemplates); $view->assign('url_themeeditor', \Core\resolve_link('/theme/editor')); $view->assign('url_themewidgets', \Core\resolve_link('/theme/widgets')); $view->assign('url_themestylesheets', \Core\resolve_link('/theme/selectstylesheets')); $view->assign('site_skins_form', $siteskinform); $view->assign('cssform', $cssform); $view->assign('cssprintform', $cssprintform); $view->assign('multisite', $multisite); $view->assign('theme_selection_enabled', $themeSelectionEnabled); $view->assign('email_selection_enabled', $emailSelectionEnabled); }
/** * @todo Finish documentation of smarty_function_widgetarea * @param array $params Associative (and/or indexed) array of smarty parameters passed in from the template * @param Smarty_Internal_Template $smarty Parent Smarty template object * * @return string|void */ function smarty_function_widgetarea($params, $smarty) { // Get all widgets set to load in this area. $body = ''; $baseurl = PageRequest::GetSystemRequest()->getBaseURL(); $template = $smarty->template_resource; $tmpl = $smarty->getTemplateVars('__core_template'); $topview = ($tmpl instanceof \Core\Templates\TemplateInterface) ? $tmpl->getView() : \Core\view(); $parameters = []; $name = null; $installable = null; $assign = null; foreach($params as $k => $v){ switch($k){ case 'name': $name = $v; break; case 'installable': $installable = $v; break; case 'assign': $assign = $v; break; default: $parameters[$k] = $v; break; } } // I need to resolve the page template down to the base version in order for the lookup to work. foreach(Core\Templates\Template::GetPaths() as $base){ if(strpos($template, $base) === 0){ $template = substr($template, strlen($base)); break; } } // Given support for page-level widgets, this logic gets slightly more difficult... $factory = new ModelFactory('WidgetInstanceModel'); $factory->order('weight'); if(Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled()){ $factory->whereGroup('or', ['site = -1', 'site = ' . MultiSiteHelper::GetCurrentSiteID()]); } $subwhere = new Core\Datamodel\DatasetWhereClause(); $subwhere->setSeparator('OR'); // First, the skin-level where clause. $skinwhere = new Core\Datamodel\DatasetWhereClause(); $skinwhere->setSeparator('AND'); $skinwhere->addWhere('template = ' . $template); $skinwhere->addWhere('widgetarea = ' . $name); $subwhere->addWhere($skinwhere); // And second, the page-level where clause. if($baseurl){ $pagewhere = new Core\Datamodel\DatasetWhereClause(); $pagewhere->setSeparator('AND'); $pagewhere->addWhere('page_baseurl = ' . $baseurl); $pagewhere->addWhere('widgetarea = ' . $name); $subwhere->addWhere($pagewhere); } $factory->where($subwhere); $widgetcount = 0; try{ $widgets = $factory->get(); } catch(Exception $e){ if(DEVELOPMENT_MODE){ $body .= '<p class="message-error">Exception while trying to load widget area ' . $name . '!</p>'; $body .= '<pre class="xdebug-var-dump">' . $e->getMessage() . '</pre>'; } else{ \Core\ErrorManagement\exception_handler($e, false); } $widgets = []; ++$widgetcount; } foreach ($widgets as $wi) { /** @var $wi WidgetInstanceModel */ // User cannot access this widget? Don't display it... if(!\Core\user()){ continue; } if (!\Core\user()->checkAccess($wi->get('access'))){ continue; } if($installable){ $wi->set('installable', $installable); } $view = $wi->execute($parameters); // Some widgets may return simply a blank string. Those should just be ignored. if ($view == ''){ continue; } // If it's just a string, return that. if (is_string($view)) { $contents = $view; } elseif($view->error == View::ERROR_NOERROR){ // Ensure that the widget's View knows it's linked to a parent! $view->parent = $topview; $contents = $view->fetch(); } else{ $contents = 'Error displaying widget [' . $wi->get('baseurl') . '], returned error [' . $view->error . ']'; } ++$widgetcount; // Does this widget have controls attached to it? $widget = $wi->getWidget(); if($widget->controls instanceof ViewControls && $widget->controls->hasLinks()){ $contents = '<div class="widget-controls-wrapper">' . '<menu id="widget-controls-' . $wi->get('id') . '">' . $widget->controls->fetch() . '</menu>' . '</div>' . $contents; } $body .= '<div class="widget">' . $contents . '</div>'; } // Do some sanitizing for the css data $class = 'widgetarea-' . strtolower(str_replace(' ', '', $name)); $html = '<div class="widgetarea ' . $class . '" widgetarea="' . $name . '">' . $body . '</div>'; // No widgets, no inner content! if($widgetcount == 0){ $html = ''; } if($assign){ $smarty->assign($assign, $html); } else{ return $html; } }
/** * Display a listing of all pages registered in the system. */ public function pages(){ $view = $this->getView(); $request = $this->getPageRequest(); if(!\Core\user()->checkAccess('p:/core/pages/view')){ return View::ERROR_ACCESSDENIED; } // Build a list of create pages for all registered components. $components = Core::GetComponents(); $links = []; $componentopts = ['' => '-- ' . t('STRING_VIEW_ALL_COMPONENTS') . ' --']; foreach($components as $c){ /** @var Component_2_1 $c */ foreach($c->getXML()->getElements('/pages/pagecreate') as $node){ /** @var DOMElement $node */ $links[] = ['baseurl' => $node->getAttribute('baseurl'), 'title' => $node->getAttribute('title')]; } $componentopts[$c->getKeyName()] = $c->getName(); } // Sort them by name! asort($componentopts); $pageschema = PageModel::GetSchema(); $table = new Core\ListingTable\Table(); $table->setLimit(20); // Set the model that this table will be pulling data from. $table->setModelName('PageModel'); // Gimme filters! $table->addFilter( 'text', [ 'name' => 'title', 'title' => t('STRING_TITLE'), 'link' => FilterForm::LINK_TYPE_CONTAINS, ] ); $table->addFilter( 'text', [ 'name' => 'rewriteurl', 'title' => t('STRING_URL'), 'link' => FilterForm::LINK_TYPE_CONTAINS, ] ); $table->addFilter( 'text', [ 'name' => 'parenturl', 'title' => t('STRING_PARENT_URL'), 'link' => FilterForm::LINK_TYPE_STARTSWITH, ] ); $table->addFilter( 'select', [ 'name' => 'component', 'title' => t('STRING_COMPONENT'), 'options' => $componentopts, 'link' => FilterForm::LINK_TYPE_STANDARD, ] ); $table->addFilter( 'select', [ 'name' => 'page_types', 'title' => t('STRING_INCLUDE_ADMIN_PAGES'), 'options' => ['all' => t('STRING_VIEW_ALL_PAGES'), 'no_admin' => t('STRING_EXCLUDE_ADMIN_PAGES')], 'value' => 'no_admin', ] ); // Add in all the columns for this listing table. if(Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled() && \Core\user()->checkAccess('g:admin')){ $table->addColumn('Site', 'site', false); $ms = true; } else{ $ms = false; } $table->addColumn(t('STRING_TITLE'), 'title'); $table->addColumn(t('STRING_URL'), 'rewriteurl'); $table->addColumn(t('STRING_VIEWS'), 'pageviews', false); $table->addColumn(t('STRING_SCORE'), 'popularity'); $table->addColumn(t('STRING_CACHE'), 'expires'); $table->addColumn(t('STRING_CREATED'), 'created', false); $table->addColumn(t('STRING_LAST_UPDATED'), 'updated', false); $table->addColumn(t('STRING_STATUS')); $table->addColumn(t('STRING_PUBLISHED'), 'published'); $table->addColumn(t('STRING_EXPIRES'), 'published_expires'); $table->addColumn(t('STRING_SEO_TITLE')); $table->addColumn(t('STRING_SEO_DESCRIPTION'), null, false); $table->addColumn(t('STRING_ACCESS'), 'access'); $table->addColumn(t('STRING_COMPONENT'), 'component', false); // This page will also feature a quick-edit feature. //$table->setEditFormCaller('AdminController::PagesSave'); $table->loadFiltersFromRequest(); if($table->getFilterValue('page_types') == 'no_admin'){ $table->getModelFactory()->where('admin = 0'); $table->getModelFactory()->where('selectable = 1'); } $view->title = 't:STRING_ALL_PAGES'; //$view->assign('filters', $filters); //$view->assign('listings', $listings); $view->assign('links', $links); $view->assign('multisite', $ms); $view->assign('listing', $table); $view->assign('page_opts', PageModel::GetPagesAsOptions(false, '-- Select Parent URL --')); $view->assign('expire_opts', $pageschema['expires']['form']['options']); }
/** * Get the page model for the current page. * * @return PageModel */ public function getPageModel() { if ($this->_pagemodel === null) { $uri = $this->uriresolved; $pagefac = new ModelFactory('PageModel'); $pagefac->where('rewriteurl = ' . $uri); //$pagefac->where('fuzzy = 0'); $pagefac->limit(1); if(Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled()){ $pagefac->whereGroup('OR', array('site = -1', 'site = ' . MultiSiteHelper::GetCurrentSiteID())); } $p = $pagefac->get(); // Split this URL, it'll be used somewhere. $pagedat = $this->splitParts(); if ($p) { // :) Found it $this->_pagemodel = $p; } elseif ($pagedat && isset($pagedat['baseurl'])) { // Is this even a valid controller? // This will allow a page to be called with it being in the pages database. $p = new PageModel($pagedat['baseurl']); if(!$p->exists()){ $p->set('rewriteurl', $pagedat['rewriteurl']); } $this->_pagemodel = $p; } else { // No page in the database and no valid controller... sigh $this->_pagemodel = new PageModel(); } //var_dump($p); die(); // Make sure all the parameters from both standard GET and core parameters are tacked on. if ($pagedat && $pagedat['parameters']) { foreach ($pagedat['parameters'] as $k => $v) { $this->_pagemodel->setParameter($k, $v); } } if (is_array($_GET)) { foreach ($_GET as $k => $v) { if (is_numeric($k)) continue; $this->_pagemodel->setParameter($k, $v); } } } return $this->_pagemodel; }
/** * Display a listing of all widgets registered in the system. */ public function admin(){ $view = $this->getView(); $request = $this->getPageRequest(); $viewer = \Core\user()->checkAccess('p:/core/widgets/manage'); $manager = \Core\user()->checkAccess('p:/core/widgets/manage'); if(!($viewer || $manager)){ return View::ERROR_ACCESSDENIED; } // Build a list of create pages for all registered components. $components = Core::GetComponents(); $pages = []; $skins = []; $selected = null; $selectedtype = null; $baseurl = null; $selectoptions = []; $links = []; $theme = ThemeHandler::GetTheme(); $formtheme = null; $formskin = null; $formtemplate = null; foreach($components as $c){ /** @var Component_2_1 $c */ $viewdir = $c->getViewSearchDir(); if($viewdir){ $dirlen = strlen($viewdir); $component = $c->getName(); $dh = \Core\Filestore\Factory::Directory($viewdir); //$pagetplfiles = $dh->ls('tpl', true); $pagetplfiles = $dh->ls(null, true); // not sure why getFilename(path) isn't working as expected, but this works too. foreach($pagetplfiles as $obj){ // I don't want directories. if($obj instanceof \Core\Filestore\Directory) continue; /** @var $obj \Core\Filestore\File */ $file = substr($obj->getFilename(), $dirlen); // Since this is a template, it may actually be in a different location than where the package maintainer put it. // ie: user template user/templates/pages/user/view.tpl may be installed to themes/myawesometheme/pages/user/view.tpl instead. $tpl = Core\Templates\Template::Factory($file); if($tpl->hasWidgetAreas()){ $pagetitle = $file; if(strpos($pagetitle, 'pages/') === 0){ $pagetitle = substr($pagetitle, 6); } // Replace directory slashes with a space $pagetitle = str_replace(['/', '-'], ' ', $pagetitle); // Capitalize them $pagetitle = ucwords($pagetitle); // And trim off the ".tpl" suffix. $pagetitle = substr($pagetitle, 0, -4); $pages[$file] = $pagetitle; } } } foreach($c->getXML()->getElements('/widgets/widgetcreate') as $node){ /** @var DOMElement $node */ if($node->getAttribute('baseurl')){ $nodebaseurl = $node->getAttribute('baseurl'); $image = ''; } elseif($node->getAttribute('class')){ /** @var Widget_2_1 $obj */ $obj = Widget_2_1::Factory($node->getAttribute('class')); $nodebaseurl = '/widget/create?class=' . $node->getAttribute('class'); if($obj){ $image = $obj->getPreviewImage(); } else{ \Core\set_message('Invalid "widgetcreate" found in ' .$node->getAttribute('class') . ', ' . $node->getAttribute('title'), 'error'); $image = ''; } } else{ \Core\set_message('Invalid "widgetcreate" found in ' . $c->getName() . ', ' . $node->getAttribute('title'), 'error'); continue; } $links[] = [ 'baseurl' => $nodebaseurl, 'title' => $node->getAttribute('title'), 'preview' => $image, ]; } } // Build the array of skins for the current theme $themeskins = $theme->getSkins(); $defaultskin = null; foreach($themeskins as $dat){ $skins[ 'skins/' . $dat['file'] ] = $dat['title']; if($dat['default']){ $defaultskin = 'skins/' . $dat['file']; } } // Now that the various templates have been loaded into a flat array, I need to sort them. asort($pages); asort($skins); foreach($skins as $k => $v){ $selectoptions[ $k ] = 'Skin: ' . $v; } foreach($pages as $k => $v){ $selectoptions[ $k ] = 'Page: ' . $v; } if($request->getParameter('baseurl')){ // It's a URL-specific request, lookup which template that page used last. $baseurl = $request->getParameter('baseurl'); $page = PageModel::Construct($baseurl); if(!isset($pages[ $page->get('last_template') ])){ \Core\set_message('Requested page template does not seem to contain any widget areas.', 'error'); \Core\go_back(); } $selected = $page->get('last_template'); $selectedtype = 'url'; $formtemplate = $selected; } elseif($request->getParameter('template')){ $selected = $request->getParameter('template'); if(isset($pages[ $selected ])){ $selectedtype = 'page'; $formtemplate = $selected; } else{ $selectedtype = 'skin'; $formtheme = $theme->getKeyName(); $formskin = $selected; } } else{ // Just use the default theme skin. $selected = $defaultskin; $selectedtype = 'skin';$formtheme = $theme->getKeyName(); $formskin = $selected; } $template = \Core\Templates\Template::Factory($selected); $areas = $template->getWidgetAreas(); $installables = [0 => '']; foreach($areas as $k => $dat){ // Ensure that each area has a widgets array, (even if it's empty) $areas[$k]['widgets'] = []; $installables[] = $dat['installable']; } $installables = array_unique($installables); $factory = new ModelFactory('WidgetInstanceModel'); $factory->order('weight'); if(Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled()){ $factory->whereGroup('or', ['site = -1', 'site = ' . MultiSiteHelper::GetCurrentSiteID()]); } if($selectedtype == 'skin'){ // First, the skin-level where clause. $skinwhere = new Core\Datamodel\DatasetWhereClause(); $skinwhere->setSeparator('AND'); //$skinwhere->addWhere('theme = ' . $theme->getKeyName()); $skinwhere->addWhere('template = ' . $selected); $factory->where($skinwhere); } elseif($selectedtype == 'page'){ $factory->where('template = ' . $selected); } elseif($selectedtype == 'url'){ $factory->where('page_baseurl = ' . $baseurl); } else{ \Core\set_message('Invalid/unknown template type', 'error'); \Core\go_back(); } foreach($factory->get() as $wi){ /** @var $wi WidgetInstanceModel */ $a = $wi->get('widgetarea'); $areas[$a]['widgets'][] = $wi; } $available = WidgetModel::Find(['installable IN ' . implode(', ', $installables)]); /* $table = new Core\ListingTable\Table(); $table->setName('/admin/widgets'); $table->setModelName('WidgetModel'); // Add in all the columns for this listing table. $table->addColumn('Title', 'title'); if(Core::IsComponentAvailable('enterprise') && MultiSiteHelper::IsEnabled() && \Core\user()->checkAccess('g:admin')){ $table->addColumn('Site', 'site', false); $ms = true; } else{ $ms = false; } $table->getModelFactory()->where('installable IN ' . implode(', ', $installables)); $table->addColumn('Base URL', 'baseurl'); $table->addColumn('Installable', 'installable'); $table->addColumn('Created', 'created'); $table->loadFiltersFromRequest(); */ $view->mastertemplate = 'admin'; $view->title = 'All Widgets'; //$view->assign('table', $table); $view->assign('available_widgets', $available); $view->assign('links', $links); $view->assign('manager', $manager); $view->assign('theme', $formtheme); $view->assign('skin', $formskin); $view->assign('template', $selected); $view->assign('page_template', $formtemplate); $view->assign('page_baseurl', $baseurl); $view->assign('options', $selectoptions); $view->assign('selected', $selected); $view->assign('areas', $areas); //$view->assign('multisite', $ms); }
public function sitemap(){ $view = $this->getView(); $req = $this->getPageRequest(); // Give me every registered (public) page! $factory = new ModelFactory('PageModel'); $factory->where('indexable = 1'); $factory->order('title'); // Multisite? if(Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled()){ $factory->whereGroup( 'OR', array( 'site = ' . MultiSiteHelper::GetCurrentSiteID(), 'site = -1' ) ); $site = MultiSiteHelper::GetCurrentSiteID(); } else{ $site = null; } // Run this through the streamer, just in case there are a lot of pages... $stream = new \Core\Datamodel\DatasetStream($factory->getDataset()); $user = \Core\user(); $toshow = array(); while(($record = $stream->getRecord())){ if(!$user->checkAccess( $record['access'] )){ // Skip any further operations if the user does not have access to this page continue; } if($record['published_status'] != 'published'){ // Skip any further operations if the page isn't even marked as published. continue; } $page = new PageModel(); $page->_loadFromRecord($record); if(!$page->isPublished()){ // Skip out if the page is not marked as published. // This has extended checks other than simply if the status is set as "published", // such as publish date and expiration date. continue; } $toshow[] = $page; } // Anything else? $extra = HookHandler::DispatchHook('/sitemap/getlisting'); $toshow = array_merge($toshow, $extra); // This page allows for a few content types. switch($req->ctype){ case View::CTYPE_XML: $view->contenttype = View::CTYPE_XML; break; case View::CTYPE_HTML: $view->contenttype = View::CTYPE_HTML; break; } $view->title = 'Sitemap'; $view->assign('pages', $toshow); $view->assign('site', $site); }
/** * Transpose a populated form element from the underlying ConfigModel object. * Will populate the name, options, validation, etc. * * @return \FormElement * * @throws \Exception */ public function getAsFormElement(){ // key is in the format of: // /user/displayname/displayoptions $key = $this->get('key'); $attributes = $this->getFormAttributes(); $val = \ConfigHandler::Get($key); $type = $attributes['type']; $el = \FormElement::Factory($type, $attributes); if($type == 'radio'){ // Ensure that this matches what the radios will have. if ($val == '1' || $val == 'true' || $val == 'yes') $val = 'true'; else $val = 'false'; } if($this->get('type') == 'int' && $type == 'text'){ $el->validation = '/^[0-9]*$/'; $el->validationmessage = $attributes['group'] . ' - ' . $attributes['title'] . ' expects only whole numbers with no punctuation.'; } if($type == 'checkboxes' && !is_array($val)){ // Convert the found value to an array so it matches what checkboxes are expecting. $val = array_map('trim', explode('|', $val)); } $el->set('value', $val); // If multisite is enabled and this config is NOT set to overrideable, then set the field as read only! if(Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled() && MultiSiteHelper::GetCurrentSiteID()){ if(!$this->get('overrideable')){ $el->set('readonly', true); $el->set('disabled', true); } } return $el; }
/** * Get the current user model that is logged in. * * To support legacy systems, this will also return the User object if it's available instead. * This support is for < 2.8.x Core installations and will be removed after some amount of time TBD. * * If no user systems are currently available, null is returned. * * @return \UserModel */ function user(){ static $_CurrentUserAccount = null; if(!class_exists('\\UserModel')){ return null; } if($_CurrentUserAccount !== null){ // Cache this for the page load. return $_CurrentUserAccount; } if(isset($_SERVER['HTTP_X_CORE_AUTH_KEY'])){ // Allow an auth key to be used to authentication the requested user instead! $user = \UserModel::Find(['apikey = ' . $_SERVER['HTTP_X_CORE_AUTH_KEY']], 1); if($user){ $_CurrentUserAccount = $user; } } elseif(Session::Get('user') instanceof \UserModel){ // There is a valid user account in the session! // But check if this user is forced to be resynced first. if(isset(Session::$Externals['user_forcesync'])){ // A force sync was requested by something that modified the original UserModel object. // Keep the user logged in, but reload the data from the database. $_CurrentUserAccount = \UserModel::Construct(Session::Get('user')->get('id')); // And cache this updated user model back to the session. Session::Set('user', $_CurrentUserAccount); unset(Session::$Externals['user_forcesync']); } else{ $_CurrentUserAccount = Session::Get('user'); } } if($_CurrentUserAccount === null){ // No valid user found. $_CurrentUserAccount = new \UserModel(); } // If this is in multisite mode, blank out the access string cache too! // This is because siteA may have some groups, while siteB may have another. // We don't want a user going to a site they have full access to, hopping to another and having cached permissions! if(\Core::IsComponentAvailable('multisite') && class_exists('MultiSiteHelper') && \MultiSiteHelper::IsEnabled()){ $_CurrentUserAccount->clearAccessStringCache(); } // Did this user request sudo access for another user? if(Session::Get('user_sudo') !== null){ $sudo = Session::Get('user_sudo'); if($sudo instanceof \UserModel){ // It's a valid user! if($_CurrentUserAccount->checkAccess('p:/user/users/sudo')){ // This user can SUDO! // (only if the other user is < SA or current == SA). if($sudo->checkAccess('g:admin') && !$_CurrentUserAccount->checkAccess('g:admin')){ Session::UnsetKey('user_sudo'); \SystemLogModel::LogSecurityEvent('/user/sudo', 'Authorized but non-SA user requested sudo access to a system admin!', null, $sudo->get('id')); } else{ // Ok, everything is good. // Remap the current user over to this sudo'd account! $_CurrentUserAccount = $sudo; } } else{ // This user can NOT sudo!!! Session::UnsetKey('user_sudo'); \SystemLogModel::LogSecurityEvent('/user/sudo', 'Unauthorized user requested sudo access to another user!', null, $sudo->get('id')); } } else{ Session::UnsetKey('user_sudo'); } } return $_CurrentUserAccount; }
/** * Set all groups for a given user on the current site from a set of IDs. * * @param array $groups * @param bool|Model|string $context True to set all context groups, false to ignore, a string or model for the * specific context. * * @throws Exception */ protected function _setGroups($groups, $context) { // Map the groups to a complex array if necessary. foreach($groups as $key => $data) { if(!is_array($data)) { $groups[ $key ] = [ 'group_id' => $data, 'context' => '', 'context_pk' => '', ]; } } if($context === false) { // Skip all context groups. $contextname = null; $contextpk = null; } elseif($context === true) { // Skip regular groups, but include all context groups. $contextname = null; $contextpk = null; } elseif($context instanceof Model) { $contextname = substr(get_class($context), 0, -5); $contextpk = $context->getPrimaryKeyString(); $context = true; } elseif(is_scalar($context)) { $contextname = $context; $contextpk = null; $context = true; } else { throw new Exception('If a context is provided, please ensure it is either a model or model name'); } $uugs = $this->getLink('UserUserGroup'); foreach($uugs as $uug) { /** @var UserUserGroupModel $uug */ // Only process the requested group types. if($context && !$uug->get('context')) { // A context option was selected, but this is a regular group, skip it. continue; } elseif(!$context && $uug->get('context')) { // Similarly, no context was requested, but this group has one. continue; } elseif($context && $contextname && $uug->get('context') != $contextname) { // A context was requested, and a specific context name was set also! // But it doesn't match.... SKIP! continue; } elseif($context && $contextpk && $uug->get('context_pk') != $contextpk) { // A context was requested, and a specific context name was set also! // But it doesn't match.... SKIP! continue; } if(Core::IsComponentAvailable('multisite') && MultiSiteHelper::IsEnabled()) { // Only return this site's groups if in multisite mode $ugsite = $uug->getLink('UserGroup')->get('site'); if(!($ugsite == -1 || $ugsite == MultiSiteHelper::GetCurrentSiteID())) { /// Skip any group not on this site... they'll simply be ignored. continue; } } $gid = $uug->get('group_id'); $gcontext = $uug->get('context'); $gcontextpk = $uug->get('context_pk'); foreach($groups as $key => $data) { if($data['group_id'] == $gid && $data['context'] == $gcontext && $data['context_pk'] == $gcontextpk ) { // Yay, group matches up with both! // Unlink it from the groups array so it doesn't try to get recreated. unset($groups[ $key ]); continue 2; } } // This group isn't in the new list, unset it! $this->deleteLink($uug); } // Any new groups remaining? foreach($groups as $data) { $this->setLink( 'UserUserGroup', new UserUserGroupModel( $this->get('id'), $data['group_id'], $data['context'], $data['context_pk'] ) ); } // And clear the cache! $this->clearAccessStringCache(); }