Example #1
0
/**
 * 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);
	}
}
Example #2
0
	/**
	 * 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';
 }
Example #4
0
 /**
  * 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');
	}