/** * 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(); }
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(); }