cache() public static method

Get the cache object
public static cache ( ) : Gdn_Cache
return Gdn_Cache
示例#1
0
 /**
  * Initialize a new instance of the {@link CategoryCollection} class.
  *
  * @param Gdn_SQLDriver|null $sql The database layer dependency.
  * @param Gdn_Cache|null $cache The cache layer dependency.
  */
 public function __construct(Gdn_SQLDriver $sql = null, Gdn_Cache $cache = null)
 {
     if ($sql === null) {
         $sql = Gdn::sql();
     }
     $this->sql = $sql;
     if ($cache === null) {
         $cache = Gdn::cache();
     }
     $this->cache = $cache;
 }
 protected function getCount($Table)
 {
     // Try and get the count from the cache.
     $Key = "{$Table}.CountRows";
     $Count = Gdn::cache()->get($Key);
     if ($Count !== Gdn_Cache::CACHEOP_FAILURE) {
         return $Count;
     }
     // The count wasn't in the cache so grab it from the table.
     $Count = Gdn::sql()->select($Table . 'ID', 'count', 'CountRows')->from($Table)->get()->value('CountRows');
     // Save the value to the cache.
     Gdn::cache()->store($Key, $Count, array(Gdn_Cache::FEATURE_EXPIRY => 5 * 60 + mt_rand(0, 30)));
     return $Count;
 }
 /**
  * Initialize a new instance of the {@link CategoryCollection} class.
  *
  * @param Gdn_SQLDriver|null $sql The database layer dependency.
  * @param Gdn_Cache|null $cache The cache layer dependency.
  */
 public function __construct(Gdn_SQLDriver $sql = null, Gdn_Cache $cache = null)
 {
     if ($sql === null) {
         $sql = Gdn::sql();
     }
     $this->sql = $sql;
     if ($cache === null) {
         $cache = Gdn::cache();
     }
     $this->cache = $cache;
     $this->setStaticCalculator([$this, 'defaultCalculator']);
     $this->setUserCalculator(function (&$category) {
         // do nothing
     });
 }
示例#4
0
 /**
  * Save a message.
  *
  * @param array $FormPostValues Message data.
  * @param bool $Settings
  * @return int The MessageID.
  */
 public function save($FormPostValues, $Settings = false)
 {
     // The "location" is packed into a single input with a / delimiter. Need to explode it into three different fields for saving
     $Location = val('Location', $FormPostValues, '');
     if ($Location != '') {
         $Location = explode('/', $Location);
         $Application = val(0, $Location, '');
         if (in_array($Application, $this->_SpecialLocations)) {
             $FormPostValues['Application'] = null;
             $FormPostValues['Controller'] = $Application;
             $FormPostValues['Method'] = null;
         } else {
             $FormPostValues['Application'] = $Application;
             $FormPostValues['Controller'] = val(1, $Location, '');
             $FormPostValues['Method'] = val(2, $Location, '');
         }
     }
     Gdn::cache()->remove('Messages');
     return parent::save($FormPostValues, $Settings);
 }
 /**
  * Increments view count for the specified discussion.
  *
  * @since 2.0.0
  * @access public
  *
  * @param int $DiscussionID Unique ID of discussion to get +1 view.
  */
 public function addView($DiscussionID)
 {
     $IncrementBy = 0;
     if (c('Vanilla.Views.Denormalize', false) && Gdn::cache()->activeEnabled() && Gdn::cache()->Type() != Gdn_Cache::CACHE_TYPE_NULL) {
         $WritebackLimit = c('Vanilla.Views.DenormalizeWriteback', 10);
         $CacheKey = sprintf(DiscussionModel::CACHE_DISCUSSIONVIEWS, $DiscussionID);
         // Increment. If not success, create key.
         $Views = Gdn::cache()->increment($CacheKey);
         if ($Views === Gdn_Cache::CACHEOP_FAILURE) {
             Gdn::cache()->store($CacheKey, 1);
         }
         // Every X views, writeback to Discussions
         if ($Views % $WritebackLimit == 0) {
             $IncrementBy = floor($Views / $WritebackLimit) * $WritebackLimit;
             Gdn::cache()->Decrement($CacheKey, $IncrementBy);
         }
     } else {
         $IncrementBy = 1;
     }
     if ($IncrementBy) {
         $this->SQL->update('Discussion')->set('CountViews', "CountViews + {$IncrementBy}", false)->where('DiscussionID', $DiscussionID)->put();
     }
 }
示例#6
0
 /**
  * Save the provided library's data to the on disk location.
  *
  * @param string $CacheName name of cache library
  * @return void
  */
 public static function saveCache($CacheName)
 {
     if ($CacheName != 'locale') {
         return;
     }
     if (!array_key_exists($CacheName, self::$Caches)) {
         return false;
     }
     $UseCache = Gdn::cache()->type() == Gdn_Cache::CACHE_TYPE_MEMORY && Gdn::cache()->activeEnabled();
     if ($UseCache) {
         $CacheKey = sprintf(Gdn_LibraryMap::CACHE_CACHE_NAME_FORMAT, $CacheName);
         $Stored = Gdn::cache()->store($CacheKey, self::$Caches[$CacheName]['cache']);
     } else {
         $FileName = self::$Caches[$CacheName]['ondisk'];
         $CacheContents = "";
         foreach (self::$Caches[$CacheName]['cache'] as $SectionTitle => $SectionData) {
             $CacheContents .= "[{$SectionTitle}]\n";
             foreach ($SectionData as $StoreKey => $StoreValue) {
                 $CacheContents .= "{$StoreKey} = \"{$StoreValue}\"\n";
             }
         }
         try {
             // Fix slashes to get around parse_ini_file issue that drops off \ when loading network file.
             $CacheContents = str_replace("\\", "/", $CacheContents);
             Gdn_FileSystem::saveFile(PATH_CACHE . DS . $FileName, $CacheContents, LOCK_EX);
         } catch (Exception $e) {
         }
     }
 }
