Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(dev/core#174) Forms/Sessions - Store state via Civi::cache('session') #12362

Merged
merged 2 commits into from
Jul 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CRM/Admin/Form/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ public function commonProcess(&$params) {
}

CRM_Core_Config::clearDBCache();
Civi::cache('session')->clear(); // This doesn't make a lot of sense to me, but it maintains pre-existing behavior.
CRM_Utils_System::flushCache();
CRM_Core_Resources::singleton()->resetCacheCode();

Expand Down
1 change: 1 addition & 0 deletions CRM/Admin/Form/Setting/UpdateConfigBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public function postProcess() {

// clear all caches
CRM_Core_Config::clearDBCache();
Civi::cache('session')->clear();
CRM_Utils_System::flushCache();

parent::rebuildMenu();
Expand Down
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
1 change: 1 addition & 0 deletions CRM/Core/BAO/ConfigSetting.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ public static function doSiteMove($defaultValues = array()) {

// clear all caches
CRM_Core_Config::clearDBCache();
Civi::cache('session')->clear();
$moveStatus .= ts('Database cache tables cleared.') . '<br />';

$resetSessionTable = CRM_Utils_Request::retrieve('resetSessionTable',
Expand Down
1 change: 1 addition & 0 deletions CRM/Core/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ public function cleanupCaches($sessionReset = TRUE) {

// clear all caches
self::clearDBCache();
Civi::cache('session')->clear();
CRM_Utils_System::flushCache();

if ($sessionReset) {
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