2007-04-16 22:46:55 +02:00
< ? php
/**
2016-03-19 14:06:07 +01:00
* EGroupware - eTemplate request object storing request - data directly in the form itself
2007-04-16 22:46:55 +02:00
*
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
2016-03-19 14:06:07 +01:00
* @ package api
* @ subpackage etemplate
2007-04-16 22:46:55 +02:00
* @ link http :// www . egroupware . org
* @ author Ralf Becker < RalfBecker @ outdoor - training . de >
2016-03-19 14:06:07 +01:00
* @ copyright ( c ) 2007 - 16 by Ralf Becker < RalfBecker @ outdoor - training . de >
2007-04-16 22:46:55 +02:00
* @ version $Id $
*/
2016-03-19 14:06:07 +01:00
namespace EGroupware\Api\Etemplate ;
2016-03-20 14:02:55 +01:00
use EGroupware\Api ;
2007-04-16 22:46:55 +02:00
/**
2009-03-16 13:58:24 +01:00
* Class to represent the persitent information of an eTemplate request
*
2015-09-03 09:12:35 +02:00
* Current default for etemplate_request is to store request - data in egw_cache by
* setting a not set etemplate_request :: $request_class to 'etemplate_request_cache' .
*
2009-03-16 13:58:24 +01:00
* This class stores the request - data direct in a hidden var in the form .
* As this would allow an evil user to manipulate it and therefore compromise the security
* of an EGroupware instance , this class should only be used , if mcrypt is available
* to encrypt that data . The factory method etemplate_request :: read () ensures that ,
* by using etemplate_request_session instead .
*
* The key used to encrypt the request can be set in header . inc . php by setting
*
* $GLOBALS [ 'egw_info' ][ 'server' ][ 'etemplate_form_key' ] = 'something secret' ;
*
* if this var is not set , the db_pass and EGW_SERVER_ROOT is used instead .
*
2015-09-03 09:12:35 +02:00
* The request object should be instancated only via the factory method etemplate_request :: read ( $id = null )
2009-03-16 13:58:24 +01:00
*
2016-03-19 14:06:07 +01:00
* $request = Api\Etemplate\Request :: read ();
2009-03-16 13:58:24 +01:00
*
* // add request data
*
* $id = $request -> id ();
*
* b ) open or modify an existing request :
*
2016-03-19 14:06:07 +01:00
* if ( ! ( $request = Api\Etemplate\Request :: read ( $id )))
2007-04-16 22:46:55 +02:00
* {
* // request not found
* }
2009-03-16 13:58:24 +01:00
*
* Ajax requests can use this object to open the original request by using the id , they have to transmitt back ,
* and register further variables , modify the registered ones or delete them AND then update the id , if it changed :
*
2013-10-11 13:20:21 +02:00
* eTemplate2 :
*
* if (( $new_id = $request -> id ()) != $exec_id )
* {
2016-03-20 14:02:55 +01:00
* Api\Json\Response :: get () -> generic ( 'assign' , array (
2013-10-11 13:20:21 +02:00
* 'etemplate_exec_id' => $id ,
* 'id' => '' ,
* 'key' => 'etemplate_exec_id' ,
* 'value' => $new_id ,
* ));
* }
*
* old eTemplate :
*
* if (( $new_id = $request -> id ()) != $exec_id )
2009-03-16 13:58:24 +01:00
* {
2016-03-20 14:02:55 +01:00
* Api\Json\Response :: get () -> assign ( 'etemplate_exec_id' , 'value' , $new_id );
2009-03-16 13:58:24 +01:00
* }
*
2008-08-30 13:17:04 +02:00
* For an example look in link_widget :: ajax_search ()
2014-01-15 17:46:16 +01:00
*
* @ property - read boolean $data_modified true if data was modified and therefore needs saving
2014-12-17 14:58:15 +01:00
* @ property int $output_mode
* @ property array $content
* @ property array $changes
* @ property array $sel_options
* @ property array $readonlys
* @ property array $preserv
* @ property string $method
* @ property array $ignore_validation
* @ property array $template
* @ property string $app_header
2007-04-16 22:46:55 +02:00
*/
2016-03-19 14:06:07 +01:00
class Request
2007-04-16 22:46:55 +02:00
{
/**
* here is the request data stored
*
* @ var array
*/
2019-03-19 15:34:44 +01:00
protected $data = [
'content' => [],
'readonlys' => [],
];
2007-04-16 22:46:55 +02:00
/**
* Flag if data has been modified and therefor need to be stored again in the session
*
* @ var boolean
*/
2009-03-16 13:58:24 +01:00
protected $data_modified = false ;
2014-01-15 17:46:16 +01:00
/**
* Flag that stored data should be removed by destructor , if not modified .
*
* @ var boolean
*/
protected $remove_if_not_modified = false ;
2007-04-16 22:46:55 +02:00
/**
2009-03-16 13:58:24 +01:00
* mcrypt resource
*
* @ var resource
*/
static protected $mcrypt ;
/**
* See gzcompress , set it to 0 to not compress
*
* @ var int
*/
static public $compression_level = 6 ;
/**
* Name of request class used
*
* Can be set here to force a certain class , otherwise the factory method chooses one
2007-04-16 22:46:55 +02:00
*
* @ var string
*/
2016-09-24 19:07:37 +02:00
static public $request_class ; // = 'EGroupware\Api\Etemplate\Request\Session';
2009-03-16 13:58:24 +01:00
2007-04-16 22:46:55 +02:00
/**
2009-03-16 13:58:24 +01:00
* Factory method to get a new request object or the one for an existing request
2007-04-16 22:46:55 +02:00
*
2014-01-15 17:46:16 +01:00
* New default is to use egw_cache to store requests and no longer request or
* session documented below :
*
2009-03-16 13:58:24 +01:00
* If mcrypt AND gzcompress is available this factory method chooses etemplate_request ,
* which stores the request data encrypted in a hidden var directly in the form ,
* over etemplate_request_session , which stores the data in the session ( and causing
* the sesison to constantly grow ) .
*
2015-09-03 09:12:35 +02:00
* @ param string $id = null
2020-01-29 11:08:44 +01:00
* @ param bool $handle_not_found = true true : handle not found by trying to redirect , false : just return null
* @ return Request | null null if Request not found and $handle_not_found === false
2007-04-16 22:46:55 +02:00
*/
2020-01-29 11:08:44 +01:00
public static function read ( $id = null , $handle_not_found = true )
2007-04-16 22:46:55 +02:00
{
2009-03-16 13:58:24 +01:00
if ( is_null ( self :: $request_class ))
{
2014-01-15 17:46:16 +01:00
// new default to use egw_cache to store requests
2016-03-19 14:06:07 +01:00
self :: $request_class = __CLASS__ . '\\Cache' ;
2014-01-15 17:46:16 +01:00
/* old default to use request if mcrypt and gzcompress are available and session if not
2009-04-20 14:43:44 +02:00
self :: $request_class = check_load_extension ( 'mcrypt' ) && function_exists ( 'gzcompress' ) &&
2016-09-24 19:07:37 +02:00
self :: init_crypt () ? __CLASS__ : 'EGroupware\Api\Etemplate\Request\Session' ;
2014-01-15 17:46:16 +01:00
*/
2009-03-16 13:58:24 +01:00
}
if ( self :: $request_class != __CLASS__ )
{
2014-01-15 17:46:16 +01:00
$request = call_user_func ( self :: $request_class . '::read' , $id );
2009-03-16 13:58:24 +01:00
}
2014-01-15 17:46:16 +01:00
else
2009-03-16 13:58:24 +01:00
{
2016-03-19 14:06:07 +01:00
$request = new Request ();
2009-03-16 13:58:24 +01:00
2014-01-15 17:46:16 +01:00
if ( ! is_null ( $id ))
2009-03-16 13:58:24 +01:00
{
2014-01-15 17:46:16 +01:00
$id = base64_decode ( $id );
2009-03-16 13:58:24 +01:00
2014-01-15 17:46:16 +01:00
// decrypt the data if available
if ( self :: init_crypt ())
{
$id = mdecrypt_generic ( self :: $mcrypt , $id );
}
// uncompress the data if available
if ( self :: $compression_level && function_exists ( 'gzcompress' ))
{
//$len_compressed = bytes($id);
//$time = microtime(true);
$id = gzuncompress ( $id );
//$time = number_format(1000.0 * (microtime(true) - $time),1);
//$len_uncompressed = bytes($id);
//error_log(__METHOD__."() uncompressed from $len_compressed to $len_uncompressed bytes $time ms");
}
$request -> data = unserialize ( $id );
if ( ! $request -> data )
{
error_log ( __METHOD__ . " () id not valid! " );
$request = false ;
}
//error_log(__METHOD__."() size of request = ".bytes($id));
2009-03-16 13:58:24 +01:00
}
2014-01-15 17:46:16 +01:00
}
2020-01-29 11:08:44 +01:00
if ( ! $request && $handle_not_found ) // eT2 request/session expired
2014-01-15 17:46:16 +01:00
{
list ( $app ) = explode ( '.' , $_GET [ 'menuaction' ]);
2016-09-09 18:27:14 +02:00
$global = false ;
if ( isset ( $GLOBALS [ 'egw_info' ][ 'apps' ][ $app ]))
{
$index_url = isset ( $GLOBALS [ 'egw_info' ][ 'apps' ][ $app ][ 'index' ]) ?
'/index.php?menuaction=' . $GLOBALS [ 'egw_info' ][ 'apps' ][ $app ][ 'index' ] : '/' . $app . '/index.php' ;
}
else
{
2016-11-16 17:20:03 +01:00
$index_url = Api\Framework :: link ( '/index.php' );
2016-09-09 18:27:14 +02:00
$global = true ;
$app = null ;
}
2014-10-08 22:02:59 +02:00
// add a unique token to redirect to avoid client-side framework tries refreshing via nextmatch
$index_url .= ( strpos ( $index_url , '?' ) ? '&' : '?' ) . 'redirect=' . microtime ( true );
2016-03-20 14:02:55 +01:00
error_log ( __METHOD__ . " (' $id ', ...) eT2 request not found / expired --> redirecting app $app to $index_url (_GET[menuaction]= $_GET[menuaction] , isJSONRequest()= " . array2string ( Api\Json\Request :: isJSONRequest ()) . ')' );
if ( Api\Json\Request :: isJSONRequest ())
2014-01-27 17:30:34 +01:00
{
// we must not redirect ajax_destroy_session calls, as they might originate from our own redirect!
if ( strpos ( $_GET [ 'menuaction' ], '.ajax_destroy_session.etemplate' ) === false )
{
2016-03-20 14:02:55 +01:00
$response = Api\Json\Response :: get ();
2022-07-05 08:43:53 +02:00
$response -> redirect ( Api\Framework :: link ( $index_url ), $global , $app );
2016-03-20 17:30:01 +01:00
exit ;
2014-01-27 17:30:34 +01:00
}
}
else
{
2016-04-07 22:42:06 +02:00
Api\Framework :: redirect_link ( $index_url );
2014-01-27 17:30:34 +01:00
}
2009-03-16 13:58:24 +01:00
}
return $request ;
2007-04-16 22:46:55 +02:00
}
2009-03-16 13:58:24 +01:00
2020-01-29 11:08:44 +01:00
/**
* CSRF check using an etemplate - exec - id
*
* If eTemplate request object could not be read , the function will NOT return ,
* but send an Ajax error response and exit or die with the error - message !
*
* @ param string $id etemplate - exec - id
* @ param string $caller calling method to log
* @ param array $args = [] arguments to log
* @ throws Api\Json\Exception
*/
public static function csrfCheck ( $id , $caller , $args = [])
{
if ( ! self :: read ( $id , false )) // false: do NOT handle not found, but return null
{
error_log ( __METHOD__ . " (' $id ', $caller , " . json_encode ( $args ) . " ) called with invalid/expired etemplate_exec_id: possible CSRF detected from IP " . $_SERVER [ 'REMOTE_ADDR' ] . ' to ' . $_SERVER [ 'REQUEST_METHOD' ] . ' ' . $_SERVER [ 'REQUEST_URI' ]);
$msg = lang ( 'Request could not be processed, please reload your window (press F5 or Cmd R)!' );
if ( Api\Json\Request :: isJSONRequest ())
{
Api\Json\Response :: get () -> message ( $msg , 'error' );
exit ;
}
die ( $msg );
}
}
2007-04-16 22:46:55 +02:00
/**
2009-03-16 13:58:24 +01:00
* Private constructor to force the instancation of this class only via it ' s static factory method read
2007-04-16 22:46:55 +02:00
*
2015-09-03 09:12:35 +02:00
* @ param string $id = null
2007-04-16 22:46:55 +02:00
*/
2009-03-16 13:58:24 +01:00
private function __construct ( $id = null )
2007-04-16 22:46:55 +02:00
{
2015-09-03 09:12:35 +02:00
unset ( $id );
2007-04-16 22:46:55 +02:00
}
2009-03-16 13:58:24 +01:00
2007-04-16 22:46:55 +02:00
/**
2009-03-16 13:58:24 +01:00
* return the id of this request
2007-04-16 22:46:55 +02:00
*
2009-03-16 13:58:24 +01:00
* @ return string
2007-04-16 22:46:55 +02:00
*/
2009-03-16 13:58:24 +01:00
public function & id ()
2007-04-16 22:46:55 +02:00
{
2017-04-04 15:04:44 +02:00
$this -> cleanup ();
2014-01-15 17:46:16 +01:00
$data = serialize ( $this -> data );
2009-03-16 13:58:24 +01:00
// compress the data if available
if ( self :: $compression_level && function_exists ( 'gzcompress' ))
2007-04-16 22:46:55 +02:00
{
2009-03-16 13:58:24 +01:00
//$len_uncompressed = bytes($id);
//$time = microtime(true);
2014-01-15 17:46:16 +01:00
$data = gzcompress ( $data , self :: $compression_level );
2009-03-16 13:58:24 +01:00
//$time = number_format(1000.0 * (microtime(true) - $time),1);
//$len_compressed = bytes($id);
//error_log(__METHOD__."() compressed from $len_uncompressed to $len_compressed bytes in $time ms");
2007-04-16 22:46:55 +02:00
}
2009-03-16 13:58:24 +01:00
// encrypt the data if available
if ( self :: init_crypt ())
{
2014-01-15 17:46:16 +01:00
$data = mcrypt_generic ( self :: $mcrypt , $data );
2009-03-16 13:58:24 +01:00
}
2014-01-15 17:46:16 +01:00
$id = base64_encode ( $data );
2009-03-16 13:58:24 +01:00
//error_log(__METHOD__."() #$this->id: size of request = ".bytes($id));//.", id='$id'");
//self::debug();
return $id ;
2007-04-16 22:46:55 +02:00
}
2009-03-16 13:58:24 +01:00
2017-04-04 15:04:44 +02:00
/**
* Clean up data before storing it : currently only removes " real " nextmatch rows
*/
protected function cleanup ()
{
2017-04-04 16:52:25 +02:00
if ( isset ( $this -> data [ 'content' ][ 'nm' ]))
2017-04-04 15:04:44 +02:00
{
2017-04-04 16:52:25 +02:00
if ( is_array ( $this -> data [ 'content' ][ 'nm' ][ 'rows' ]))
2017-04-04 15:04:44 +02:00
{
2017-04-04 16:52:25 +02:00
foreach ( array_keys ( $this -> data [ 'content' ][ 'nm' ][ 'rows' ]) as $n )
2017-04-04 15:04:44 +02:00
{
2017-04-04 16:52:25 +02:00
if ( is_int ( $n ))
{
unset ( $this -> data [ 'content' ][ 'nm' ][ 'rows' ][ $n ]);
}
2017-04-04 15:04:44 +02:00
}
2017-04-04 16:52:25 +02:00
//error_log(__METHOD__."() content[nm][rows]=".array2string($this->data['content']['nm']['rows']));
2017-04-04 15:04:44 +02:00
}
2017-04-04 16:52:25 +02:00
// do not store actions
unset ( $this -> data [ 'content' ][ 'nm' ][ 'actions' ], $this -> data [ 'content' ][ 'nm' ][ 'action_links' ]);
2017-04-04 15:04:44 +02:00
}
}
2007-04-16 22:46:55 +02:00
/**
* Register a form - variable to be processed
*
2015-09-03 09:12:35 +02:00
* @ param string $_form_name form - name
2007-04-16 22:46:55 +02:00
* @ param string $type etemplate type
2015-09-03 09:12:35 +02:00
* @ param array $data = array () optional extra data
2007-04-16 22:46:55 +02:00
*/
2015-09-03 09:12:35 +02:00
public function set_to_process ( $_form_name , $type , $data = array ())
2007-04-16 22:46:55 +02:00
{
2015-09-03 09:12:35 +02:00
if ( ! $_form_name || ! $type ) return ;
2009-03-16 13:58:24 +01:00
2009-11-24 11:56:41 +01:00
//echo '<p>'.__METHOD__."($form_name,$type,".array2string($data).")</p>\n";
2007-04-16 22:46:55 +02:00
$data [ 'type' ] = $type ;
2009-03-16 13:58:24 +01:00
2010-05-11 16:52:45 +02:00
// unquote single and double quotes, as this is how they get returned in $_POST
2015-09-03 09:12:35 +02:00
$form_name = str_replace ( array ( '\\\'' , '"' ), array ( '\'' , '"' ), $_form_name );
2010-05-11 16:52:45 +02:00
2007-04-16 22:46:55 +02:00
$this -> data [ 'to_process' ][ $form_name ] = $data ;
$this -> data_modified = true ;
}
2009-03-16 13:58:24 +01:00
/**
* Set an attribute of a to - process record
*
2015-09-03 09:12:35 +02:00
* @ param string $_form_name form - name
2009-03-16 13:58:24 +01:00
* @ param string $attribute etemplate type
* @ param array $value
2015-09-03 09:12:35 +02:00
* @ param boolean $add_to_array = false should $value be added to the attribute array
2009-03-16 13:58:24 +01:00
*/
2015-09-03 09:12:35 +02:00
public function set_to_process_attribute ( $_form_name , $attribute , $value , $add_to_array = false )
2009-03-16 13:58:24 +01:00
{
2009-11-24 11:56:41 +01:00
//echo '<p>'.__METHOD__."($form_name,$attribute,$value,$add_to_array)</p>\n";
2015-09-03 09:12:35 +02:00
if ( ! $_form_name ) return ;
2009-03-16 13:58:24 +01:00
2010-05-11 16:52:45 +02:00
// unquote single and double quotes, as this is how they get returned in $_POST
2015-09-03 09:12:35 +02:00
$form_name = str_replace ( array ( '\\\'' , '"' ), array ( '\'' , '"' ), $_form_name );
2010-05-11 16:52:45 +02:00
2009-03-16 13:58:24 +01:00
if ( $add_to_array )
{
$this -> data [ 'to_process' ][ $form_name ][ $attribute ][] = $value ;
}
else
{
$this -> data [ 'to_process' ][ $form_name ][ $attribute ] = $value ;
}
$this -> data_modified = true ;
}
2007-04-16 22:46:55 +02:00
/**
* Unregister a form - variable to be no longer processed
*
* @ param string $form_name form - name
*/
public function unset_to_process ( $form_name )
{
2009-11-24 11:56:41 +01:00
//echo '<p>'.__METHOD__."($form_name) isset_to_process($form_name)=".$this->isset_to_process($form_name)."</p>\n";
2007-04-16 22:46:55 +02:00
unset ( $this -> data [ 'to_process' ][ $form_name ]);
$this -> data_modified = true ;
}
2009-03-16 13:58:24 +01:00
2007-04-16 22:46:55 +02:00
/**
* return the data of a form - var to process or the whole array
*
2015-09-03 09:12:35 +02:00
* @ param string $form_name = null
2007-04-16 22:46:55 +02:00
* @ return array
*/
public function get_to_process ( $form_name = null )
{
2009-11-24 11:56:41 +01:00
//echo '<p>'.__METHOD__."($form_name)</p>\n";
2007-04-16 22:46:55 +02:00
return $form_name ? $this -> data [ 'to_process' ][ $form_name ] : $this -> data [ 'to_process' ];
}
2009-03-16 13:58:24 +01:00
2007-04-16 22:46:55 +02:00
/**
* check if something set for a given $form_name
*
* @ param string $form_name
* @ return boolean
*/
public function isset_to_process ( $form_name )
{
2009-11-24 11:56:41 +01:00
//echo '<p>'.__METHOD__."($form_name) = ".array2string(isset($this->data['to_process'][$form_name]))."</p>\n";
2007-04-16 22:46:55 +02:00
return isset ( $this -> data [ 'to_process' ][ $form_name ]);
}
2009-03-16 13:58:24 +01:00
2016-11-17 11:08:54 +01:00
/**
* creates a new unique request - id
*
* @ return string
2020-01-29 11:08:44 +01:00
* @ throws \Exception if it was not possible to gather sufficient entropy .
2016-11-17 11:08:54 +01:00
*/
static function request_id ()
{
2017-01-27 17:37:04 +01:00
// replace url-unsafe chars with _ to not run into url-encoding issues when used in a url
$userID = preg_replace ( '/[^a-z0-9_\\.@-]/i' , '_' , $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_lid' ]);
2016-11-17 11:08:54 +01:00
2020-01-29 11:08:44 +01:00
// replace + with _ to not run into url-encoding issues when used in a url
$token = str_replace ( '+' , '_' , base64_encode ( random_bytes ( 32 )));
2016-11-17 11:08:54 +01:00
return $GLOBALS [ 'egw_info' ][ 'flags' ][ 'currentapp' ] . '_' . $userID . '_' . $token ;
}
2007-04-16 22:46:55 +02:00
/**
* magic function to set all request - vars , used eg . as $request -> method = 'app.class.method' ;
*
* @ param string $var
* @ param mixed $val
*/
2021-10-07 10:14:08 +02:00
public function __set ( $var , $val )
2007-04-16 22:46:55 +02:00
{
2021-10-07 10:14:08 +02:00
if ( ! isset ( $this -> data [ $var ]) || $this -> data [ $var ] !== $val )
2007-04-16 22:46:55 +02:00
{
$this -> data [ $var ] = $val ;
2014-01-15 17:46:16 +01:00
//error_log(__METHOD__."('$var', ...) data of id=$this->id changed ...");
2007-04-16 22:46:55 +02:00
$this -> data_modified = true ;
}
}
2009-03-16 13:58:24 +01:00
2007-04-16 22:46:55 +02:00
/**
* magic function to access the request - vars , used eg . as $method = $request -> method ;
*
* @ param string $var
* @ return mixed
*/
2009-03-16 13:58:24 +01:00
public function & __get ( $var )
2007-04-16 22:46:55 +02:00
{
2014-01-15 17:46:16 +01:00
if ( $var == 'data_modified' ) return $this -> data_modified ;
2007-04-16 22:46:55 +02:00
return $this -> data [ $var ];
}
2009-11-24 11:56:41 +01:00
2009-05-27 16:57:29 +02:00
/**
* magic function to see if a request - var has been set
*
* @ param string $var
* @ return boolean
*/
public function __isset ( $var )
{
return array_key_exists ( $var , $this -> data );
}
2007-04-16 22:46:55 +02:00
/**
2009-03-16 13:58:24 +01:00
* Get the names / keys of existing variables
*
* @ return array
2007-04-16 22:46:55 +02:00
*/
2009-03-16 13:58:24 +01:00
public function names ()
2007-04-16 22:46:55 +02:00
{
2009-03-16 13:58:24 +01:00
return array_keys ( $this -> data );
2007-04-16 22:46:55 +02:00
}
/**
2009-03-16 13:58:24 +01:00
* Output the size - wise important parts of a request
2007-04-16 22:46:55 +02:00
*
2009-03-16 13:58:24 +01:00
* @ param double $min_share minimum share to be reported ( in percent of the whole request )
* @ param double $dump_share minimum share from which on a variable get output
2007-04-16 22:46:55 +02:00
*/
2009-03-16 13:58:24 +01:00
public function debug ( $min_share = 1.0 , $dump_share = 25.0 )
2007-04-16 22:46:55 +02:00
{
2009-03-16 13:58:24 +01:00
echo " <p><b>total size request data = " . ( $total = strlen ( serialize ( $this -> data ))) . " </b></p> \n " ;
echo " <p>shares bigger then $min_share % percent of it:</p> \n " ;
foreach ( $this -> data as $key => $val )
2007-04-16 22:46:55 +02:00
{
2009-03-16 13:58:24 +01:00
$len = strlen ( is_array ( $val ) ? serialize ( $val ) : $val );
2021-03-31 17:49:43 +02:00
$len .= ' (' . sprintf ( '%2.1f' ,( $percent = 100.0 * $len / $total )) . '%)' ;
2009-03-16 13:58:24 +01:00
if ( $percent < $min_share ) continue ;
echo " <p><b> $key </b>: strlen( \$ val)= $len </p> \n " ;
if ( $percent >= $dump_share ) _debug_array ( $val );
if ( is_array ( $val ) && $len > 2000 )
{
foreach ( $val as $k => $v )
{
$l = strlen ( is_array ( $v ) ? serialize ( $v ) : $v );
2021-03-31 17:49:43 +02:00
$l .= ' (' . sprintf ( '%2.1f' ,( $p = 100.0 * $l / $total )) . '%)' ;
2009-03-16 13:58:24 +01:00
if ( $p < $min_share ) continue ;
echo " <p> - { $key } [ $k ]: strlen( \$ v)= $l </p> \n " ;
}
}
2007-04-16 22:46:55 +02:00
}
}
/**
2009-03-16 13:58:24 +01:00
* Check if session encryption is configured , possible and initialise it
2007-04-16 22:46:55 +02:00
*
2015-09-03 09:12:35 +02:00
* @ param string $algo = 'tripledes'
* @ param string $mode = 'ecb'
2009-03-16 13:58:24 +01:00
* @ return boolean true if encryption is used , false otherwise
2007-04-16 22:46:55 +02:00
*/
2009-03-16 13:58:24 +01:00
static public function init_crypt ( $algo = 'tripledes' , $mode = 'ecb' )
2007-04-16 22:46:55 +02:00
{
2009-03-16 13:58:24 +01:00
if ( is_null ( self :: $mcrypt ))
2007-04-16 22:46:55 +02:00
{
2009-03-16 13:58:24 +01:00
if ( isset ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'etemplate_form_key' ]))
{
$key = $GLOBALS [ 'egw_info' ][ 'server' ][ 'etemplate_form_key' ];
}
else
{
$key = $GLOBALS [ 'egw_info' ][ 'server' ][ 'db_pass' ] . EGW_SERVER_ROOT ;
}
2009-04-20 14:43:44 +02:00
if ( ! check_load_extension ( 'mcrypt' ))
2009-03-16 13:58:24 +01:00
{
error_log ( __METHOD__ . " () required PHP extension mcrypt not loaded and can not be loaded, eTemplate requests get NOT encrypted! " );
return false ;
}
if ( ! ( self :: $mcrypt = mcrypt_module_open ( $algo , '' , $mode , '' )))
{
error_log ( __METHOD__ . " () could not mcrypt_module_open(algo=' $algo ','',mode=' $mode ',''), eTemplate requests get NOT encrypted! " );
return false ;
}
$iv_size = mcrypt_enc_get_iv_size ( self :: $mcrypt );
2021-03-31 17:49:43 +02:00
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'mcrypt_iv' ]) || strlen ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'mcrypt_iv' ]) < $iv_size )
{
if ( ! ( $iv = mcrypt_create_iv ( $iv_size , MCRYPT_DEV_RANDOM )))
{
return self :: $mcrypt = false ;
}
}
else
{
$iv = substr ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'mcrypt_iv' ], 0 , $iv_size );
}
2009-03-16 13:58:24 +01:00
$key_size = mcrypt_enc_get_key_size ( self :: $mcrypt );
2012-10-23 10:20:54 +02:00
if ( bytes ( $key ) > $key_size ) $key = cut_bytes ( $key , 0 , $key_size - 1 );
2007-04-16 22:46:55 +02:00
2009-03-16 13:58:24 +01:00
if ( mcrypt_generic_init ( self :: $mcrypt , $key , $iv ) < 0 )
2007-04-16 22:46:55 +02:00
{
2009-03-16 13:58:24 +01:00
error_log ( __METHOD__ . " () could not initialise mcrypt, sessions get NOT encrypted! " );
return self :: $mcrypt = false ;
2007-04-16 22:46:55 +02:00
}
}
2009-03-16 13:58:24 +01:00
return is_resource ( self :: $mcrypt );
}
/**
* Destructor
*/
function __destruct ()
{
if ( self :: $mcrypt )
{
mcrypt_generic_deinit ( self :: $mcrypt );
self :: $mcrypt = null ;
}
2007-04-16 22:46:55 +02:00
}
2014-01-15 17:46:16 +01:00
/**
* Mark request as to destroy , if it does not get modified before destructor is called
*
* If that function is called , request is removed from storage , further modification will work !
*/
public function remove_if_not_modified ()
{
$this -> remove_if_not_modified = true ;
}
2022-07-05 08:43:53 +02:00
}