示例#7
0
 /**
  *
  *
  * @return bool|null
  * @throws Exception
  */
 public function save()
 {
     if (!$this->Dirty) {
         return null;
     }
     $this->EventArguments['ConfigDirty'] =& $this->Dirty;
     $this->EventArguments['ConfigNoSave'] = false;
     $this->EventArguments['ConfigType'] = $this->Type;
     $this->EventArguments['ConfigSource'] = $this->Source;
     $this->EventArguments['ConfigData'] = $this->Settings;
     $this->fireEvent('BeforeSave');
     if ($this->EventArguments['ConfigNoSave']) {
         $this->Dirty = false;
         return true;
     }
     // Check for and fire callback if one exists
     if ($this->Callback && is_callable($this->Callback)) {
         $CallbackOptions = array();
         if (!is_array($this->CallbackOptions)) {
             $this->CallbackOptions = array();
         }
         $CallbackOptions = array_merge($CallbackOptions, $this->CallbackOptions, array('ConfigDirty' => $this->Dirty, 'ConfigType' => $this->Type, 'ConfigSource' => $this->Source, 'ConfigData' => $this->Settings, 'SourceObject' => $this));
         $ConfigSaved = call_user_func($this->Callback, $CallbackOptions);
         if ($ConfigSaved) {
             $this->Dirty = false;
             return true;
         }
     }
     switch ($this->Type) {
         case 'file':
             if (empty($this->Source)) {
                 trigger_error(errorMessage('You must specify a file path to be saved.', 'Configuration', 'Save'), E_USER_ERROR);
             }
             $CheckWrite = $this->Source;
             if (!file_exists($CheckWrite)) {
                 $CheckWrite = dirname($CheckWrite);
             }
             if (!is_writable($CheckWrite)) {
                 throw new Exception(sprintf(t("Unable to write to config file '%s' when saving."), $this->Source));
             }
             $Group = $this->Group;
             $Data =& $this->Settings;
             ksort($Data);
             // Check for the case when the configuration is the group.
             if (is_array($Data) && count($Data) == 1 && array_key_exists($Group, $Data)) {
                 $Data = $Data[$Group];
             }
             // Do a sanity check on the config save.
             if ($this->Source == Gdn::config()->defaultPath()) {
                 // Log root config changes
                 try {
                     $LogData = $this->Initial;
                     $LogData['_New'] = $this->Settings;
                     LogModel::insert('Edit', 'Configuration', $LogData);
                 } catch (Exception $Ex) {
                 }
                 if (!isset($Data['Database'])) {
                     if ($Pm = Gdn::pluginManager()) {
                         $Pm->EventArguments['Data'] = $Data;
                         $Pm->EventArguments['Backtrace'] = debug_backtrace();
                         $Pm->fireEvent('ConfigError');
                     }
                     return false;
                 }
             }
             // Write config data to string format, ready for saving
             $FileContents = Gdn_Configuration::format($Data, array('VariableName' => $Group, 'WrapPHP' => true, 'ByLine' => true));
             if ($FileContents === false) {
                 trigger_error(errorMessage('Failed to define configuration file contents.', 'Configuration', 'Save'), E_USER_ERROR);
             }
             // Save to cache if we're into that sort of thing
             $FileKey = sprintf(Gdn_Configuration::CONFIG_FILE_CACHE_KEY, $this->Source);
             if ($this->Configuration && $this->Configuration->caching() && Gdn::cache()->type() == Gdn_Cache::CACHE_TYPE_MEMORY && Gdn::cache()->activeEnabled()) {
                 $CachedConfigData = Gdn::cache()->store($FileKey, $Data, array(Gdn_Cache::FEATURE_NOPREFIX => true, Gdn_Cache::FEATURE_EXPIRY => 3600));
             }
             $TmpFile = tempnam(PATH_CONF, 'config');
             $Result = false;
             if (file_put_contents($TmpFile, $FileContents) !== false) {
                 chmod($TmpFile, 0775);
                 $Result = rename($TmpFile, $this->Source);
             }
             if ($Result) {
                 if (function_exists('apc_delete_file')) {
                     // This fixes a bug with some configurations of apc.
                     @apc_delete_file($this->Source);
                 } elseif (function_exists('opcache_invalidate')) {
                     @opcache_invalidate($this->Source);
                 }
             }
             $this->Dirty = false;
             return $Result;
             break;
         case 'json':
         case 'array':
         case 'string':
             /**
              * How would these even save? String config data must be handled by
              * an event hook or callback, if at all.
              */
             $this->Dirty = false;
             return false;
             break;
     }
 }
 /**
  * Takes a set of discussion identifiers and returns their comment counts in the same order.
  */
 public function getCommentCounts()
 {
     $this->AllowJSONP(true);
     $vanilla_identifier = val('vanilla_identifier', $_GET);
     if (!is_array($vanilla_identifier)) {
         $vanilla_identifier = array($vanilla_identifier);
     }
     $vanilla_identifier = array_unique($vanilla_identifier);
     $FinalData = array_fill_keys($vanilla_identifier, 0);
     $Misses = array();
     $CacheKey = 'embed.comments.count.%s';
     $OriginalIDs = array();
     foreach ($vanilla_identifier as $ForeignID) {
         $HashedForeignID = ForeignIDHash($ForeignID);
         // Keep record of non-hashed identifiers for the reply
         $OriginalIDs[$HashedForeignID] = $ForeignID;
         $RealCacheKey = sprintf($CacheKey, $HashedForeignID);
         $Comments = Gdn::cache()->get($RealCacheKey);
         if ($Comments !== Gdn_Cache::CACHEOP_FAILURE) {
             $FinalData[$ForeignID] = $Comments;
         } else {
             $Misses[] = $HashedForeignID;
         }
     }
     if (sizeof($Misses)) {
         $CountData = Gdn::sql()->select('ForeignID, CountComments')->from('Discussion')->where('Type', 'page')->whereIn('ForeignID', $Misses)->get()->resultArray();
         foreach ($CountData as $Row) {
             // Get original identifier to send back
             $ForeignID = $OriginalIDs[$Row['ForeignID']];
             $FinalData[$ForeignID] = $Row['CountComments'];
             // Cache using the hashed identifier
             $RealCacheKey = sprintf($CacheKey, $Row['ForeignID']);
             Gdn::cache()->store($RealCacheKey, $Row['CountComments'], array(Gdn_Cache::FEATURE_EXPIRY => 60));
         }
     }
     $this->setData('CountData', $FinalData);
     $this->DeliveryMethod = DELIVERY_METHOD_JSON;
     $this->DeliveryType = DELIVERY_TYPE_DATA;
     $this->render();
 }
