mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-29 10:09:10 +01:00
377 lines
11 KiB
PHP
377 lines
11 KiB
PHP
<?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
|
|
* @copyright (c) 2007-19 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
*/
|
|
|
|
use EGroupware\Api;
|
|
|
|
/**
|
|
* setup command: create or update the header.inc.php
|
|
*
|
|
* @ToDo: incorporate setup_header here
|
|
*/
|
|
class setup_cmd_header extends setup_cmd
|
|
{
|
|
/**
|
|
* 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
|
|
*
|
|
* @param string|array $sub_command ='create' 'create','edit','delete'(-domain) or array with all arguments
|
|
* @param array $arguments =null comand line arguments
|
|
*/
|
|
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);
|
|
|
|
// header is 3 levels lower then this command in setup/inc
|
|
$this->header_path = dirname(dirname(__DIR__)).'/header.inc.php';
|
|
|
|
// 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] != ':')
|
|
{
|
|
$this->header_path = dirname(dirname(__DIR__)).'/'.$this->header_path;
|
|
}
|
|
}
|
|
$this->setup_header = new setup_header();
|
|
}
|
|
|
|
/**
|
|
* Create or update header.inc.php
|
|
*
|
|
* @param boolean $check_only =false only run the checks (and throw the exceptions), but not the command itself
|
|
* @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
|
|
}
|
|
if (!file_exists($this->header_path) || filesize($this->header_path) < 200) // redirect header in rpms is ~150 byte
|
|
{
|
|
if ($this->sub_command != 'create')
|
|
{
|
|
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);
|
|
}
|
|
$this->defaults(false);
|
|
}
|
|
else
|
|
{
|
|
if ($this->sub_command == 'create')
|
|
{
|
|
throw new Api\Exception\WrongUserinput(
|
|
lang('EGroupware configuration file header.inc.php already exists, you need to use --edit-header or delete it first!'),20);
|
|
}
|
|
if ($this->arguments)
|
|
{
|
|
list($this->header_admin_password,$this->header_admin_user) = explode(',',$this->arguments[1]);
|
|
}
|
|
$this->check_setup_auth($this->header_admin_user,$this->header_admin_password); // no domain, we require header access!
|
|
|
|
$GLOBALS['egw_info']['server']['server_root'] = EGW_SERVER_ROOT;
|
|
$GLOBALS['egw_info']['server']['include_root'] = EGW_INCLUDE_ROOT;
|
|
}
|
|
|
|
if ($this->arguments) // we have command line arguments
|
|
{
|
|
$this->_parse_cli_arguments();
|
|
}
|
|
elseif ($this->sub_command == 'delete')
|
|
{
|
|
self::_delete_domain($this->domain);
|
|
}
|
|
else
|
|
{
|
|
$this->_parse_properties();
|
|
}
|
|
if (($errors = $this->validation_errors($GLOBALS['egw_info']['server']['server_root'],
|
|
$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']);
|
|
}
|
|
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);
|
|
}
|
|
if ($check_only)
|
|
{
|
|
return true;
|
|
}
|
|
// 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']);
|
|
}
|
|
$header = $this->generate($GLOBALS['egw_info'],$GLOBALS['egw_domain']);
|
|
|
|
if ($this->arguments)
|
|
{
|
|
echo $header; // for cli, we echo the header
|
|
}
|
|
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
|
|
{
|
|
if (file_exists($this->header_path) && !is_writable($this->header_path))
|
|
{
|
|
unlink($this->header_path);
|
|
}
|
|
if (($f = fopen($this->header_path,'wb')) && fwrite($f,$header))
|
|
{
|
|
fclose($f);
|
|
return lang('header.inc.php successful written.');
|
|
}
|
|
}
|
|
throw new Api\Exception\NoPermission(lang("Failed writing configuration file header.inc.php, check the permissions !!!"),24);
|
|
}
|
|
|
|
/**
|
|
* Magic method to allow to call all methods from setup_header, as if they were our own
|
|
*
|
|
* @param string $method
|
|
* @param array $args =null
|
|
* @return mixed
|
|
*/
|
|
function __call($method,array $args=null)
|
|
{
|
|
if (method_exists($this->setup_header,$method))
|
|
{
|
|
return call_user_func_array(array($this->setup_header,$method),$args);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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'),
|
|
),
|
|
),
|
|
'--session-handler' => array(
|
|
'session_handler' => array(
|
|
'type' => 'egw_info/server/',
|
|
'allowed' => array('files'=>'files','memcache'=>'memcache','db'=>'db'),
|
|
),
|
|
),
|
|
'--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,
|
|
);
|
|
|
|
/**
|
|
* 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)
|
|
{
|
|
$parts = explode('/',$name);
|
|
$name = array_pop($parts);
|
|
}
|
|
if (isset($this->$name))
|
|
{
|
|
$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';
|
|
|
|
if ($arg == '--delete-domain')
|
|
{
|
|
$this->_delete_domain($values);
|
|
continue;
|
|
}
|
|
|
|
if (!isset(self::$options[$arg]))
|
|
{
|
|
throw new Api\Exception\WrongUserinput(lang("Unknown option '%1' !!!",$arg),90);
|
|
}
|
|
|
|
$option = self::$options[$arg];
|
|
$vals = !is_array($option) ? array($values) : explode(',',$values);
|
|
if (!is_array($option)) $option = array($option => $option);
|
|
$n = 0;
|
|
foreach($option as $name => $data)
|
|
{
|
|
if ($n >= count($vals)) break;
|
|
|
|
$this->_parse_value($arg,$name,$data,$vals[$n++]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a given domain/instance from the header
|
|
*
|
|
* @param string $domain
|
|
*/
|
|
private static function _delete_domain($domain)
|
|
{
|
|
if (!isset($GLOBALS['egw_domain'][$domain]))
|
|
{
|
|
throw new Api\Exception\WrongUserinput(lang("Domain '%1' does NOT exist !!!",$domain),92);
|
|
}
|
|
unset($GLOBALS['egw_domain'][$domain]);
|
|
}
|
|
|
|
/**
|
|
* 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)
|
|
{
|
|
static $domain=null;
|
|
|
|
if (!is_array($data)) $data = array('type' => $data);
|
|
$type = $data['type'] ?? '';
|
|
|
|
if (isset($data['allowed']))
|
|
{
|
|
if (!isset($data['allowed'][$value]))
|
|
{
|
|
throw new Api\Exception\WrongUserinput(lang("'%1' is not allowed as %2. arguments of option %3 !!!",$value,1,$arg),91);
|
|
}
|
|
$value = $data['allowed'][$value];
|
|
}
|
|
if ($type == '@')
|
|
{
|
|
$domain = $arg == '--domain' && !$value ? 'default' : $value;
|
|
if ($arg == '--domain' && (!isset($GLOBALS['egw_domain'][$domain]) || $this->sub_command == 'create'))
|
|
{
|
|
$GLOBALS['egw_domain'][$domain] = $this->domain_defaults($GLOBALS['egw_info']['server']['header_admin_user'],$GLOBALS['egw_info']['server']['header_admin_password']);
|
|
}
|
|
}
|
|
elseif ($value !== '')
|
|
{
|
|
self::_set_global(str_replace('@', $domain ?? '', $type), $name, $value);
|
|
if ($type == 'egw_info/server/server_root')
|
|
{
|
|
self::_set_global('egw_info/server/include_root', $name, $value);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set a value in $GLOBALS with (multidimensional) key $index[/$name]
|
|
*
|
|
* @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
|
|
*/
|
|
private static function _set_global($index, $name, $value)
|
|
{
|
|
if (substr($index,-1) == '/') $index .= $name;
|
|
|
|
$var = null;
|
|
foreach(explode('/',$index) as $n)
|
|
{
|
|
if (isset($var))
|
|
{
|
|
$var =& $var[$n];
|
|
}
|
|
else
|
|
{
|
|
$var =& $GLOBALS[$n];
|
|
}
|
|
}
|
|
$var = $value;
|
|
}
|
|
} |