mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-10-05 17:52:03 +02:00
* API/preferences: caching preferences in instance cache instead of session, to get immediate update in long running sessions (eg. sync) and get smaller sessions
This commit is contained in:
parent
6fa4cc864e
commit
0e0993863c
@ -130,6 +130,64 @@ class preferences
|
|||||||
self::__construct();
|
self::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic function to avoid storing perferences in session, as they get re-read on each request by egw_session::verify()
|
||||||
|
*
|
||||||
|
* @return array with class vars to store
|
||||||
|
*/
|
||||||
|
function __sleep()
|
||||||
|
{
|
||||||
|
$vars = array_keys(get_object_vars($this));
|
||||||
|
|
||||||
|
return array_diff($vars, array('data', 'user', 'group', 'default', 'forced', 'session'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lifetime in seconds of cached items 1d
|
||||||
|
*/
|
||||||
|
const CACHE_LIFETIME = 86400;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read preferences of requested id(s)
|
||||||
|
*
|
||||||
|
* @param int|array $ids
|
||||||
|
* @return array id => app => preference data
|
||||||
|
*/
|
||||||
|
function cache_read($ids)
|
||||||
|
{
|
||||||
|
$prefs = $db_read = array();
|
||||||
|
|
||||||
|
foreach((array)$ids as $id)
|
||||||
|
{
|
||||||
|
$prefs[$id] = egw_cache::getInstance(__CLASS__, $id);
|
||||||
|
if (!isset($prefs[$id])) $db_read[] = $id;
|
||||||
|
}
|
||||||
|
if ($db_read)
|
||||||
|
{
|
||||||
|
foreach($this->db->select($this->table,'*',array('preference_owner' => $db_read),__LINE__,__FILE__) as $row)
|
||||||
|
{
|
||||||
|
// The following replacement is required for PostgreSQL to work
|
||||||
|
$app = trim($row['preference_app']);
|
||||||
|
$value = unserialize($row['preference_value']);
|
||||||
|
if($value === false)
|
||||||
|
{
|
||||||
|
// manually retrieve the string lengths of the serialized array if unserialize failed
|
||||||
|
$value = unserialize(preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.mb_strlen('$2','8bit').':\"$2\";'", $row['preference_value']));
|
||||||
|
}
|
||||||
|
$this->unquote($value);
|
||||||
|
|
||||||
|
$prefs[$row['preference_owner']][$app] = $value;
|
||||||
|
}
|
||||||
|
foreach($db_read as $id)
|
||||||
|
{
|
||||||
|
if (!isset($prefs[$id])) $prefs[$id] = array();
|
||||||
|
egw_cache::setInstance(__CLASS__, $id, $prefs[$id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//error_log(__METHOD__.'('.array2string($ids).') read-from-db='.array2string($db_read));
|
||||||
|
return $prefs;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************\
|
/**************************************************************************\
|
||||||
* These are the standard $this->account_id specific functions *
|
* These are the standard $this->account_id specific functions *
|
||||||
\**************************************************************************/
|
\**************************************************************************/
|
||||||
@ -201,12 +259,12 @@ class preferences
|
|||||||
$GLOBALS['egw']->accounts->get_account_name($this->account_id,$lid,$fname,$lname);
|
$GLOBALS['egw']->accounts->get_account_name($this->account_id,$lid,$fname,$lname);
|
||||||
|
|
||||||
$this->values = array( // standard notify replacements
|
$this->values = array( // standard notify replacements
|
||||||
'fullname' => $GLOBALS['egw']->common->display_fullname('',$fname,$lname),
|
'fullname' => common::display_fullname('',$fname,$lname),
|
||||||
'firstname' => $fname,
|
'firstname' => $fname,
|
||||||
'lastname' => $lname,
|
'lastname' => $lname,
|
||||||
'domain' => $GLOBALS['egw_info']['server']['mail_suffix'],
|
'domain' => $GLOBALS['egw_info']['server']['mail_suffix'],
|
||||||
'email' => $this->email_address($this->account_id),
|
'email' => $this->email_address($this->account_id),
|
||||||
'date' => $GLOBALS['egw']->common->show_date('',$GLOBALS['egw_info']['user']['preferences']['common']['dateformat']),
|
'date' => common::show_date('',$GLOBALS['egw_info']['user']['preferences']['common']['dateformat']),
|
||||||
);
|
);
|
||||||
// do this first, as it might be already contain some substitues
|
// do this first, as it might be already contain some substitues
|
||||||
//
|
//
|
||||||
@ -280,47 +338,33 @@ class preferences
|
|||||||
*/
|
*/
|
||||||
function read_repository($use_session=true)
|
function read_repository($use_session=true)
|
||||||
{
|
{
|
||||||
$this->session = $use_session ? $GLOBALS['egw']->session->appsession('preferences','preferences') : array();
|
$this->session = $use_session ? egw_cache::getSession('preferences','preferences') : array();
|
||||||
if (!is_array($this->session))
|
if (!is_array($this->session))
|
||||||
{
|
{
|
||||||
$this->session = array();
|
$this->session = array();
|
||||||
}
|
}
|
||||||
$this->forced = $this->default = $this->user = $this->group = array();
|
$this->forced = $this->default = $this->user = $this->group = array();
|
||||||
$primary_group = $GLOBALS['egw']->accounts->id2name($this->account_id,'account_primary_group');
|
$primary_group = accounts::id2name($this->account_id, 'account_primary_group');
|
||||||
foreach($this->db->select($this->table,'*',array('preference_owner' => array(
|
foreach($this->cache_read(array(
|
||||||
self::DEFAULT_ID,
|
self::DEFAULT_ID,
|
||||||
self::FORCED_ID,
|
self::FORCED_ID,
|
||||||
$this->account_id,
|
$this->account_id,
|
||||||
$primary_group+self::DEFAULT_ID, // need to offset it with DEFAULT_ID = -2!
|
$primary_group+self::DEFAULT_ID, // need to offset it with DEFAULT_ID = -2!
|
||||||
)),__LINE__,__FILE__) as $row)
|
)) as $id => $values)
|
||||||
{
|
{
|
||||||
// The following replacement is required for PostgreSQL to work
|
switch($id)
|
||||||
$app = trim($row['preference_app']);
|
|
||||||
$value = unserialize($row['preference_value']);
|
|
||||||
if($value === false)
|
|
||||||
{
|
|
||||||
// manually retrieve the string lengths of the serialized array if unserialize failed
|
|
||||||
$value = unserialize(preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.mb_strlen('$2','8bit').':\"$2\";'", $row['preference_value']));
|
|
||||||
}
|
|
||||||
$this->unquote($value);
|
|
||||||
if (!is_array($value))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch($row['preference_owner'])
|
|
||||||
{
|
{
|
||||||
case self::FORCED_ID:
|
case self::FORCED_ID:
|
||||||
$this->forced[$app] = $value;
|
$this->forced = $values;
|
||||||
break;
|
break;
|
||||||
case self::DEFAULT_ID:
|
case self::DEFAULT_ID:
|
||||||
//if ($app=='common') error_log(__METHOD__.__LINE__.array2string($value));
|
$this->default = $values;
|
||||||
$this->default[$app] = $value;
|
|
||||||
break;
|
break;
|
||||||
case $this->account_id: // user
|
case $this->account_id: // user
|
||||||
$this->user[$app] = $value;
|
$this->user = $values;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$this->group[$app] = $value;
|
$this->group = $values;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -387,10 +431,6 @@ class preferences
|
|||||||
echo 'group<pre>'; print_r($this->group); echo "</pre>\n";
|
echo 'group<pre>'; print_r($this->group); echo "</pre>\n";
|
||||||
echo 'effectiv<pre>'; print_r($this->data); echo "</pre>\n";
|
echo 'effectiv<pre>'; print_r($this->data); echo "</pre>\n";
|
||||||
}
|
}
|
||||||
//error_log(__METHOD__.__LINE__.'->user: remote_application_url:'.array2string($this->user['common']['remote_application_url']));
|
|
||||||
//error_log(__METHOD__.__LINE__.'->default: remote_application_url:'.array2string($this->default['common']['remote_application_url']));
|
|
||||||
//error_log(__METHOD__.__LINE__.'->forced: remote_application_url:'.array2string($this->forced['common']['remote_application_url']));
|
|
||||||
//error_log(__METHOD__.__LINE__.'->effective: remote_application_url:'.array2string($this->data['common']['remote_application_url']));
|
|
||||||
$this->check_set_tz_offset();
|
$this->check_set_tz_offset();
|
||||||
|
|
||||||
return $this->data;
|
return $this->data;
|
||||||
@ -421,14 +461,14 @@ class preferences
|
|||||||
*/
|
*/
|
||||||
function check_set_tz_offset()
|
function check_set_tz_offset()
|
||||||
{
|
{
|
||||||
$prefs =& $this->data['common'];
|
$prefs =& $GLOBALS['egw_info']['user']['preferences']['common'];
|
||||||
|
|
||||||
if (!empty($prefs['tz']))
|
if (!empty($prefs['tz']))
|
||||||
{
|
{
|
||||||
egw_time::setUserPrefs($prefs['tz'],$prefs['dateformat'],$prefs['timeformat']);
|
egw_time::setUserPrefs($prefs['tz'],$prefs['dateformat'],$prefs['timeformat']);
|
||||||
// set the old preference for compatibilty with old code
|
// set the old preference for compatibilty with old code
|
||||||
$GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'] = egw_time::tz_offset_s()/3600;
|
$prefs['tz_offset'] = egw_time::tz_offset_s()/3600;
|
||||||
//echo "<p>".__METHOD__."() tz=$prefs[tz] --> tz_offset={$GLOBALS['egw_info']['user']['preferences']['common']['tz_offset']}</p>\n";
|
//echo "<p>".__METHOD__."() tz=$prefs[tz] --> tz_offset=$prefs[tz_offset]</p>\n";
|
||||||
|
|
||||||
// ToDo: get rid of that
|
// ToDo: get rid of that
|
||||||
if (isset($GLOBALS['egw']) && ($GLOBALS['egw'] instanceof egw))
|
if (isset($GLOBALS['egw']) && ($GLOBALS['egw'] instanceof egw))
|
||||||
@ -719,14 +759,15 @@ class preferences
|
|||||||
}
|
}
|
||||||
//echo "<p>preferences::save_repository(,$type): account_id=$account_id, prefs="; print_r($prefs); echo "</p>\n";
|
//echo "<p>preferences::save_repository(,$type): account_id=$account_id, prefs="; print_r($prefs); echo "</p>\n";
|
||||||
|
|
||||||
if (isset($GLOBALS['egw_setup']) || !$GLOBALS['egw']->acl->check('session_only_preferences',1,'preferences'))
|
if (isset($GLOBALS['egw_setup']) || !$GLOBALS['egw']->acl->check('session_only_preferences',1,'preferences') &&
|
||||||
|
(!($old_prefs = $this->cache_read($account_id)) || $old_prefs[$account_id] != $prefs))
|
||||||
{
|
{
|
||||||
$this->db->transaction_begin();
|
$this->db->transaction_begin();
|
||||||
$this->db->delete($this->table,array('preference_owner' => $account_id),__LINE__,__FILE__);
|
$this->db->delete($this->table,array('preference_owner' => $account_id),__LINE__,__FILE__);
|
||||||
|
|
||||||
foreach($prefs as $app => $value)
|
foreach($prefs as $app => $value)
|
||||||
{
|
{
|
||||||
if (!is_array($value))
|
if (!is_array($value) || !$value)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -741,17 +782,8 @@ class preferences
|
|||||||
}
|
}
|
||||||
$this->db->transaction_commit();
|
$this->db->transaction_commit();
|
||||||
|
|
||||||
if (!isset($GLOBALS['egw_setup']))
|
// update instance-wide cache
|
||||||
{
|
egw_cache::setInstance(__CLASS__, $account_id, $prefs);
|
||||||
// no need to invalidate session cache, if we write the prefs to the session too
|
|
||||||
$egw = unserialize($_SESSION[egw_session::EGW_OBJECT_CACHE]);
|
|
||||||
$egw->preferences = $this;
|
|
||||||
$_SESSION[egw_session::EGW_OBJECT_CACHE] = serialize($egw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isset($GLOBALS['egw_setup']))
|
|
||||||
{
|
|
||||||
$_SESSION[egw_session::EGW_INFO_CACHE]['user']['preferences'] = $GLOBALS['egw_info']['user']['preferences'] = $this->data;
|
|
||||||
}
|
}
|
||||||
return $this->data;
|
return $this->data;
|
||||||
}
|
}
|
||||||
@ -843,7 +875,7 @@ class preferences
|
|||||||
if (!isset($GLOBALS['egw_info']['user']['preferences']['common']['lang']) ||
|
if (!isset($GLOBALS['egw_info']['user']['preferences']['common']['lang']) ||
|
||||||
!$GLOBALS['egw_info']['user']['preferences']['common']['lang'])
|
!$GLOBALS['egw_info']['user']['preferences']['common']['lang'])
|
||||||
{
|
{
|
||||||
$this->add('common','lang',$GLOBALS['egw']->common->getPreferredLanguage());
|
$this->add('common','lang',common::getPreferredLanguage());
|
||||||
$preferences_update = True;
|
$preferences_update = True;
|
||||||
}
|
}
|
||||||
if ($preferences_update)
|
if ($preferences_update)
|
||||||
|
Loading…
Reference in New Issue
Block a user