示例#9
0
 /**
  * Log the access of a resource.
  *
  * Since resources can be accessed with every page view this event will only log when the cache is enabled
  * and once every five minutes.
  *
  * @param string $event The name of the event to log.
  * @param string $level The log level of the event.
  * @param string $message The log message format.
  * @param array $context Additional information to pass to the event.
  */
 public static function logAccess($event, $level, $message, $context = array())
 {
     // Throttle the log access to 1 event every 5 minutes.
     if (Gdn::cache()->activeEnabled()) {
         $userID = Gdn::session()->UserID;
         $path = Gdn::request()->path();
         $key = "log:{$event}:{$userID}:{$path}";
         if (Gdn::cache()->get($key) === false) {
             self::event($event, $level, $message, $context);
             Gdn::cache()->store($key, time(), array(Gdn_Cache::FEATURE_EXPIRY => 300));
         }
     }
 }
示例#10
0
 /**
  *
  *
  * @throws Exception
  */
 public function ping()
 {
     $start = microtime(true);
     $this->setData('pong', true);
     $this->MasterView = 'empty';
     $this->CssClass = 'Home';
     $valid = true;
     // Test the cache.
     if (Gdn::cache()->activeEnabled()) {
         $k = betterRandomString(20);
         Gdn::cache()->store($k, 1);
         Gdn::cache()->increment($k, 1);
         $v = Gdn::cache()->get($k);
         if ($v !== 2) {
             $valid = false;
             $this->setData('cache', false);
         } else {
             $this->setData('cache', true);
         }
     } else {
         $this->setData('cache', 'disabled');
     }
     // Test the db.
     try {
         $users = Gdn::sql()->get('User', 'UserID', 'asc', 1);
         $this->setData('database', true);
     } catch (Exception $ex) {
         $this->setData('database', false);
         $valid = false;
     }
     $this->EventArguments['Valid'] =& $valid;
     $this->fireEvent('Ping');
     if (!$valid) {
         $this->statusCode(500);
     }
     $time = microtime(true) - $start;
     $this->setData('time', Gdn_Format::timespan($time));
     $this->setData('time_s', $time);
     $this->setData('valid', $valid);
     $this->title('Ping');
     $this->render();
 }
示例#11
0
 /**
  * Sets UserMeta data to the UserMeta table.
  *
  * This method takes a UserID, Key, and Value, and attempts to set $Key = $Value for $UserID.
  * $Key can be an SQL wildcard, thereby allowing multiple variations of a $Key to be set. $UserID
  * can be an array, thereby allowing multiple users' $Keys to be set to the same $Value.
  *
  * ++ Before any queries are run, $Key is converted to its fully qualified format (Plugin.<PluginName> prepended)
  * ++ to prevent collisions in the meta table when multiple plugins have similar key names.
  *
  * If $Value == null, the matching row(s) are deleted instead of updated.
  *
  * @param $UserID int UserID or array of UserIDs
  * @param $Key string relative user key
  * @param $Value mixed optional value to set, null to delete
  * @return void
  */
 public function setUserMeta($UserID, $Key, $Value = null)
 {
     if (Gdn::cache()->activeEnabled()) {
         if (is_array($UserID)) {
             foreach ($UserID as $ID) {
                 $this->SetUserMeta($ID, $Key, $Value);
             }
             return;
         }
         $UserMeta = $this->GetUserMeta($UserID);
         if (!stristr($Key, '%')) {
             if ($Value === null) {
                 unset($UserMeta[$Key]);
             } else {
                 $UserMeta[$Key] = $Value;
             }
         } else {
             $MatchKey = str_replace('%', '*', $Key);
             foreach ($UserMeta as $UserMetaKey => $UserMetaValue) {
                 if (fnmatch($MatchKey, $UserMetaKey)) {
                     if ($Value === null) {
                         unset($UserMeta[$UserMetaKey]);
                     } else {
                         $UserMeta[$UserMetaKey] = $Value;
                     }
                 }
             }
         }
         $CacheKey = 'UserMeta_' . $UserID;
         Gdn::cache()->store($CacheKey, $UserMeta, array(Gdn_Cache::FEATURE_EXPIRY => 3600));
         // Update the DB.
         $this->SQL->reset();
         if ($Value === null) {
             $Q = $this->SQL->where('UserID', $UserID);
             if (stristr($Key, '%')) {
                 $Q->like('Name', $Key);
             } else {
                 $Q->where('Name', $Key);
             }
             $Q->delete('UserMeta');
         } else {
             $Px = $this->SQL->Database->DatabasePrefix;
             $Sql = "insert {$Px}UserMeta (UserID, Name, Value) values(:UserID, :Name, :Value) on duplicate key update Value = :Value1";
             $Params = array(':UserID' => $UserID, ':Name' => $Key, ':Value' => $Value, ':Value1' => $Value);
             $this->Database->query($Sql, $Params);
         }
         return;
     }
     if (is_null($Value)) {
         // Delete
         $UserMetaQuery = Gdn::sql();
         if (is_array($UserID)) {
             $UserMetaQuery->whereIn('UserID', $UserID);
         } else {
             $UserMetaQuery->where('UserID', $UserID);
         }
         if (stristr($Key, '%')) {
             $UserMetaQuery->like('Name', $Key);
         } else {
             $UserMetaQuery->where('Name', $Key);
         }
         $UserMetaQuery->delete('UserMeta');
     } else {
         // Set
         if (!is_array($UserID)) {
             $UserID = array($UserID);
         }
         foreach ($UserID as $UID) {
             try {
                 Gdn::sql()->insert('UserMeta', array('UserID' => $UID, 'Name' => $Key, 'Value' => $Value));
             } catch (Exception $e) {
                 Gdn::sql()->update('UserMeta', array('Value' => $Value), array('UserID' => $UID, 'Name' => $Key))->put();
             }
         }
     }
     return;
 }
