public function view() { $page = PageRequest::GetSystemRequest(); $pageview = $page->getView(); $pagemetas = $pageview->meta; $view = $this->getView(); // The main identifier for livefyre, retrieved from within the livefyre "install" section. // Transposed to siteId $siteid = ConfigHandler::Get('/livefyre/siteid'); if (!$siteid) { $msg = 'Livefyre is not configured yet.'; if (\Core\user()->checkAccess('g:admin')) { $msg .= ' Please <a href="' . \Core\resolve_link('/livefyre') . '">configure it now</a>'; } return $msg; } // The "article" is the base url. This doesn't change despite changing URLs. // Transposed to articleId $article = $page->getBaseURL(); // The title, used in the collectionMeta. // Transposed to title $title = $pageview->title; // The canonical URL, used in the collectionMeta. $url = $pageview->canonicalurl; $view->assign('siteId', $siteid); $view->assign('articleId', $article); $view->assign('title', $title); $view->assign('url', $url); }
public function index() { $view = $this->getView(); $request = $this->getPageRequest(); if (!\Core\user()->checkAccess('g:admin')) { return View::ERROR_ACCESSDENIED; } if ($request->isPost()) { // Update/save the site id. ConfigHandler::Set('/livefyre/siteid', $_POST['siteid']); \Core\set_message('Set Site ID Successfully!', 'success'); \Core\reload(); } // Pull the configuration options to see if livefyre is currently setup. $siteid = ConfigHandler::Get('/livefyre/siteid'); // Generate the form to either set or update the siteid. $form = new Form(); $form->set('method', 'POST'); $form->addElement('text', ['name' => 'siteid', 'title' => 'Site ID', 'value' => $siteid]); $view->assign('siteid', $siteid); $view->assign('url', ROOT_URL_NOSSL); $view->assign('form', $form); // Setup instructions: // http://www.livefyre.com/install/ }
public function render() { if (!isset($this->_attributes['title'])) { $this->_attributes['title'] = ConfigHandler::Get('/captcha/formtext'); } return parent::render(); }
public static function SiteSearch() { $key = \ConfigHandler::Get('/google/cse/key'); $min = \ConfigHandler::Get('/core/markup/minified'); // If there's no code available, don't display anything. if (!$key) { return; } $script = <<<EOD \t\t<script> \t\t\t(function() { \t\t\t\tvar cx = '{$key}'; \t\t\t\tvar gcse = document.createElement('script'); \t\t\t\tgcse.type = 'text/javascript'; \t\t\t\tgcse.async = true; \t\t\t\tgcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + \t\t\t\t\t\t'//www.google.com/cse/cse.js?cx=' + cx; \t\t\t\tvar s = document.getElementsByTagName('script')[0]; \t\t\t\ts.parentNode.insertBefore(gcse, s); \t\t\t})(); \t\t</script> EOD; // Just to make it a little smaller... if ($min) { $script = trim(str_replace(array("\n", "\r"), '', $script)); } // Add the necessary script \Core\view()->addScript($script, 'foot'); return true; }
/** * @deprecated 2012.06.13 */ public function execute() { $v = $this->getView(); $u = Core::User(); $v->assign('user', $u); $v->assign('loggedin', $u->exists()); $v->assign('allowregister', ConfigHandler::Get('/user/register/allowpublic')); }
public static function InstallTracking() { $siteid = \ConfigHandler::Get('/piwik/siteid'); $server = \ConfigHandler::Get('/piwik/server/host'); $all_domains = \ConfigHandler::Get('/piwik/tracking/all_subdomains'); $domain_title = \ConfigHandler::Get('/piwik/tracking/domain_title'); // If there's no code available, don't display anything. if (!($siteid && $server)) { return; } // Trim the server. $server = trim($server, '/'); $paqopts = []; $paqopts[] = '"trackPageView"'; $paqopts[] = '"enableLinkTracking"'; if ($all_domains) { $h = '*.' . HOST; if (strpos($h, '*.www.') === 0) { $h = str_replace('*.www.', '*.', $h); } $paqopts[] = '"setCookieDomain", "' . $h . '"'; } if ($domain_title) { $paqopts[] = '"setDocumentTitle", document.domain + "/" + document.title'; } $paqstr = ''; foreach ($paqopts as $k => $v) { $paqstr .= ' _paq.push([' . $v . ']);' . "\n"; } // This version of the script is Piwik's newest version as of 2013.06.19 $script = <<<EOD <!-- Piwik --> <script type="text/javascript"> var _paq = _paq || []; {$paqstr} (function() { var u=(("https:" == document.location.protocol) ? "https" : "http") + "://{$server}/"; _paq.push(['setTrackerUrl', u+'piwik.php']); _paq.push(['setSiteId', {$siteid}]); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.type='text/javascript'; g.defer=true; g.async=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); })(); </script> <!-- End Piwik Code --> EOD; // Add the necessary scripts \Core\view()->addScript($script, 'head'); \Core\view()->appendBodyContent('<noscript><p><img src="http://' . $server . '/piwik.php?idsite=1" style="border:0" alt="" /></p></noscript>'); return true; }
public static function InstallTracking() { $gacode = \ConfigHandler::Get('/google-analytics/accountid'); $tagcode = \ConfigHandler::Get('/google/tagmanager/tagid'); //$site = HOST; $min = \ConfigHandler::Get('/core/markup/minified'); // If there's no code available, don't display anything. if ($tagcode) { // Tag Manager, load EITHER this or analytics. $script = <<<EOD <noscript> \t<iframe src="//www.googletagmanager.com/ns.html?id={$tagcode}" height="0" width="0" style="display:none;visibility:hidden"></iframe> </noscript> <script> \t(function(w,d,s,l,i){ \t\tw[l]=w[l]||[]; \t\tw[l].push( { \t\t\t'gtm.start': new Date().getTime(), \t\t\tevent:'gtm.js' \t\t}); \t\tvar f=d.getElementsByTagName(s)[0], \t\t\tj=d.createElement(s), \t\t\tdl=l!='dataLayer'?'&l='+l:''; \t\tj.async=true; \t\tj.src='//www.googletagmanager.com/gtm.js?id='+i+dl; \t\tf.parentNode.insertBefore(j,f); \t})(window,document,'script','dataLayer','{$tagcode}'); </script> EOD; } elseif ($gacode) { // This version of the script is Google's newest version as of 2014.05 $script = <<<EOD <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', '{$gacode}', 'auto'); ga('send', 'pageview'); </script> EOD; } else { return null; } // Just to make it a little smaller... if ($min) { $script = trim(str_replace(array("\n", "\r"), '', $script)); } // Add the necessary script \Core\view()->addScript($script, 'foot'); return true; }
public static function Load() { // I need jquery UI as a pre-req... if (!JQuery::IncludeJQueryUI()) { return false; } if (ConfigHandler::Get('/core/javascript/minified')) { \Core\view()->addScript('js/jquery.lightbox-0.5.min.js'); } else { \Core\view()->addScript('js/jquery.lightbox-0.5.js'); } \Core\view()->addStylesheet('css/jquery.lightbox-0.5.css'); // IMPORTANT! Tells the script that the include succeeded! return true; }
/** * Simple method to handle any legacy call to favicon.ico */ public function index() { $view = $this->getView(); $image = ConfigHandler::Get('/favicon/image'); $file = \Core\Filestore\Factory::File($image); $view->contenttype = 'image/png'; $view->record = false; $view->mode = View::MODE_NOOUTPUT; // Fix Bug #562, Favicon "none" option. // Do not render anything if no icon is selected. if (!$image) { return; } if (!$file->exists()) { return; } $file->displayPreview('32x32!'); }
/** * Widget to display some of the newest registrations, (if any). */ public function newestSignups(){ if(!\Core\user()->checkAccess('p:/user/users/manage')){ return ''; } // How far back do I want to search for? // 1 month sounds good! $date = new CoreDateTime(); $date->modify('-1 month'); $searches = UserModel::Find(['created > ' . $date->getFormatted('U')], 10, 'created DESC'); // No results? No problem :) if(!sizeof($searches)) return ''; $view = $this->getView(); $view->assign('enableavatar', (\ConfigHandler::Get('/user/enableavatar'))); $view->assign('users', $searches); }
public function register() { $view = $this->getView(); $user = \Core\user(); // Set the access permissions for this page as anonymous-only. if(!$user->checkAccess('g:anonymous;g:!admin')){ return ''; } // Also disallow access to this page if the configuration option is disabled. if(!ConfigHandler::Get('/user/register/allowpublic')){ return ''; } $auths = \Core\User\Helper::GetEnabledAuthDrivers(); $view->assign('drivers', $auths); }
public function __construct() { $admin = \Core\user()->checkAccess('g:admin'); $this->canupload = $admin || \Core\user()->checkAccess('p:/mediamanager/upload'); $this->canaccess = $this->canupload || \Core\user()->checkAccess('p:/mediamanager/browse'); switch (\ConfigHandler::Get('/mediamanager/sandbox')) { case 'user-sandboxed': $this->_basedir = 'public/media/' . \Core\user()->get('id') . '/'; break; case 'shared-user-sandbox': $this->_basedir = 'public/media/'; break; case 'completely-open': $this->_basedir = 'public/'; break; default: $this->_basedir = 'public/media/'; break; } }
public function badge() { $view = $this->getView(); $request = $this->getRequest(); $uid = $request->getParameter('user'); if ($uid instanceof UserModel) { $user = $uid; $uid = $user->get('id'); } else { $user = UserModel::Construct($uid); } $direction = $request->getParameter('direction') ? $request->getParameter('direction') : 'horizontal'; $orientation = $request->getParameter('orientation') ? $request->getParameter('orientation') : 'left'; $view->assign('enableavatar', \ConfigHandler::Get('/user/enableavatar')); $view->assign('link', UserSocialHelper::ResolveProfileLink($user)); $view->assign('user', $user); $view->assign('profiles', $user->get('external_profiles')); $view->assign('direction', $direction); $view->assign('orientation', $orientation); $view->assign('title', $request->getParameter('title')); }
public function fetch() { $data = []; $image = ConfigHandler::Get('/favicon/image'); if ($image) { $file = \Core\Filestore\Factory::File($image); } else { // Check the theme default. $file = \Core\Filestore\Factory::File('asset/images/favicon.png'); //return []; } if (!$file->exists()) { return []; } $data['favicon'] = '<link rel="icon" type="image/png" href="' . $file->getPreviewURL('32x32!') . '"/>'; $data['favicon-apple-touch-icon'] = '<link rel="apple-touch-icon" type="image/png" sizes="72x72" href="' . $file->getPreviewURL('72x72!') . '"/>'; $data['favicon-apple-touch-icon-2'] = '<link rel="apple-touch-icon" type="image/png" sizes="114x114" href="' . $file->getPreviewURL('114x114!') . '"/>'; $data['favicon-apple-touch-icon-retina'] = '<link rel="apple-touch-icon" sizes="512x512" type="image/png" href="' . $file->getPreviewURL('512x512!') . '"/>'; $data['favicon-windows-8'] = '<meta name="msapplication-TileImage" content="' . $file->getPreviewURL('270x270!') . '"/>'; return $data; }
public static function IncludeJQuery() { $use2x = \ConfigHandler::Get('/jquery/use_2_x'); if ($use2x === 'auto') { // Determine if it should be used based on the UA. // Remember, only IE <= 8.0 requires this. $ua = \Core\UserAgent::Construct(); if ($ua->browser == 'IE' && $ua->version <= 8) { $use2x = '0'; } else { $use2x = '1'; } } if ($use2x == '1') { // The site is setup to use 2.x, (default as of Core 4.0). \Core\view()->addScript('js/jquery/jquery-2.1.4.js'); } else { // The admin requested not to use the new version of jQuery. Stick with 1.11 then. \Core\view()->addScript('js/jquery/jquery-1.11.0.js'); } // IMPORTANT! Tells the script that the include succeeded! return true; }
/** * Display the login widget for facebook. This is actually just a button and FB handles the rest :) */ public function login() { // If facebook isn't in the list of allowed user backends, just exit out. if (!in_array('facebook', ConfigHandler::Get('/user/backends'))) { return ''; } $view = $this->getView(); $facebook = new Facebook(['appId' => FACEBOOK_APP_ID, 'secret' => FACEBOOK_APP_SECRET]); $user = $facebook->getUser(); if ($user) { // User was already logged in. try { $user_profile = $facebook->api('/me'); $facebooklink = false; } catch (Exception $c) { $facebooklink = $facebook->getLoginUrl(); } // $logoutUrl = $facebook->getLogoutUrl(); } else { $facebooklink = $facebook->getLoginUrl(); } $view->assign('facebooklink', $facebooklink); }
public static function Check() { $pw = \ConfigHandler::Get('/security/site_password'); if ($pw == '') { return true; } if (EXEC_MODE != 'WEB') { // Simple site passwords only work when on the web. return true; } if (isset($_SERVER['PHP_AUTH_PW'])) { $userpw = $_SERVER['PHP_AUTH_PW']; } else { $userpw = null; } if ($userpw != $pw) { header('WWW-Authenticate: Basic realm="' . SITENAME . '"'); header('HTTP/1.0 401 Unauthorized'); echo 'Access to ' . SITENAME . ' requires a password.'; exit; } // Else everything. return true; }
public function configure() { $view = $this->getView(); $request = $this->getPageRequest(); if (!\Core\user()->checkAccess('g:admin')) { return View::ERROR_ACCESSDENIED; } if ($request->isPost()) { \ConfigHandler::Set('/piwik/server/host', $_POST['server_host']); \ConfigHandler::Set('/piwik/siteid', $_POST['site_id']); \ConfigHandler::Set('/piwik/tracking/all_subdomains', $_POST['all_domains']); \ConfigHandler::Set('/piwik/tracking/domain_title', $_POST['domain_title']); \Core\set_message('Updated Piwik settings successfully', 'success'); \Core\reload(); } $form = new Form(); $form->addElement('text', ['name' => 'server_host', 'title' => 'Server Host', 'required' => false, 'value' => \ConfigHandler::Get('/piwik/server/host'), 'description' => 'Enter the hostname of your Piwik server without the protocol']); $form->addElement('text', ['name' => 'site_id', 'title' => 'Site ID', 'required' => false, 'value' => \ConfigHandler::Get('/piwik/siteid'), 'description' => 'Enter the Site ID of this installation']); $form->addElement('checkbox', ['name' => 'all_domains', 'title' => 'Track visitors across all subdomains of your site', 'description' => 'So if one visitor visits x.corepl.us and y.corepl.us, they will be counted as a single unique visitor.', 'value' => '1', 'checked' => \ConfigHandler::Get('/piwik/tracking/all_subdomains')]); $form->addElement('checkbox', ['name' => 'domain_title', 'title' => 'Prepend the site domain to the page title when tracking', 'description' => 'So if someone visits the "About" page on blog.corepl.us it will be recorded as "blog / About". This is the easiest way to get an overview of your traffic by sub-domain. ', 'value' => '1', 'checked' => \ConfigHandler::Get('/piwik/tracking/domain_title')]); $form->addElement('submit', ['name' => 'submit', 'value' => 'Update']); $view->title = 'Piwik Analytics'; $view->assign('form', $form); }
private function _forgotPassword1(){ $view = $this->getView(); $request = $this->getPageRequest(); // Create a simple form to render. This is better than doing it in the template. $form = new Form(); $form->set('method', 'POST'); if(\Core\user()->exists()){ // This may happen with the enable-password feature for facebook accounts. // They shouldn't have the option to change the email, but it should display where the information will go to. $form->addElement('system', ['name' => 'email', 'value' => \Core\user()->get('email')]); $current = \Core\user()->get('email'); } else{ $form->addElement('text', ['name' => 'email', 'title' => 'Email', 'required' => true]); $current = false; } $form->addElement('submit', ['name' => 'submit', 'value' => 'Send Reset Instructions']); $view->title = 'Forgot Password'; // This is step 1 $view->assign('step', 1); $view->assign('form', $form); $view->assign('current', $current); $view->assign('can_change_email', \ConfigHandler::Get('/user/email/allowchanging')); // Google has no business indexing user-action pages. $view->addMetaName('robots', 'noindex'); // There's really nothing to do here except for check the email and send it. if($request->isPost()){ if(\Core\user()->exists()){ /** @var UserModel $u */ $u = \Core\user(); } else{ /** @var UserModel $u */ $u = UserModel::Find(array('email' => $_POST['email']), 1); } if(!$u){ \Core\set_message('t:MESSAGE_ERROR_USER_LOGIN_EMAIL_NOT_FOUND'); SystemLogModel::LogSecurityEvent('/user/forgotpassword/send', 'Failed Forgot Password. Invalid email requested for reset: [' . $_POST['email'] . ']'); return; } // Use the Nonce system to generate a one-time key with this user's data. $nonce = NonceModel::Generate( '20 minutes', null, [ 'type' => 'password-reset', 'user' => $u->get('id'), ] ); $link = '/datastoreauth/forgotpassword/' . $nonce; $e = new Email(); $e->setSubject('Forgot Password Request'); $e->to($u->get('email')); $e->templatename = 'emails/user/datastoreauth_forgotpassword.tpl'; $e->assign('link', \Core\resolve_link($link)); $e->assign('ip', REMOTE_IP); try{ $e->send(); SystemLogModel::LogSecurityEvent('/user/forgotpassword/send', 'Forgot password request sent successfully', null, $u->get('id')); } catch(Exception $e){ \Core\set_message('Error sending the email, ' . $e->getMessage(), 'error'); SystemLogModel::LogErrorEvent('/user/forgotpassword/send', $e->getMessage()); return; } // Otherwise, it must have sent, (hopefully)... \Core\set_message('t:MESSAGE_SUCCESS_PLEASE_CHECK_EMAIL_FOR_PASSWORD_RESET_INSTRUCTIONS'); \core\redirect('/'); } }
/** * Interface to display and manage the spam keywords on the site. */ public function spam_keywords() { $view = $this->getView(); if (!\Core\user()->checkAccess('g:admin')) { return View::ERROR_ACCESSDENIED; } $threshold = \ConfigHandler::Get('/security/spam_threshold'); $table = new Core\ListingTable\Table(); $table->setLimit(100); // Set the model that this table will be pulling data from. $table->setModelName('SpamHamKeywordModel'); // Add in all the columns for this listing table. $table->addColumn('Keyword', 'keyword'); $table->addColumn('Score', 'score'); // This page will also feature a quick-edit feature. $table->setEditFormCaller('SecurityController::SpamKeywordsSave'); $table->loadFiltersFromRequest(); $view->addControl('Import Spam Training', '/security/spam/train', 'strikethrough'); $view->mastertemplate = 'admin'; $view->title = 'Spam Keywords'; $view->assign('listing', $table); $view->assign('threshold', $threshold); }
public function now(){ $request = $this->getPageRequest(); $view = $this->getView(); if(!$request->isJSON()) return View::ERROR_BADREQUEST; $view->contenttype = View::CTYPE_JSON; $view->mode = View::MODE_AJAX; $view->record = false; $limit = $this->_getQueryLimit(); $duration = 60; // Use FindRaw because it's faster than using full Models for everything, especially when dealing with 20k + records. $listings = UserActivityModel::FindRaw('datetime >= ' . (Time::GetCurrent() - $duration), $limit, 'datetime DESC'); $data = array(); // Performance reports $data['information'] = array( 'duration' => $duration, ); $data['performance'] = array('get' => 0, 'post' => 0); $data['requests'] = array('get' => 0, 'post' => 0); $users = array(); $bots = array(); $guestname = \ConfigHandler::Get('/user/displayname/anonymous'); foreach($listings as $log){ if($log['type'] == 'GET'){ $data['performance']['get'] += $log['processing_time']; $data['requests']['get']++; } elseif($log['type'] == 'POST'){ $data['performance']['post'] += $log['processing_time']; $data['requests']['post']++; } $ua = new \Core\UserAgent($log['useragent']); if(class_exists('\\geocode\\IPLookup')){ // If the geo library is available, use that to resolve the IP to something more meaningful than just a number. $lookup = new \geocode\IPLookup($log['ip_addr']); $file = \Core\Filestore\Factory::File('assets/images/iso-country-flags/' . strtolower($lookup->country) . '.png'); if($lookup->province && $lookup->city){ $title = $lookup->city . ', ' . $lookup->province . ', ' . $lookup->getCountryName(); } elseif($lookup->province){ $title = $lookup->province . ', ' . $lookup->getCountryName(); } elseif($lookup->city){ $title = $lookup->city . ' ' . $lookup->getCountryName(); } else{ $title = $lookup->getCountryName(); } $ip = '<span title="' . $title . '">'; if($file->exists()){ $ip .= '<img src="' . $file->getPreviewURL('20x20') . '" alt="' . $lookup->country . '"/> '; } $ip .= $log['ip_addr']; $ip .= '</span>'; } else{ $ip = $log['ip_addr']; } // Bots have their own data, because, well... they're bots. // Damn bots! if($ua->isBot()){ if(!isset($bots[ $log['ip_addr'] ])){ $bots[ $log['ip_addr'] ] = array( 'ip' => $ip, 'useragent' => $log['useragent'], 'lastpage' => $log['request'], 'status' => $log['status'], //'type' => $ua->, 'browser' => $ua->getAsHTML(), 'count' => 1, ); } else{ $bots[$log['ip_addr']]['count']++; } } // The user agent information I want to know on a per-user basis, not a per-click basis. else{ if(!isset($users[ $log['session_id'] ])){ $thisuser = UserModel::Construct($log['user_id']); $users[ $log['session_id'] ] = array( 'session' => $log['session_id'], 'ip' => $ip, 'user_id' => $log['user_id'], 'username' => ($thisuser ? $thisuser->getDisplayName() : $guestname), 'useragent' => $log['useragent'], 'lastpage' => $log['request'], //'type' => $ua->type, 'browser' => $ua->getAsHTML(), 'os' => '', 'count' => 1, ); } else{ $users[$log['session_id']]['count'] ++; } } } //UserAgent::Test(); die(); if($data['requests']['get'] > 0) $data['performance']['get'] = round($data['performance']['get'] / $data['requests']['get'], 2); if($data['requests']['post'] > 0) $data['performance']['post'] = $data['performance']['post'] / $data['requests']['post']; $data['users'] = array_values($users); $data['bots'] = array_values($bots); //var_dump($data, $users, $listings); die(); $view->jsondata = $data; }
/** * Get the directory iterator object of this object, ready to be iterated. * * @return DirectoryCAEIterator */ public function getDirectoryIterator() { if (is_null($this->_iterator)) { $this->_iterator = new CAEDirectoryIterator(); // @todo I imagine the calling function would want every directory, including the view... // this can be ignored manually if neeeded externally. // Ignore the view search directory if it has one. (provided via above loop) //if($this->hasView()) $this->_iterator->addIgnore($this->getViewSearchDir()); // Ignore the component metaxml, this will get added automatically via the installer. $this->_iterator->addIgnore($this->getXMLFilename()); // The core has a "few" extra ignores to it... if ($this->_name == 'core') { $this->_iterator->addIgnores('components/', 'config/', 'dropins/', 'exports/', 'nbproject/', 'scripts/', 'themes/', 'update_site/', 'utils/'); if (ConfigHandler::Get('/core/filestore/assetdir')) $this->_iterator->addIgnore(ConfigHandler::Get('/core/filestore/assetdir')); if (ConfigHandler::Get('/core/filestore/publicdir')) $this->_iterator->addIgnore(ConfigHandler::Get('/core/filestore/publicdir')); } // If the author set any files to be ignored.. ignore those too. $list = $this->getElements('/ignorefiles/file'); foreach ($list as $el) { $this->_iterator->addIgnores($this->getBaseDir() . $el->getAttribute('filename')); } $this->_iterator->setPath($this->getBaseDir()); // @todo Should this be done on the cached copy or not? // If additional 'addIgnores' are done, this scan will be invalidated and counter-productive. $this->_iterator->scan(); } // Do not return the original object, because the act of using the iterator will change it. // It tends to be very schroeder-esque..... Damn effing cat! return clone $this->_iterator; }
/** * Get if this theme is currently set as the site default. * * @return bool */ public function isDefault() { return \ConfigHandler::Get('/theme/selected') == $this->getKeyName(); }
public static function GetEnabledAuthDrivers(){ static $auths = null; if($auths === null){ // Get the available user auth systems available. $allauths = Helper::$AuthDrivers; // Which ones are currently enabled by the admin. $enabled = array_map('trim', explode('|', \ConfigHandler::Get('/user/authdrivers'))); // The classes of the actual driver backend. $auths = []; foreach($enabled as $name){ // Skip blank entries. if(!$name) continue; if(!isset($allauths[$name])){ // Skip non-present auth drivers. Means it's currently not installed. trigger_error('Bad Auth Driver [' . $name . '], it is not provided by any enabled component!', E_USER_NOTICE); continue; } try{ $ref = new \ReflectionClass( $allauths[$name] ); $auths[ $name ] = $ref->newInstance(); } catch(\Exception $e){ // I don't care, it just won't be enabled. // Do however notify the admin of this. trigger_error('Bad Auth Driver [' . $name . ']: ' . $e->getMessage(), E_USER_NOTICE); } } // There needs to be at least one! if(!sizeof($auths)){ $auths['datastore'] = new AuthDrivers\datastore(); } } return $auths; }
/** * Get an ascii hash of the filename. * useful for transposing this file to another page call. * * @return string The encoded string */ public function getFilenameHash() { $full = $this->getFilename(); if ($this->_type == 'asset'){ $base = 'assets/'; $filename = substr($full, strlen(Filestore\get_asset_path())); // If the filename starts with the current theme, (which it very well may), // trim that off too. // this script is meant to be a generic resource handle that gets resolved by the receiving script. if(strpos($filename, \ConfigHandler::Get('/theme/selected') . '/') === 0){ $filename = substr($filename, strlen(\ConfigHandler::Get('/theme/selected')) + 1); } elseif(strpos($filename, 'default/') === 0){ $filename = substr($filename, 8); } // And now I can add the base onto it. $filename = $base . $filename; } elseif ($this->_type == 'public'){ $filename = 'public/' . substr($full, strlen(Filestore\get_public_path() )); } elseif ($this->_type == 'private'){ $filename = 'private/' . substr($full, strlen(Filestore\get_private_path() )); } elseif ($this->_type == 'tmp'){ $filename = 'tmp/' . substr($full, strlen(Filestore\get_tmp_path() )); } else{ $filename = $full; } return 'base64:' . base64_encode($filename); }
/** * Cleanup any expired sessions from the database. * * @return bool Always returns true :) */ public static function CleanupExpired(){ static $lastexecuted = 0; /** * Delete ANY session that has expired. */ $ttl = \ConfigHandler::Get('/core/session/ttl'); $datetime = (\Time::GetCurrentGMT() - $ttl); if($lastexecuted == $datetime){ // This operation was already called this second. No need to do it again. // This is used because if a LOT of user operations occur on a given page, // this method may be called many many many times. return true; } // Low-level datasets are used here because they have less overhead than // the full-blown model system. $dataset = new Datamodel\Dataset(); $dataset->table('session'); $dataset->where('updated < ' . $datetime); $dataset->delete()->execute(); $lastexecuted = $datetime; // Always return TRUE return true; }
/** * Execute the actual cron for the requested type. * * @param string $cron Cron type to execute. * * @return CronLogModel * @throws Exception */ private function _performcron($cron) { switch ($cron) { case '1-minute': case '5-minute': case '15-minute': case '30-minute': case 'hourly': case '2-hour': case '3-hour': case '6-hour': case '12-hour': case 'daily': case 'weekly': case 'monthly': break; default: throw new Exception('Unsupported cron type: [' . $cron . ']'); } if (!ConfigHandler::Get('/cron/enabled')) { $msg = 'Cron execution is globally disabled via the site configuration, not executing cron!'; SystemLogModel::LogInfoEvent('/cron/' . $cron, $msg); // It needs to return something. $log = new CronLogModel(); $log->set('status', 'fail'); return $log; } // First, check and see if there's one that's still running. $runninglogs = CronLogModel::Find(array('cron' => $cron, 'status' => 'running')); if (sizeof($runninglogs)) { foreach ($runninglogs as $log) { /** @var $log CronLogModel */ $log->set('status', 'fail'); $log->set('log', $log->get('log') . "\n------------\nTIMED OUT!"); $log->save(); } } // Start recording. $log = new CronLogModel(); $log->set('cron', $cron); $log->set('status', 'running'); $log->set('memory', memory_get_usage()); $log->set('ip', REMOTE_IP); $log->save(); $start = microtime(true) * 1000; $sep = '==========================================' . "\n"; $contents = "Starting cron execution for {$cron}\n{$sep}"; // This uses the hook system, but will be slightly different than most things. $overallresult = true; $hook = HookHandler::GetHook('/cron/' . $cron); $hookcount = 0; $hooksuccesses = 0; if ($hook) { if ($hook->getBindingCount()) { $hookcount = $hook->getBindingCount(); $bindings = $hook->getBindings(); foreach ($bindings as $b) { $contents .= sprintf("\nExecuting Binding %s...\n", $b['call']); // Since these systems will just be writing to STDOUT, I'll need to capture that. try { ob_start(); $execution = $hook->callBinding($b, array()); $executiondata = ob_get_clean(); } catch (Exception $e) { $execution = false; $executiondata = 'EXCEPTION: ' . $e->getMessage() . ob_get_clean(); } if ($executiondata == '' && $execution) { $contents .= "Cron executed successfully with no output\n"; ++$hooksuccesses; } elseif ($execution) { $contents .= $executiondata . "\n"; ++$hooksuccesses; } else { $contents .= $executiondata . "\n!!FAILED\n"; $overallresult = false; } } } else { $contents = 'No bindings located for requested cron'; $overallresult = true; } } else { $contents = 'Invalid hook requested: ' . $cron; $overallresult = false; } // Just in case the contents are returning html... (they should be plain text). // Replace the most common line endings with things that make sense for plain text. // This is to ensure that all the available scenarios are met and saved/displayed without extra whitespace. // // Since some systems will provide plain text (easy!), windows/os9 line endings, // HTML (br and br/), and formatted HTML (br + \n). $contents = str_ireplace(["\r\n<br>", "\r\n<br/>", "\r\n<br />", "\n<br>", "\n<br/>", "\n<br />", "<br>", "<br/>", "<br />", "\r\n", "\r"], "\n", $contents); // Save the results. $log->set('completed', Time::GetCurrentGMT()); $log->set('duration', microtime(true) * 1000 - $start); $log->set('log', $contents); $log->set('status', $overallresult ? 'pass' : 'fail'); $log->save(); // Make a copy of this in the system log too if applicable. // This time is listed in ms $time = microtime(true) * 1000 - $start; // 0.01 = 10 ns // 1 = 1 ms // 1000 = 1 second if ($time < 1) { // TIME is less than 1, which means it executed faster than 1ms, display in nanoseconds. $time = round($time, 4) * 1000 . ' ns'; } elseif ($time < 1000) { // TIME is less than 1000, which means it executed faster than 1 second, display in milliseconds. $time = round($time, 0) . ' ms'; } else { // TIME is at least 1 second or longer... Display in minutes:seconds, (no need to display 1.453 seconds!) // First, convert the milliseconds to seconds; they are more manageable for what I need to do. // This will change time from 12345(ms) to 13(seconds) $time = ceil($time / 1000); $minutes = floor($time / 60); $seconds = $time - $minutes * 60; if ($minutes > 0) { $time = $minutes . 'm ' . str_pad($seconds, 2, '0', STR_PAD_LEFT) . 's'; } else { $time = $seconds . ' seconds'; } } if ($hookcount > 0) { $msg = 'Cron ' . $cron . ' completed in ' . $time . '. ' . $hooksuccesses . ' out of ' . $hookcount . ' hooks called successfully.'; SystemLogModel::LogInfoEvent('/cron/' . $cron, $msg, $contents); } // Just to notify the calling function. return $log; }
/** * Get the repository XML as a string that can be returned to the browser or cached for future use. * * @return string */ private function _getRepoXML() { $repo = new RepoXML(); $repo->setDescription(ConfigHandler::Get('/package_repository/description')); $dir = Factory::Directory(\ConfigHandler::Get('/package_repository/base_directory')); $coredir = $dir->getPath() . 'core/'; $componentdir = $dir->getPath() . 'components/'; $themedir = $dir->getPath() . 'themes/'; $tmpdir = Factory::Directory('tmp/exports/'); $gpg = new Core\GPG\GPG(); $keysfound = []; $private = ConfigHandler::Get('/package_repository/is_private') || strpos($dir->getPath(), ROOT_PDIR) !== 0; $addedpackages = 0; $failedpackages = 0; $iterator = new \Core\Filestore\DirectoryIterator($dir); // Only find signed packages. $iterator->findExtensions = ['asc']; // Recurse into sub directories $iterator->recursive = true; // No directories $iterator->findDirectories = false; // Just files $iterator->findFiles = true; // And sort them by their filename to make things easy. $iterator->sortBy('filename'); // Ensure that the necessary temp directory exists. $tmpdir->mkdir(); foreach ($iterator as $file) { /** @var \Core\Filestore\File $file */ $fullpath = $file->getFilename(); // Used in the XML file. if ($private) { $relpath = \Core\resolve_link('/packagerepository/download?file=' . substr($file->getFilename(), strlen($dir->getPath()))); } else { $relpath = $file->getFilename(ROOT_PDIR); } // Drop the .asc extension. $basename = $file->getBasename(true); // Tarball of the temporary package $tgz = Factory::File($tmpdir->getPath() . $basename); $output = []; // I need to 1) retrieve and 2) verify the key for this package. try { $signature = $gpg->verifyFileSignature($fullpath); if (!in_array($signature->keyID, $keysfound)) { $repo->addKey($signature->keyID, null, null); $keysfound[] = $signature->keyID; } } catch (\Exception $e) { trigger_error($fullpath . ' was not able to be verified as authentic, (probably because the GPG public key was not available)'); $failedpackages++; continue; } // decode and untar it in a temp directory to get the package.xml file. exec('gpg --homedir "' . GPG_HOMEDIR . '" -q -d "' . $fullpath . '" > "' . $tgz->getFilename() . '" 2>/dev/null', $output, $ret); if ($ret) { trigger_error('Decryption of file ' . $fullpath . ' failed!'); $failedpackages++; continue; } exec('tar -xzf "' . $tgz->getFilename() . '" -C "' . $tmpdir->getPath() . '" ./package.xml', $output, $ret); if ($ret) { trigger_error('Unable to extract package.xml from' . $tgz->getFilename()); unlink($tmpdir->getPath() . $basename); $failedpackages++; continue; } // Read in that package file and append it to the repo xml. $package = new PackageXML($tmpdir->getPath() . 'package.xml'); $package->getRootDOM()->setAttribute('key', $signature->keyID); $package->setFileLocation($relpath); $repo->addPackage($package); $addedpackages++; // But I can still cleanup! unlink($tmpdir->getPath() . 'package.xml'); $tgz->delete(); } return $repo->asPrettyXML(); }
private static function _Rotate(){ $dir = new DirectoryLocal('logs/'); $entries = $dir->ls('log'); foreach($entries as $file){ /** @var \Core\Filestore\Backends\FileLocal $file */ $log = new LogFile($file->getBasename(true)); try{ $log->archive(); echo 'Archived ' . $file->getBasename(true) . ' log.' . NL; } catch(\Exception $e){ echo $e->getMessage(); return false; } } if(\ConfigHandler::Get('/core/logs/rotate/keep')){ $entries = $dir->ls(); $types = []; foreach($entries as $file){ /** @var \Core\Filestore\Backends\FileLocal $file */ $base = $file->getBasename(); // I want only the filename before the first '.'. $base = substr($base, 0, strpos($base, '.')); if(!isset($types[$base])){ $types[$base] = []; } $types[$base][ $file->getMTime() ] = $file; } foreach($types as $base => $files){ // This will sort the files newest-to-oldest. krsort($files); $limit = \ConfigHandler::Get('/core/logs/rotate/keep'); $x = 0; $deleted = 0; foreach($files as $file){ /** @var \Core\Filestore\Backends\FileLocal $file */ ++$x; if($x > $limit){ if($file->exists()){ $file->delete(); ++$deleted; } } } if($deleted > 0){ echo 'Purged ' . $deleted . ' old ' . $base . ' log file(s).' . NL; } } } return true; }
/** * Get an array (locale => [lang, dialect, charset, dir]) of all locales enabled on the system, * XORed from the list of currently available locales on the native system. * * @return array */ public static function GetLocalesEnabled(){ $all = self::GetLocalesAvailable(); $enabled = \ConfigHandler::Get('/core/language/languages_enabled'); // This is expected to be a pipe-seperated list of languages/locales enabled. $enabled = array_map('trim', explode('|', $enabled)); // Return any enabled locale as long as it's available on the system. // Remap them to an array to ensure that the locale description/label is returned too. // This comes from the original GetLocalesAvaiable method. $out = []; foreach($enabled as $v){ if(isset($all[$v])){ $out[$v] = $all[$v]; } } return $out; }