public function Index() { $this->Permission('Garden.Settings.Manage'); $this->AddSideMenu('dashboard/statistics'); //$this->AddJsFile('statistics.js'); $this->Title(T('Vanilla Statistics')); $this->EnableSlicing($this); if ($this->Form->IsPostBack()) { $Flow = TRUE; if ($Flow && $this->Form->GetFormValue('ClearCredentials')) { Gdn::InstallationID(FALSE); Gdn::InstallationSecret(FALSE); Gdn::Statistics()->Tick(); $Flow = FALSE; } if ($Flow && $this->Form->GetFormValue('SaveIdentity')) { Gdn::InstallationID($this->Form->GetFormValue('InstallationID')); Gdn::InstallationSecret($this->Form->GetFormValue('InstallationSecret')); $this->InformMessage(T("Your settings have been saved.")); } if ($Flow && $this->Form->GetFormValue('AllowLocal')) { SaveToConfig('Garden.Analytics.AllowLocal', TRUE); } if ($Flow && $this->Form->GetFormValue('Allow')) { SaveToConfig('Garden.Analytics.Enabled', TRUE); } } $AnalyticsEnabled = Gdn_Statistics::CheckIsEnabled(); if ($AnalyticsEnabled) { $ConfFile = PATH_LOCAL_CONF.DS.'config.php'; $this->SetData('ConfWritable', $ConfWritable = is_writable($ConfFile)); if (!$ConfWritable) $AnalyticsEnabled = FALSE; } $this->SetData('AnalyticsEnabled', $AnalyticsEnabled); $NotifyMessage = Gdn::Get('Garden.Analytics.Notify', FALSE); $this->SetData('NotifyMessage', $NotifyMessage); if ($NotifyMessage !== FALSE) Gdn::Set('Garden.Analytics.Notify', NULL); $this->Form->SetFormValue('InstallationID', Gdn::InstallationID()); $this->Form->SetFormValue('InstallationSecret', Gdn::InstallationSecret()); $this->Render(); }
public function DiscussionsController_AfterRenderAsset_Handler($Sender) { $AssetName = GetValueR('EventArguments.AssetName', $Sender); if ($AssetName != "Content") { return; } $CurTime = time(); $LastTime = Gdn::Get('TimeCheck', $LastTime); $SFVcount = Gdn::Get('ViewCount', $SFVcount); $SFUcount = Gdn::Get('UserCount', $SFUcount); $SFDcount = Gdn::Get('DiscussionCount', $SFDcount); $SFCcount = Gdn::Get('CommentCount', $SFCcount); // refresh counts every 60 seconds unless config is set // e.g. $Configuration['Plugins']['StatisticsFooter']['Refresh'] = '90'; $IncSec = C('Plugins.StatisticsFooter.Refresh', 60); if ($CurTime > $LastTime) { $LastTime = time() + $IncSec; Gdn::Set('TimeCheck', $LastTime); $SFVcount = $this->GetViewCount(); Gdn::Set('ViewCount', $SFVcount); $SFUcount = $this->GetUserCount(); Gdn::Set('UserCount', $SFUcount); $SFDcount = $this->GetDiscussionCount(); Gdn::Set('DiscussionCount', $SFDcount); $SFCcount = $this->GetCommentCount(); Gdn::Set('CommentCount', $SFCcount); } $SFPcount = $SFDcount + $SFCcount; $ShowMe = C('Plugins.StatisticsFooter.Show'); if (strpos($ShowMe, "v") !== FALSE) { echo Wrap(Wrap(T('View Count')) . Gdn_Format::BigNumber($SFVcount), 'div', array('class' => 'SFBox SFVCBox')); } if (strpos($ShowMe, "u") !== FALSE) { echo Wrap(Wrap(T('User Count')) . Gdn_Format::BigNumber($SFUcount), 'div', array('class' => 'SFBox SFUBox')); } if (strpos($ShowMe, "t") !== FALSE) { echo Wrap(Wrap(T('Topic Count')) . Gdn_Format::BigNumber($SFDcount), 'div', array('class' => 'SFBox SFTBox')); } if (strpos($ShowMe, "c") !== FALSE) { echo Wrap(Wrap(T('Post Count')) . Gdn_Format::BigNumber($SFPcount), 'div', array('class' => 'SFBox SFPBox')); } }
public function Update() { // Check for permission or flood control. // These settings are loaded/saved to the database because we don't want the config file storing non/config information. $Now = time(); $LastTime = Gdn::Get('Garden.Update.LastTimestamp', 0); if ($LastTime + (60 * 60 * 24) > $Now) { // Check for flood control. $Count = Gdn::Get('Garden.Update.Count', 0) + 1; if ($Count > 5) { if (!Gdn::Session()->CheckPermission('Garden.Settings.Manage')) { // We are only allowing an update of 5 times every 24 hours. throw PermissionException(); } } } else { $Count = 1; } Gdn::Set('Garden.Update.LastTimestamp', $Now); Gdn::Set('Garden.Update.Count', $Count); // Run the structure. $UpdateModel = new UpdateModel(); $UpdateModel->RunStructure(); $this->SetData('Success', TRUE); $this->MasterView = 'none'; $this->Render(); }
/** * This is the asynchronous callback * * This method is triggerd on every page request via a callback AJAX request * so that it may execute asychronously and reduce lag for users. It tracks * views, handles registration for new installations, and sends stats every * day as needed. * * @return void; */ public function Tick() { // If we're local and not allowed, or just directly disabled, gtfo if (!self::CheckIsEnabled()) { return; } if (Gdn::Session()->CheckPermission('Garden.Settings.Manage')) { if (Gdn::Get('Garden.Analytics.Notify', FALSE) !== FALSE) { $CallMessage = '<span class="InformSprite Bandaid"></span> '; $CallMessage .= sprintf(T("There's a problem with Vanilla Analytics that needs your attention.<br/> Handle it <a href=\"%s\">here »</a>"), Url('dashboard/statistics')); Gdn::Controller()->InformMessage($CallMessage, array('CssClass' => 'HasSprite')); } } // If the config file is not writable, gtfo $ConfFile = PATH_LOCAL_CONF . DS . 'config.php'; if (!is_writable($ConfFile)) { return; } $InstallationID = Gdn::InstallationID(); // Check if we're registered with the central server already. If not, this request is // hijacked and used to perform that task instead of sending stats or recording a tick. if (is_null($InstallationID)) { $AttemptedRegistration = Gdn::Get('Garden.Analytics.Registering', FALSE); // If we last attempted to register less than 60 seconds ago, do nothing. Could still be working. if ($AttemptedRegistration !== FALSE && time() - $AttemptedRegistration < 60) { return; } return $this->Register(); } // Add a pageview entry. $TimeSlot = date('Ymd'); $Px = Gdn::Database()->DatabasePrefix; try { Gdn::Database()->Query("insert into {$Px}AnalyticsLocal (TimeSlot, Views) values (:TimeSlot, 1)\n on duplicate key update Views = Views+1", array(':TimeSlot' => $TimeSlot)); } catch (Exception $e) { // If we just tried to run the structure, and failed, don't blindly try again. // Just disable ourselves quietly. if (Gdn::Get('Garden.Analytics.AutoStructure', FALSE)) { SaveToConfig('Garden.Analytics.Enabled', FALSE); Gdn::Set('Garden.Analytics.AutoStructure', NULL); return; } // If we get here, insert failed. Try proxyconnect to the utility structure Gdn::Set('Garden.Analytics.AutoStructure', TRUE); ProxyRequest(Url('utility/update', TRUE), 0, FALSE); } // If we get here and this is true, we successfully ran the auto structure. Remove config flag. if (Gdn::Get('Garden.Analytics.AutoStructure', FALSE)) { Gdn::Set('Garden.Analytics.AutoStructure', NULL); } // Fire an event for plugins to track their own stats. // TODO: Make this analyze the path and throw a specific event (this event will change in future versions). $this->EventArguments['Path'] = Gdn::Request()->Post('Path'); $this->FireEvent('Tick'); // If we get here, the installation is registered and we can decide on whether or not to send stats now. $LastSentDate = self::LastSentDate(); if (empty($LastSentDate) || $LastSentDate < date('Ymd', strtotime('-1 day'))) { return $this->Stats(); } }
/** * Run a structure update on the database. * * @since 2.0.? * @access public */ public function Update() { try { // Check for permission or flood control. // These settings are loaded/saved to the database because we don't want the config file storing non/config information. $Now = time(); $LastTime = Gdn::Get('Garden.Update.LastTimestamp', 0); if ($LastTime + 60 * 60 * 24 > $Now) { // Check for flood control. $Count = Gdn::Get('Garden.Update.Count', 0) + 1; if ($Count > 5) { if (!Gdn::Session()->CheckPermission('Garden.Settings.Manage')) { // We are only allowing an update of 5 times every 24 hours. throw PermissionException(); } } } else { $Count = 1; } Gdn::Set('Garden.Update.LastTimestamp', $Now); Gdn::Set('Garden.Update.Count', $Count); } catch (PermissionException $Ex) { return; } catch (Exception $Ex) { } try { // Run the structure. $UpdateModel = new UpdateModel(); $UpdateModel->RunStructure(); $this->SetData('Success', TRUE); } catch (Exception $Ex) { $this->SetData('Success', FALSE); if (Debug()) { throw $Ex; } } if (Gdn::Session()->CheckPermission('Garden.Settings.Manage')) { SaveToConfig('Garden.Version', APPLICATION_VERSION); } if ($Target = $this->Request->Get('Target')) { Redirect($Target); } $this->FireEvent('AfterUpdate'); $this->MasterView = 'empty'; $this->CssClass = 'Home'; $this->Render(); }
public function GetBatch($Table, $Key, $Limit = 10000, $Max = FALSE) { $Key = "DBA.Range.{$Key}"; // See if there is already a range. $Current = @unserialize(Gdn::Get($Key, '')); if (!is_array($Current) || !isset($Current['Min']) || !isset($Current['Max'])) { list($Current['Min'], $Current['Max']) = $this->PrimaryKeyRange($Table); if ($Max && $Current['Max'] > $Max) { $Current['Max'] = $Max; } } if (!isset($Current['To'])) { $Current['To'] = $Current['Max']; } else { $Current['To'] -= $Limit - 1; } $Current['From'] = $Current['To'] - $Limit; Gdn::Set($Key, serialize($Current)); $Current['Complete'] = $Current['To'] < $Current['Min']; $Total = $Current['Max'] - $Current['Min']; if ($Total > 0) { $Complete = $Current['Max'] - $Current['From']; $Percent = 100 * $Complete / $Total; if ($Percent > 100) { $Percent = 100; } $Current['Percent'] = round($Percent) . '%'; } return $Current; }
public static function Throttled($SetThrottled = NULL) { static $Throttled = NULL; // Set if (!is_null($SetThrottled)) { if ($SetThrottled) { $ThrottleDelay = C('Garden.Analytics.ThrottleDelay', 3600); $ThrottleValue = time() + $ThrottleDelay; } else { $ThrottleValue = NULL; } $Throttled = !is_null($ThrottleValue) ? $ThrottleValue : 0; Gdn::Set('Garden.Analytics.Throttle', $ThrottleValue); } // Lazy Load if ($Throttled === NULL) { $Throttled = Gdn::Get('Garden.Analytics.Throttle', 0); } return $Throttled > time(); }
/** * * * @param $Response * @param $Raw */ protected function doneRegister($Response, $Raw) { $VanillaID = val('VanillaID', $Response, false); $Secret = val('Secret', $Response, false); if (($Secret && $VanillaID) !== false) { Gdn::InstallationID($VanillaID); Gdn::InstallationSecret($Secret); Gdn::Set('Garden.Analytics.Registering', null); Gdn::Set('Garden.Analytics.LastSentDate', null); } }