示例#12
0
 /**
  * Get the permissions for one or more roles.
  *
  * @param int $roleID The role to get the permissions for.
  * @return array Returns a permission array suitable for use in a session.
  */
 public function getPermissionsByRole($roleID)
 {
     $inc = Gdn::userModel()->getPermissionsIncrement();
     $key = "perms:{$inc}:role:{$roleID}";
     $permissions = Gdn::cache()->get($key);
     if ($permissions === Gdn_Cache::CACHEOP_FAILURE) {
         $sql = clone $this->SQL;
         $sql->reset();
         // Select all of the permission columns.
         $permissionColumns = $this->permissionColumns();
         foreach ($permissionColumns as $columnName => $value) {
             $sql->select('p.`' . $columnName . '`', 'MAX');
         }
         $sql->from('Permission p')->where('p.RoleID', $roleID)->select(array('p.JunctionTable', 'p.JunctionColumn', 'p.JunctionID'))->groupBy(array('p.JunctionTable', 'p.JunctionColumn', 'p.JunctionID'));
         $permissions = $sql->get()->resultArray();
         $permissions = UserModel::compilePermissions($permissions);
         Gdn::cache()->store($key, $permissions);
     }
     return $permissions;
 }
 /**
  * Select content based on its Score.
  *
  * @param array|int $Parameters
  * @return array|false
  */
 protected function selectByScore($Parameters)
 {
     if (!is_array($Parameters)) {
         $MinScore = $Parameters;
     } else {
         $MinScore = val('Score', $Parameters, null);
     }
     if (!is_integer($MinScore)) {
         $MinScore = false;
     }
     // Check cache
     $SelectorScoreCacheKey = "modules.promotedcontent.score.{$MinScore}";
     $Content = Gdn::cache()->get($SelectorScoreCacheKey);
     if ($Content == Gdn_Cache::CACHEOP_FAILURE) {
         // Get matching Discussions
         $Discussions = array();
         if ($this->ShowDiscussions()) {
             $Discussions = Gdn::sql()->select('d.*')->from('Discussion d')->orderBy('DateInserted', 'DESC')->limit($this->Limit);
             if ($MinScore !== false) {
                 $Discussions->where('Score >', $MinScore);
             }
             $Discussions = $Discussions->get()->result(DATASET_TYPE_ARRAY);
         }
         // Get matching Comments
         $Comments = array();
         if ($this->ShowComments()) {
             $Comments = Gdn::sql()->select('c.*')->from('Comment c')->orderBy('DateInserted', 'DESC')->limit($this->Limit);
             if ($MinScore !== false) {
                 $Comments->where('Score >', $MinScore);
             }
             $Comments = $Comments->get()->result(DATASET_TYPE_ARRAY);
             $this->JoinCategory($Comments);
         }
         // Interleave
         $Content = $this->Union('DateInserted', array('Discussion' => $Discussions, 'Comment' => $Comments));
         $this->processContent($Content);
         // Add result to cache
         Gdn::cache()->store($SelectorScoreCacheKey, $Content, array(Gdn_Cache::FEATURE_EXPIRY => $this->Expiry));
     }
     $this->Security($Content);
     $this->Condense($Content, $this->Limit);
     return $Content;
 }
示例#14
0
 /**
  *
  *
  * @param string $Sql
  * @param null $InputParameters
  * @param array $Options
  * @return Gdn_DataSet|object|string
  */
 public function query($Sql, $InputParameters = null, $Options = array())
 {
     $Trace = debug_backtrace();
     $Method = '';
     foreach ($Trace as $Info) {
         $Class = val('class', $Info, '');
         if ($Class === '' || stringEndsWith($Class, 'Model', true) || stringEndsWith($Class, 'Plugin', true)) {
             $Type = val('type', $Info, '');
             $Method = $Class . $Type . $Info['function'] . '(' . self::formatArgs($Info['args']) . ')';
             break;
         }
     }
     // Save the query for debugging
     // echo '<br />adding to queries: '.$Sql;
     $Query = array('Sql' => $Sql, 'Parameters' => $InputParameters, 'Method' => $Method);
     $SaveQuery = true;
     if (isset($Options['Cache'])) {
         $CacheKeys = (array) $Options['Cache'];
         $Cache = array();
         $AllSet = true;
         foreach ($CacheKeys as $CacheKey) {
             $Value = Gdn::cache()->get($CacheKey);
             $CacheValue = $Value !== Gdn_Cache::CACHEOP_FAILURE;
             $AllSet &= $CacheValue;
             $Cache[$CacheKey] = $CacheValue;
         }
         $SaveQuery = !$AllSet;
         $Query['Cache'] = $Cache;
     }
     // Start the Query Timer
     $TimeStart = now();
     $Result = parent::query($Sql, $InputParameters, $Options);
     $Query = array_merge($this->LastInfo, $Query);
     // Aggregate the query times
     $TimeEnd = now();
     $this->_ExecutionTime += $TimeEnd - $TimeStart;
     if ($SaveQuery && !stringBeginsWith($Sql, 'set names')) {
         $Query['Time'] = $TimeEnd - $TimeStart;
         $this->_Queries[] = $Query;
     }
     return $Result;
 }
示例#15
0
 /**
  * Discussion view counter.
  *
  * @param $Sender
  * @param $Args
  */
 public function gdn_statistics_tick_handler($Sender, $Args)
 {
     $Path = Gdn::request()->post('Path');
     $Args = Gdn::request()->post('Args');
     parse_str($Args, $Args);
     $ResolvedPath = trim(Gdn::request()->post('ResolvedPath'), '/');
     $ResolvedArgs = Gdn::request()->post('ResolvedArgs');
     $DiscussionID = null;
     $DiscussionModel = new DiscussionModel();
     // Comment permalink
     if ($ResolvedPath == 'vanilla/discussion/comment') {
         $CommentID = val('CommentID', $ResolvedArgs);
         $CommentModel = new CommentModel();
         $Comment = $CommentModel->getID($CommentID);
         $DiscussionID = val('DiscussionID', $Comment);
     } elseif ($ResolvedPath == 'vanilla/discussion/index') {
         $DiscussionID = val('DiscussionID', $ResolvedArgs, null);
     } elseif ($ResolvedPath == 'vanilla/discussion/embed') {
         $ForeignID = val('vanilla_identifier', $Args);
         if ($ForeignID) {
             // This will be hit a lot so let's try caching it...
             $Key = "DiscussionID.ForeignID.page.{$ForeignID}";
             $DiscussionID = Gdn::cache()->get($Key);
             if (!$DiscussionID) {
                 $Discussion = $DiscussionModel->getForeignID($ForeignID, 'page');
                 $DiscussionID = val('DiscussionID', $Discussion);
                 Gdn::cache()->store($Key, $DiscussionID, array(Gdn_Cache::FEATURE_EXPIRY, 1800));
             }
         }
     }
     if ($DiscussionID) {
         $DiscussionModel->addView($DiscussionID);
     }
 }
