2007-12-09 09:03:15 +01:00
< ? php
/**
* eGgroupWare setup - create or update the header . inc . php
*
* @ link http :// www . egroupware . org
* @ author Ralf Becker < RalfBecker - AT - outdoor - training . de >
* @ package setup
2016-05-01 17:56:49 +02:00
* @ copyright ( c ) 2007 - 16 by Ralf Becker < RalfBecker - AT - outdoor - training . de >
2007-12-09 09:03:15 +01:00
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
2008-08-20 11:01:29 +02:00
* @ version $Id $
2007-12-09 09:03:15 +01:00
*/
2016-05-01 17:56:49 +02:00
use EGroupware\Api ;
2007-12-09 09:03:15 +01:00
/**
* setup command : create or update the header . inc . php
2008-08-20 11:01:29 +02:00
*
2007-12-09 09:03:15 +01:00
* @ ToDo : incorporate setup_header here
*/
2008-08-20 11:01:29 +02:00
class setup_cmd_header extends setup_cmd
2007-12-09 09:03:15 +01:00
{
/**
* Instance of setup ' s header object
*
* @ var setup_header
*/
private $setup_header ;
/**
* Full path of the header . inc . php
*
* @ var string
*/
private $header_path ;
/**
* Constructor
*
2016-05-01 17:56:49 +02:00
* @ param string | array $sub_command = 'create' 'create' , 'edit' , 'delete' ( - domain ) or array with all arguments
* @ param array $arguments = null comand line arguments
2007-12-09 09:03:15 +01:00
*/
function __construct ( $sub_command = 'create' , $arguments = null )
{
if ( ! is_array ( $sub_command ))
{
$sub_command = array (
'sub_command' => $sub_command ,
'arguments' => $arguments ,
);
}
//echo __CLASS__.'::__construct()'; _debug_array($domain);
admin_cmd :: __construct ( $sub_command );
2008-08-20 11:01:29 +02:00
2009-05-30 22:15:31 +02:00
// header is 3 levels lower then this command in setup/inc
2016-05-26 10:44:48 +02:00
$this -> header_path = dirname ( dirname ( __DIR__ )) . '/header.inc.php' ;
2009-05-31 11:51:57 +02:00
// if header is a symlink --> work on it's target
if ( is_link ( $this -> header_path ))
{
$this -> header_path = readlink ( $this -> header_path );
if ( $this -> header_path [ 0 ] != '/' && $this -> header_path [ 1 ] != ':' )
{
2016-05-26 10:44:48 +02:00
$this -> header_path = dirname ( dirname ( __DIR__ )) . '/' . $this -> header_path ;
2009-05-31 11:51:57 +02:00
}
}
2009-06-08 18:21:14 +02:00
$this -> setup_header = new setup_header ();
2007-12-09 09:03:15 +01:00
}
/**
2008-08-20 11:01:29 +02:00
* Create or update header . inc . php
*
2016-05-01 17:56:49 +02:00
* @ param boolean $check_only = false only run the checks ( and throw the exceptions ), but not the command itself
2007-12-09 09:03:15 +01:00
* @ return string serialized $GLOBALS defined in the header . inc . php
* @ throws Exception ( lang ( 'Wrong credentials to access the header.inc.php file!' ), 2 );
* @ throws Exception ( 'header.inc.php not found!' );
*/
protected function exec ( $check_only = false )
{
if ( $check_only && $this -> remote_id )
{
return true ; // can only check locally
}
2009-05-30 22:15:31 +02:00
if ( ! file_exists ( $this -> header_path ) || filesize ( $this -> header_path ) < 200 ) // redirect header in rpms is ~150 byte
2007-12-09 09:03:15 +01:00
{
if ( $this -> sub_command != 'create' )
{
2016-05-26 10:44:48 +02:00
throw new Api\Exception\WrongUserinput ( lang ( 'EGroupware configuration file (header.inc.php) does NOT exist.' ) . " \n " . lang ( 'Use --create-header to create the configuration file (--usage gives more options).' ), 1 );
2007-12-09 09:03:15 +01:00
}
2008-08-20 11:01:29 +02:00
$this -> defaults ( false );
2007-12-09 09:03:15 +01:00
}
else
{
if ( $this -> sub_command == 'create' )
{
2016-05-01 17:56:49 +02:00
throw new Api\Exception\WrongUserinput (
2016-05-26 10:44:48 +02:00
lang ( 'EGroupware configuration file header.inc.php already exists, you need to use --edit-header or delete it first!' ), 20 );
2007-12-09 09:03:15 +01:00
}
2007-12-10 05:59:01 +01:00
if ( $this -> arguments )
2007-12-09 09:03:15 +01:00
{
2007-12-10 05:59:01 +01:00
list ( $this -> header_admin_password , $this -> header_admin_user ) = explode ( ',' , $this -> arguments [ 1 ]);
2007-12-09 09:03:15 +01:00
}
2007-12-10 05:59:01 +01:00
$this -> check_setup_auth ( $this -> header_admin_user , $this -> header_admin_password ); // no domain, we require header access!
2007-12-09 09:03:15 +01:00
$GLOBALS [ 'egw_info' ][ 'server' ][ 'server_root' ] = EGW_SERVER_ROOT ;
$GLOBALS [ 'egw_info' ][ 'server' ][ 'include_root' ] = EGW_INCLUDE_ROOT ;
}
2008-08-20 11:01:29 +02:00
2007-12-09 09:03:15 +01:00
if ( $this -> arguments ) // we have command line arguments
{
$this -> _parse_cli_arguments ();
}
2007-12-10 05:59:01 +01:00
elseif ( $this -> sub_command == 'delete' )
{
self :: _delete_domain ( $this -> domain );
}
2007-12-09 09:03:15 +01:00
else
{
$this -> _parse_properties ();
}
2008-08-20 11:01:29 +02:00
if (( $errors = $this -> validation_errors ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'server_root' ],
2007-12-09 09:03:15 +01:00
$GLOBALS [ 'egw_info' ][ 'server' ][ 'include_root' ])))
{
if ( $this -> arguments )
{
unset ( $GLOBALS [ 'egw_info' ][ 'flags' ]);
echo '$GLOBALS[egw_info] = ' ; print_r ( $GLOBALS [ 'egw_info' ]);
echo '$GLOBALS[egw_domain] = ' ; print_r ( $GLOBALS [ 'egw_domain' ]);
}
2016-05-01 17:56:49 +02:00
throw new Api\Exception\WrongUserinput ( lang ( 'Configuration errors:' ) . " \n - " . implode ( " \n - " , $errors ) . " \n " . lang ( " You need to fix the above errors, before the configuration file header.inc.php can be written! " ), 23 );
2007-12-09 09:03:15 +01:00
}
if ( $check_only )
{
return true ;
}
2019-05-28 13:38:21 +02:00
// check if php has persistent mysql connections disabled --> disable it in header, to not fill the log with warnings
if ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'db_persistent' ])
{
$GLOBALS [ 'egw_info' ][ 'server' ][ 'db_persistent' ] = $this -> check_db_persistent ( $GLOBALS [ 'egw_domain' ]);
}
2008-08-20 11:01:29 +02:00
$header = $this -> generate ( $GLOBALS [ 'egw_info' ], $GLOBALS [ 'egw_domain' ]);
2007-12-09 09:03:15 +01:00
if ( $this -> arguments )
{
echo $header ; // for cli, we echo the header
}
2009-05-30 22:15:31 +02:00
if ( file_exists ( $this -> header_path ) && is_writable ( $this -> header_path ) || is_writable ( dirname ( $this -> header_path )) ||
function_exists ( 'posix_getuid' ) && ! posix_getuid ()) // root has all rights
2007-12-09 09:03:15 +01:00
{
2009-06-21 14:34:02 +02:00
if ( file_exists ( $this -> header_path ) && ! is_writable ( $this -> header_path ))
2009-06-18 23:21:20 +02:00
{
unlink ( $this -> header_path );
}
2016-05-01 17:56:49 +02:00
if (( $f = fopen ( $this -> header_path , 'wb' )) && fwrite ( $f , $header ))
2007-12-09 09:03:15 +01:00
{
fclose ( $f );
return lang ( 'header.inc.php successful written.' );
}
}
2016-05-01 17:56:49 +02:00
throw new Api\Exception\NoPermission ( lang ( " Failed writing configuration file header.inc.php, check the permissions !!! " ), 24 );
2007-12-09 09:03:15 +01:00
}
2008-08-20 11:01:29 +02:00
/**
* Magic method to allow to call all methods from setup_header , as if they were our own
*
* @ param string $method
2016-05-01 17:56:49 +02:00
* @ param array $args = null
2008-08-20 11:01:29 +02:00
* @ return mixed
*/
2009-06-08 18:21:14 +02:00
function __call ( $method , array $args = null )
2008-08-20 11:01:29 +02:00
{
if ( method_exists ( $this -> setup_header , $method ))
{
return call_user_func_array ( array ( $this -> setup_header , $method ), $args );
}
}
2007-12-09 09:03:15 +01:00
/**
* Available options and allowed arguments
*
* @ var array
*/
static $options = array (
'--create-header' => array (
'header_admin_password' => 'egw_info/server/' ,
'header_admin_user' => 'egw_info/server/' ,
),
'--edit-header' => array (
'header_admin_password' => 'egw_info/server/' ,
'header_admin_user' => 'egw_info/server/' ,
'new_admin_password' => 'egw_info/server/header_admin_password' ,
'new_admin_user' => 'egw_info/server/header_admin_user' ,
),
'--server-root' => 'egw_info/server/server_root' ,
'--include-root' => 'egw_info/server/include_root' ,
'--session-type' => array (
'sessions_type' => array (
'type' => 'egw_info/server/' ,
'allowed' => array ( 'php' => 'php4' , 'php4' => 'php4' , 'php-restore' => 'php4-restore' , 'php4-restore' => 'php4-restore' , 'db' => 'db' ),
),
),
2008-08-20 11:01:29 +02:00
'--session-handler' => array (
'session_handler' => array (
'type' => 'egw_info/server/' ,
'allowed' => array ( 'files' => 'files' , 'memcache' => 'memcache' , 'db' => 'db' ),
),
),
2007-12-09 09:03:15 +01:00
'--limit-access' => 'egw_info/server/setup_acl' , // name used in setup
'--setup-acl' => 'egw_info/server/setup_acl' , // alias to match the real name
'--mcrypt' => array (
'mcrypt_enabled' => array (
'type' => 'egw_info/server/' ,
'allowed' => array ( 'on' => true , 'off' => false ),
),
'mcrypt_iv' => 'egw_info/server/' ,
'mcrypt' => 'egw_info/versions/mcrypt' ,
),
'--domain-selectbox' => array (
'show_domain_selectbox' => array (
'type' => 'egw_info/server/' ,
'allowed' => array ( 'on' => true , 'off' => false ),
),
),
'--db-persistent' => array (
'db_persistent' => array (
'type' => 'egw_info/server/' ,
'allowed' => array ( 'on' => true , 'off' => false ),
),
),
'--domain' => array (
'domain' => '@' ,
'db_name' => 'egw_domain/@/' ,
'db_user' => 'egw_domain/@/' ,
'db_pass' => 'egw_domain/@/' ,
'db_type' => 'egw_domain/@/' ,
'db_host' => 'egw_domain/@/' ,
'db_port' => 'egw_domain/@/' ,
'config_user' => 'egw_domain/@/' ,
'config_passwd' => 'egw_domain/@/' ,
),
'--delete-domain' => true ,
);
2008-08-20 11:01:29 +02:00
2007-12-09 09:03:15 +01:00
/**
* Parses properties from this object
*/
private function _parse_properties ()
{
foreach ( self :: $options as $arg => $option )
{
foreach ( is_array ( $option ) ? $option : array ( $option => $option ) as $name => $data )
{
if ( strpos ( $name , '/' ) !== false )
{
$name = array_pop ( $parts = explode ( '/' , $name ));
}
if ( isset ( $this -> $name ))
2008-08-20 11:01:29 +02:00
{
2007-12-09 09:03:15 +01:00
$this -> _parse_value ( $arg , $name , $data , $this -> $name );
}
}
}
}
/**
* Parses command line arguments in $this -> arguments
*/
private function _parse_cli_arguments ()
{
$arguments = $this -> arguments ;
while (( $arg = array_shift ( $arguments )))
{
$values = count ( $arguments ) && substr ( $arguments [ 0 ], 0 , 2 ) !== '--' ? array_shift ( $arguments ) : 'on' ;
2008-08-20 11:01:29 +02:00
2007-12-09 09:03:15 +01:00
if ( $arg == '--delete-domain' )
{
2007-12-10 05:59:01 +01:00
$this -> _delete_domain ( $values );
2007-12-09 09:03:15 +01:00
continue ;
}
2008-08-20 11:01:29 +02:00
2007-12-09 09:03:15 +01:00
if ( ! isset ( self :: $options [ $arg ]))
{
2016-05-01 17:56:49 +02:00
throw new Api\Exception\WrongUserinput ( lang ( " Unknown option '%1' !!! " , $arg ), 90 );
2007-12-09 09:03:15 +01:00
}
2008-08-20 11:01:29 +02:00
2007-12-09 09:03:15 +01:00
$option = self :: $options [ $arg ];
2016-05-01 17:56:49 +02:00
$vals = ! is_array ( $option ) ? array ( $values ) : explode ( ',' , $values );
2007-12-09 09:03:15 +01:00
if ( ! is_array ( $option )) $option = array ( $option => $option );
$n = 0 ;
foreach ( $option as $name => $data )
{
2016-05-01 17:56:49 +02:00
if ( $n >= count ( $vals )) break ;
2007-12-09 09:03:15 +01:00
2016-05-01 17:56:49 +02:00
$this -> _parse_value ( $arg , $name , $data , $vals [ $n ++ ]);
2007-12-09 09:03:15 +01:00
}
}
}
2008-08-20 11:01:29 +02:00
2007-12-10 05:59:01 +01:00
/**
* Delete a given domain / instance from the header
*
* @ param string $domain
*/
private static function _delete_domain ( $domain )
{
if ( ! isset ( $GLOBALS [ 'egw_domain' ][ $domain ]))
{
2016-05-01 17:56:49 +02:00
throw new Api\Exception\WrongUserinput ( lang ( " Domain '%1' does NOT exist !!! " , $domain ), 92 );
2007-12-10 05:59:01 +01:00
}
unset ( $GLOBALS [ 'egw_domain' ][ $domain ]);
}
2007-12-09 09:03:15 +01:00
/**
* Parses a single value
*
* @ param string $arg current cli argument processed
* @ param string $name name of the property
* @ param array / string $data string with type or array containing values for type , allowed
* @ param mixed $value value to set
*/
private function _parse_value ( $arg , $name , $data , $value )
{
2016-05-01 17:56:49 +02:00
static $domain = null ;
2007-12-09 09:03:15 +01:00
if ( ! is_array ( $data )) $data = array ( 'type' => $data );
$type = $data [ 'type' ];
2008-08-20 11:01:29 +02:00
2007-12-09 09:03:15 +01:00
if ( isset ( $data [ 'allowed' ]))
{
if ( ! isset ( $data [ 'allowed' ][ $value ]))
{
2016-05-01 17:56:49 +02:00
throw new Api\Exception\WrongUserinput ( lang ( " '%1' is not allowed as %2. arguments of option %3 !!! " , $value , 1 , $arg ), 91 );
2007-12-09 09:03:15 +01:00
}
$value = $data [ 'allowed' ][ $value ];
}
if ( $type == '@' )
{
$domain = $arg == '--domain' && ! $value ? 'default' : $value ;
if ( $arg == '--domain' && ( ! isset ( $GLOBALS [ 'egw_domain' ][ $domain ]) || $this -> sub_command == 'create' ))
{
2008-08-20 11:01:29 +02:00
$GLOBALS [ 'egw_domain' ][ $domain ] = $this -> domain_defaults ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'header_admin_user' ], $GLOBALS [ 'egw_info' ][ 'server' ][ 'header_admin_password' ]);
2007-12-09 09:03:15 +01:00
}
}
elseif ( $value !== '' )
{
self :: _set_value ( $GLOBALS , str_replace ( '@' , $domain , $type ), $name , $value );
if ( $type == 'egw_info/server/server_root' )
{
self :: _set_value ( $GLOBALS , 'egw_info/server/include_root' , $name , $value );
}
}
}
/**
* Set a value in the given array $arr with ( multidimensional ) key $index [ / $name ]
*
* @ param array & $arr
* @ param string $index multidimensional index written with / as separator , eg . egw_info / server /
* @ param string $name additional index to use if $index end with a slash
* @ param mixed $value value to set
*/
static private function _set_value ( & $arr , $index , $name , $value )
{
if ( substr ( $index , - 1 ) == '/' ) $index .= $name ;
2008-08-20 11:01:29 +02:00
2007-12-09 09:03:15 +01:00
$var =& $arr ;
foreach ( explode ( '/' , $index ) as $name )
{
$var =& $var [ $name ];
}
2016-05-01 17:56:49 +02:00
if ( true ) $var = strpos ( $name , 'passw' ) !== false ? md5 ( $value ) : $value ;
2007-12-09 09:03:15 +01:00
}
}