Skip to content

Commit

Permalink
(REVERT) Cumulative changes for master-psr16-full
Browse files Browse the repository at this point in the history
  • Loading branch information
totten committed Jun 27, 2018
1 parent 5db1add commit 4d9ea27
Show file tree
Hide file tree
Showing 36 changed files with 1,215 additions and 138 deletions.
2 changes: 1 addition & 1 deletion CRM/ACL/BAO/ACL.php
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ public static function group(
$aclKeys = array_keys($acls);
$aclKeys = implode(',', $aclKeys);

$cacheKey = "$tableName-$aclKeys";
$cacheKey = CRM_Core_BAO_Cache::cleanKey("$tableName-$aclKeys");
$cache = CRM_Utils_Cache::singleton();
$ids = $cache->get($cacheKey);
if (!$ids) {
Expand Down
3 changes: 2 additions & 1 deletion CRM/Contact/BAO/ContactType.php
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,9 @@ public static function getSelectElements(
}

$argString = $all ? 'CRM_CT_GSE_1' : 'CRM_CT_GSE_0';
$argString .= $isSeparator ? '_1' : '_0';
$argString .= $isSeparator ? '_1' : ' _0';
$argString .= $separator;
$argString = CRM_Core_BAO_Cache::cleanKey($argString);
if (!array_key_exists($argString, $_cache)) {
$cache = CRM_Utils_Cache::singleton();
$_cache[$argString] = $cache->get($argString);
Expand Down
57 changes: 48 additions & 9 deletions CRM/Core/BAO/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ public static function &getItem($group, $path, $componentID = NULL) {
$argString = "CRM_CT_{$group}_{$path}_{$componentID}";
if (!array_key_exists($argString, self::$_cache)) {
$cache = CRM_Utils_Cache::singleton();
self::$_cache[$argString] = $cache->get($argString);
self::$_cache[$argString] = $cache->get(self::cleanKey($argString));
if (!self::$_cache[$argString]) {
$table = self::getTableName();
$where = self::whereCache($group, $path, $componentID);
$rawData = CRM_Core_DAO::singleValueQuery("SELECT data FROM $table WHERE $where");
$data = $rawData ? self::decode($rawData) : NULL;

self::$_cache[$argString] = $data;
$cache->set($argString, self::$_cache[$argString]);
$cache->set(self::cleanKey($argString), self::$_cache[$argString]);
}
}
return self::$_cache[$argString];
Expand All @@ -99,7 +99,7 @@ public static function &getItems($group, $componentID = NULL) {
$argString = "CRM_CT_CI_{$group}_{$componentID}";
if (!array_key_exists($argString, self::$_cache)) {
$cache = CRM_Utils_Cache::singleton();
self::$_cache[$argString] = $cache->get($argString);
self::$_cache[$argString] = $cache->get(self::cleanKey($argString));
if (!self::$_cache[$argString]) {
$table = self::getTableName();
$where = self::whereCache($group, NULL, $componentID);
Expand All @@ -112,7 +112,7 @@ public static function &getItems($group, $componentID = NULL) {
$dao->free();

self::$_cache[$argString] = $result;
$cache->set($argString, self::$_cache[$argString]);
$cache->set(self::cleanKey($argString), self::$_cache[$argString]);
}
}

Expand Down Expand Up @@ -182,11 +182,11 @@ public static function setItem(&$data, $group, $path, $componentID = NULL) {
$cache = CRM_Utils_Cache::singleton();
$data = self::decode($dataSerialized);
self::$_cache[$argString] = $data;
$cache->set($argString, $data);
$cache->set(self::cleanKey($argString), $data);

$argString = "CRM_CT_CI_{$group}_{$componentID}";
unset(self::$_cache[$argString]);
$cache->delete($argString);
$cache->delete(self::cleanKey($argString));
}

/**
Expand Down Expand Up @@ -304,7 +304,7 @@ public static function restoreSessionFromCache($names) {
* @param bool $table
* @param bool $prevNext
*/
public static function cleanup($session = FALSE, $table = FALSE, $prevNext = FALSE) {
public static function cleanup($session = FALSE, $table = FALSE, $prevNext = FALSE, $expired = FALSE) {
// first delete all sessions more than 20 minutes old which are related to any potential transaction
$timeIntervalMins = (int) Civi::settings()->get('secure_cache_timeout_minutes');
if ($timeIntervalMins && $session) {
Expand Down Expand Up @@ -338,10 +338,10 @@ public static function cleanup($session = FALSE, $table = FALSE, $prevNext = FAL
$timeIntervalDays = 2;

if (mt_rand(1, 100000) % $cleanUpNumber == 0) {
$session = $table = $prevNext = TRUE;
$expired = $session = $table = $prevNext = TRUE;
}

if (!$session && !$table && !$prevNext) {
if (!$session && !$table && !$prevNext && !$expired) {
return;
}

Expand All @@ -363,6 +363,14 @@ public static function cleanup($session = FALSE, $table = FALSE, $prevNext = FAL
";
CRM_Core_DAO::executeQuery($sql);
}

if ($expired) {
$sql = "DELETE FROM civicrm_cache WHERE expired_date < %1";
$params = [
1 => [date(CRM_Utils_Cache_SqlGroup::TS_FMT, CRM_Utils_Time::getTimeRaw()), 'String'],
];
CRM_Core_DAO::executeQuery($sql, $params);
}
}

/**
Expand Down Expand Up @@ -417,4 +425,35 @@ protected static function whereCache($group, $path, $componentID) {
return $clauses ? implode(' AND ', $clauses) : '(1)';
}

/**
* Normalize a cache key.
*
* This bridges an impedance mismatch between our traditional caching
* and PSR-16 -- PSR-16 accepts a narrower range of cache keys.
*
* @param string $key
* Ex: 'ab/cd:ef'
* @return string
* Ex: '_abcd1234abcd1234' or 'ab_xx/cd_xxef'.
* A similar key, but suitable for use with PSR-16-compliant cache providers.
*/
public static function cleanKey($key) {
if (!is_string($key) && !is_int($key)) {
throw new \RuntimeException("Malformed cache key");
}

$maxLen = 64;
$escape = '-';

if (strlen($key) >= $maxLen) {
return $escape . md5($key);
}

$r = preg_replace_callback(';[^A-Za-z0-9_\. ];', function($m) use ($escape) {
return $escape . dechex(ord($m[0]));
}, $key);

return strlen($r) >= $maxLen ? $escape . md5($key) : $r;
}

}
4 changes: 2 additions & 2 deletions CRM/Core/OptionGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ protected static function flushValues($name, $flip, $grouping, $localize, $condi
/**
* @return string
*/
protected static function createCacheKey() {
$cacheKey = "CRM_OG_" . serialize(func_get_args());
protected static function createCacheKey($id) {
$cacheKey = "CRM_OG_" . preg_replace('/[^a-zA-Z0-9]/', '', $id) . '_' . md5(serialize(func_get_args()));
return $cacheKey;
}

Expand Down
2 changes: 1 addition & 1 deletion CRM/Core/PseudoConstant.php
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ public static function populate(
$key = 'id',
$force = NULL
) {
$cacheKey = "CRM_PC_{$name}_{$all}_{$key}_{$retrieve}_{$filter}_{$condition}_{$orderby}";
$cacheKey = CRM_Core_BAO_Cache::cleanKey("CRM_PC_{$name}_{$all}_{$key}_{$retrieve}_{$filter}_{$condition}_{$orderby}");
$cache = CRM_Utils_Cache::singleton();
$var = $cache->get($cacheKey);
if ($var && empty($force)) {
Expand Down
4 changes: 2 additions & 2 deletions CRM/Cxn/CiviCxnHttp.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function send($verb, $url, $blob, $headers = array()) {
$lowVerb = strtolower($verb);

if ($lowVerb === 'get' && $this->cache) {
$cachePath = 'get/' . md5($url);
$cachePath = 'get_' . md5($url);
$cacheLine = $this->cache->get($cachePath);
if ($cacheLine && $cacheLine['expires'] > CRM_Utils_Time::getTimeRaw()) {
return $cacheLine['data'];
Expand All @@ -66,7 +66,7 @@ public function send($verb, $url, $blob, $headers = array()) {
if ($lowVerb === 'get' && $this->cache) {
$expires = CRM_Utils_Http::parseExpiration($result[0]);
if ($expires !== NULL) {
$cachePath = 'get/' . md5($url);
$cachePath = 'get_' . md5($url);
$cacheLine = array(
'url' => $url,
'expires' => $expires,
Expand Down
6 changes: 3 additions & 3 deletions CRM/Extension/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ public function getActiveModuleFiles($fresh = FALSE) {

$moduleExtensions = NULL;
if ($this->cache && !$fresh) {
$moduleExtensions = $this->cache->get($this->cacheKey . '/moduleFiles');
$moduleExtensions = $this->cache->get($this->cacheKey . '_moduleFiles');
}

if (!is_array($moduleExtensions)) {
Expand Down Expand Up @@ -315,7 +315,7 @@ public function getActiveModuleFiles($fresh = FALSE) {
}

if ($this->cache) {
$this->cache->set($this->cacheKey . '/moduleFiles', $moduleExtensions);
$this->cache->set($this->cacheKey . '_moduleFiles', $moduleExtensions);
}
}
return $moduleExtensions;
Expand Down Expand Up @@ -461,7 +461,7 @@ public function refresh() {
$this->infos = array();
$this->moduleExtensions = NULL;
if ($this->cache) {
$this->cache->delete($this->cacheKey . '/moduleFiles');
$this->cache->delete($this->cacheKey . '_moduleFiles');
}
// FIXME: How can code so code wrong be so right?
CRM_Extension_System::singleton()->getClassLoader()->refresh();
Expand Down
26 changes: 26 additions & 0 deletions CRM/Utils/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,30 @@ public static function create($params = array()) {
throw new CRM_Core_Exception("Failed to instantiate cache. No supported cache type found. " . print_r($params, 1));
}

/**
* Assert that a key is well-formed.
*
* @param string $key
* @return string
* Same $key, if it's valid.
* @throws \CRM_Utils_Cache_InvalidArgumentException
*/
public static function assertValidKey($key) {
$strict = CRM_Utils_Constant::value('CIVICRM_PSR16_STRICT', FALSE) || defined('CIVICRM_TEST');

if (!is_string($key)) {
throw new CRM_Utils_Cache_InvalidArgumentException("Invalid cache key: Not a string");
}

if ($strict && !preg_match(';^[A-Za-z0-9_\-\. ]+$;', $key)) {
throw new CRM_Utils_Cache_InvalidArgumentException("Invalid cache key: Illegal characters");
}

if ($strict && strlen($key) > 255) {
throw new CRM_Utils_Cache_InvalidArgumentException("Invalid cache key: Too long");
}

return $key;
}

}
43 changes: 36 additions & 7 deletions CRM/Utils/Cache/APCcache.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
* @copyright CiviCRM LLC (c) 2004-2018
*/
class CRM_Utils_Cache_APCcache implements CRM_Utils_Cache_Interface {

use CRM_Utils_Cache_NaiveMultipleTrait; // TODO Consider native implementation.
use CRM_Utils_Cache_NaiveHasTrait; // TODO Native implementation

const DEFAULT_TIMEOUT = 3600;
const DEFAULT_PREFIX = '';

Expand Down Expand Up @@ -72,23 +76,37 @@ public function __construct(&$config) {
/**
* @param $key
* @param $value
* @param null|int|\DateInterval $ttl
*
* @return bool
*/
public function set($key, &$value) {
if (!apc_store($this->_prefix . $key, $value, $this->_timeout)) {
public function set($key, $value, $ttl = NULL) {
CRM_Utils_Cache::assertValidKey($key);
if (is_int($ttl) && $ttl <= 0) {
return $this->delete($key);
}

$ttl = CRM_Utils_Date::convertCacheTtl($ttl, $this->_timeout);
$expires = time() + $ttl;
if (!apc_store($this->_prefix . $key, ['e' => $expires, 'v' => $value], $ttl)) {
return FALSE;
}
return TRUE;
}

/**
* @param $key
* @param mixed $default
*
* @return mixed
*/
public function get($key) {
return apc_fetch($this->_prefix . $key);
public function get($key, $default = NULL) {
CRM_Utils_Cache::assertValidKey($key);
$result = apc_fetch($this->_prefix . $key, $success);
if ($success && isset($result['e']) && $result['e'] > time()) {
return $this->reobjectify($result['v']);
}
return $default;
}

/**
Expand All @@ -97,22 +115,33 @@ public function get($key) {
* @return bool|string[]
*/
public function delete($key) {
return apc_delete($this->_prefix . $key);
CRM_Utils_Cache::assertValidKey($key);
apc_delete($this->_prefix . $key);
return TRUE;
}

public function flush() {
$allinfo = apc_cache_info('user');
$keys = $allinfo['cache_list'];
$prefix = $this->_prefix . "CRM_"; // Our keys follows this pattern: ([A-Za-z0-9_]+)?CRM_[A-Za-z0-9_]+
$prefix = $this->_prefix; // Our keys follows this pattern: ([A-Za-z0-9_]+)?CRM_[A-Za-z0-9_]+
$lp = strlen($prefix); // Get prefix length

foreach ($keys as $key) {
$name = $key['info'];
if ($prefix == substr($name, 0, $lp)) {
// Ours?
apc_delete($this->_prefix . $name);
apc_delete($name);
}
}
return TRUE;
}

public function clear() {
return $this->flush();
}

private function reobjectify($value) {
return is_object($value) ? unserialize(serialize($value)) : $value;
}

}
Loading

0 comments on commit 4d9ea27

Please sign in to comment.