示例#16
0
 /**
  * Return the number of unanswered questions.
  *
  * @return int
  */
 public function getUnansweredCount()
 {
     // TODO: Dekludge this when category permissions are refactored (tburry).
     $cacheKey = Gdn::request()->webRoot() . '/QnA-UnansweredCount';
     $questionCount = Gdn::cache()->get($cacheKey);
     if ($questionCount === Gdn_Cache::CACHEOP_FAILURE) {
         $questionCount = Gdn::sql()->beginWhereGroup()->where('QnA', null)->orWhereIn('QnA', array('Unanswered', 'Rejected'))->endWhereGroup()->getCount('Discussion', array('Type' => 'Question'));
         Gdn::cache()->store($cacheKey, $questionCount, array(Gdn_Cache::FEATURE_EXPIRY => 15 * 60));
     }
     // Check to see if another plugin can handle this.
     $this->EventArguments['questionCount'] =& $questionCount;
     $this->fireEvent('unansweredCount');
     return $questionCount;
 }
示例#17
0
 /**
  * Wrapper for GetCountWhere that takes care of caching specific operation counts.
  *
  * @param string $Operation Comma-delimited list of operation types to get (sum of) counts for.
  * @return int
  */
 public function getOperationCount($Operation)
 {
     if ($Operation == 'edits') {
         $Operation = array('edit', 'delete');
     } else {
         $Operation = explode(',', $Operation);
     }
     sort($Operation);
     array_map('ucfirst', $Operation);
     $CacheKey = 'Moderation.LogCount.' . implode('.', $Operation);
     $Count = Gdn::cache()->get($CacheKey);
     if ($Count === Gdn_Cache::CACHEOP_FAILURE) {
         $Count = $this->getCountWhere(array('Operation' => $Operation));
         Gdn::cache()->store($CacheKey, $Count, array(Gdn_Cache::FEATURE_EXPIRY => 300));
     }
     return $Count;
 }
示例#18
0
 /**
  *
  *
  * @param string $Key Cache key.
  * @param array $Options
  * @return mixed
  */
 protected function fallback($Key, $Options)
 {
     $Fallback = val(Gdn_Cache::FEATURE_FALLBACK, $Options, null);
     if (is_null($Fallback)) {
         return Gdn_Cache::CACHEOP_FAILURE;
     }
     $FallbackType = array_shift($Fallback);
     switch ($FallbackType) {
         case 'query':
             $QueryFallbackField = array_shift($Fallback);
             $QueryFallbackCode = array_shift($Fallback);
             $FallbackResult = Gdn::database()->query($QueryFallbackCode);
             if ($FallbackResult->numRows()) {
                 if (!is_null($QueryFallbackField)) {
                     $FallbackResult = val($QueryFallbackField, $FallbackResult->firstRow(DATASET_TYPE_ARRAY));
                 } else {
                     $FallbackResult = $FallbackResult->resultArray();
                 }
             }
             break;
         case 'callback':
             $CallbackFallbackMethod = array_shift($Fallback);
             $CallbackFallbackArgs = $Fallback;
             $FallbackResult = call_user_func_array($CallbackFallbackMethod, $CallbackFallbackArgs);
             break;
     }
     Gdn::cache()->store($Key, $FallbackResult);
     return $FallbackResult;
 }
示例#19
0
 /**
  *
  *
  * @param $Users
  * @param string $UserIDColumn
  * @param string $RolesColumn
  */
 public static function setUserRoles(&$Users, $UserIDColumn = 'UserID', $RolesColumn = 'Roles')
 {
     $UserIDs = array_unique(ConsolidateArrayValuesByKey($Users, $UserIDColumn));
     // Try and get all of the mappings from the cache.
     $Keys = array();
     foreach ($UserIDs as $UserID) {
         $Keys[$UserID] = formatString(UserModel::USERROLES_KEY, array('UserID' => $UserID));
     }
     $UserRoles = Gdn::cache()->get($Keys);
     if (!is_array($UserRoles)) {
         $UserRoles = array();
     }
     // Grab all of the data that doesn't exist from the DB.
     $MissingIDs = array();
     foreach ($Keys as $UserID => $Key) {
         if (!array_key_exists($Key, $UserRoles)) {
             $MissingIDs[$UserID] = $Key;
         }
     }
     if (count($MissingIDs) > 0) {
         $DbUserRoles = Gdn::sql()->select('ur.*')->from('UserRole ur')->whereIn('ur.UserID', array_keys($MissingIDs))->get()->resultArray();
         $DbUserRoles = Gdn_DataSet::Index($DbUserRoles, 'UserID', array('Unique' => false));
         // Store the user role mappings.
         foreach ($DbUserRoles as $UserID => $Rows) {
             $RoleIDs = consolidateArrayValuesByKey($Rows, 'RoleID');
             $Key = $Keys[$UserID];
             Gdn::cache()->store($Key, $RoleIDs);
             $UserRoles[$Key] = $RoleIDs;
         }
     }
     $AllRoles = self::roles();
     // roles indexed by role id.
     // Skip personal info roles
     if (!checkPermission('Garden.PersonalInfo.View')) {
         $AllRoles = array_filter($AllRoles, 'self::FilterPersonalInfo');
     }
     // Join the users.
     foreach ($Users as &$User) {
         $UserID = val($UserIDColumn, $User);
         $Key = $Keys[$UserID];
         $RoleIDs = val($Key, $UserRoles, array());
         $Roles = array();
         foreach ($RoleIDs as $RoleID) {
             if (!array_key_exists($RoleID, $AllRoles)) {
                 continue;
             }
             $Roles[$RoleID] = $AllRoles[$RoleID]['Name'];
         }
         setValue($RolesColumn, $User, $Roles);
     }
 }
