/** * Get the template for this page's skin. * * @return \TemplatePHTML */ protected function getTemplate() { if($this->_template === null){ $c = get_called_class(); $template = str_replace('Core\\Installer\\', '', $c); $template = strtolower($template); $this->_template = Templates\Template::Factory(ROOT_PDIR . 'install/templates/' . $template . '.phtml'); } return $this->_template; }
/** * Get this result entry as rendered HTML. * * @return string */ public function fetch(){ $modelname = get_class($this->_model); // Trim off the "Model" part $modelname = substr($modelname, 0, -5); // And lowercase it. $modelname = strtolower($modelname); if(!Template::ResolveFile('search/model/' . $modelname . '.tpl')){ $out = parent::fetch(); if(DEVELOPMENT_MODE){ $out .= '<p class="message-error">Unable to find template [/search/model/' . $modelname . '.tpl] !</p>'; } return $out; } $tpl = Template::Factory('search/model/' . $modelname . '.tpl'); $tpl->assign('result', $this); $tpl->assign('model', $this->_model); return $tpl->fetch(); }
public static function _SaveEditorHandler(Form $form) { $newmodel = $form->getModel(); $file = $form->getElement('file')->get('value'); $activefile = $form->getElement('filetype')->get('value'); // The inbound file types depends on how to read the file. switch ($activefile) { case 'template': $filename = \Core\Templates\Template::ResolveFile($file); $customfilename = ROOT_PDIR . 'themes/custom/' . $file; break; case 'file': $filename = $file; // It'll get transposed. $customfilename = ROOT_PDIR . 'themes/custom/' . $file; break; default: \Core\set_message('Unsupported file type: ' . $activefile, 'error'); return false; } $customfh = \Core\Filestore\Factory::File($customfilename); if ($customfh->exists()) { // If the custom one exists... this will be the source file too! $sourcefh = $customfh; } else { $sourcefh = \Core\Filestore\Factory::File($filename); } // Check and see if they're the same, ie: no change. I don't want to create a bunch of moot revisions. if ($newmodel->get('content') == $sourcefh->getContents()) { \Core\set_message('No changes performed.', 'info'); return '/theme'; } // Before I overwrite this file, check and see if the original has been snapshot first! $c = ThemeTemplateChangeModel::Count(['filename = ' . $file]); if (!$c) { $original = new ThemeTemplateChangeModel(); $original->setFromArray(['comment' => 'Original File', 'filename' => $file, 'content' => $sourcefh->getContents(), 'content_md5' => $sourcefh->getHash(), 'updated' => $sourcefh->getMTime()]); $original->save(); } // All destination files get written to the custom directory! $customfh->putContents($newmodel->get('content')); $hash = $customfh->getHash(); /* // What happens now is based on the type of the inbound file. switch($activefile){ case 'skin': // Just replace the contents of that file. $fh->putContents($newmodel->get('content')); $hash = $fh->getHash(); break; case 'template': // This gets written into the current theme directory. $themefh = \Core\Filestore\Factory::File(ROOT_PDIR . 'themes/' . ConfigHandler::Get('/theme/selected') . '/' . $file); $themefh->putContents($newmodel->get('content')); $hash = $themefh->getHash(); break; case 'style': case 'file': // This gets written into the current theme directory. $themefh = \Core\Filestore\Factory::File(ROOT_PDIR . 'themes/' . ConfigHandler::Get('/theme/selected') . '/' . $file); $themefh->putContents($newmodel->get('content')); $hash = $themefh->getHash(); // This is required to get assets updated to the CDN correctly. $theme = ThemeHandler::GetTheme(); $hash = $themefh->getHash(); $theme->addAssetFile(array('file' => $file, 'md5' => $hash)); $theme->save(); $theme->reinstall(); default: } */ // Make a record of this change too! $change = new ThemeTemplateChangeModel(); $change->setFromArray(['comment' => $newmodel->get('comment'), 'filename' => $file, 'content' => $newmodel->get('content'), 'content_md5' => $hash]); $change->save(); if ($activefile == 'file') { // Reinstall all assets too! foreach (Core::GetComponents() as $component) { $component->reinstall(); } // And the current theme. ThemeHandler::GetTheme(ConfigHandler::Get('/theme/selected'))->reinstall(); } \Core\set_message('Updated file successfully', 'success'); return '/theme'; }
/** * Load all the components in the system, replacement for the Core. * @throws CoreException */ private function _loadComponents() { // cannot reload components. if ($this->_components) return null; $this->_components = array(); $this->_libraries = array(); $tempcomponents = false; Core\Utilities\Logger\write_debug('Starting loading of component metadata'); // If the site is in DEVELOPMENT mode, component caching would probably be a bad idea; ie: the developer probably wants // those component files loaded everytime. if(DEVELOPMENT_MODE){ $enablecache = false; } else{ $enablecache = true; } // Is there a cache of elements available? This is a primary system cache that greatly increases performance, // since it will no longer have to run through each component.xml file to register each one. if($enablecache){ Core\Utilities\Logger\write_debug('Checking core-components cache'); // Try to load up the cached components and check them first. $tempcomponents = \Core\Cache::Get('core-components', (3600 * 24)); if($tempcomponents !== false){ // Cached components only need to be loaded. foreach ($tempcomponents as $c) { try { $c->load(); } catch (Exception $e) { // Don't completely bail out here, just invalidate the cache and continue on. \Core\Cache::Delete('core-components'); $tempcomponents = false; } } } } if(!$enablecache || $tempcomponents == false){ \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Scanning for component.xml files manually'); Core\Utilities\Logger\write_debug('Scanning for component.xml files manually'); // Core is first, (obviously) $tempcomponents['core'] = ComponentFactory::Load(ROOT_PDIR . 'core/component.xml'); Core\Utilities\Logger\write_debug('Core component loaded'); // First, build my cache of components, regardless if the component is installed or not. $dh = opendir(ROOT_PDIR . 'components'); if (!$dh) throw new CoreException('Unable to open directory [' . ROOT_PDIR . 'components/] for reading.'); // This will read through every directory in 'components', which is // where all components in the system are installed to. while (($file = readdir($dh)) !== false) { // skip hidden directories. if ($file{0} == '.') continue; // skip non-directories if (!is_dir(ROOT_PDIR . 'components/' . $file)) continue; // Skip directories that do not have a readable component.xml file. if (!is_readable(ROOT_PDIR . 'components/' . $file . '/component.xml')) continue; //Core\Utilities\Logger\write_debug(' * Loading component ' . $file); $c = ComponentFactory::Load(ROOT_PDIR . 'components/' . $file . '/component.xml'); Core\Utilities\Logger\write_debug('Opened component ' . $file); // All further operations are case insensitive. // The original call to Component needs to be case sensitive because it sets the filename to pull. $file = strtolower($file); // If the component was flagged as invalid.. just skip to the next one. if (!$c->isValid()) { if (DEVELOPMENT_MODE) { \Core\set_message('Component ' . $c->getName() . ' appears to be invalid.'); } continue; } $tempcomponents[$file] = $c; unset($c); } closedir($dh); \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Component XML files scanned'); // Now I probably could actually load the components! foreach ($tempcomponents as $c) { /** @var Component_2_1 $c */ try { // Load some of the data in the class so that it's available in the cached version. // This is because the component 2.1 has built-in caching for many of the XML requests. // by calling them once, that lookup data is cached in that component, which in turn gets // copied to the cache version here! $c->load(); $c->getClassList(); $c->getViewSearchDir(); $c->getSmartyPluginDirectory(); $c->getWidgetList(); } catch (Exception $e) { var_dump($e); die(); } } // Cache this list! if($enablecache){ Core\Utilities\Logger\write_debug(' * Caching core-components for next pass'); \Core\Cache::Set('core-components', $tempcomponents, (3600 * 24)); } } $list = $tempcomponents; \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Component metadata loaded, starting registration'); Core\Utilities\Logger\write_debug(' * Component metadata loaded, starting registration'); // The core component at a minimum needs to be loaded and registered. // $this->_registerComponent($list['core']); // $this->_components['core']->loadFiles(); // unset($list['core']); // Now that I have a list of components available, copy them into a list of // components that are installed. do { $size = sizeof($list); foreach ($list as $n => $c) { /** @var $c Component_2_1 */ // Disabled components don't get recognized. if($c->isInstalled() && !$c->isEnabled()){ // But they do get sent to the disabled list! $this->_componentsDisabled[$n] = $c; unset($list[$n]); continue; } // Clear out the temporary class list $this->_tmpclasses = []; // If it's loaded, register it and remove it from the list! if ($c->isInstalled() && $c->isLoadable() && $c->loadFiles()) { try{ // Allow for on-the-fly package upgrading regardless of DEV mode or not. if ($c->needsUpdated()) { // Load this component's classes in case an upgrade operation requires one. // This allows a component to be loaded partially without completely being loaded. $this->_tmpclasses = $c->getClassList(); // Lock the site first! // This is because some upgrade procedures take a long time to upgrade. file_put_contents(TMP_DIR . 'lock.message', 'Core Plus is being upgraded, please try again in a minute. '); $c->upgrade(); unlink(TMP_DIR . 'lock.message'); } } catch(Exception $e){ SystemLogModel::LogErrorEvent('/core/component/failedupgrade', 'Ignoring component [' . $n . '] due to an error during upgrading!', $e->getMessage()); unlink(TMP_DIR . 'lock.message'); //$c->disable(); $this->_componentsDisabled[$n] = $c; unset($list[$n]); continue; } try{ $this->_components[$n] = $c; $this->_registerComponent($c); $c->loadSupplementalModels(); } catch(Exception $e){ SystemLogModel::LogErrorEvent('/core/component/failedregister', 'Ignoring component [' . $n . '] due to an error during registration!', $e->getMessage()); //$c->disable(); $this->_componentsDisabled[$n] = $c; unset($list[$n]); continue; } unset($list[$n]); continue; } // Allow for on-the-fly package upgrading regardless of DEV mode or not. // Guess this is needed for the loadFiles part... if ($c->isInstalled() && $c->needsUpdated() && $c->isLoadable()) { // Lock the site first! // This is because some upgrade procedures take a long time to upgrade. file_put_contents(TMP_DIR . 'lock.message', 'Core Plus is being upgraded, please try again in a minute. '); $c->upgrade(); $c->loadFiles(); $this->_components[$n] = $c; $this->_registerComponent($c); unlink(TMP_DIR . 'lock.message'); unset($list[$n]); continue; } // Allow packages to be auto-installed if in DEV mode. // If DEV mode is not enabled, just install the new component, do not enable it. if (!$c->isInstalled() && $c->isLoadable()) { // Load this component's classes in case an install operation requires one. // This allows a component to be loaded partially without completely being loaded. $this->_tmpclasses = $c->getClassList(); // w00t $c->install(); // BLAH, until I fix the disabled-packages-not-viewable bug... $c->enable(); $c->loadFiles(); $this->_components[$n] = $c; $this->_registerComponent($c); /* if(!DEVELOPMENT_MODE){ $c->disable(); } else{ $c->enable(); $c->loadFiles(); $this->_components[$n] = $c; $this->_registerComponent($c); } */ unset($list[$n]); continue; } } } while ($size > 0 && ($size != sizeof($list))); // If dev mode is enabled, display a list of components installed but not loadable. foreach ($list as $n => $c) { //$this->_components[$n] = $c; $this->_componentsDisabled[$n] = $c; // Ignore anything with the execmode different, those should be minor notices for debugging if anything. if ($c->error & Component_2_1::ERROR_WRONGEXECMODE) continue; if (DEVELOPMENT_MODE) { SystemLogModel::LogErrorEvent('/core/component/missingrequirement', 'Could not load installed component ' . $n . ' due to requirement failed.', $c->getErrors()); } } // Don't forget to load the themes too! if(class_exists('ThemeHandler')){ foreach(ThemeHandler::GetAllThemes() as $theme){ /** @var $theme Theme */ $theme->load(); } } // Lastly, make sure that the template path cache is updated! if(class_exists('\\Core\\Templates\\Template')){ \Core\Templates\Template::RequeryPaths(); } }
/** * Generate and print the rendered login markup to STDOUT. * * @param array $form_options * * @return void */ public function renderLogin($form_options = []) { if (!FACEBOOK_APP_ID) { echo 'Please configure Facebook with your APP_ID.'; return; } if (!FACEBOOK_APP_SECRET) { echo 'Please configure Facebook with your APP_SECRET.'; return; } $facebook = new \Facebook(['appId' => FACEBOOK_APP_ID, 'secret' => FACEBOOK_APP_SECRET]); // User was already logged in. try { $user = $facebook->getUser(); if ($user) { $user_profile = $facebook->api('/me'); $facebooklink = false; } else { $facebooklink = $facebook->getLoginUrl(); } } catch (\Exception $c) { $facebooklink = $facebook->getLoginUrl(); } // $logoutUrl = $facebook->getLogoutUrl(); $tpl = \Core\Templates\Template::Factory('includes/user/facebook_login.tpl'); $tpl->assign('facebooklink', $facebooklink); $tpl->render(); }
/** * Render this table's head content, (everything above the records). * * @return string Full HTML Markup. */ private function _renderHead(){ $template = Template::Factory('includes/listingtable/head.tpl'); $f = $this->getFilters(); if(!$this->_hassort){ // One final check for if these filters are sortable. $f->hassort = false; } $tableclasses = ['listing']; if($this->_hassort){ $tableclasses[] = 'listing-table-sortable'; } $atts = []; $atts['class'] = implode(' ', $tableclasses); $atts['data-table-name'] = $this->_name; $atts['data-table-sortable'] = ($this->_hassort ? 1 : 0); $tableAttributes = ''; foreach($atts as $k => $v){ $tableAttributes .= ' ' . $k . '="' . $v . '"'; } if($this->_editform !== null){ $this->addControl( [ 'link' => '#', 'class' => 'control-edit-toggle', 'icon' => 'pencil-square-o', 'title' => 'Quick Edit', ] ); } $template->assign('filters', $f); $template->assign('filters_rendered', $this->_renderFilters()); $template->assign('pagination_rendered', $this->_renderPagination()); $template->assign('table_attributes', $tableAttributes); $template->assign('edit_form', $this->_editform); $template->assign('columns', $this->_columns); $template->assign('controls', $this->getControls()); return $template->fetch(); }
/** * Set a template filename to be remembered if fetch or render are called with null parameters. * * @param string $template Filename to remember for this template. * * @return void */ public function setFilename($template) { // Make sure it's resolved first. $this->_filename = Templates\Template::ResolveFile($template); }
/** * Render this form element and return the HTML content. * * @return string */ public function render() { $file = $this->getTemplateName(); $tpl = \Core\Templates\Template::Factory($file); if($this->get('value')){ /** @var UserModel $user */ $user = UserModel::Construct($this->get('value')); } else{ $user = null; } $tpl->assign('element', $this); $tpl->assign('can_lookup', \Core\user()->checkAccess('p:/user/search/autocomplete')); $tpl->assign('username', ($user ? $user->getDisplayName() : '')); return $tpl->fetch(); }
/** * 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); }
/** * Standard render function for this form element * * @return string */ public function render() { static $renderedcount = 0; $renderedcount++; $this->_targetname = '_formaccessstring' . $renderedcount . \Core\random_hex(8); $v = trim($this->get('value')); $checked = 'advanced'; $advanced_groups = array(); $type = 'whitelist'; if ($v == '*') { $checked = 'basic_anyone'; } elseif ($v == '!*') { $checked = 'basic_admin'; } elseif (!$v) { // Blank value $checked = 'advanced'; } elseif ($v == 'g:anonymous') { $checked = 'basic_anonymous'; } elseif ($v == 'g:authenticated') { $checked = 'basic_authenticated'; } elseif ($v == 'none') { // Allow for a blank value. $checked = null; $type = null; } else { // Determine the sub groups checked. $checked = 'advanced'; $parts = array_map('trim', explode(';', $v)); foreach ($parts as $p) { if ($p == '*') { // If a wildcard is present, mark the groups as ones to blacklist. $type = 'blacklist'; continue; } list($t, $tv) = explode(':', $p); // Trim off the '!' in front of it, it'll be picked up by the presence of the '*' at the end. if ($tv{0} == '!') $tv = substr($tv, 1); $advanced_groups[] = $tv; } } $groups = array(); // Tack on the system groups. $anongroup = new UserGroupModel(); $anongroup->setFromArray( array( 'id' => 'anonymous', 'name' => 'Anonymous Users' ) ); $authgroup = new UserGroupModel(); $authgroup->setFromArray( array( 'id' => 'authenticated', 'name' => 'Authenticated Users' ) ); $groups[] = $anongroup; $groups[] = $authgroup; // Find all the groups currently on the site. $groups = array_merge($groups, UserGroupModel::Find(null, null, 'name')); foreach ($groups as $k => $v) { if (in_array($v->get('id'), $advanced_groups)) $v['checked'] = true; } $tpl = \Core\Templates\Template::Factory($this->getTemplateName()); $tpl->assign('element', $this); $tpl->assign('groups', $groups); $tpl->assign('dynname', $this->_targetname); $tpl->assign('main_checked', $checked); $tpl->assign('advanced_type', $type); return $tpl->fetch(); }
/** * Fetch this view as an HTML string. * @return mixed|null|string */ public function fetch() { if($this->_fetchCache !== null){ // w00t ;) return $this->_fetchCache; } try{ $body = $this->fetchBody(); \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record( 'Fetched application content from within View->fetch() for ' . $this->templatename ); } catch(Exception $e){ $this->error = View::ERROR_SERVERERROR; \Core\ErrorManagement\exception_handler($e, ($this->mode == View::MODE_PAGE)); $body = ''; } // If there's no template, I have nothing to even do! if ($this->mastertemplate === false) { return $body; } // Else if it's null, it's just not set yet :p // @deprecated here! elseif ($this->mastertemplate === null) { $this->mastertemplate = ConfigHandler::Get('/theme/default_template'); } // Whee! //var_dump($this->templatename, Core\Templates\Template::ResolveFile($this->templatename)); // Content types take priority on controlling the master template. if ($this->contenttype == View::CTYPE_JSON) { $mastertpl = false; } else { // Master template depends on the render mode. switch ($this->mode) { case View::MODE_PAGEORAJAX: if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){ $mastertpl = false; $this->mode = View::MODE_AJAX; } else{ $mastertpl = ROOT_PDIR . 'themes/' . ConfigHandler::Get('/theme/selected') . '/skins/' . $this->mastertemplate; $this->mode = View::MODE_PAGE; } break; case View::MODE_NOOUTPUT: case View::MODE_AJAX: $mastertpl = false; break; case View::MODE_PAGE: case View::MODE_EMAILORPRINT: $mastertpl = Core\Templates\Template::ResolveFile('skins/' . $this->mastertemplate); //$mastertpl = ROOT_PDIR . 'themes/' . ConfigHandler::Get('/theme/selected') . '/skins/' . $this->mastertemplate; break; case View::MODE_WIDGET: $mastertpl = Core\Templates\Template::ResolveFile('widgetcontainers/' . $this->mastertemplate); break; } } // If there's *still* no template, I still have nothing to do. if (!$mastertpl) return $body; $template = \Core\Templates\Template::Factory($mastertpl); // Ensure that the template is linked to this View correctly. $template->setView($this); //$template = new Core\Templates\Template(); //$template->setBaseURL('/'); // Page-level views have some special variables. if ($this->mode == View::MODE_PAGE) { $template->assign('breadcrumbs', $this->getBreadcrumbs()); $template->assign('controls', $this->controls); $template->assign('messages', Core::GetMessages()); // Tack on the pre and post body variables from the current page. //$body = CurrentPage::GetBodyPre() . $body . CurrentPage::GetBodyPost(); } // Widgets need some special variables too. //if($this->mode == View::MODE_WIDGET){ // //var_dump($this->getVariable('widget')); die(); // $template->assign('widget', $this->getVariable('widget')); //} // This logic is needed for the SEO title, since that's usually completely human unfriendly. if(isset($this->meta['title']) && $this->meta['title']){ $template->assign('seotitle', $this->meta['title']); } else{ $template->assign('seotitle', $this->getTitle()); } $template->assign('title', $this->getTitle()); $template->assign('body', $body); // The body needs some custom classes for assisting the designers. // These are mainly pulled from the UA. $ua = \Core\UserAgent::Construct(); $this->bodyclasses = array_merge($this->bodyclasses, $ua->getPseudoIdentifier(true)); // Provide a way for stylesheets to target this page specifically. switch ($this->error) { case View::ERROR_BADREQUEST: case View::ERROR_PAYMENTREQUIRED: case View::ERROR_ACCESSDENIED: case View::ERROR_NOTFOUND: case View::ERROR_METHODNOTALLOWED: case View::ERROR_NOTACCEPTABLE: case View::ERROR_PROXYAUTHENTICATIONREQUIRED: case View::ERROR_REQUESTTIMEOUT: case View::ERROR_CONFLICT: case View::ERROR_GONE: case View::ERROR_LENGTHREQUIRED: case View::ERROR_PRECONDITIONFAILED: case View::ERROR_ENTITYTOOLARGE: case View::ERROR_URITOOLARGE: case View::ERROR_UNSUPPORTEDMEDIATYPE: case View::ERROR_RANGENOTSATISFIABLE: case View::ERROR_EXPECTATIONFAILED: case View::ERROR_UNAUTHORIZED: $url = 'error-' . $this->error; break; case 403: $url = "error-403 page-user-login"; break; default: $url = strtolower(trim(preg_replace('/[^a-z0-9\-]*/i', '', str_replace('/', '-', $this->baseurl)), '-')); } while($url != ''){ $this->bodyclasses[] = 'page-' . $url; $url = substr($url, 0, strrpos($url, '-')); } $bodyclasses = strtolower(implode(' ', $this->bodyclasses)); $template->assign('body_classes', $bodyclasses); try{ $data = $template->fetch(); } catch(SmartyException $e){ $this->error = View::ERROR_SERVERERROR; error_log('[view error]'); error_log('Template name: [' . $mastertpl . ']'); \Core\ErrorManagement\exception_handler($e); require(ROOT_PDIR . 'core/templates/halt_pages/fatal_error.inc.html'); die(); } catch(TemplateException $e){ $this->error = View::ERROR_SERVERERROR; error_log('[view error]'); error_log('Template name: [' . $mastertpl . ']'); \Core\ErrorManagement\exception_handler($e); require(ROOT_PDIR . 'core/templates/halt_pages/fatal_error.inc.html'); die(); } if($this->mode == View::MODE_EMAILORPRINT && $this->contenttype == View::CTYPE_HTML){ // Inform other elements that the page is just about to be rendered. HookHandler::DispatchHook('/core/page/rendering', $this); // Replace the </head> tag with the head data from the current page // and the </body> with the foot data from the current page. // This is needed to be done at this stage because some element in // the template after rendering may add additional script to the head. // Also tack on any attributes for the <html> tag. if(preg_match('#</head>#i', $data)){ // I need to do preg_replace because I only want to replace the FIRST instance of </head> $data = preg_replace('#</head>#i', $this->getHeadContent() . "\n" . '</head>', $data, 1); } } elseif ($this->mode == View::MODE_PAGE && $this->contenttype == View::CTYPE_HTML) { // Inform other elements that the page is just about to be rendered. HookHandler::DispatchHook('/core/page/rendering', $this); // Metadata! w00t // Replace the </head> tag with the head data from the current page // and the </body> with the foot data from the current page. // This is needed to be done at this stage because some element in // the template after rendering may add additional script to the head. // Also tack on any attributes for the <html> tag. if(preg_match('#</head>#i', $data)){ // I need to do preg_replace because I only want to replace the FIRST instance of </head> $data = preg_replace('#</head>#i', $this->getHeadContent() . "\n" . '</head>', $data, 1); } if(preg_match('#</body>#i', $data)){ // I need to use strrpos because I only want the LAST instance of </body> $match = strrpos($data, '</body>'); $foot = $this->getFootContent(); if(defined('ENABLE_XHPROF') && function_exists('xhprof_disable')){ require_once('xhprof_lib/utils/xhprof_lib.php'); #SKIPCOMPILER require_once('xhprof_lib/utils/xhprof_runs.php'); #SKIPCOMPILER $xhprof_data = xhprof_disable(); $namespace = trim(str_replace(['.', '/'], '-', HOST . REL_REQUEST_PATH), '-'); $xhprof_runs = new XHProfRuns_Default(); $run_id = $xhprof_runs->save_run($xhprof_data, $namespace); define('XHPROF_RUN', $run_id); define('XHPROF_SOURCE', $namespace); $xhprof_link = sprintf( '<a href="' . SERVERNAME . '/xhprof/index.php?run=%s&source=%s" target="_blank">View XHprof Profiler Report</a>' . "\n", $run_id, $namespace ); } else{ $xhprof_link = ''; } // If the viewmode is regular and DEVELOPMENT_MODE is enabled, show some possibly useful information now that everything's said and done. if (DEVELOPMENT_MODE) { $legend = '<div class="fieldset-title">%s<i class="icon-chevron-down expandable-hint"></i><i class="icon-chevron-up collapsible-hint"></i></div>' . "\n"; $debug = ''; $debug .= '<pre class="xdebug-var-dump screen">'; $debug .= '<fieldset class="debug-section collapsible" id="debug-section-template-information">'; $debug .= sprintf($legend, 'Template Information'); $debug .= "<span>"; $debug .= 'Base URL: ' . $this->baseurl . "\n"; $debug .= 'Template Requested: ' . $this->templatename . "\n"; $debug .= 'Template Actually Used: ' . \Core\Templates\Template::ResolveFile($this->templatename) . "\n"; $debug .= 'Master Skin: ' . $this->mastertemplate . "\n"; $debug .= "</span>"; $debug .= '</fieldset>'; $debug .= '<fieldset class="debug-section collapsible" id="debug-section-performance-information">'; $debug .= sprintf($legend, 'Performance Information'); $debug .= "<span>"; $debug .= $xhprof_link; $debug .= "Database Reads: " . \Core\Utilities\Profiler\DatamodelProfiler::GetDefaultProfiler()->readCount() . "\n"; $debug .= "Database Writes: " . \Core\Utilities\Profiler\DatamodelProfiler::GetDefaultProfiler()->writeCount() . "\n"; //$debug .= "Number of queries: " . DB::Singleton()->counter . "\n"; //$debug .= "Amount of memory used by PHP: " . \Core\Filestore\format_size(memory_get_usage()) . "\n"; $debug .= "Amount of memory used by PHP: " . \Core\Filestore\format_size(memory_get_peak_usage(true)) . "\n"; $profiler = Core\Utilities\Profiler\Profiler::GetDefaultProfiler(); $debug .= "Total processing time: " . $profiler->getTimeFormatted() . "\n"; $debug .= "</span>"; $debug .= '</fieldset>'; $debug .= '<fieldset class="debug-section collapsible" id="debug-section-profiler-information">'; $debug .= sprintf($legend, 'Core Profiler'); $debug .= "<span>"; $debug .= $profiler->getEventTimesFormatted(); $debug .= "</span>"; $debug .= '</fieldset>'; $debug .= '<fieldset class="debug-section collapsible collapsed" id="debug-section-components-information">'; // Tack on what components are currently installed. $debug .= sprintf($legend, 'Available Components'); $debugcomponents = array_merge(Core::GetComponents(), Core::GetDisabledComponents()); $debug .= "<span>"; // Give me sorting! ksort($debugcomponents); foreach ($debugcomponents as $l => $v) { if($v->isEnabled() && $v->isReady()){ $debug .= '[<span style="color:green;">Enabled</span>]'; } elseif($v->isEnabled() && !$v->isReady()){ $debug .= '[<span style="color:red;">!ERROR!</span>]'; } else{ $debug .= '[<span style="color:red;">Disabled</span>]'; } $debug .= $v->getName() . ' ' . $v->getVersion() . "<br/>"; } $debug .= "</span>"; $debug .= '</fieldset>'; $debug .= '<fieldset class="debug-section collapsible collapsed" id="debug-section-hooks-information">'; // I wanna see what hooks are registered too! $debug .= sprintf($legend, 'Registered Hooks'); foreach(HookHandler::GetAllHooks() as $hook){ $debug .= "<span>"; /** @var $hook Hook */ $debug .= $hook->name; if($hook->description) $debug .= ' <em> - ' . $hook->description . '</em>'; $debug .= "\n" . '<span style="color:#999;">Return expected: ' . $hook->returnType . '</span>'; $debug .= "\n" . '<span style="color:#999;">Attached by ' . $hook->getBindingCount() . ' binding(s).</span>'; foreach($hook->getBindings() as $b){ $debug .= "\n" . ' * ' . $b['call']; } $debug .= "\n\n"; $debug .= "</span>"; } $debug .= '</fieldset>'; // Display the licensed content on this application $debug .= '<fieldset class="debug-section collapsible collapsed" id="debug-section-licenser-information">'; $debug .= sprintf($legend, 'Licensed Information'); $lic = \Core\Licenser::GetRaw(); $debug .= '<div>'; foreach($lic as $dat){ $debug .= $dat['url'] . '::' . $dat['feature'] . ' => ' . $dat['value'] . "\n"; } $debug .= '</div></fieldset>'; $debug .= '<fieldset class="debug-section collapsible collapsed" id="debug-section-includes-information">'; // I want to see how many files were included. $debug .= sprintf($legend, 'Included Files'); $debug .= '<span>Number: ' . sizeof(get_included_files()) . "</span>"; $debug .= '<span>'. implode("<br/>", get_included_files()) . "</span>"; $debug .= '</fieldset>'; $debug .= '<fieldset class="debug-section collapsible collapsed" id="debug-section-query-information">'; $debug .= sprintf($legend, 'Query Log'); $profiler = \Core\Utilities\Profiler\DatamodelProfiler::GetDefaultProfiler(); $debug .= '<div>' . $profiler->getEventTimesFormatted() . '</div>'; $debug .= '</fieldset>'; // Display all the i18n strings available on the system. $debug .= '<fieldset class="debug-section collapsible collapsed" id="debug-section-i18nstrings-information">'; $debug .= sprintf($legend, 'I18N Strings Available'); $strings = \Core\i18n\I18NLoader::GetAllStrings(); $debug .= '<ul>'; foreach($strings as &$s){ $debug .= '<li>' . $s['key'] . '</li>'; } $debug .= '</ul>'; $debug .= '</fieldset>'; $debug .= '</pre>'; // And append! $foot .= "\n" . $debug; } $data = substr_replace($data, $foot . "\n" . '</body>', $match, 7); } $data = preg_replace('#<html#', '<html ' . $this->getHTMLAttributes(), $data, 1); // This logic has been migrated to the {$body_classes} variable. /* if(preg_match('/<body[^>]*>/', $data, $matches)){ // body is $matches[0]. $fullbody = $matches[0]; if($fullbody == '<body>'){ $body = '<body class="' . $bodyclass . '">'; } elseif(strpos($fullbody, 'class=') === false){ // Almost as easy, other elements but no class. $body = substr($fullbody, 0, -1) . ' class="' . $bodyclass . '">'; } else{ // parsing HTML is far easier with XML objects. $node = new SimpleXMLElement($fullbody . '</body>'); $body = '<body'; foreach($node->attributes() as $k => $v){ if($k == 'class'){ $body .= ' ' . $k . '="' . $bodyclass . ' ' . $v . '"'; } else{ $body .= ' ' . $k . '="' . $v . '"'; } } $body .= '>'; } // And replace! $data = preg_replace('#<body[^>]*>#', $body, $data, 1); } */ } $this->_fetchCache = $data; return $data; }
/** * Hook into /core/page/rendering to add the control link for this page if necessary and the user has the appropriate permissions. */ public static function HookPageRender(){ $viewer = \Core\user()->checkAccess('p:/core/widgets/manage'); $manager = \Core\user()->checkAccess('p:/core/widgets/manage'); if(!($viewer || $manager)){ // User does not have access to view nor to edit widgets, simply return out of here. return true; } $request = \Core\page_request(); $view = \Core\view(); $page = $request->getPageModel(); $tmplName = $page->get('last_template') ? $page->get('last_template') : $view->templatename; if(!$tmplName){ // This page has no templates, ergo no widget areas. return true; } $template = \Core\Templates\Template::Factory($tmplName); $areas = $template->getWidgetAreas(); if(!sizeof($areas)){ // Selected template does not have any widget areas defined, no need to display the option then! return true; } // Otherwise... $view->addControl('Page Widgets', '/admin/widgets?baseurl=' . $page->get('baseurl'), 'cog'); return true; }
/** * Inject a CSS file or snippet into the head of a page. * * This is the recommended way to inject stylesheets into your application. * * Any inline styles or links to stylesheets added via the `{css}` smarty block are automatically moved into the head of the document. * Redundant file includes and inline styles are omitted automatically. * * CSS files have their minified version sent automatically when the Core config option is set to do so. * * #### Smarty Parameters * * * media * * (string) The media attribute, defaults to "all". * * href * * The source of the linked CSS asset. * * Can be fully resolved or a Core asset/* path. * * link * * alias of href. * * src * * alias of href. * * optional * * Set to "1" if this is an optional stylesheet where the admin can toggle on/off its inclusion. * * Currently only supported in theme skins. * * default * * If optional="1", this is if the file is included by default or not. * * title * * If optional="1", this is an optional title displayed for the admin. * * #### Example Usage * * Include an asset file located in css/ called styles.css. * <pre> * {css src="css/styles.css"}{/css} * </pre> * * (For a theme skin), provide the admin with the option to include this stylesheet * <pre> * {css src="css/opt/full-width.css" optional="1" default="0" title="Set the page to be full width"}{/css} * </pre> * * Inject these styles into the page * <pre> * {css} * <style> * .blah { * width: auto; * } * </style> * {/css} * </pre> * * @param array $params Associative (and/or indexed) array of smarty parameters passed in from the template * @param string|null $content Null on opening pass, rendered source of the contents inside the block on closing pass * @param Smarty $smarty Parent Smarty template object * @param boolean $repeat True at the first call of the block-function (the opening tag) and * false on all subsequent calls to the block function (the block's closing tag). * Each time the function implementation returns with $repeat being TRUE, * the contents between {func}...{/func} are evaluated and the function implementation * is called again with the new block contents in the parameter $content. */ function smarty_block_css($params, $content, $smarty, &$repeat){ // This only needs to be called once. if($repeat) return; // media type is the first parameter to check for. $media = (isset($params['media'])) ? $params['media'] : 'all'; $inline = isset($params['inline']) && $params['inline'] == '1' ? true : false; $tmpl = $smarty->getTemplateVars('__core_template'); $view = ($tmpl instanceof \Core\Templates\TemplateInterface) ? $tmpl->getView() : \Core\view(); // See if there's a "href" set. If so, that's probably an asset. // I have a tendency of calling this different things, since things in the head all have // different names for this crap! // as such, support a bunch of different properties.... $href = null; if(isset($params['href'])) $href = $params['href']; elseif(isset($params['link'])) $href = $params['link']; elseif(isset($params['src'])) $href = $params['src']; // Standard include from an asset. if($href !== null){ // If optional is set, then look up the data to see if it's set. if(isset($params['optional']) && $params['optional']){ $file = $smarty->template_resource; // Trim off the base directory. $paths = \Core\Templates\Template::GetPaths(); foreach($paths as $p){ if(strpos($file, $p) === 0){ $file = substr($file, strlen($p)); break; } } // Look up and see if this css is requested to be loaded by the user. $model = TemplateCssModel::Construct($file, $href); $enabled = $model->exists() ? $model->get('enabled') : (isset($params['default']) ? $params['default'] : 0); if(!$enabled) return; } if($inline){ // Allow stylesheets to be rendered "in-line" in the code. // This is only really useful for emails and other HTML fragments. $file = Core\Filestore\resolve_asset_file($href); if(\ConfigHandler::Get('/core/javascript/minified')){ // Remove the extension from the filename, (makes the logic cleaner). $dir = $file->getDirectoryName(); $filename = $file->getBaseFilename(true); $ext = $file->getExtension(); // Core is set to use minified css and javascript assets, try to locate those! // I need to do the check based on the base $filename, because 'assets/css/reset.css' may reside in one // of many locations, and not all of them may have a minified version. // Try to load the minified version instead. $minified = $filename . '.min.' . $ext; $minfile = \Core\Filestore\Factory::File($dir . $minified); if($minfile->exists()){ // Overwrite the $file variable so it's returned instead. $file = $minfile; } } $view->addStyle('<style media="' . $media . '">' . $file->getContents() . '</style>'); } else{ $view->addStylesheet($href, $media); } } // Styles defined inline, fine as well. The styles will be displayed in the head. elseif($content){ $view->addStyle($content); } }
/** * Generate and print the rendered registration markup to STDOUT. * * @return void */ public function renderRegister() { /** @var \Form $form */ $form = new \Form(); $form->set('callsmethod', 'GPGAuthController::RegisterHandler'); $form->addElement('hidden', ['name' => 'redirect', 'value' => CUR_CALL]); $key = \NonceModel::Generate('5 minutes', null, ['original_redirect' => CUR_CALL]); $url = \Core\resolve_link('/gpgauth/rawupload'); $cmd = <<<EOD gpg --list-secret-keys; \\ echo -n "Please enter the 8-characters of the key to use (the part after the '/' on the 'sec' line: "; \\ read IN; \\ gpg --export -a \$IN 2>/dev/null | curl --data-binary @- \\ --header "X-Core-Nonce-Key: $key" \\ $url EOD; $form->addElement( 'text', [ 'name' => 'email', 'required' => true, 'title' => 'Email Address', 'description' => 'Your email address, MUST be included in the GPG key!', ] ); $form->addElement( 'textarea', [ 'name' => 'key', 'required' => true, 'title' => 'GPG Public Key', ] ); $form->addElement('submit', ['value' => 'Continue With GPG']); $tpl = \Core\Templates\Template::Factory('includes/user/gpg_register.tpl'); $tpl->assign('form', $form); $tpl->assign('cmd', $cmd); $tpl->assign('nonce', $key); $tpl->assign('is_manager', \Core\user()->checkAccess('p:/user/users/manage')); $tpl->render(); }
private function _render($readonly = false){ $filterset = $this->hasSet(); $tpl = \Core\Templates\Template::Factory('forms/filters.tpl'); $tpl->assign('filtersset', $filterset); $tpl->assign('elements', $this->_elements); $tpl->assign('hassort', $this->hassort); $tpl->assign('sortkey', $this->getSortKey()); $tpl->assign('sortdir', $this->getSortDirection()); $tpl->assign('readonly', $readonly); $tpl->assign('records_total', $this->_total); $tpl->assign('records_current', min($this->_limit, $this->_total)); return $tpl->fetch(); }
/** * Render this form and all inside elements to valid HTML. * * This will also save the form to the session data for post-submission validation. * (if called with null or "foot") * * @param mixed $part "body|head|foot| or null * Render just a specific part of the form. Useful for advanced usage. * null: Render all of the form and its element. * "head": Render just the beginning of the form, including the <form> opening tag. * "body": Render just the body of the form, specifically the elements. * "foot": Render just the end of the form, including the </form> closing tag. * * @return string (valid HTML) */ public function render($part = null) { // Check and see if there are any elements in this form that require a fileupload. foreach ($this->getElements() as $e) { if ($e->requiresupload) { $this->set('enctype', 'multipart/form-data'); break; } } // Will be used to know if the errors in elements should be removed prior to rendering. $ignoreerrors = false; // Slip in the formid tracker to remember this submission. if (($part === null || $part == 'body') && $this->get('callsmethod')) { /*$e = new FormHiddenInput(array('name' => '___formid', 'value' => $this->get('uniqueid'))); $this->_elements = array_merge(array($e), $this->_elements); */ /* // I need to ensure a repeatable but unique id for this form. // Essentially when this form is submitted, I need to be able to know that it's the same form upon re-rendering. if (!$this->get('uniqueid')) { $hash = $this->generateUniqueHash(); $this->set('uniqueid', $hash); $this->getElementByName('___formid')->set('value', $hash); } */ // Was this form already submitted, (and thus saved in the session? // If so, render that form instead! This way the values get transported seamlessly. // I need the hash at present, regardless if all elements have been rendered to the screen or not. $hash = ($this->get('uniqueid') ? $this->get('uniqueid') : $this->generateUniqueHash()); if (($savedform = \Core\Session::Get('FormData/' . $hash)) !== null) { if (($savedform = unserialize($savedform))) { /** @var Form $savedform */ // If this form is not set as persistent, then don't restore the values! if($savedform->persistent){ foreach($this->_elements as $k => $element){ /** @var FormElement $element */ if($element->persistent){ $this->_elements[$k] = $savedform->_elements[$k]; } } } } else { $ignoreerrors = true; } } else { $ignoreerrors = true; } } if(($part == null || $part == 'foot') && $this->get('callsmethod')){ // I need to ensure a repeatable but unique id for this form. // Essentially when this form is submitted, I need to be able to know that it's the same form upon re-rendering. if (!$this->get('uniqueid')) { $hash = $this->generateUniqueHash(); $this->set('uniqueid', $hash); } } if ($ignoreerrors) { foreach ($this->getElements(true) as $el) { $el->setError(false); } } $tpl = \Core\Templates\Template::Factory('forms/form.tpl'); $tpl->assign('group', $this); if ($part === null || $part == 'body') { $els = ''; // Fill in the elements foreach ($this->_elements as $e) { $els .= $e->render(); } $tpl->assign('elements', $els); } switch ($part) { case null: $out = $tpl->fetch('forms/form.tpl'); break; case 'head': $out = $tpl->fetch('forms/form.head.tpl'); break; case 'body': $out = $tpl->fetch('forms/form.body.tpl'); break; case 'foot': $out = $tpl->fetch('forms/form.foot.tpl'); break; default: if(($el = $this->getElement($part)) !== false){ $out = $el->render(); } } // Save it $this->referrer = \Core\page_request()->referrer; $this->originalurl = CUR_CALL; $this->persistent = false; if (($part === null || $part == 'foot') && $this->get('callsmethod')) { $this->saveToSession(); } return $out; }
/** * Get an array of alternative display templates for this instance. * * This is based on the widget's baseurl. * * @return array */ public function getAlternativeTemplateOptions(){ $parts = $this->splitParts(); // Figure out the template directory for custom pages, (if it exists) // In order to get the types, I need to sift through all the potential template directories and look for a directory // with the matching name. $tmpname = 'widgets' . strtolower('/' . substr($parts['controller'], 0, -6) . '/' . $parts['method']); $matches = []; foreach(\Core\Templates\Template::GetPaths() as $d){ if(is_dir($d . $tmpname)){ // Yay, sift through that and get the files! $dir = \Core\Filestore\Factory::Directory($d . $tmpname); foreach($dir->ls('tpl') as $file){ // Skip directories if($file instanceof \Core\Filestore\Directory) continue; /** @var $file \Core\Filestore\File */ //$fullpath = $tmpname . $file->getBaseFilename(); $name = $fullpath = $file->getBaseFilename(); // Do some template updates and make it a little more friendlier to read. $name = ucwords(str_replace('-', ' ', substr($name, 0, -4))) . ' Template'; $matches[ $fullpath ] = $name; } } } return ['' => '-- Default Template --'] + $matches; }
/** * Generate and print the rendered registration markup to STDOUT. * * @return void */ public function renderRegister() { $form = new \Form(); $complexity = $this->getPasswordComplexityAsHTML(); $usermanager = \Core\user()->checkAccess('p:/user/users/manage'); if($complexity){ $password_desc = 'Please set a secure password that <br/>' . $complexity; } else{ $password_desc = t('MESSAGE_PLEASE_SET_SECURE_PASSWORD'); } // I can utilize this form, but tweak the necessary options as necessary. // Replace the password field with a text input for the GPG key. $form->set('callsmethod', 'DatastoreAuthController::RegisterHandler'); $form->addElement('hidden', ['name' => 'redirect']); $form->addElement( 'text', [ 'required' => true, 'name' => 'email', 'title' => t('STRING_EMAIL'), 'description' => ($usermanager ? 'The email address of the user to create' : 'Your email address'), ] ); if($usermanager){ $form->addElement( 'checkbox', [ 'name' => 'pwgen', 'value' => '1', 'title' => t('STRING_GENERATE_SECURE_PASSWORD'), 'description' => t('MESSAGE_GENERATE_SECURE_PASSWORD'), ] ); } $form->addElement( 'password', [ 'required' => ($usermanager ? false : true), 'name' => 'pass', 'title' => t('STRING_PASSWORD'), 'description' => $password_desc, ] ); $form->addElement( 'password', [ 'required' => ($usermanager ? false : true), 'name' => 'pass2', 'title' => t('STRING_CONFIRM_PASSWORD'), 'description' => t('MESSAGE_CONFIRM_PASSWORD'), ] ); $form->addElement('submit', ['value' => t('STRING_CONTINUE')]); $tpl = Template::Factory('includes/user/datastore_register.tpl'); $tpl->assign('is_manager', $usermanager); $tpl->assign('form', $form); $tpl->render(); }
public function render(){ if(!$this->get('templatename')){ throw new Exception('Unable to render pageselectinput element without templatename set!'); } // Figure out the template directory for custom pages, (if it exists) // In order to get the types, I need to sift through all the potential template directories and look for a directory // with the matching name. $tmpname = substr($this->get('templatename'), 0, -4) . '/'; $matches = array(); foreach(\Core\Templates\Template::GetPaths() as $d){ if(is_dir($d . $tmpname)){ // Yay, sift through that and get the files! $dir = \Core\Filestore\Factory::Directory($d . $tmpname); foreach($dir->ls('tpl') as $file){ // Skip directories if($file instanceof \Core\Filestore\Directory) continue; /** @var $file \Core\Filestore\File */ //$fullpath = $tmpname . $file->getBaseFilename(); $fullpath = $file->getBaseFilename(); $name = $file->getBaseFilename(); // Do some template updates and make it a little more friendlier to read. $name = ucwords(str_replace('-', ' ', substr($name, 0, -4))) . ' Template'; $matches[ $fullpath ] = $name; } } } // Are there any matches? If not just return a blank string. if(!sizeof($matches)){ return ''; } $options = array_merge(array('' => '-- Default Page Template --'), $matches); $this->set('options', $options); return parent::render(); }
/** * @return string * @throws Exception */ public function render() { if (!$this->get('id')) { // This system requires a valid id. ++self::$_AutoID; $this->set('id', 'formfileinput-' . self::$_AutoID); } if (!$this->get('basedir')) { throw new Exception('FormFileInput cannot be rendered without a basedir attribute!'); } // If multiple is set, but the name does not have a [] at the end.... add it. if ($this->get('multiple') && !preg_match('/.*\[.*\]/', $this->get('name'))) $this->_attributes['name'] .= '[]'; $file = $this->getTemplateName(); $tpl = \Core\Templates\Template::Factory($file); $mediaavailable = Core::IsComponentAvailable('media-manager'); $browsable = ( $mediaavailable && \Core\user()->checkAccess('p:/mediamanager/browse') && ($this->get('browsable') || $this->get('browseable')) ); //var_dump($file, $this); die(); $tpl->assign('element', $this); $tpl->assign('browsable', $browsable); return $tpl->fetch(); }
/** * Get all the email skins registered for this theme. * Each template can be a different site skin, ie: 2-column, 3-column, etc. * * @return array */ public function getEmailSkins() { $out = []; $default = null; $currenttheme = false; // If this theme is currently selected, check the default template too. if ($this->getKeyName() == \ConfigHandler::Get('/theme/selected')) { $default = \ConfigHandler::Get('/theme/default_email_template'); $currenttheme = true; } foreach ($this->_xmlloader->getElements('//emailskins/file') as $f) { $basefilename = $f->getAttribute('filename'); $filename = $this->getBaseDir() . 'emailskins/' . $basefilename; $skin = \Core\Templates\Template::Factory($filename); $title = $basefilename; // The return is expecting an array. $out[] = ['filename' => $filename, 'file' => $basefilename, 'title' => $title, 'default' => $default == $basefilename, 'current_theme' => $currenttheme]; } // Tack on the main default... no skin! $out[] = ['filename' => '', 'file' => '', 'title' => '-- No Skin --', 'default' => $default == '', 'current_theme' => $currenttheme]; return $out; }
public function render() { // Make sure that some defaults are set first. if (!$this->get('name')) { $this->set('name', 'address'); } if ($this->_model && ($this->_model->exists() || $this->_model->changed())) { // There is a valid model set, I can pull all the values from that! // This should also be used if the model was created but doesn't exist in the database, but was changed. // ie: a user entered information on a new model, but had an error that kicked it back. // that model may not exist, but it has been changed with the user's data, and so needs to be preserved. $v = $this->_model->getAsArray(); } else { // There is no model currently set, fine... I'll just use some defaults. $v = ['id' => '', 'label' => '', 'address1' => '', 'address2' => '', 'city' => REMOTE_CITY, 'province' => REMOTE_PROVINCE, 'postal' => '', 'country' => REMOTE_COUNTRY]; } $id = $v['id']; $label = $v['label']; $address1 = $v['address1']; $address2 = $v['address2']; $city = $v['city']; $province = $v['province']; $postal = $v['postal']; $country = $v['country']; // Get the provinces for the given selected country, (to save an ajax call) $provinces = GeoProvinceModel::Find(['country = ' . $country]); $countries = GeoCountryModel::Find(null, null, 'name'); // Convert the provinces to JSON data so the javascript // can use it as if it had loaded from the server. $provincejs = []; foreach ($provinces as $p) { /** @var GeoProvinceModel $p */ $provincejs[] = $p->getAsArray(); } $file = $this->getTemplateName(); $tpl = \Core\Templates\Template::Factory($file); $tpl->assign('id', $id); $tpl->assign('use_label', $this->_attributes['use_label']); $tpl->assign('label', $label); $tpl->assign('address1', $address1); $tpl->assign('address2', $address2); $tpl->assign('city', $city); $tpl->assign('province', $province); $tpl->assign('postal', $postal); $tpl->assign('country', $country); $tpl->assign('provinces', $provinces); $tpl->assign('province_json', json_encode($provincejs)); $tpl->assign('countries', $countries); $tpl->assign('element', $this); $tpl->assign('req', $this->get('required')); return $tpl->fetch(); }