Skip to content

Commit

Permalink
(dev/core#174) Forms/Sessions - Store state via Civi::cache('session')
Browse files Browse the repository at this point in the history
  • Loading branch information
totten committed Jun 28, 2018
1 parent 96b9e96 commit b6d24f2
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 42 deletions.
81 changes: 40 additions & 41 deletions CRM/Core/BAO/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@
*/
class CRM_Core_BAO_Cache extends CRM_Core_DAO_Cache {

/**
* When store session/form state, how long should the data be retained?
*
* @var int, number of second
*/
const DEFAULT_SESSION_TTL = 172800; // Two days: 2*24*60*60

/**
* @var array ($cacheKey => $cacheValue)
*/
Expand Down Expand Up @@ -237,7 +244,8 @@ public static function storeSessionToCache($names, $resetSession = TRUE) {
if (!empty($_SESSION[$sessionName[0]][$sessionName[1]])) {
$value = $_SESSION[$sessionName[0]][$sessionName[1]];
}
self::setItem($value, 'CiviCRM Session', "{$sessionName[0]}_{$sessionName[1]}");
$key = "{$sessionName[0]}_{$sessionName[1]}";
Civi::cache('session')->set($key, $value, self::pickSessionTtl($key));
if ($resetSession) {
$_SESSION[$sessionName[0]][$sessionName[1]] = NULL;
unset($_SESSION[$sessionName[0]][$sessionName[1]]);
Expand All @@ -248,7 +256,7 @@ public static function storeSessionToCache($names, $resetSession = TRUE) {
if (!empty($_SESSION[$sessionName])) {
$value = $_SESSION[$sessionName];
}
self::setItem($value, 'CiviCRM Session', $sessionName);
Civi::cache('session')->set($sessionName, $value, self::pickSessionTtl($sessionName));
if ($resetSession) {
$_SESSION[$sessionName] = NULL;
unset($_SESSION[$sessionName]);
Expand All @@ -275,24 +283,46 @@ public static function storeSessionToCache($names, $resetSession = TRUE) {
public static function restoreSessionFromCache($names) {
foreach ($names as $key => $sessionName) {
if (is_array($sessionName)) {
$value = self::getItem('CiviCRM Session',
"{$sessionName[0]}_{$sessionName[1]}"
);
$value = Civi::cache('session')->get("{$sessionName[0]}_{$sessionName[1]}");
if ($value) {
$_SESSION[$sessionName[0]][$sessionName[1]] = $value;
}
}
else {
$value = self::getItem('CiviCRM Session',
$sessionName
);
$value = Civi::cache('session')->get($sessionName);
if ($value) {
$_SESSION[$sessionName] = $value;
}
}
}
}

/**
* Determine how long session-state should be retained.
*
* @param string $sessionKey
* Ex: '_CRM_Admin_Form_Preferences_Display_f1a5f232e3d850a29a7a4d4079d7c37b_4654_container'
* Ex: 'CiviCRM_CRM_Admin_Form_Preferences_Display_f1a5f232e3d850a29a7a4d4079d7c37b_4654'
* @return int
* Number of seconds.
*/
protected static function pickSessionTtl($sessionKey) {
$secureSessionTimeoutMinutes = (int) Civi::settings()->get('secure_cache_timeout_minutes');
if ($secureSessionTimeoutMinutes) {
$transactionPages = array(
'CRM_Contribute_Controller_Contribution',
'CRM_Event_Controller_Registration',
);
foreach ($transactionPages as $transactionPage) {
if (strpos($sessionKey, $transactionPage) !== FALSE) {
return $secureSessionTimeoutMinutes * 60;
}
}
}

return self::DEFAULT_SESSION_TTL;
}

/**
* Do periodic cleanup of the CiviCRM session table.
*
Expand All @@ -305,32 +335,6 @@ public static function restoreSessionFromCache($names) {
* @param bool $prevNext
*/
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) {
$transactionPages = array(
'CRM_Contribute_Controller_Contribution',
'CRM_Event_Controller_Registration',
);

$params = array(
1 => array(
date('Y-m-d H:i:s', time() - $timeIntervalMins * 60),
'String',
),
);
foreach ($transactionPages as $trPage) {
$params[] = array("%${trPage}%", 'String');
$where[] = 'path LIKE %' . count($params);
}

$sql = "
DELETE FROM civicrm_cache
WHERE group_name = 'CiviCRM Session'
AND created_date <= %1
AND (" . implode(' OR ', $where) . ")";
CRM_Core_DAO::executeQuery($sql, $params);
}
// clean up the session cache every $cacheCleanUpNumber probabilistically
$cleanUpNumber = 757;

Expand All @@ -355,13 +359,8 @@ public static function cleanup($session = FALSE, $table = FALSE, $prevNext = FAL
}

if ($session) {

$sql = "
DELETE FROM civicrm_cache
WHERE group_name = 'CiviCRM Session'
AND created_date < date_sub( NOW( ), INTERVAL $timeIntervalDays DAY )
";
CRM_Core_DAO::executeQuery($sql);
// Session caches are just regular caches, so they expire naturally per TTL.
$expired = TRUE;
}

if ($expired) {
Expand Down
2 changes: 1 addition & 1 deletion CRM/Core/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ public function getVars(&$vars, $prefix = '') {
$values = &$this->_session[$this->_key];
}
else {
$values = CRM_Core_BAO_Cache::getItem('CiviCRM Session', "CiviCRM_{$prefix}");
$values = Civi::cache('session')->get("CiviCRM_{$prefix}");
}

if ($values) {
Expand Down
1 change: 1 addition & 0 deletions Civi/Core/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ public function createContainer() {
'js_strings' => 'js_strings',
'community_messages' => 'community_messages',
'checks' => 'checks',
'session' => 'CiviCRM Session',
);
foreach ($basicCaches as $cacheSvc => $cacheGrp) {
$container->setDefinition("cache.{$cacheSvc}", new Definition(
Expand Down

0 comments on commit b6d24f2

Please sign in to comment.