示例#20
0
 /**
  * Grab and update the category cache
  *
  * @since 2.0.18
  * @access public
  * @param int $ID
  * @param array $Data
  */
 public static function setCache($ID = false, $Data = false)
 {
     self::instance()->collection->refreshCache((int) $ID);
     $Categories = Gdn::cache()->get(self::CACHE_KEY);
     self::$Categories = null;
     if (!$Categories) {
         return;
     }
     // Extract actual category list, remove key if malformed
     if (!$ID || !is_array($Categories) || !array_key_exists('categories', $Categories)) {
         Gdn::cache()->remove(self::CACHE_KEY);
         return;
     }
     $Categories = $Categories['categories'];
     // Check for category in list, otherwise remove key if not found
     if (!array_key_exists($ID, $Categories)) {
         Gdn::cache()->remove(self::CACHE_KEY);
         return;
     }
     $Category = $Categories[$ID];
     $Category = array_merge($Category, $Data);
     $Categories[$ID] = $Category;
     // Update memcache entry
     self::$Categories = $Categories;
     unset($Categories);
     self::BuildCache($ID);
     self::JoinUserData(self::$Categories, true);
 }
示例#21
0
<div id="Sql" class="DebugInfo">
    <h2>Debug Information</h2>
    <?php 
// Add the canonical Url.
if (method_exists($Sender, 'CanonicalUrl')) {
    $CanonicalUrl = htmlspecialchars($Sender->canonicalUrl(), ENT_COMPAT, c('Garden.Charset', 'UTF-8'));
    echo '<div class="CanonicalUrl"><b>' . t('Canonical Url') . "</b>: <a href=\"{$CanonicalUrl}\" accesskey=\"r\">{$CanonicalUrl}</a></div>";
}
?>

    <?php 
