|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* eGgroupWare setup - abstract baseclass for all setup commands, extending admin_cmd |
|
4
|
|
|
* |
|
5
|
|
|
* @link http://www.egroupware.org |
|
6
|
|
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> |
|
7
|
|
|
* @package setup |
|
8
|
|
|
* @copyright (c) 2007-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de> |
|
9
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License |
|
10
|
|
|
* @version $Id$ |
|
11
|
|
|
*/ |
|
12
|
|
|
|
|
13
|
|
|
use EGroupware\Api; |
|
14
|
|
|
use EGroupware\Api\Egw; |
|
15
|
|
|
|
|
16
|
|
|
/** |
|
17
|
|
|
* setup command: abstract baseclass for all setup commands, extending admin_cmd |
|
18
|
|
|
*/ |
|
19
|
|
|
abstract class setup_cmd extends admin_cmd |
|
20
|
|
|
{ |
|
21
|
|
|
/** |
|
22
|
|
|
* Defaults set for empty options while running the command |
|
23
|
|
|
* |
|
24
|
|
|
* @var array |
|
25
|
|
|
*/ |
|
26
|
|
|
public $set_defaults = array(); |
|
27
|
|
|
|
|
28
|
|
|
/** |
|
29
|
|
|
* Should be called by every command usually requiring header admin rights |
|
30
|
|
|
* |
|
31
|
|
|
* @throws Api\Exception\NoPermission(lang('Wrong credentials to access the header.inc.php file!'),2); |
|
32
|
|
|
*/ |
|
33
|
|
|
protected function _check_header_access() |
|
34
|
|
|
{ |
|
35
|
|
|
if (!$this->header_secret && $this->header_admin_user) // no secret specified but header_admin_user/password |
|
|
|
|
|
|
36
|
|
|
{ |
|
37
|
|
|
if (!$this->uid) $this->uid = true; |
|
|
|
|
|
|
38
|
|
|
$this->set_header_secret($this->header_admin_user,$this->header_admin_password); |
|
|
|
|
|
|
39
|
|
|
} |
|
40
|
|
|
$secret = $this->_calc_header_secret($GLOBALS['egw_info']['server']['header_admin_user'], |
|
41
|
|
|
$GLOBALS['egw_info']['server']['header_admin_password']); |
|
42
|
|
|
if ($this->uid === true) unset($this->uid); |
|
|
|
|
|
|
43
|
|
|
|
|
44
|
|
|
if ($this->header_secret != $secret) |
|
45
|
|
|
{ |
|
46
|
|
|
//echo "_check_header_access: header_secret='$this->header_secret' != '$secret'=_calc_header_secret({$GLOBALS['egw_info']['server']['header_admin_user']},{$GLOBALS['egw_info']['server']['header_admin_password']})\n"; |
|
47
|
|
|
throw new Api\Exception\NoPermission(lang('Wrong credentials to access the header.inc.php file!'),5); |
|
48
|
|
|
} |
|
49
|
|
|
|
|
50
|
|
|
} |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* Set the user and pw required for any operation on the header file |
|
54
|
|
|
* |
|
55
|
|
|
* @param string $user |
|
56
|
|
|
* @param string $pw password or md5 hash of it |
|
57
|
|
|
*/ |
|
58
|
|
|
public function set_header_secret($user,$pw) |
|
59
|
|
|
{ |
|
60
|
|
|
if ($this->uid || parent::save(false)) // we need to save first, to get the uid |
|
61
|
|
|
{ |
|
62
|
|
|
$this->header_secret = $this->_calc_header_secret($user,$pw); |
|
|
|
|
|
|
63
|
|
|
} |
|
64
|
|
|
else |
|
65
|
|
|
{ |
|
66
|
|
|
throw new Exception ('failed to set header_secret!'); |
|
67
|
|
|
} |
|
68
|
|
|
} |
|
69
|
|
|
|
|
70
|
|
|
/** |
|
71
|
|
|
* Calculate the header_secret used to access the header from this command |
|
72
|
|
|
* |
|
73
|
|
|
* It's an md5 over the uid, header-admin-user and -password. |
|
74
|
|
|
* |
|
75
|
|
|
* @param string $header_admin_user |
|
76
|
|
|
* @param string $header_admin_password |
|
77
|
|
|
* @return string |
|
78
|
|
|
*/ |
|
79
|
|
|
private function _calc_header_secret($header_admin_user=null,$header_admin_password=null) |
|
80
|
|
|
{ |
|
81
|
|
|
if (!self::is_md5($header_admin_password)) $header_admin_password = md5($header_admin_password); |
|
82
|
|
|
|
|
83
|
|
|
$secret = md5($this->uid.$header_admin_user.$header_admin_password); |
|
84
|
|
|
//echo "header_secret='$secret' = md5('$this->uid'.'$header_admin_user'.'$header_admin_password')\n"; |
|
85
|
|
|
return $secret; |
|
86
|
|
|
} |
|
87
|
|
|
|
|
88
|
|
|
/** |
|
89
|
|
|
* Saving the object to the database, reimplemented to not do it in setup context |
|
90
|
|
|
* |
|
91
|
|
|
* @param boolean $set_modifier =true set the current user as modifier or 0 (= run by the system) |
|
92
|
|
|
* @return boolean true on success, false otherwise |
|
93
|
|
|
*/ |
|
94
|
|
|
function save($set_modifier=true) |
|
95
|
|
|
{ |
|
96
|
|
|
if (isset($GLOBALS['egw']->db) && is_object($GLOBALS['egw']->db) && $GLOBALS['egw']->db->Database) |
|
97
|
|
|
{ |
|
98
|
|
|
return parent::save($set_modifier); |
|
99
|
|
|
} |
|
100
|
|
|
return true; |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
/** |
|
104
|
|
|
* Reference to the setup object, after calling check_setup_auth method |
|
105
|
|
|
* |
|
106
|
|
|
* @var setup |
|
107
|
|
|
*/ |
|
108
|
|
|
static protected $egw_setup; |
|
109
|
|
|
|
|
110
|
|
|
static private $egw_accounts_backup; |
|
111
|
|
|
|
|
112
|
|
|
/** |
|
113
|
|
|
* Create the setup enviroment (for running within setup or EGw) |
|
114
|
|
|
*/ |
|
115
|
|
|
static protected function _setup_enviroment($domain=null) |
|
116
|
|
|
{ |
|
117
|
|
|
if (!is_object($GLOBALS['egw_setup'])) |
|
118
|
|
|
{ |
|
119
|
|
|
require_once(EGW_INCLUDE_ROOT.'/setup/inc/class.setup.inc.php'); |
|
120
|
|
|
$GLOBALS['egw_setup'] = new setup(true,true); |
|
121
|
|
|
} |
|
122
|
|
|
self::$egw_setup = $GLOBALS['egw_setup']; |
|
123
|
|
|
self::$egw_setup->ConfigDomain = $domain; |
|
124
|
|
|
|
|
125
|
|
|
if (isset($GLOBALS['egw_info']['server']['header_admin_user']) && !isset($GLOBALS['egw_domain']) && |
|
126
|
|
|
is_object($GLOBALS['egw']) && $GLOBALS['egw'] instanceof Egw) |
|
127
|
|
|
{ |
|
128
|
|
|
// we run inside EGw, not setup --> read egw_domain array from the header via the showheader cmd |
|
129
|
|
|
$cmd = new setup_cmd_showheader(null); // null = only header, no db stuff, no hashes |
|
130
|
|
|
$header = $cmd->run(); |
|
131
|
|
|
$GLOBALS['egw_domain'] = $header['egw_domain']; |
|
132
|
|
|
|
|
133
|
|
|
if (is_object($GLOBALS['egw']->accounts) && is_null(self::$egw_accounts_backup)) |
|
134
|
|
|
{ |
|
135
|
|
|
self::$egw_accounts_backup = $GLOBALS['egw']->accounts; |
|
136
|
|
|
unset($GLOBALS['egw']->accounts); |
|
137
|
|
|
} |
|
138
|
|
|
if ($this->config) self::$egw_setup->setup_account_object($this->config); |
|
|
|
|
|
|
139
|
|
|
} |
|
140
|
|
|
if (is_object($GLOBALS['egw']->db) && $domain) |
|
141
|
|
|
{ |
|
142
|
|
|
$GLOBALS['egw']->db->disconnect(); |
|
143
|
|
|
$GLOBALS['egw']->db = new Api\Db($GLOBALS['egw_domain'][$domain]); |
|
144
|
|
|
|
|
145
|
|
|
// change caching to managed instance |
|
146
|
|
|
Api\Cache::unset_instance_key(); |
|
147
|
|
|
} |
|
148
|
|
|
} |
|
149
|
|
|
|
|
150
|
|
|
/** |
|
151
|
|
|
* Restore EGw's db connection |
|
152
|
|
|
* |
|
153
|
|
|
*/ |
|
154
|
|
|
static function restore_db() |
|
155
|
|
|
{ |
|
156
|
|
|
if (is_object($GLOBALS['egw']->db)) |
|
157
|
|
|
{ |
|
158
|
|
|
$GLOBALS['egw']->db->disconnect(); |
|
159
|
|
|
$GLOBALS['egw']->db = new Api\Db($GLOBALS['egw_info']['server']); |
|
160
|
|
|
|
|
161
|
|
|
// change caching back to own instance |
|
162
|
|
|
Api\Cache::unset_instance_key(); |
|
163
|
|
|
|
|
164
|
|
|
if (!is_null(self::$egw_accounts_backup)) |
|
165
|
|
|
{ |
|
166
|
|
|
$GLOBALS['egw']->accounts = self::$egw_accounts_backup; |
|
167
|
|
|
Api\Accounts::cache_invalidate(); |
|
168
|
|
|
unset(self::$egw_accounts_backup); |
|
169
|
|
|
} |
|
170
|
|
|
} |
|
171
|
|
|
} |
|
172
|
|
|
|
|
173
|
|
|
/** |
|
174
|
|
|
* Creates a setup like enviroment and checks for the header user/pw or config_user/pw if domain given |
|
175
|
|
|
* |
|
176
|
|
|
* @param string $user |
|
177
|
|
|
* @param string $pw |
|
178
|
|
|
* @param string $domain =null if given we also check agains config user/pw |
|
179
|
|
|
* @throws Api\Exception\NoPermission(lang('Access denied: wrong username or password for manage-header !!!'),21); |
|
180
|
|
|
* @throws Api\Exception\NoPermission(lang("Access denied: wrong username or password to configure the domain '%1(%2)' !!!",$domain,$GLOBALS['egw_domain'][$domain]['db_type']),40); |
|
181
|
|
|
*/ |
|
182
|
|
|
static function check_setup_auth($user,$pw,$domain=null) |
|
183
|
|
|
{ |
|
184
|
|
|
self::_setup_enviroment($domain); |
|
185
|
|
|
|
|
186
|
|
|
// check the authentication if a header_admin_password is set, if not we dont have a header yet and no authentication |
|
187
|
|
|
if ($GLOBALS['egw_info']['server']['header_admin_password']) // if that's not given we dont have a header yet |
|
188
|
|
|
{ |
|
189
|
|
|
if (!self::$egw_setup->check_auth($user,$pw,$GLOBALS['egw_info']['server']['header_admin_user'], |
|
190
|
|
|
$GLOBALS['egw_info']['server']['header_admin_password']) && |
|
191
|
|
|
(is_null($domain) || !isset($GLOBALS['egw_domain'][$domain]) || // if valid domain given check it's config user/pw |
|
192
|
|
|
!self::$egw_setup->check_auth($user,$pw,$GLOBALS['egw_domain'][$domain]['config_user'], |
|
193
|
|
|
$GLOBALS['egw_domain'][$domain]['config_passwd']))) |
|
194
|
|
|
{ |
|
195
|
|
|
if (is_null($domain)) |
|
196
|
|
|
{ |
|
197
|
|
|
throw new Api\Exception\NoPermission(lang('Access denied: wrong username or password for manage-header !!!'),21); |
|
198
|
|
|
} |
|
199
|
|
|
else |
|
200
|
|
|
{ |
|
201
|
|
|
throw new Api\Exception\NoPermission(lang("Access denied: wrong username or password to configure the domain '%1(%2)' !!!",$domain,$GLOBALS['egw_domain'][$domain]['db_type']),40); |
|
|
|
|
|
|
202
|
|
|
} |
|
203
|
|
|
} |
|
204
|
|
|
} |
|
205
|
|
|
} |
|
206
|
|
|
|
|
207
|
|
|
/** |
|
208
|
|
|
* Applications which are currently not installed (set after call to check_installed, for the last/only domain only) |
|
209
|
|
|
* |
|
210
|
|
|
* @var array |
|
211
|
|
|
*/ |
|
212
|
|
|
static public $apps_to_install=array(); |
|
213
|
|
|
/** |
|
214
|
|
|
* Applications which are currently need update (set after call to check_installed, for the last/only domain only) |
|
215
|
|
|
* |
|
216
|
|
|
* @var array |
|
217
|
|
|
*/ |
|
218
|
|
|
static public $apps_to_upgrade=array(); |
|
219
|
|
|
|
|
220
|
|
|
/** |
|
221
|
|
|
* Check if EGw is installed, which versions and if an update is needed |
|
222
|
|
|
* |
|
223
|
|
|
* Sets self::$apps_to_update and self::$apps_to_install for the last/only domain only! |
|
224
|
|
|
* |
|
225
|
|
|
* @param string $domain ='' domain to check, default '' = all |
|
226
|
|
|
* @param int/array $stop =0 stop checks before given exit-code(s), default 0 = all checks |
|
|
|
|
|
|
227
|
|
|
* @param boolean $verbose =false echo messages as they happen, instead returning them |
|
228
|
|
|
* @return array with translated messages |
|
229
|
|
|
*/ |
|
230
|
|
|
static function check_installed($domain='',$stop=0,$verbose=false) |
|
231
|
|
|
{ |
|
232
|
|
|
self::_setup_enviroment($domain); |
|
233
|
|
|
|
|
234
|
|
|
global $setup_info; |
|
235
|
|
|
static $header_checks=true; // output the header checks only once |
|
236
|
|
|
|
|
237
|
|
|
$messages = array(); |
|
238
|
|
|
|
|
239
|
|
|
if ($stop && !is_array($stop)) $stop = array($stop); |
|
240
|
|
|
|
|
241
|
|
|
$versions =& $GLOBALS['egw_info']['server']['versions']; |
|
242
|
|
|
|
|
243
|
|
|
if (!$versions['api']) |
|
244
|
|
|
{ |
|
245
|
|
|
if (!include(EGW_INCLUDE_ROOT.'/api/setup/setup.inc.php')) |
|
246
|
|
|
{ |
|
247
|
|
|
throw new Api\Exception\WrongUserinput(lang("EGroupware sources in '%1' are not complete, file '%2' missing !!!",realpath('..'),'api/setup/setup.inc.php'),99); // should not happen ;-) |
|
|
|
|
|
|
248
|
|
|
} |
|
249
|
|
|
$versions['api'] = $setup_info['api']['version']; |
|
250
|
|
|
unset($setup_info); |
|
251
|
|
|
} |
|
252
|
|
|
if ($header_checks) |
|
253
|
|
|
{ |
|
254
|
|
|
$messages[] = self::_echo_message($verbose,lang('EGroupware API version %1 found.',$versions['api'])); |
|
255
|
|
|
} |
|
256
|
|
|
$header_stage = self::$egw_setup->detection->check_header(); |
|
257
|
|
|
if ($stop && in_array($header_stage,$stop)) return true; |
|
258
|
|
|
|
|
259
|
|
|
switch ($header_stage) |
|
260
|
|
|
{ |
|
261
|
|
|
case 1: 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); |
|
262
|
|
|
|
|
263
|
|
|
// case 2: throw new Api\Exception\WrongUserinput(lang('EGroupware configuration file (header.inc.php) version %1 exists%2',$versions['header'],'.')."\n".lang('No header admin password set! Use --edit-header <password>[,<user>] to set one (--usage gives more options).'),2); |
|
264
|
|
|
|
|
265
|
|
|
case 3: throw new Api\Exception\WrongUserinput(lang('EGroupware configuration file (header.inc.php) version %1 exists%2',$versions['header'],'.')."\n".lang('No EGroupware domains / database instances exist! Use --edit-header --domain to add one (--usage gives more options).'),3); |
|
266
|
|
|
|
|
267
|
|
|
case 4: throw new Api\Exception\WrongUserinput(lang('EGroupware configuration file (header.inc.php) version %1 exists%2',$versions['header'],'.')."\n".lang('It needs upgrading to version %1! Use --update-header <password>[,<user>] to do so (--usage gives more options).',$versions['current_header']),4); |
|
268
|
|
|
} |
|
269
|
|
|
if ($header_checks) |
|
270
|
|
|
{ |
|
271
|
|
|
$messages[] = self::_echo_message($verbose,lang('EGroupware configuration file (header.inc.php) version %1 exists%2', |
|
272
|
|
|
$versions['header'],' '.lang('and is up to date'))); |
|
273
|
|
|
} |
|
274
|
|
|
unset($header_checks); // no further output of the header checks |
|
275
|
|
|
|
|
276
|
|
|
$domains = $GLOBALS['egw_domain']; |
|
277
|
|
|
if ($domain) // domain to check given |
|
278
|
|
|
{ |
|
279
|
|
|
if (!isset($GLOBALS['egw_domain'][$domain])) throw new Api\Exception\WrongUserinput(lang("Domain '%1' does NOT exist !!!",$domain), 92); |
|
280
|
|
|
|
|
281
|
|
|
$domains = array($domain => $GLOBALS['egw_domain'][$domain]); |
|
282
|
|
|
} |
|
283
|
|
|
foreach($domains as $domain => $data) |
|
284
|
|
|
{ |
|
285
|
|
|
self::$egw_setup->ConfigDomain = $domain; // set the domain the setup class operates on |
|
286
|
|
|
if (count($GLOBALS['egw_domain']) > 1) |
|
287
|
|
|
{ |
|
288
|
|
|
self::_echo_message($verbose); |
|
289
|
|
|
$messages[] = self::_echo_message($verbose,lang('EGroupware domain/instance %1(%2):',$domain,$data['db_type'])); |
|
290
|
|
|
} |
|
291
|
|
|
$setup_info = self::$egw_setup->detection->get_versions(); |
|
292
|
|
|
// check if there's already a db-connection and close if, otherwise the db-connection of the previous domain will be used |
|
293
|
|
|
if (is_object(self::$egw_setup->db)) |
|
294
|
|
|
{ |
|
295
|
|
|
self::$egw_setup->db->disconnect(); |
|
296
|
|
|
} |
|
297
|
|
|
self::$egw_setup->loaddb(); |
|
298
|
|
|
|
|
299
|
|
|
$db = $data['db_type'].'://'.$data['db_user'].':'.$data['db_pass'].'@'.$data['db_host'].'/'.$data['db_name']; |
|
300
|
|
|
|
|
301
|
|
|
$db_stage =& $GLOBALS['egw_info']['setup']['stage']['db']; |
|
302
|
|
|
if (($db_stage = self::$egw_setup->detection->check_db($setup_info)) != 1) |
|
303
|
|
|
{ |
|
304
|
|
|
$setup_info = self::$egw_setup->detection->get_db_versions($setup_info); |
|
305
|
|
|
$db_stage = self::$egw_setup->detection->check_db($setup_info); |
|
306
|
|
|
} |
|
307
|
|
|
if ($stop && in_array(10+$db_stage,$stop)) |
|
308
|
|
|
{ |
|
309
|
|
|
return $messages; |
|
310
|
|
|
} |
|
311
|
|
|
switch($db_stage) |
|
312
|
|
|
{ |
|
313
|
|
|
case 1: throw new Api\Exception\WrongUserinput(lang('Your Database is not working!')." $db: ".self::$egw_setup->db->Error,11); |
|
314
|
|
|
|
|
315
|
|
|
case 3: throw new Api\Exception\WrongUserinput(lang('Your database is working, but you dont have any applications installed')." ($db). ".lang("Use --install to install EGroupware."),13); |
|
316
|
|
|
|
|
317
|
|
|
case 4: throw new Api\Exception\WrongUserinput(lang('EGroupware API needs a database (schema) update from version %1 to %2!',$setup_info['api']['currentver'],$versions['api']).' '.lang('Use --update to do so.'),14); |
|
318
|
|
|
|
|
319
|
|
|
case 10: // also check apps of updates |
|
320
|
|
|
self::$apps_to_upgrade = self::$apps_to_install = array(); |
|
321
|
|
|
foreach($setup_info as $app => $data) |
|
|
|
|
|
|
322
|
|
|
{ |
|
323
|
|
|
if ($data['currentver'] && $data['version'] && $data['version'] != 'deleted' && $data['version'] != $data['currentver']) |
|
324
|
|
|
{ |
|
325
|
|
|
self::$apps_to_upgrade[] = $app; |
|
326
|
|
|
} |
|
327
|
|
|
if (!isset($data['enabled']) && isset($data['version'])) // jdots eg. is no app, but a template |
|
328
|
|
|
{ |
|
329
|
|
|
self::$apps_to_install[] = $app; |
|
330
|
|
|
} |
|
331
|
|
|
} |
|
332
|
|
|
// add autodeinstall apps |
|
333
|
|
|
self::$apps_to_upgrade = array_unique(array_merge(self::$apps_to_upgrade, self::check_autodeinstall())); |
|
334
|
|
|
|
|
335
|
|
|
if (self::$apps_to_install) |
|
336
|
|
|
{ |
|
337
|
|
|
self::_echo_message($verbose); |
|
338
|
|
|
$messages[] = self::_echo_message($verbose,lang('The following applications are NOT installed:').' '.implode(', ',self::$apps_to_install)); |
|
339
|
|
|
} |
|
340
|
|
|
if (self::$apps_to_upgrade) |
|
|
|
|
|
|
341
|
|
|
{ |
|
342
|
|
|
$db_stage = 4; |
|
343
|
|
|
if ($stop && in_array(10+$db_stage,$stop)) return $messages; |
|
344
|
|
|
|
|
345
|
|
|
throw new Api\Exception\WrongUserinput(lang('The following applications need to be upgraded:').' '.implode(', ',self::$apps_to_upgrade).'! '.lang('Use --update to do so.'),14); |
|
346
|
|
|
} |
|
347
|
|
|
break; |
|
348
|
|
|
} |
|
349
|
|
|
$messages[] = self::_echo_message($verbose,lang("database is version %1 and up to date.",$setup_info['api']['currentver'])); |
|
350
|
|
|
|
|
351
|
|
|
self::$egw_setup->detection->check_config(); |
|
352
|
|
|
if ($GLOBALS['egw_info']['setup']['config_errors'] && $stop && !in_array(15,$stop)) |
|
353
|
|
|
{ |
|
354
|
|
|
throw new Api\Exception\WrongUserinput(lang('You need to configure EGroupware:')."\n- ".@implode("\n- ",$GLOBALS['egw_info']['setup']['config_errors']),15); |
|
355
|
|
|
} |
|
356
|
|
|
} |
|
357
|
|
|
return $messages; |
|
358
|
|
|
} |
|
359
|
|
|
|
|
360
|
|
|
/** |
|
361
|
|
|
* Check if there are apps which should be autoinstalled |
|
362
|
|
|
* |
|
363
|
|
|
* @return array with app-names |
|
364
|
|
|
*/ |
|
365
|
|
|
static function check_autoinstall() |
|
366
|
|
|
{ |
|
367
|
|
|
$ret = array_filter(self::$apps_to_install, function($app) |
|
368
|
|
|
{ |
|
369
|
|
|
global $setup_info; |
|
370
|
|
|
return $setup_info[$app]['autoinstall']; |
|
371
|
|
|
}); |
|
372
|
|
|
//error_log(__METHOD__."() apps_to_install=".array2string(self::$apps_to_install).' returning '.array2string($ret)); |
|
373
|
|
|
return $ret; |
|
374
|
|
|
} |
|
375
|
|
|
|
|
376
|
|
|
/** |
|
377
|
|
|
* Check if app should be automatically deinstalled |
|
378
|
|
|
* |
|
379
|
|
|
* @return array with app-names to automatic deinstall |
|
380
|
|
|
*/ |
|
381
|
|
|
static function check_autodeinstall() |
|
382
|
|
|
{ |
|
383
|
|
|
global $setup_info; |
|
384
|
|
|
|
|
385
|
|
|
$ret = array_values(array_filter(array_keys($setup_info), function($app) |
|
386
|
|
|
{ |
|
387
|
|
|
global $setup_info; |
|
388
|
|
|
if (empty($setup_info[$app]['autodeinstall'])) |
|
389
|
|
|
{ |
|
390
|
|
|
return false; |
|
391
|
|
|
} |
|
392
|
|
|
$autodeinstall = $setup_info[$app]['autodeinstall']; |
|
393
|
|
|
if (!is_bool($autodeinstall)) |
|
394
|
|
|
{ |
|
395
|
|
|
try { |
|
396
|
|
|
$autodeinstall = (bool)$GLOBALS['egw_setup']->db->query($autodeinstall, __LINE__, __FILE__)->fetchColumn(); |
|
397
|
|
|
} |
|
398
|
|
|
catch (\Exception $e) { |
|
399
|
|
|
_egw_log_exception($e); |
|
400
|
|
|
$autodeinstall = false; |
|
401
|
|
|
} |
|
402
|
|
|
} |
|
403
|
|
|
return $autodeinstall; |
|
404
|
|
|
})); |
|
405
|
|
|
//error_log(__METHOD__."() apps=".json_encode(array_keys($setup_info)).' returning '.json_encode($ret)); |
|
406
|
|
|
return $ret; |
|
407
|
|
|
} |
|
408
|
|
|
|
|
409
|
|
|
/** |
|
410
|
|
|
* Echo the given message, if $verbose |
|
411
|
|
|
* |
|
412
|
|
|
* @param boolean $verbose |
|
413
|
|
|
* @param string $msg |
|
414
|
|
|
* @return string $msg |
|
415
|
|
|
*/ |
|
416
|
|
|
static function _echo_message($verbose,$msg='') |
|
417
|
|
|
{ |
|
418
|
|
|
if ($verbose) echo $msg."\n"; |
|
419
|
|
|
|
|
420
|
|
|
return $msg; |
|
421
|
|
|
} |
|
422
|
|
|
} |
|
423
|
|
|
|