Пример #1
0
	/**
	 * Function to record activity, ie: a page view.
	 *
	 * @static
	 *
	 */
	public static function RecordActivity(){

		$request = \PageRequest::GetSystemRequest();
		$view = $request->getView();

		if(!$view->record) return true;

		try{

			$processingtime = (round(Profiler::GetDefaultProfiler()->getTime(), 3) * 1000);

			$log = new \UserActivityModel();
			$log->setFromArray(
				[
					'datetime' => microtime(true),
					'session_id' => session_id(),
					'user_id' => \Core\user()->get('id'),
					'ip_addr' => REMOTE_IP,
					'useragent' => $request->useragent,
					'referrer' => $request->referrer,
					'type' => $_SERVER['REQUEST_METHOD'],
					'request' => $_SERVER['REQUEST_URI'],
					'baseurl' => $request->getBaseURL(),
					'status' => $view->error,
					'db_reads' => DatamodelProfiler::GetDefaultProfiler()->readCount(),
					'db_writes' => (DatamodelProfiler::GetDefaultProfiler()->writeCount() + 1),
					'processing_time' => $processingtime,
				]
			);

			if(defined('XHPROF_RUN') && defined('XHPROF_SOURCE')){
				$log->set('xhprof_run', XHPROF_RUN);
				$log->set('xhprof_source', XHPROF_SOURCE);
			}

			$log->save();
		}
		catch(\Exception $e){
			// I don't actually care if it couldn't save.
			// This could happen if the user refreshes the page twice with in a second.
			// (and with a system that responds in about 100ms, it's very possible).
			\Core\ErrorManagement\exception_handler($e);
		}
	}
	public function historical(){
		$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;

		$profiler = new \Core\Utilities\Profiler\Profiler('useractivity');

		$limit  = $this->_getQueryLimit();
		$dstart = $request->getParameter('dstart');
		$dend   = $request->getParameter('dend');

		if(!$dend){
			$dend = Time::GetCurrent();
		}
		else{
			$dend = strtotime($dend);
		}
		if(!$dstart){
			$dstart = $dend - (3600 * 24 * 30);
		}
		else{
			$dstart = strtotime($dstart);
		}
		// Use FindRaw because it's faster than using full Models for everything, especially when dealing with 20k + records.
		$listings = UserActivityModel::FindRaw(array('datetime >= ' . $dstart, 'datetime <= ' . $dend), $limit, 'datetime DESC');
		$profiler->record('Found raw models');

		$data = array(
			'performance' => array('get' => 0, 'post' => 0),
			'requests'    => array('get' => 0, 'post' => 0),
			'counts'      => array('bots' => 0, 'users' => 0, 'visitors' => 0),
			'browsers'    => array(),
			'referrers'   => array(),
			'ips'         => array(),
			'os'          => array(),
			'notfounds'   => array(),
			'pages'       => array(),
		);

		$sessions = array();
		$x = 0;

		foreach($listings as $log){
			++$x;

			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 = \Core\UserAgent::Construct($log['useragent']);

			if($ua->isBot()){
				$data['counts']['bots']++;
			}
			else{
				$data['counts']['users']++;

				if(!isset($sessions[ $log['session_id'] ])) $sessions[ $log['session_id'] ] = true;
			}

			$browser = $ua->browser . ' ' . $ua->version;

			if(!isset($data['browsers'][ $browser ])) $data['browsers'][ $browser ] = 1;
			else $data['browsers'][ $browser ]++;

			if($log['referrer'] == ''){
				$referrer = 'none';
			}
			elseif(strpos($log['referrer'], 'http://' . HOST) === 0){
				$referrer = 'internal';
			}
			elseif(strpos($log['referrer'], 'https://' . HOST) === 0){
				$referrer = 'internal-ssl';
			}
			else{
				// I want to trim the referrer a bit so I don't end up with a bunch of one-offs.
				if(($qpos = strpos($log['referrer'], '?')) !== false) $referrer = substr($log['referrer'], 0, $qpos);
				else $referrer = $log['referrer'];
			}

			if(!isset($data['referrers'][ $referrer ])) $data['referrers'][ $referrer ] = 1;
			else $data['referrers'][ $referrer ]++;

			if(!isset($data['ips'][ $log['ip_addr'] ])) $data['ips'][ $log['ip_addr'] ] = 1;
			else $data['ips'][ $log['ip_addr'] ]++;

			if(!isset($data['os'][ $ua->platform ])) $data['os'][ $ua->platform ] = 1;
			else $data['os'][ $ua->platform ]++;

			if($log['status'] == 404){
				if(!isset($data['notfounds'][ $log['request'] ])) $data['notfounds'][ $log['request'] ] = 1;
				else $data['notfounds'][ $log['request'] ]++;
			}

			if($log['status'] == 200){
				if(!isset($data['pages'][ $log['baseurl'] ])) $data['pages'][ $log['baseurl'] ] = 1;
				else $data['pages'][ $log['baseurl'] ]++;
			}

			$profiler->record('Parsed record #' . $x);
		}
//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['counts']['visitors'] = sizeof($sessions);

		// Do some sorting on a few of the arrays.
		arsort($data['browsers']);
		arsort($data['referrers']);
		arsort($data['ips']);
		arsort($data['os']);
		arsort($data['notfounds']);
		arsort($data['pages']);

		$profiler->record('Sorted all data');

		// DEBUG!
		//echo '<pre>';
		//echo $profiler->getEventTimesFormatted();
		//die();

		//var_dump($data, $users, $listings); die();
		$view->jsondata = $data;
	}
 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();
 }
Пример #4
0
 public function actionLogAlbum()
 {
     $id = Yii::app()->request->getParam('id');
     $album = AlbumModel::model()->findByPk($id);
     if (!Yii::app()->user->isGuest) {
         $activity = new UserActivityModel();
         $activity->channel = 'wap';
         $activity->user_id = Yii::app()->user->getId();
         $activity->user_phone = Yii::app()->user->getState('phone');
         $activity->loged_time = date('Y-m-d H:i:s');
         $activity->activity = 'play_album';
         $activity->obj1_id = $album->id;
         $activity->obj1_name = $album->name;
         $activity->obj1_url_key = $album->url_key;
         $activity->obj2_id = $album->artist_id;
         $activity->obj2_name = $album->artist_name;
         $ret = $activity->save();
         if ($ret) {
             echo "1";
         } else {
             echo CHtml::errorSummary($activity);
         }
         Yii::app()->end();
     }
     echo '';
     Yii::app()->end();
 }