// Add some cache info.
if (Gdn::cache()->activeEnabled()) {
    echo '<h3>Cache Information</h3>';
    echo '<pre>';
    echo '<b>Cache Revision</b>: ' . Gdn::cache()->GetRevision() . "\n";
    echo '<b>Permissions Revision</b>: ' . Gdn::userModel()->GetPermissionsIncrement() . "\n";
    if (property_exists('Gdn_Cache', 'GetCount')) {
        echo '<b>Cache Gets</b>: ' . sprintf('%s in %ss', Gdn_Cache::$GetCount, Gdn_Cache::$GetTime);
    }
    echo '</pre>';
    if (property_exists('Gdn_Cache', 'trackGet') && sizeof(Gdn_Cache::$trackGet)) {
        uasort(Gdn_Cache::$trackGet, function ($a, $b) {
            return $b['hits'] - $a['hits'];
        });
        $numKeys = sizeof(Gdn_Cache::$trackGet);
        $duplicateGets = 0;
        $wastedBytes = 0;
        $totalBytes = 0;
        foreach (Gdn_Cache::$trackGet as $key => $keyData) {
            if ($keyData['hits'] > 1) {
 /**
  *
  *
  * @param null $SearchPaths
  */
 public function clearPluginCache($SearchPaths = null)
 {
     if (!is_null($SearchPaths)) {
         if (!is_array($SearchPaths)) {
             $SearchPaths = array($SearchPaths);
         }
     } else {
         $SearchPaths = $this->searchPaths();
     }
     foreach ($SearchPaths as $SearchPath => $SearchPathName) {
         $SearchPathCacheKey = "Garden.Plugins.PathCache.{$SearchPath}";
         if ($this->Apc) {
             apc_delete($SearchPathCacheKey);
         } else {
             Gdn::cache()->remove($SearchPathCacheKey, array(Gdn_Cache::FEATURE_NOPREFIX => true));
         }
     }
 }
 /**
  * Increments overall pageview view count.
  *
  * @since 2.1a
  * @access public
  */
 public function addView($ViewType = 'normal')
 {
     // Add a pageview entry.
     $TimeSlot = date('Ymd');
     $Px = Gdn::database()->DatabasePrefix;
     $Views = 1;
     $EmbedViews = 0;
     try {
         if (C('Garden.Analytics.Views.Denormalize', false) && Gdn::cache()->activeEnabled() && Gdn::cache()->type() != Gdn_Cache::CACHE_TYPE_NULL) {
             $CacheKey = "QueryCache.Analytics.CountViews";
             // Increment. If not success, create key.
             $Incremented = Gdn::cache()->increment($CacheKey);
             if ($Incremented === Gdn_Cache::CACHEOP_FAILURE) {
                 Gdn::cache()->store($CacheKey, 1);
             }
             // Get current cache value
             $Views = Gdn::cache()->get($CacheKey);
             if ($ViewType == 'embed') {
                 $EmbedCacheKey = "QueryCache.Analytics.CountEmbedViews";
                 // Increment. If not success, create key.
                 $EmbedIncremented = Gdn::cache()->increment($EmbedCacheKey);
                 if ($EmbedIncremented === Gdn_Cache::CACHEOP_FAILURE) {
                     Gdn::cache()->store($EmbedCacheKey, 1);
                 }
                 // Get current cache value
                 $EmbedViews = Gdn::cache()->get($EmbedCacheKey);
             }
             // Every X views, writeback to AnalyticsLocal
             $DenormalizeWriteback = C('Garden.Analytics.Views.DenormalizeWriteback', 10);
             if ($Views % $DenormalizeWriteback == 0) {
                 Gdn::controller()->setData('WritebackViews', $Views);
                 Gdn::controller()->setData('WritebackEmbed', $EmbedViews);
                 Gdn::database()->query("insert into {$Px}AnalyticsLocal (TimeSlot, Views, EmbedViews) values (:TimeSlot, {$Views}, {$EmbedViews})\n               on duplicate key update\n                  Views = COALESCE(Views, 0)+{$Views},\n                  EmbedViews = COALESCE(EmbedViews, 0)+{$EmbedViews}", array(':TimeSlot' => $TimeSlot));
                 // ... and get rid of those views from the keys
                 if ($Views) {
                     Gdn::cache()->decrement($CacheKey, $Views);
                 }
                 if ($EmbedViews) {
                     Gdn::cache()->decrement($EmbedCacheKey, $EmbedViews);
                 }
             }
         } else {
             $ExtraViews = 1;
             $ExtraEmbedViews = $ViewType == 'embed' ? 1 : 0;
             Gdn::database()->query("insert into {$Px}AnalyticsLocal (TimeSlot, Views, EmbedViews) values (:TimeSlot, {$ExtraViews}, {$ExtraEmbedViews})\n               on duplicate key update\n                  Views = COALESCE(Views, 0)+{$ExtraViews},\n                  EmbedViews = COALESCE(EmbedViews, 0)+{$ExtraEmbedViews}", array(':TimeSlot' => $TimeSlot));
         }
     } catch (Exception $Ex) {
         if (Gdn::session()->checkPermission('Garden.Settings.Manage')) {
             throw $Ex;
         }
     }
 }
示例#24
0
 /**
  *
  *
  * @return bool|int|mixed
  */
 public function getPermissionsIncrement()
 {
     $PermissionsIncrementKey = self::INC_PERMISSIONS_KEY;
     $PermissionsKeyValue = Gdn::cache()->get($PermissionsIncrementKey);
     if (!$PermissionsKeyValue) {
         $Stored = Gdn::cache()->store($PermissionsIncrementKey, 1);
         return $Stored ? 1 : false;
     }
     return $PermissionsKeyValue;
 }
示例#25
0
$Construct->Table('Media')->PrimaryKey('MediaID')->Column('Name', 'varchar(255)')->Column('Path', 'varchar(255)')->Column('Type', 'varchar(128)')->Column('Size', 'int(11)')->Column('InsertUserID', 'int(11)')->Column('DateInserted', 'datetime')->Column('ForeignID', 'int(11)', TRUE)->Column('ForeignTable', 'varchar(24)', TRUE)->Column('ImageWidth', 'usmallint', NULL)->Column('ImageHeight', 'usmallint', NULL)->Column('ThumbWidth', 'usmallint', NULL)->Column('ThumbHeight', 'usmallint', NULL)->Column('ThumbPath', 'varchar(255)', NULL)->Set(FALSE, FALSE);
// Merge backup.
$Construct->Table('UserMerge')->PrimaryKey('MergeID')->Column('OldUserID', 'int', FALSE, 'key')->Column('NewUserID', 'int', FALSE, 'key')->Column('DateInserted', 'datetime')->Column('InsertUserID', 'int')->Column('DateUpdated', 'datetime', TRUE)->Column('UpdateUserID', 'int', TRUE)->Column('Attributes', 'text', TRUE)->Set();
$Construct->Table('UserMergeItem')->Column('MergeID', 'int', FALSE, 'key')->Column('Table', 'varchar(30)')->Column('Column', 'varchar(30)')->Column('RecordID', 'int')->Column('OldUserID', 'int')->Column('NewUserID', 'int')->Set();
// Save the current input formatter to the user's config.
// This will allow us to change the default later and grandfather existing forums in.
SaveToConfig('Garden.InputFormatter', C('Garden.InputFormatter'));
// We need to undo cleditor's bad behavior for our reformed users.
// If you still need to manipulate this, do it in memory instead (SAVE = false).
SaveToConfig('Garden.Html.SafeStyles', TRUE);
// Make sure the smarty folders exist.
if (!file_exists(PATH_CACHE . '/Smarty')) {
    @mkdir(PATH_CACHE . '/Smarty');
}
if (!file_exists(PATH_CACHE . '/Smarty/cache')) {
    @mkdir(PATH_CACHE . '/Smarty/cache');
}
if (!file_exists(PATH_CACHE . '/Smarty/compile')) {
    @mkdir(PATH_CACHE . '/Smarty/compile');
}
// Disallow additional super-admin users.
// Get admins' UserIDs, sort lowest to highest, & exempt lowest UserID.
$users = Gdn::userModel()->getWhere(array('Admin' => 1))->resultArray();
$affect = ConsolidateArrayValuesByKey($users, 'UserID');
sort($affect);
array_shift($affect);
if (count($affect)) {
    // Remove admin power & flush cache.
    Gdn::userModel()->update(array('Admin' => 0), array('UserID' => $affect));
    Gdn::cache()->flush();
}
示例#26
0
 /**
  *
  *
  * @param $Name
  * @param array $Properties
  * @return mixed|string
  */
 public static function module($Name, $Properties = array())
 {
     if (isset($Properties['cache'])) {
         $Key = isset($Properties['cachekey']) ? $Properties['cachekey'] : 'module.' . $Name;
         $Result = Gdn::cache()->get($Key);
         if ($Result !== Gdn_Cache::CACHEOP_FAILURE) {
             //            Trace('Module: '.$Result, $Key);
             return $Result;
         }
     }
     try {
         if (!class_exists($Name)) {
             if (debug()) {
                 $Result = "Error: {$Name} doesn't exist";
             } else {
                 $Result = "<!-- Error: {$Name} doesn't exist -->";
             }
         } else {
             $Module = new $Name(Gdn::controller(), '');
             $Module->Visible = true;
             // Add properties passed in from the controller.
             $ControllerProperties = Gdn::controller()->data('_properties.' . strtolower($Name), array());
             $Properties = array_merge($ControllerProperties, $Properties);
             foreach ($Properties as $Name => $value) {
                 // Check for a setter method
                 if (method_exists($Module, $method = 'set' . ucfirst($Name))) {
                     $Module->{$method}($value);
                 } else {
                     $Module->{$Name} = $value;
                 }
             }
             $Result = $Module->toString();
         }
     } catch (Exception $Ex) {
         if (debug()) {
             $Result = '<pre class="Exception">' . htmlspecialchars($Ex->getMessage() . "\n" . $Ex->getTraceAsString()) . '</pre>';
         } else {
             $Result = $Ex->getMessage();
         }
     }
     if (isset($Key)) {
         //         Trace($Result, "Store $Key");
         Gdn::cache()->store($Key, $Result, array(Gdn_Cache::FEATURE_EXPIRY => $Properties['cache']));
     }
     return $Result;
 }
示例#27
0
 /**
  * Executes a string of SQL. Returns a @@DataSet object.
  *
  * @param string $Sql A string of SQL to be executed.
  * @param array $InputParameters An array of values with as many elements as there are bound parameters in the SQL statement being executed.
  */
 public function query($Sql, $InputParameters = null, $Options = array())
 {
     $this->LastInfo = array();
     if ($Sql == '') {
         trigger_error(errorMessage('Database was queried with an empty string.', $this->ClassName, 'Query'), E_USER_ERROR);
     }
     // Get the return type.
     if (isset($Options['ReturnType'])) {
         $ReturnType = $Options['ReturnType'];
     } elseif (preg_match('/^\\s*"?(insert)\\s+/i', $Sql)) {
         $ReturnType = 'ID';
     } elseif (!preg_match('/^\\s*"?(update|delete|replace|create|drop|load data|copy|alter|grant|revoke|lock|unlock)\\s+/i', $Sql)) {
         $ReturnType = 'DataSet';
     } else {
         $ReturnType = null;
     }
     if (isset($Options['Cache'])) {
         // Check to see if the query is cached.
         $CacheKeys = (array) val('Cache', $Options, null);
         $CacheOperation = val('CacheOperation', $Options, null);
         if (is_null($CacheOperation)) {
             switch ($ReturnType) {
                 case 'DataSet':
                     $CacheOperation = 'get';
                     break;
                 case 'ID':
                 case null:
                     $CacheOperation = 'remove';
                     break;
             }
         }
         switch ($CacheOperation) {
             case 'get':
                 foreach ($CacheKeys as $CacheKey) {
                     $Data = Gdn::cache()->get($CacheKey);
                 }
                 // Cache hit. Return.
                 if ($Data !== Gdn_Cache::CACHEOP_FAILURE) {
                     return new Gdn_DataSet($Data);
                 }
                 // Cache miss. Save later.
                 $StoreCacheKey = $CacheKey;
                 break;
             case 'increment':
             case 'decrement':
                 $CacheMethod = ucfirst($CacheOperation);
                 foreach ($CacheKeys as $CacheKey) {
                     $CacheResult = Gdn::cache()->{$CacheMethod}($CacheKey);
                 }
                 break;
             case 'remove':
                 foreach ($CacheKeys as $CacheKey) {
                     $Res = Gdn::cache()->remove($CacheKey);
                 }
                 break;
         }
     }
     // We will retry this query a few times if it fails.
     $tries = $this->ConnectRetries + 1;
     if ($tries < 1) {
         $tries = 1;
     }
     for ($try = 0; $try < $tries; $try++) {
         if (val('Type', $Options) == 'select' && val('Slave', $Options, null) !== false) {
             $PDO = $this->slave();
             $this->LastInfo['connection'] = 'slave';
         } else {
             $PDO = $this->connection();
             $this->LastInfo['connection'] = 'master';
         }
         // Make sure other unbufferred queries are not open
         if (is_object($this->_CurrentResultSet)) {
             $this->_CurrentResultSet->result();
             $this->_CurrentResultSet->freePDOStatement(false);
         }
         $PDOStatement = null;
         try {
             // Prepare / Execute
             if (!is_null($InputParameters) && count($InputParameters) > 0) {
                 $PDOStatement = $PDO->prepare($Sql);
                 if (!is_object($PDOStatement)) {
                     trigger_error(errorMessage('PDO Statement failed to prepare', $this->ClassName, 'Query', $this->getPDOErrorMessage($PDO->errorInfo())), E_USER_ERROR);
                 } elseif ($PDOStatement->execute($InputParameters) === false) {
                     trigger_error(errorMessage($this->getPDOErrorMessage($PDOStatement->errorInfo()), $this->ClassName, 'Query', $Sql), E_USER_ERROR);
                 }
             } else {
                 $PDOStatement = $PDO->query($Sql);
             }
             if ($PDOStatement === false) {
                 list($state, $code, $message) = $PDO->errorInfo();
                 // Detect mysql "server has gone away" and try to reconnect.
                 if ($code == 2006 && $try < $tries) {
                     $this->closeConnection();
                     continue;
                 } else {
                     throw new Gdn_UserException($message, $code);
                 }
             }
             // If we get here then the pdo statement prepared properly.
             break;
         } catch (Gdn_UserException $uex) {
             trigger_error($uex->getMessage(), E_USER_ERROR);
         } catch (Exception $ex) {
             list($state, $code, $message) = $PDO->errorInfo();
             // If the error code is consistent with a disconnect, attempt to retry
             if ($code == 2006 && $try < $tries) {
                 $this->closeConnection();
                 continue;
             }
             if (!$message) {
                 $message = $ex->getMessage();
             }
             trigger_error($message, E_USER_ERROR);
         }
     }
     if ($PDOStatement instanceof PDOStatement) {
         $this->LastInfo['RowCount'] = $PDOStatement->rowCount();
     }
     // Did this query modify data in any way?
     if ($ReturnType == 'ID') {
         $this->_CurrentResultSet = $PDO->lastInsertId();
         if (is_a($PDOStatement, 'PDOStatement')) {
             $PDOStatement->closeCursor();
         }
     } else {
         if ($ReturnType == 'DataSet') {
             // Create a DataSet to manage the resultset
             $this->_CurrentResultSet = new Gdn_DataSet();
             $this->_CurrentResultSet->Connection = $PDO;
             $this->_CurrentResultSet->pdoStatement($PDOStatement);
         } elseif (is_a($PDOStatement, 'PDOStatement')) {
             $PDOStatement->closeCursor();
         }
     }
     if (isset($StoreCacheKey)) {
         if ($CacheOperation == 'get') {
             Gdn::cache()->store($StoreCacheKey, $this->_CurrentResultSet instanceof Gdn_DataSet ? $this->_CurrentResultSet->resultArray() : $this->_CurrentResultSet, val('CacheOptions', $Options, array()));
         }
     }
     return $this->_CurrentResultSet;
 }
 public function removePageCache($DiscussionID, $From = 1)
 {
     if (!$this->pageCache) {
         return;
     }
     $CountComments = $this->SQL->getWhere('Discussion', array('DiscussionID' => $DiscussionID))->value('CountComments');
     $Limit = c('Vanilla.Comments.PerPage', 30);
     $PageCount = PageNumber($CountComments, $Limit) + 1;
     for ($Page = $From; $Page <= $PageCount; $Page++) {
         $CacheKey = "Comment.Page.{$Limit}.{$DiscussionID}.{$Page}";
         Gdn::cache()->Remove($CacheKey);
     }
 }
示例#29
0
 /**
  * Proxy an RSS feed for Dashboard use across our kingdom.
  *
  * @param Gdn_Controller $sender
  * @param $Url
  * @return mixed|string
  * @throws Exception
  */
 public function homeController_proxyFeed_create($sender, $Url)
 {
     $Key = 'Feed|' . $Url;
     $Feed = Gdn::cache()->get($Key);
     if (!$Feed) {
         $Feed = ProxyRequest($Url, 5);
         Gdn::cache()->store($Key, $Feed, array(Gdn_Cache::FEATURE_EXPIRY => 5 * 60));
     }
     return $Feed;
 }