/** * Take a GMT date and return the formatted string. * * @todo Finish documentation of smarty_function_date * * #### Smarty Parameters * * * date (or unnamed variable) * * format * * assign * * #### Example Usage * * <pre> * {date 1234567890} * </pre> * * @param array $params Associative (and/or indexed) array of smarty parameters passed in from the template * @param Smarty $smarty Parent Smarty template object * * @throws SmartyException * * @return string */ function smarty_function_date($params, $smarty){ if(array_key_exists('date', $params)){ $date = $params['date']; } elseif(isset($params[0])){ $date = $params[0]; } else{ // Use "now" as the time. $date = \Core\Date\DateTime::Now(Time::FORMAT_RFC2822); } if(!$date){ if(DEVELOPMENT_MODE){ return 'Parameter [date] was empty, cowardly refusing to format an empty string.'; } else{ return ''; } } $format = isset($params['format']) ? $params['format'] : \Core\Date\DateTime::RELATIVE; //$timezone = isset($params['timezone']) ? $params['timezone'] : Time::TIMEZONE_GMT; $coredate = new \Core\Date\DateTime($date); if(isset($params['assign']) && $params['assign']){ $smarty->assign($params['assign'], $coredate->format($format)); } else{ return $coredate->format($format); } }
/** * Get the released/packaged date of this version as a UTC int * * @return int */ public function getReleasedDateUTC(){ if(!$this->_packageddate){ return 0; } $d = new \Core\Date\DateTime($this->_packageddate); return $d->format('U', \Core\Date\Timezone::TIMEZONE_GMT); }
public static function _GenerateLicenses(Form $form) { $qty = $form->getElementValue('qty'); if (!is_numeric($qty)) { Core::SetMessage('Please set a valid quantity', 'error'); return false; } if ($qty < 1) { Core::SetMessage('Please set a quantity greater than 0', 'error'); return false; } if ($qty > 999) { Core::SetMessage('Quantity limited to 999', 'warning'); $qty = 999; } $expires = new \Core\Date\DateTime(); $expires->modify($form->getElementValue('duration')); $expires = $expires->format('Y-m-d'); for ($i = 0; $i < $qty; $i++) { $license = new PackageRepositoryLicenseModel(); $license->set('password', \Core\random_hex(rand(35, 49))); $license->set('expires', $expires); $license->save(); } Core::SetMessage('Generated ' . $qty . ' license(s)!', 'success'); return '/packagerepositorylicense/admin'; }
/** * Method to cleanup the Cron database from old entries. */ public static function _CleanupDatabase() { $date = new \Core\Date\DateTime(); $date->modify('-2 hours'); $hours = $date->format('U'); $date->modify('-1 day'); $day = $date->format('U'); $date->modify('-1 week'); $week = $date->format('U'); $date->modify('-3 weeks'); $month = $date->format('U'); $date->modify('-5 months'); $half = $date->format('U'); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = 1-minute')->where('created <= ' . $hours)->execute(); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = 5-minute')->where('created <= ' . $hours)->execute(); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = 15-minute')->where('created <= ' . $hours)->execute(); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = 30-minute')->where('created <= ' . $hours)->execute(); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = hourly')->where('created <= ' . $week)->execute(); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = 2-hour')->where('created <= ' . $week)->execute(); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = 3-hour')->where('created <= ' . $week)->execute(); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = 6-hour')->where('created <= ' . $week)->execute(); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = 12-hour')->where('created <= ' . $week)->execute(); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = daily')->where('created <= ' . $week)->execute(); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = weekly')->where('created <= ' . $month)->execute(); \Core\Datamodel\Dataset::Init()->delete()->table('cron_log')->where('cron = monthly')->where('created <= ' . $half)->execute(); return true; }
public function analytics() { $request = $this->getPageRequest(); $view = $this->getView(); $manager = \Core\user()->checkAccess('p:/package_repository/view_analytics'); if (!$manager) { return View::ERROR_ACCESSDENIED; } // Retrieve a list of connections to this repo for both downloading and checks! $where = new \Core\Datamodel\DatasetWhereClause(); $where->addWhereSub('OR', ['baseurl = /packagerepository', 'baseurl = /packagerepository/download']); // Default to a 3-month window for now just to have a relatively useful sample of data. // This will be expanded to include a filter at some point in time. $window = new \Core\Date\DateTime(); $window->modify('-3 months'); $window = $window->format('U'); // Generate a boilerplate dataset for the all-history view. // This is required because the graphing software expects all data to be in the same columns, // and these columns are simply indexed arrays. // As we're pulling the data potentially out-of-order and across different versions, // this array will provide a consistent scaffold for unset versions. $allboilerplate = []; // Series Boilerplate $allmonths = []; // Labels // This goes back 12 months. $date = new \Core\Date\DateTime(); $date->modify('-11 months'); for ($i = 1; $i <= 12; $i++) { $allboilerplate[$date->format('Ym')] = null; $allmonths[] = $date->format('M'); $date->nextMonth(); } $raw = UserActivityModel::FindRaw($where); // Will contain a list of useragents along with the count of how many access. $useragents = []; // Will contain how many times a given IP has requested the site. // This is for a metric that currently is not enabled. $ipaddresses = []; // A rich list of hosts along with the latest version, the IP connecting from, and the date of the last check. $hosts = []; // All series for the bar graph at the top of the page, Keyed by version and contains the total number of hits. $allseries = []; $allseries['Total'] = ['class' => 'series-other', 'name' => 'Total', 'title' => 'Total', 'useragent' => '', 'values' => $allboilerplate]; // Used so I can compare the version of the connecting useragent against the current version of Core. // This of course does noothing to ensure that this site is updated, but it at least should give some perspective. $currentVersion = Core::VersionSplit(Core::GetComponent('core')->getVersion()); foreach ($raw as $dat) { if (strpos($dat['useragent'], '(http://corepl.us)') !== false) { /** @var string $ua ex: "Core Plus 1.2.3" */ $ua = str_replace(' (http://corepl.us)', '', $dat['useragent']); /** @var string $version Just the version, ex: "1.2.3" */ $version = str_replace('Core Plus ', '', $ua); /** @var string $referrer Original Site/Server, ex: "http://corepl.us" */ $referrer = $dat['referrer'] ? $dat['referrer'] : $dat['ip_addr']; // The set of logic to compare the current version of Core against the version connecting. // This is used primarily to set a class name onto the graphs so that they can be coloured specifically. $v = Core::VersionSplit($version); // These two values are used in the historical map, (as revision may be a bit useless at this scale). $briefVersion = $v['major'] . '.' . $v['minor'] . '.x'; $briefUA = 'Core Plus ' . $briefVersion; if ($v['major'] == $currentVersion['major'] && $v['minor'] == $currentVersion['minor']) { // Check is same version as current (or newer), blue! $class = 'series-current'; } elseif ($v['major'] + 2 <= $currentVersion['major']) { // Check is at least 2 major versions out of date, red. $class = 'series-outdated-2'; } elseif ($v['major'] + 1 <= $currentVersion['major']) { // Check is at least 1 major version out of date, green. $class = 'series-outdated-1'; } else { // Same major version, close enough. $class = 'series-outdated-0'; } $month = date('Ym', $dat['datetime']); } else { $ua = 'Other'; $briefUA = 'Other'; $version = null; $briefVersion = null; $referrer = null; $class = 'series-other'; $month = null; } // All Data! if ($month && array_key_exists($month, $allboilerplate)) { if (!isset($allseries[$briefUA])) { $allseries[$briefUA] = ['class' => $class, 'name' => $briefVersion, 'title' => $briefUA, 'useragent' => $briefUA, 'values' => $allboilerplate]; } $allseries[$briefUA]['values'][$month]++; //$allseries['Total']['values'][$month]++; } // Is this data new enough to display on the graph? // This is required because the "all" graph at the top needs all-time, (or at least the past 12 months). if ($dat['datetime'] >= $window) { // USER AGENT DATA if (!isset($useragents[$ua])) { $useragents[$ua] = ['value' => 0, 'class' => $class, 'name' => $version, 'title' => $ua, 'useragent' => $ua]; } $useragents[$ua]['value']++; // IP ADDRESS DATA if (!isset($ipaddresses[$dat['ip_addr']])) { $ipaddresses[$dat['ip_addr']] = ['ip_addr' => $dat['ip_addr'], 'count' => 0]; } $ipaddresses[$dat['ip_addr']]['count']++; // HOSTS DATA if ($version && $referrer) { $k = $referrer . '-' . $dat['ip_addr']; if (!isset($hosts[$k])) { $hosts[$k] = ['servername' => $referrer, 'ip_addr' => $dat['ip_addr'], 'version' => '0.0', 'datetime' => 1]; } if (Core::VersionCompare($hosts[$k]['version'], $version, 'lt')) { $hosts[$k]['version'] = $version; } if ($hosts[$k]['datetime'] < $dat['datetime']) { $hosts[$k]['datetime'] = $dat['datetime']; } } } } ksort($useragents); ksort($hosts, SORT_NATURAL); ksort($allseries, SORT_NATURAL); ksort($ipaddresses, SORT_NATURAL); // Update the title of the values now that the totals have been created. // Also, take this opportunity to set the chart data as necessary, (as its format will be slightly different). $chart = ['versions' => ['labels' => [], 'series' => []], 'all' => ['labels' => array_values($allmonths), 'series' => []], 'ips' => []]; foreach ($useragents as &$dat) { $dat['title'] .= ' (' . $dat['value'] . ' Total Hits)'; $chart['versions']['labels'][] = $dat['name']; $chart['versions']['series'][] = ['value' => $dat['value'], 'className' => $dat['class'], 'name' => $dat['name'], 'title' => $dat['title']]; } foreach ($allseries as &$dat) { $data = []; foreach ($dat['values'] as $v) { $data[] = ['value' => $v, 'title' => $dat['title'] . ' (' . $v . ' Monthly Hits)']; //$data[] = $v; } $chart['all']['series'][] = ['data' => $data, 'className' => $dat['class'], 'name' => $dat['name'], 'title' => $dat['title']]; } // Convert these to JSON data! $chart['versions'] = json_encode($chart['versions']); $chart['all'] = json_encode($chart['all']); //$chart['ips'] = json_encode($chart['ips']); $view->title = 't:STRING_PACKAGE_REPOSITORY_ANALYTICS'; $view->assign('chart', $chart); $view->assign('raw', $raw); $view->assign('ip_addresses', $ipaddresses); $view->assign('useragents', $useragents); $view->assign('hosts', $hosts); //var_dump($chart, $useragents, $ipaddresses, $ipversion, $raw); die(); }
/** * Render the View to the browser. */ public function render(){ \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Starting PageRequest->render()'); $view = $this->getView(); $page = $this->getPageModel(); // Dispatch the hooks here if it's a 404 or 403. if ($view->error == View::ERROR_ACCESSDENIED || $view->error == View::ERROR_NOTFOUND) { // Let other things chew through it... (optionally) HookHandler::DispatchHook('/core/page/error-' . $view->error, $view); } try { // This will pre-fetch the contents of the entire page and store it into memory. // If it is cacheable, then it will be cached and used for the next execution. // If the user has the view user activity permission, add the link to that page! if(\Core\user()->checkAccess('p:user_activity_list') && $page && $page->exists()){ $view->addControl( 'User Activity Details', '/useractivity/details?filter[baseurl]=' . $page->get('baseurl'), 'eye' ); } $view->fetch(); } catch (Exception $e) { // If something happens in the rendering of the template... consider it a server error. $view->error = View::ERROR_SERVERERROR; $view->baseurl = '/error/error/500'; $view->setParameters(array()); $view->templatename = '/pages/error/error500.tpl'; $view->mastertemplate = ConfigHandler::Get('/theme/default_template'); $view->assignVariable('exception', $e); \Core\ErrorManagement\exception_handler($e); $view->fetch(); } if($this->isCacheable()){ $uakey = \Core\UserAgent::Construct()->getPseudoIdentifier(); $urlkey = $this->host . $this->uri; $expires = $page->get('expires'); // Number of seconds. $key = 'page-cache-' . md5($urlkey . '-' . $uakey); $d = new \Core\Date\DateTime(); $d->modify('+' . $expires . ' seconds'); $view->headers['Cache-Control'] = 'max-age=' . $expires; $view->headers['Expires'] = $d->format('r', \Core\Date\Timezone::TIMEZONE_GMT); $view->headers['Vary'] = 'Accept-Encoding,User-Agent,Cookie'; $view->headers['X-Core-Cached-Date'] = \Core\Date\DateTime::NowGMT('r'); $view->headers['X-Core-Cached-Server'] = 1; // @todo Implement multi-server support. $view->headers['X-Core-Cached-Render-Time'] = \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->getTimeFormatted(); // Record the actual View into cache. \Core\Cache::Set($key, $view, $expires); // And record the key onto an index cache record so there's a record of what to delete on updates. $indexkey = $page->getIndexCacheKey(); $index = \Core\Cache::Get($indexkey, SECONDS_ONE_DAY); if(!$index){ $index = []; } $index[] = $key; \Core\Cache::Set($indexkey, $index, SECONDS_ONE_DAY); } elseif(($reason = $this->isNotCacheableReason()) !== null){ $view->headers['X-Core-NotCached-Reason'] = $reason; } $view->headers['X-Core-Render-Time'] = \Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->getTimeFormatted(); $view->render(); // Make sure I update any existing page now that the controller has ran. if ($page && $page->exists() && $view->error == View::ERROR_NOERROR) { // Only increase the pageview count if the visitor is not a bot. // UA detection isn't very accurate, but this isn't for precision accuracy, merely a rough estimate. if(!\Core\UserAgent::Construct()->isBot()){ $page->set('pageviews', $page->get('pageviews') + 1); } $page->set('last_template', $view->templatename); $page->set('body', $view->fetchBody()); $page->save(); } // Just before the page stops execution... HookHandler::DispatchHook('/core/page/postrender'); }