2010-09-08 09:46:37 +02:00
< ? php
/**
* eGroupWare API - Preferences
*
* @ link http :// www . egroupware . org
* @ author Joseph Engo < jengo @ phpgroupware . org >
* @ author Mark Peters < skeeter @ phpgroupware . org >
* @ author Ralf Becker < RalfBecker - AT - outdoor - training . de > merging prefs on runtime , session prefs and reworked the class
* Copyright ( C ) 2000 , 2001 Joseph Engo
* @ license http :// opensource . org / licenses / lgpl - license . php LGPL - GNU Lesser General Public License
* @ package api
* @ version $Id $
*/
/**
* preferences class used for setting application preferences
*
* the prefs are read into 5 arrays :
* $data the effective prefs used everywhere in phpgw , they are merged from the other 3 arrays
* $user the stored user prefs , only used for manipulating and storeing the user prefs
* $group the stored prefs of users primary groupd , only used for manipulating and storeing the user prefs
* $default the default preferences , always used when the user has no own preference set
* $forced forced preferences set by the admin , they take precedence over user or default prefs
2011-04-19 08:47:26 +02:00
*
2010-09-08 09:46:37 +02:00
* To update the prefs of a certain group , not just the primary group of the user , you have to
* create a new instance of preferences class , with the given id of the group . This takes into
* account the offset of DEFAULT_ID , we are using currently for groups ( as - 1 , and - 2 ) are already
* taken !
*/
class preferences
{
/**
* account_id for default prefs
*/
const DEFAULT_ID = - 2 ;
/**
* account_id for forced prefs
*/
const FORCED_ID = - 1 ;
/**
* account the class is instanciated for
* @ var int
*/
var $account_id ;
/**
* account - type u or g
* @ var string
*/
var $account_type ;
/**
* effectiv user prefs , used by all apps
* @ var array
*/
var $data = array ();
/**
* set user prefs for saveing ( no defaults / forced prefs merged )
* @ var array
*/
var $user = array ();
/**
* primary group prefs
* @ var array
*/
var $group = array ();
/**
* default prefs
* @ var array
*/
var $default = array ();
/**
* forced prefs
* @ var array
*/
var $forced = array ();
/**
* session / tempory prefs
* @ var array
*/
var $session = array ();
/**
* @ var egw_db
*/
var $db ;
/**
* table - name
* @ var string
*/
var $table = 'egw_preferences' ;
var $values , $vars ; // standard notify substitues, will be set by standard_substitues()
/**
* Contstructor
*
* @ param int | string $account_id = ''
* @ return preferences
*/
function __construct ( $account_id = '' )
{
if ( isset ( $GLOBALS [ 'egw' ] -> db ))
{
$this -> db = $GLOBALS [ 'egw' ] -> db ;
}
else
{
$this -> db = $GLOBALS [ 'egw_setup' ] -> db ;
$this -> table = $GLOBALS [ 'egw_setup' ] -> prefs_table ;
}
// if we got instancated for a group, need to set offset of DEFAULT_ID!
if ( $account_id < 0 && $GLOBALS [ 'egw' ] -> accounts -> exists ( $account_id ) == 2 )
{
$this -> account_id = $account_id + self :: DEFAULT_ID ;
}
else
{
$this -> account_id = get_account_id ( $account_id );
}
}
/**
* Old PHP4 contstructor
*
* @ param int | string $account_id = ''
* @ return preferences
* @ deprecated
*/
function preferences ( $account_id = '' )
{
self :: __construct ();
}
/************************************************************************** \
* These are the standard $this -> account_id specific functions *
\ **************************************************************************/
/**
* parses a notify and replaces the substitutes
*
* @ param string $msg message to parse / substitute
* @ param array $values = array () extra vars to replace in addition to $this -> values , vars are in an array with \
* $key => $value pairs , $key does not include the $ ' s and is the * untranslated * name
* @ param boolean $use_standard_values = true should the standard values are used
* @ return string with parsed notify - msg
*/
function parse_notify ( $msg , $values = array (), $use_standard_values = True )
{
$vals = $values ? $values : array ();
if ( $use_standard_values && is_array ( $this -> values ))
{
$vals += $this -> values ;
}
foreach ( $vals as $key => $val )
{
if ( $this -> debug ) error_log ( __METHOD__ . " replacing \$ \$ $key\ $\ $ with $val " );
$replace [] = '$$' . $key . '$$' ;
$with [] = $val ;
}
return str_replace ( $replace , $with , $msg );
}
/**
* replaces the english key ' s with translated ones , or if $un_lang the opposite
*
* @ param string $msg message to translate
* @ param array $values = array () extra vars to replace in addition to $this -> values , vars are in an array with \
* $key => $value pairs , $key does not include the $ ' s and is the * untranslated * name
* @ param boolean $un_lang = false if true translate back
* @ return string
*/
function lang_notify ( $msg , $vals = array (), $un_lang = False )
{
foreach ( $vals as $key => $val )
{
$lname = ( $lname = lang ( $key )) == $key . '*' ? $key : $lname ;
if ( $un_lang )
{
$langs [ $lname ] = '$$' . $key . '$$' ;
}
else
{
$langs [ $key ] = '$$' . $lname . '$$' ;
}
}
return $this -> parse_notify ( $msg , $langs , False );
}
/**
* define some standard substitues - values and use them on the prefs , if needed
*/
function standard_substitutes ()
{
if ( $this -> debug ) error_log ( __METHOD__ . " is called " );
if ( ! is_array ( @ $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ]))
{
$GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ] = $this -> data ; // else no lang()
}
// we cant use phpgw_info/user/fullname, as it's not set when we run
$GLOBALS [ 'egw' ] -> accounts -> get_account_name ( $this -> account_id , $lid , $fname , $lname );
$this -> values = array ( // standard notify replacements
'fullname' => $GLOBALS [ 'egw' ] -> common -> display_fullname ( '' , $fname , $lname ),
'firstname' => $fname ,
'lastname' => $lname ,
'domain' => $GLOBALS [ 'egw_info' ][ 'server' ][ 'mail_suffix' ],
'email' => $this -> email_address ( $this -> account_id ),
'date' => $GLOBALS [ 'egw' ] -> common -> show_date ( '' , $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ]),
);
// do this first, as it might be already contain some substitues
//
$this -> values [ 'email' ] = $this -> parse_notify ( $this -> values [ 'email' ]);
$this -> vars = array ( // langs have to be in common !!!
'fullname' => lang ( 'name of the user, eg. "%1"' , $this -> values [ 'fullname' ]),
'firstname' => lang ( 'first name of the user, eg. "%1"' , $this -> values [ 'firstname' ]),
'lastname' => lang ( 'last name of the user, eg. "%1"' , $this -> values [ 'lastname' ]),
'domain' => lang ( 'domain name for mail-address, eg. "%1"' , $this -> values [ 'domain' ]),
'email' => lang ( 'email-address of the user, eg. "%1"' , $this -> values [ 'email' ]),
'date' => lang ( 'todays date, eg. "%1"' , $this -> values [ 'date' ]),
);
if ( $this -> debug ) error_log ( __METHOD__ . print_r ( $this -> vars , true ));
// do the substituetion in the effective prefs (data)
//
foreach ( $this -> data as $app => $data )
{
foreach ( $data as $key => $val )
{
if ( ! is_array ( $val ) && strpos ( $val , '$$' ) !== False )
{
$this -> data [ $app ][ $key ] = $this -> parse_notify ( $val );
}
elseif ( is_array ( $val ))
{
foreach ( $val as $k => $v )
{
if ( ! is_array ( $v ) && strpos ( $v , '$$' ) !== False )
{
$this -> data [ $app ][ $key ][ $k ] = $this -> parse_notify ( $v );
}
}
}
}
}
}
/**
* unquote ( stripslashes ) recursivly the whole array
*
* @ param array & $arr array to unquote ( var - param ! )
*/
function unquote ( & $arr )
{
if ( ! is_array ( $arr ))
{
$arr = stripslashes ( $arr );
return ;
}
foreach ( $arr as $key => $value )
{
if ( is_array ( $value ))
{
$this -> unquote ( $arr [ $key ]);
}
else
{
$arr [ $key ] = stripslashes ( $value );
}
}
}
/**
* read preferences from the repository
*
* the function ready all 3 prefs user / default / forced and merges them to the effective ones
*
* @ param boolean $use_session = true should the session prefs get used ( default true ) or not ( false )
* @ return array with effective prefs ( $this -> data )
*/
function read_repository ( $use_session = true )
{
$this -> session = $use_session ? $GLOBALS [ 'egw' ] -> session -> appsession ( 'preferences' , 'preferences' ) : array ();
if ( ! is_array ( $this -> session ))
{
$this -> session = array ();
}
$this -> forced = $this -> default = $this -> user = $this -> group = array ();
$primary_group = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $this -> account_id , 'account_primary_group' );
foreach ( $this -> db -> select ( $this -> table , '*' , array ( 'preference_owner' => array (
self :: DEFAULT_ID ,
self :: FORCED_ID ,
$this -> account_id ,
$primary_group + self :: DEFAULT_ID , // need to offset it with DEFAULT_ID = -2!
)), __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 );
if ( ! is_array ( $value ))
{
continue ;
}
switch ( $row [ 'preference_owner' ])
{
case self :: FORCED_ID :
$this -> forced [ $app ] = $value ;
break ;
case self :: DEFAULT_ID :
2011-09-26 12:01:53 +02:00
//if ($app=='common') error_log(__METHOD__.__LINE__.array2string($value));
2010-09-08 09:46:37 +02:00
$this -> default [ $app ] = $value ;
break ;
case $this -> account_id : // user
$this -> user [ $app ] = $value ;
break ;
default :
$this -> group [ $app ] = $value ;
break ;
}
}
$this -> data = $this -> user ;
// let the (temp.) session prefs. override the user prefs.
//
foreach ( $this -> session as $app => $values )
{
foreach ( $values as $var => $value )
{
$this -> data [ $app ][ $var ] = $value ;
}
}
// now use (primary) group defaults if needed (user-value unset or empty)
//
foreach ( $this -> group as $app => $values )
{
foreach ( $values as $var => $value )
{
if ( ! isset ( $this -> data [ $app ][ $var ]) || $this -> data [ $app ][ $var ] === '' )
{
$this -> data [ $app ][ $var ] = $value ;
}
}
}
// now use defaults if needed (user-value unset or empty)
//
foreach ( $this -> default as $app => $values )
{
foreach ( $values as $var => $value )
{
if ( ! isset ( $this -> data [ $app ][ $var ]) || $this -> data [ $app ][ $var ] === '' )
{
2011-09-26 12:01:53 +02:00
//if ($var=='remote_application_url') error_log(__METHOD__.__LINE__.' default for '.$var.' with '.$value);
2010-09-08 09:46:37 +02:00
$this -> data [ $app ][ $var ] = $value ;
}
}
}
// now set/force forced values
//
foreach ( $this -> forced as $app => $values )
{
foreach ( $values as $var => $value )
{
$this -> data [ $app ][ $var ] = $value ;
}
}
// setup the standard substitutes and substitutes the data in $this->data
//
$this -> standard_substitutes ();
// This is to supress warnings during login
if ( is_array ( $this -> data ))
{
reset ( $this -> data );
}
if ( isset ( $this -> debug ) && substr ( $GLOBALS [ 'egw_info' ][ 'flags' ][ 'currentapp' ], 0 , 3 ) != 'log' )
{
echo 'user<pre>' ; print_r ( $this -> user ); echo " </pre> \n " ;
echo 'forced<pre>' ; print_r ( $this -> forced ); echo " </pre> \n " ;
echo 'default<pre>' ; print_r ( $this -> default ); echo " </pre> \n " ;
echo 'group<pre>' ; print_r ( $this -> group ); echo " </pre> \n " ;
echo 'effectiv<pre>' ; print_r ( $this -> data ); echo " </pre> \n " ;
}
2011-09-26 12:01:53 +02:00
//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']));
2010-09-08 09:46:37 +02:00
$this -> check_set_tz_offset ();
return $this -> data ;
}
/**
* Checking new timezone ( 'tz' ) pref and setting old tz_offset pref from it
*
*/
function check_set_tz_offset ()
{
$prefs =& $this -> data [ 'common' ];
if ( ! empty ( $prefs [ 'tz' ]))
{
egw_time :: setUserPrefs ( $prefs [ 'tz' ], $prefs [ 'date_format' ], $prefs [ 'time_format' ]);
// set the old preference for compatibilty with old code
$GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ '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";
// ToDo: get rid of that
2011-09-26 12:01:53 +02:00
if ( isset ( $GLOBALS [ 'egw' ]) && ( $GLOBALS [ 'egw' ] instanceof egw ))
2010-09-08 09:46:37 +02:00
{
$GLOBALS [ 'egw' ] -> unset_datetime (); // to force an update
}
}
}
/**
* Set user timezone , if we get restored from session
*
*/
function __wakeup ()
{
$this -> check_set_tz_offset ();
}
/**
* read preferences from repository and stores in an array
*
* @ return array containing the effective user preferences
*/
function read ()
{
if ( count ( $this -> data ) == 0 )
{
$this -> read_repository ();
}
reset ( $this -> data );
return $this -> data ;
}
/**
* add preference to $app_name a particular app
*
* the effective prefs ( $this -> data ) are updated to reflect the change
*
* @ param string $app_name name of the app
* @ param string $var name of preference to be stored
* @ param mixed $value = '##undef##' value of the preference , if not given $GLOBALS [ $var ] is used
* @ param $type = 'user' of preference to set : forced , default , user
* @ return array with new effective prefs ( even when forced or default prefs are set ! )
*/
function add ( $app_name , $var , $value = '##undef##' , $type = 'user' )
{
//echo "<p>add('$app_name','$var','$value')</p>\n";
if ( $value === '##undef##' )
{
$value = $GLOBALS [ $var ];
}
switch ( $type )
{
case 'session' :
if ( ! isset ( $this -> forced [ $app_name ][ $var ]) || $this -> forced [ $app_name ][ $var ] === '' )
{
$this -> session [ $app_name ][ $var ] = $this -> data [ $app_name ][ $var ] = $value ;
$GLOBALS [ 'egw' ] -> session -> appsession ( 'preferences' , 'preferences' , $this -> session );
if ( method_exists ( $GLOBALS [ 'egw' ], 'invalidate_session_cache' )) // egw object in setup is limited
{
$GLOBALS [ 'egw' ] -> invalidate_session_cache (); // in case with cache the egw_info array in the session
}
}
break ;
case 'forced' :
$this -> data [ $app_name ][ $var ] = $this -> forced [ $app_name ][ $var ] = $value ;
break ;
case 'default' :
$this -> default [ $app_name ][ $var ] = $value ;
if (( ! isset ( $this -> forced [ $app_name ][ $var ]) || $this -> forced [ $app_name ][ $var ] === '' ) &&
( ! isset ( $this -> user [ $app_name ][ $var ]) || $this -> user [ $app_name ][ $var ] === '' ))
{
$this -> data [ $app_name ][ $var ] = $value ;
}
break ;
2011-04-19 08:47:26 +02:00
case 'user' :
2010-09-08 09:46:37 +02:00
default :
$this -> user [ $app_name ][ $var ] = $value ;
if ( ! isset ( $this -> forced [ $app_name ][ $var ]) || $this -> forced [ $app_name ][ $var ] === '' )
{
$this -> data [ $app_name ][ $var ] = $value ;
}
break ;
}
reset ( $this -> data );
return $this -> data ;
}
/**
* delete preference from $app_name
*
* the effektive prefs ( $this -> data ) are updated to reflect the change
*
* @ param string $app_name name of app
* @ param string $var = false variable to be deleted
* @ param string $type = 'user' of preference to set : forced , default , user
* @ return array with new effective prefs ( even when forced or default prefs are deleted ! )
*/
function delete ( $app_name , $var = False , $type = 'user' )
{
//echo "<p>delete('$app_name','$var','$type')</p>\n";
$set_via = array (
'forced' => array ( 'user' , 'default' ),
'default' => array ( 'forced' , 'user' ),
'user' => array ( 'forced' , 'group' , 'default' ),
'group' => array ( 'forced' ),
);
if ( ! isset ( $set_via [ $type ]))
{
$type = 'user' ;
}
$pref = & $this -> $type ;
2011-04-19 08:47:26 +02:00
if (( $all = empty ( $var ))) // to check if $var is regarded as empty (false, 0, '', null, array() should do the trick
2010-09-08 09:46:37 +02:00
{
unset ( $pref [ $app_name ]);
unset ( $this -> data [ $app_name ]);
}
else
{
unset ( $pref [ $app_name ][ $var ]);
unset ( $this -> data [ $app_name ][ $var ]);
}
// set the effectiv pref again if needed
//
foreach ( $set_via [ $type ] as $set_from )
{
2011-04-19 08:47:26 +02:00
$arr = & $this -> $set_from ;
2010-09-08 09:46:37 +02:00
if ( $all )
{
2011-04-19 08:47:26 +02:00
if ( isset ( $arr [ $app_name ]))
2010-09-08 09:46:37 +02:00
{
2011-04-19 08:47:26 +02:00
$this -> data [ $app_name ] = $arr [ $app_name ];
2010-09-08 09:46:37 +02:00
break ;
}
}
else
{
if ( $var && @ isset ( $arr [ $app_name ][ $var ]) && $arr [ $app_name ][ $var ] !== '' )
{
2011-04-19 08:47:26 +02:00
$this -> data [ $app_name ][ $var ] = $arr [ $app_name ][ $var ];
2010-09-08 09:46:37 +02:00
break ;
}
}
2011-04-19 08:47:26 +02:00
unset ( $arr );
2010-09-08 09:46:37 +02:00
}
reset ( $this -> data );
return $this -> data ;
}
/**
* delete all prefs of a given user
*
* @ param int $accountid
*/
function delete_user ( $accountid )
{
if ( $account_id > 0 )
{
$this -> delete ( $this -> table , array ( 'preference_owner' => $accountid ), __LINE__ , __FILE__ );
}
}
/**
* delete all prefs of a given group
*
* @ param int $accountid
*/
function delete_group ( $accountid )
{
if ( $account_id < 0 )
{
$this -> delete ( $this -> table , array ( 'preference_owner' => $accountid + self :: DEFAULT_ID ), __LINE__ , __FILE__ );
}
}
/**
* add complex array data preference to $app_name a particular app
*
* @ deprecated we can now correctly store arrays in the prefs , AFAIK only used in email
*
* @ param string $app_name name of the app
* @ param string $var array keys separated by '/' , eg . 'ex_accounts/1'
* @ param mixed $value = '' value of the preference
* @ return array with new effective prefs ( even when forced or default prefs are deleted ! )
*/
function add_struct ( $app_name , $var , $value = '' )
{
$parts = explode ( '/' , str_replace ( array ( '][' , '[' , ']' , '"' , " ' " ), array ( '/' , '' , '' , '' , '' ), $var ));
$data = & $this -> data [ $app_name ];
$user = & $this -> user [ $app_name ];
foreach ( $parts as $name )
{
$data = & $data [ $name ];
$user = & $user [ $name ];
}
$data = $user = $value ;
print_debug ( 'class.preferences: add_struct: $this->data[$app_name] dump:' , $this -> data [ $app_name ], 'api' );
reset ( $this -> data );
return $this -> data ;
}
/**
* delete complex array data preference from $app_name
*
* @ deprecated we can now correctly store arrays in the prefs , AFAIK only used in email
*
* @ param $app_name name of app
* @ param $var array keys separated by '/' , eg . 'ex_accounts/1'
* @ return array with new effective prefs ( even when forced or default prefs are deleted ! )
*/
function delete_struct ( $app_name , $var = '' )
{
$parts = explode ( '/' , str_replace ( array ( '][' , '[' , ']' , '"' , " ' " ), array ( '/' , '' , '' , '' , '' ), $var ));
$last = array_pop ( $parts );
$data = & $this -> data [ $app_name ];
$user = & $this -> user [ $app_name ];
foreach ( $parts as $name )
{
$data = & $data [ $name ];
$user = & $user [ $name ];
}
unset ( $user [ $last ]);
print_debug ( '* $this->data[$app_name] dump:' , $this -> data [ $app_name ], 'api' );
reset ( $this -> data );
return $this -> data ;
}
/**
* quote ( addslashes ) recursivly the whole array
*
* @ param array & $arr array to quote ( var - param ! )
*/
function quote ( & $arr )
{
if ( ! is_array ( $arr ))
{
$arr = addslashes ( $arr );
return ;
}
foreach ( $arr as $key => $value )
{
if ( is_array ( $value ))
{
$this -> quote ( $arr [ $key ]);
}
else
{
$arr [ $key ] = addslashes ( $value );
}
}
}
/**
2010-11-16 10:37:55 +01:00
* Save the the preferences to the repository
2010-09-08 09:46:37 +02:00
*
* User prefs for saveing are in $this -> user not in $this -> data , which are the effectiv prefs only !
*
2010-11-16 10:37:55 +01:00
* @ param boolean $update_session_info = false old param , seems not to be used ( not used anymore )
2010-09-08 09:46:37 +02:00
* @ param string $type = 'user' which prefs to update : user / default / forced
2010-11-16 10:37:55 +01:00
* @ param boolean $invalid_cache = true should we invalidate the cache , default true ( not used anymore )
2010-09-08 09:46:37 +02:00
* @ return array with new effective prefs ( even when forced or default prefs are deleted ! )
*/
function save_repository ( $update_session_info = False , $type = 'user' , $invalid_cache = true )
{
switch ( $type )
{
case 'forced' :
$account_id = self :: FORCED_ID ;
$prefs = & $this -> forced ;
break ;
case 'default' :
$account_id = self :: DEFAULT_ID ;
$prefs = & $this -> default ;
break ;
case 'group' :
$account_id = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $this -> account_id , 'account_primary_group' ) + self :: DEFAULT_ID ;
$prefs = & $this -> group ;
break ;
default :
$account_id = ( int ) $this -> account_id ;
$prefs = & $this -> user ; // we use the user-array as data contains default values too
break ;
}
//echo "<p>preferences::save_repository(,$type): account_id=$account_id, prefs="; print_r($prefs); echo "</p>\n";
if ( ! $GLOBALS [ 'egw' ] -> acl -> check ( 'session_only_preferences' , 1 , 'preferences' ))
{
$this -> db -> transaction_begin ();
$this -> db -> delete ( $this -> table , array ( 'preference_owner' => $account_id ), __LINE__ , __FILE__ );
foreach ( $prefs as $app => $value )
{
if ( ! is_array ( $value ))
{
continue ;
}
$this -> quote ( $value ); // this quote-ing is for serialize, not for the db
$this -> db -> insert ( $this -> table , array (
'preference_value' => serialize ( $value ),
), array (
'preference_owner' => $account_id ,
'preference_app' => $app ,
), __LINE__ , __FILE__ );
}
$this -> db -> transaction_commit ();
2010-11-16 10:37:55 +01:00
// no need to invalidate session cache, if we write the prefs to the session too
2010-11-16 15:28:33 +01:00
$egw = unserialize ( $_SESSION [ egw_session :: EGW_OBJECT_CACHE ]);
$egw -> preferences = $this ;
$_SESSION [ egw_session :: EGW_OBJECT_CACHE ] = serialize ( $egw );
2010-09-08 09:46:37 +02:00
}
2010-11-16 10:37:55 +01:00
$_SESSION [ egw_session :: EGW_INFO_CACHE ][ 'user' ][ 'preferences' ] = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ] = $this -> data ;
2010-09-08 09:46:37 +02:00
return $this -> data ;
}
/**
* insert a copy of the default preferences for use by real account_id
*
* @ deprecated not longer needed , as the defaults are merged in on runtime
*
* @ param int $account_id numerical id of account for which to create the prefs
*/
function create_defaults ( $account_id )
{
}
/**
* update the preferences array
*
* @ param array $data array of preferences
* @ return array with new effective prefs ( even when forced or default prefs are deleted ! )
*/
function update_data ( $data )
{
$this -> data = $data ;
reset ( $this -> data );
return $this -> data ;
}
/* legacy support */
function change ( $app_name , $var , $value = " " )
{
return $this -> add ( $app_name , $var , $value );
}
function commit ( $update_session_info = True )
{
//return $this->save_repository($update_session_info);
}
/************************************************************************** \
* These are the non - standard $this -> account_id specific functions *
\ **************************************************************************/
/**
* verify basic settings
*
* @ discussion
*/
function verify_basic_settings ()
{
if ( !@ is_array ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ]))
{
$GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ] = array ();
}
/* This takes care of new users who don't have proper default prefs setup */
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'flags' ][ 'nocommon_preferences' ]) ||
! $GLOBALS [ 'egw_info' ][ 'flags' ][ 'nocommon_preferences' ])
{
$preferences_update = False ;
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'maxmatchs' ]) ||
! $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'maxmatchs' ])
{
$this -> add ( 'common' , 'maxmatchs' , 15 );
$preferences_update = True ;
}
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'theme' ]) ||
! $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'theme' ])
{
$this -> add ( 'common' , 'theme' , 'default' );
$preferences_update = True ;
}
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'template_set' ]) ||
! $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'template_set' ])
{
$this -> add ( 'common' , 'template_set' , 'default' );
$preferences_update = True ;
}
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ]) ||
! $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ])
{
$this -> add ( 'common' , 'dateformat' , 'm/d/Y' );
$preferences_update = True ;
}
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'timeformat' ]) ||
! $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'timeformat' ])
{
$this -> add ( 'common' , 'timeformat' , 12 );
$preferences_update = True ;
}
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'lang' ]) ||
! $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'lang' ])
{
$this -> add ( 'common' , 'lang' , $GLOBALS [ 'egw' ] -> common -> getPreferredLanguage ());
$preferences_update = True ;
}
if ( $preferences_update )
{
$this -> save_repository ();
}
unset ( $preferences_update );
}
}
/**************************************************** \
* Email Preferences and Private Support Functions *
\ ****************************************************/
/**
* Helper function for create_email_preferences , gets mail server port number .
*
* This will generate the appropriate port number to access a
* mail server of type pop3 , pop3s , imap , imaps users value from
* $phpgw_info [ 'user' ][ 'preferences' ][ 'email' ][ 'mail_port' ] .
* if that value is not set , it generates a default port for the given $server_type .
* Someday , this * MAY * be
* ( a ) a se4rver wide admin setting , or
* ( b ) user custom preference
* Until then , simply set the port number based on the mail_server_type , thereof
* ONLY call this function AFTER [ 'email' ][ 'mail_server_type' ] has been set .
* @ param $prefs - user preferences array based on element [ 'email' ][]
* @ author Angles
* @ access Private
*/
function sub_get_mailsvr_port ( $prefs , $acctnum = 0 )
{
// first we try the port number supplied in preferences
if (( isset ( $prefs [ 'email' ][ 'accounts' ][ $acctnum ][ 'mail_port' ])) &&
( $prefs [ 'email' ][ 'accounts' ][ $acctnum ][ 'mail_port' ] != '' ))
{
$port_number = $prefs [ 'email' ][ 'accounts' ][ $acctnum ][ 'mail_port' ];
}
// preferences does not have a port number, generate a default value
else
{
if ( ! isset ( $prefs [ 'email' ][ 'accounts' ][ $acctnum ][ 'mail_server_type' ]))
{
$prefs [ 'email' ][ 'accounts' ][ $acctnum ][ 'mail_server_type' ] = $prefs [ 'email' ][ 'mail_server_type' ];
}
switch ( $prefs [ 'email' ][ 'accounts' ][ $acctnum ][ 'mail_server_type' ])
{
case 'pop3s' :
// POP3 over SSL
$port_number = 995 ;
break ;
case 'pop3' :
// POP3 normal connection, No SSL
// ( same string as normal imap above)
$port_number = 110 ;
break ;
case 'nntp' :
// NNTP news server port
$port_number = 119 ;
break ;
case 'imaps' :
// IMAP over SSL
$port_number = 993 ;
break ;
case 'imap' :
// IMAP normal connection, No SSL
default :
// UNKNOWN SERVER in Preferences, return a
// default value that is likely to work
// probably should raise some kind of error here
$port_number = 143 ;
break ;
}
}
return $port_number ;
}
/**
* Helper function for create_email_preferences , gets default userid for email
*
* This will generate the appropriate userid for accessing an email server .
* In the absence of a custom [ 'email' ][ 'userid' ], this function should be used to set it .
* @ param $accountid - as determined in and / or passed to " create_email_preferences "
* @ access Private
*/
function sub_default_userid ( $account_id = '' )
{
if ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'mail_login_type' ] == 'vmailmgr' )
{
$prefs_email_userid = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $account_id )
. '@' . $GLOBALS [ 'egw_info' ][ 'server' ][ 'mail_suffix' ];
}
else
{
$prefs_email_userid = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $account_id );
}
return $prefs_email_userid ;
}
/**
* returns the custom email - address ( if set ) or generates a default one
*
* This will generate the appropriate email address used as the " From: "
* email address when the user sends email , the localpert * part . The " personal "
* part is generated elsewhere .
* In the absence of a custom [ 'email' ][ 'address' ], this function should be used to set it .
*
* @ access public
* @ param int $accountid - as determined in and / or passed to " create_email_preferences "
* @ return string with email - address
*/
function email_address ( $account_id = '' )
{
if ( isset ( $this -> data [ 'email' ][ 'address' ]))
{
return $this -> data [ 'email' ][ 'address' ];
}
// if email-address is set in the account, return it
if (( $email = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $account_id , 'account_email' )))
{
return $email ;
}
$prefs_email_address = $GLOBALS [ 'egw' ] -> accounts -> id2name ( $account_id );
if ( strpos ( $prefs_email_address , '@' ) === False )
{
$prefs_email_address .= '@' . $GLOBALS [ 'egw_info' ][ 'server' ][ 'mail_suffix' ];
}
return $prefs_email_address ;
}
function sub_default_address ( $account_id = '' )
{
return $this -> email_address ( $account_id );
}
/**
* create email preferences
*
* @ param $account_id - optional defaults to : get_account_id ()
* fills a local copy of [ 'email' ][] prefs array which is then returned to the calling
* function , which the calling function generally tacks onto the $GLOBALS [ 'egw_info' ] array as such :
* $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ] = $GLOBALS [ 'egw' ] -> preferences -> create_email_preferences ();
* which fills an array based at :
* $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'email' ][ prefs_are_elements_here ]
* Reading the raw preference DB data and comparing to the email preference schema defined in
* / email / class . bopreferences . inc . php ( see discussion there and below ) to create default preference values
* for the in the [ 'email' ][] pref data array in cases where the user has not supplied
* a preference value for any particular preference item available to the user .
* @ access Public
*/
function create_email_preferences ( $accountid = '' , $acctnum = 0 )
{
print_debug ( 'class.preferences: create_email_preferences: ENTERING<br>' , 'messageonly' , 'api' );
// we may need function "html_quotes_decode" from the mail_msg class
$email_base =& CreateObject ( " email.mail_msg " );
$account_id = get_account_id ( $accountid );
// If the current user is not the request user, grab the preferences
// and reset back to current user.
if ( $account_id != $this -> account_id )
{
// Temporarily store the values to a temp, so when the
// read_repository() is called, it doesn't destory the
// current users settings.
$temp_account_id = $this -> account_id ;
$temp_data = $this -> data ;
// Grab the new users settings, only if they are not the
// current users settings.
$this -> account_id = $account_id ;
$prefs = $this -> read_repository ();
// Reset the data to what it was prior to this call
$this -> account_id = $temp_account_id ;
$this -> data = $temp_data ;
}
else
{
$prefs = $this -> data ;
}
// are we dealing with the default email account or an extra email account?
if ( $acctnum != 0 )
{
// prefs are actually a sub-element of the main email prefs
// at location [email][ex_accounts][X][...pref names] => pref values
// make this look like "prefs[email] so the code below code below will do its job transparently
// obtain the desired sub-array of extra account prefs
$sub_prefs = array ();
$sub_prefs [ 'email' ] = $prefs [ 'email' ][ 'ex_accounts' ][ $acctnum ];
// make the switch, make it seem like top level email prefs
$prefs = array ();
$prefs [ 'email' ] = $sub_prefs [ 'email' ];
// since we return just $prefs, it's up to the calling program to put the sub prefs in the right place
}
print_debug ( 'class.preferences: create_email_preferences: $acctnum: [' . $acctnum . '] ; raw $this->data dump' , $this -> data , 'api' );
// = = = = NOT-SIMPLE PREFS = = = =
// Default Preferences info that is:
// (a) not controlled by email prefs itself (mostly api and/or server level stuff)
// (b) too complicated to be described in the email prefs data array instructions
// --- [server][mail_server_type] ---
// Set API Level Server Mail Type if not defined
// if for some reason the API didnot have a mail server type set during initialization
if ( empty ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'mail_server_type' ]))
{
$GLOBALS [ 'egw_info' ][ 'server' ][ 'mail_server_type' ] = 'imap' ;
}
// --- [server][mail_folder] ---
// ==== UWash Mail Folder Location used to be "mail", now it's changeable, but keep the
// ==== default to "mail" so upgrades happen transparently
// --- TEMP MAKE DEFAULT UWASH MAIL FOLDER ~/mail (a.k.a. $HOME/mail)
$GLOBALS [ 'egw_info' ][ 'server' ][ 'mail_folder' ] = 'mail' ;
// --- DELETE THE ABOVE WHEN THIS OPTION GETS INTO THE SYSTEM SETUP
// pick up custom "mail_folder" if it exists (used for UWash and UWash Maildir servers)
// else use the system default (which we temporarily hard coded to "mail" just above here)
//--- [email][mail_port] ---
// These sets the mail_port server variable
// someday (not currently) this may be a site-wide property set during site setup
// additionally, someday (not currently) the user may be able to override this with
// a custom email preference. Currently, we simply use standard port numbers
// for the service in question.
$prefs [ 'email' ][ 'mail_port' ] = $this -> sub_get_mailsvr_port ( $prefs );
//--- [email][fullname] ---
// we pick this up from phpgw api for the default account
// the user does not directly manipulate this pref for the default email account
if (( string ) $acctnum == '0' )
{
$prefs [ 'email' ][ 'fullname' ] = $GLOBALS [ 'egw_info' ][ 'user' ][ 'fullname' ];
}
// = = = = SIMPLER PREFS = = = =
// Default Preferences info that is articulated in the email prefs schema array itself
// such email prefs schema array is described and established in /email/class.bopreferences
// by function "init_available_prefs", see the discussion there.
// --- create the objectified /email/class.bopreferences.inc.php ---
$bo_mail_prefs =& CreateObject ( 'email.bopreferences' );
// --- bo_mail_prefs->init_available_prefs() ---
// this fills object_email_bopreferences->std_prefs and ->cust_prefs
// we will initialize the users preferences according to the rules and instructions
// embodied in those prefs arrays, applying those rules to the unprocessed
// data read from the preferences DB. By taking the raw data and applying those rules,
// we will construct valid and known email preference data for this user.
$bo_mail_prefs -> init_available_prefs ();
// --- combine the two array (std and cust) for 1 pass handling ---
// when this preference DB was submitted and saved, it was hopefully so well structured
// that we can simply combine the two arrays, std_prefs and cust_prefs, and do a one
// pass analysis and preparation of this users preferences.
$avail_pref_array = $bo_mail_prefs -> std_prefs ;
$c_cust_prefs = count ( $bo_mail_prefs -> cust_prefs );
for ( $i = 0 ; $i < $c_cust_prefs ; $i ++ )
{
// add each custom prefs to the std prefs array
$next_idx = count ( $avail_pref_array );
$avail_pref_array [ $next_idx ] = $bo_mail_prefs -> cust_prefs [ $i ];
}
print_debug ( 'class.preferences: create_email_preferences: std AND cust arrays combined:' , $avail_pref_array , 'api' );
// --- make the schema-based pref data for this user ---
// user defined values and/or user specified custom email prefs are read from the
// prefs DB with mininal manipulation of the data. Currently the only change to
// users raw data is related to reversing the encoding of "database un-friendly" chars
// which itself may become unnecessary if and when the database handlers can reliably
// take care of this for us. Of course, password data requires special decoding,
// but the password in the array [email][paswd] should be left in encrypted form
// and only decrypted seperately when used to login in to an email server.
// --- generating a default value if necessary ---
// in the absence of a user defined custom email preference for a particular item, we can
// determine the desired default value for that pref as such:
// $this_avail_pref['init_default'] is a comma seperated seperated string which should
// be exploded into an array containing 2 elements that are:
// exploded[0] : an description of how to handle the next string element to get a default value.
// Possible "instructional tokens" for exploded[0] (called $set_proc[0] below) are:
// string
// set_or_not
// function
// init_no_fill
// varEVAL
// tells you how to handle the string in exploded[1] (called $set_proc[1] below) to get a valid
// default value for a particular preference if one is needed (i.e. if no user custom
// email preference exists that should override that default value, in which case we
// do not even need to obtain such a default value as described in ['init_default'] anyway).
// --- loop thru $avail_pref_array and process each pref item ---
$c_prefs = count ( $avail_pref_array );
for ( $i = 0 ; $i < $c_prefs ; $i ++ )
{
$this_avail_pref = $avail_pref_array [ $i ];
print_debug ( 'class.preferences: create_email_preferences: value from DB for $prefs[email][' . $this_avail_pref [ 'id' ] . '] = [' . $prefs [ 'email' ][ $this_avail_pref [ 'id' ]] . ']' , 'messageonly' , 'api' );
print_debug ( 'class.preferences: create_email_preferences: std/cust_prefs $this_avail_pref[' . $i . '] dump:' , $this_avail_pref , 'api' );
// --- is there a value in the DB for this preference item ---
// if the prefs DB has no value for this defined available preference, we must make one.
// This occurs if (a) this is user's first login, or (b) this is a custom pref which the user
// has not overriden, do a default (non-custom) value is needed.
if ( ! isset ( $prefs [ 'email' ][ $this_avail_pref [ 'id' ]]))
{
// now we are analizing an individual pref that is available to the user
// AND the user had no existing value in the prefs DB for this.
// --- get instructions on how to generate a default value ---
$set_proc = explode ( ',' , $this_avail_pref [ 'init_default' ]);
print_debug ( ' * set_proc=[' . serialize ( $set_proc ) . ']' , 'messageonly' , 'api' );
// --- use "instructional token" in $set_proc[0] to take appropriate action ---
// STRING
if ( $set_proc [ 0 ] == 'string' )
{
// means this pref item's value type is string
// which defined string default value is in $set_proc[1]
print_debug ( '* handle "string" set_proc: ' , serialize ( $set_proc ), 'api' );
if ( trim ( $set_proc [ 1 ]) == '' )
{
// this happens when $this_avail_pref['init_default'] = "string, "
$this_string = '' ;
}
else
{
$this_string = $set_proc [ 1 ];
}
$prefs [ 'email' ][ $this_avail_pref [ 'id' ]] = $this_string ;
}
// SET_OR_NOT
elseif ( $set_proc [ 0 ] == 'set_or_not' )
{
// typical with boolean options, True = "set/exists" and False = unset
print_debug ( '* handle "set_or_not" set_proc: ' , serialize ( $set_proc ), 'api' );
if ( $set_proc [ 1 ] == 'not_set' )
{
// leave it NOT SET
}
else
{
// opposite of boolean not_set = string "True" which simply sets a
// value it exists in the users session [email][] preference array
$prefs [ 'email' ][ $this_avail_pref [ 'id' ]] = 'True' ;
}
}
// FUNCTION
elseif ( $set_proc [ 0 ] == 'function' )
{
// string in $set_proc[1] should be "eval"uated as code, calling a function
// which will give us a default value to put in users session [email][] prefs array
print_debug ( ' * handle "function" set_proc: ' , serialize ( $set_proc ), 'api' );
$evaled = '' ;
//eval('$evaled = $this->'.$set_proc[1].'('.$account_id.');');
$code = '$evaled = $this->' . $set_proc [ 1 ] . '(' . $account_id . ');' ;
print_debug ( ' * $code: ' , $code , 'api' );
eval ( $code );
print_debug ( '* $evaled:' , $evaled , 'api' );
$prefs [ 'email' ][ $this_avail_pref [ 'id' ]] = $evaled ;
}
// INIT_NO_FILL
elseif ( $set_proc [ 0 ] == 'init_no_fill' )
{
// we have an available preference item that we may NOT fill with a default
// value. Only the user may supply a value for this pref item.
print_debug ( '* handle "init_no_fill" set_proc:' , serialize ( $set_proc ), 'api' );
// we are FORBADE from filling this at this time!
}
// varEVAL
elseif ( $set_proc [ 0 ] == 'varEVAL' )
{
// similar to "function" but used for array references, the string in $set_proc[1]
// represents code which typically is an array referencing a system/api property
print_debug ( '* handle "GLOBALS" set_proc:' , serialize ( $set_proc ), 'api' );
$evaled = '' ;
$code = '$evaled = ' . $set_proc [ 1 ];
print_debug ( ' * $code:' , $code , 'api' );
eval ( $code );
print_debug ( '* $evaled:' , $evaled , 'api' );
$prefs [ 'email' ][ $this_avail_pref [ 'id' ]] = $evaled ;
}
else
{
// error, no instructions on how to handle this element's default value creation
echo 'class.preferences: create_email_preferences: set_proc ERROR: ' . serialize ( $set_proc ) . '<br>' ;
}
}
else
{
// we have a value in the database, do we need to prepare it in any way?
// (the following discussion is unconfirmed:)
// DO NOT ALTER the data in the prefs array!!!! or the next time we call
// save_repository withOUT undoing what we might do here, the
// prefs will permenantly LOOSE the very thing(s) we are un-doing
/// here until the next OFFICIAL submit email prefs function, where it
// will again get this preparation before being written to the database.
// NOTE: if database de-fanging is eventually handled deeper in the
// preferences class, then the following code would become depreciated
// and should be removed in that case.
if (( $this_avail_pref [ 'type' ] == 'user_string' ) &&
( stristr ( $this_avail_pref [ 'write_props' ], 'no_db_defang' ) == False ))
{
// this value was "de-fanged" before putting it in the database
// undo that defanging now
$db_unfriendly = $email_base -> html_quotes_decode ( $prefs [ 'email' ][ $this_avail_pref [ 'id' ]]);
$prefs [ 'email' ][ $this_avail_pref [ 'id' ]] = $db_unfriendly ;
}
}
}
// users preferences are now established to known structured values...
// SANITY CHECK
// --- [email][use_trash_folder] ---
// --- [email][use_sent_folder] ---
// is it possible to use Trash and Sent folders - i.e. using IMAP server
// if not - force settings to false
if ( stristr ( $prefs [ 'email' ][ 'mail_server_type' ], 'imap' ) == False )
{
if ( isset ( $prefs [ 'email' ][ 'use_trash_folder' ]))
{
unset ( $prefs [ 'email' ][ 'use_trash_folder' ]);
}
if ( isset ( $prefs [ 'email' ][ 'use_sent_folder' ]))
{
unset ( $prefs [ 'email' ][ 'use_sent_folder' ]);
}
}
// DEBUG : force some settings to test stuff
//$prefs['email']['p_persistent'] = 'True';
print_debug ( 'class.preferences: $acctnum: [' . $acctnum . '] ; create_email_preferences: $prefs[email]' , $prefs [ 'email' ], 'api' );
print_debug ( 'class.preferences: create_email_preferences: LEAVING' , 'messageonly' , 'api' );
return $prefs ;
}
}