* Setup: support uninstalling automatic installed apps (no more reinstalling next update)

This commit is contained in:
Ralf Becker 2021-08-03 18:53:05 +02:00
parent ffc9a35020
commit d882ff4738
5 changed files with 54 additions and 20 deletions

View File

@ -71,15 +71,18 @@ class Applications
} }
/** /**
* populate array with a list of installed apps * Populate array with a list of installed apps
* *
* egw_applications.app_enabled = -1 is NOT installed, but an uninstalled autoinstall app!
*
* @return array[]
*/ */
function read_installed_apps() function read_installed_apps()
{ {
$GLOBALS['egw_info']['apps'] = Api\Cache::getInstance(__CLASS__, 'apps', function() $GLOBALS['egw_info']['apps'] = Api\Cache::getInstance(__CLASS__, 'apps', function()
{ {
$apps = array(); $apps = array();
foreach($this->db->select($this->table_name,'*',false,__LINE__,__FILE__,false,'ORDER BY app_order ASC') as $row) foreach($this->db->select($this->table_name,'*', ['app_enabled != -1'],__LINE__,__FILE__,false,'ORDER BY app_order ASC') as $row)
{ {
$apps[$row['app_name']] = Array( $apps[$row['app_name']] = Array(
'title' => $row['app_name'], 'title' => $row['app_name'],

View File

@ -226,6 +226,9 @@ if (!empty($detail = $_GET['detail']))
{ {
switch($key) switch($key)
{ {
case 'autoinstall':
$val = json_encode($val);
break;
case 'title': case 'title':
continue 2; continue 2;
case 'tables': case 'tables':

View File

@ -516,8 +516,7 @@ class setup
),False,__LINE__,__FILE__); ),False,__LINE__,__FILE__);
} }
try { try {
$this->db->insert($this->applications_table,array( $this->db->insert($this->applications_table, [
'app_name' => $appname,
'app_enabled' => $enable, 'app_enabled' => $enable,
'app_order' => $setup_info[$appname]['app_order'], 'app_order' => $setup_info[$appname]['app_order'],
'app_tables' => (string)$tables, // app_tables is NOT NULL 'app_tables' => (string)$tables, // app_tables is NOT NULL
@ -525,7 +524,9 @@ class setup
'app_index' => $setup_info[$appname]['index'], 'app_index' => $setup_info[$appname]['index'],
'app_icon' => $setup_info[$appname]['icon'], 'app_icon' => $setup_info[$appname]['icon'],
'app_icon_app' => $setup_info[$appname]['icon_app'], 'app_icon_app' => $setup_info[$appname]['icon_app'],
),False,__LINE__,__FILE__); ], [
'app_name' => $appname,
], __LINE__, __FILE__);
} }
catch (Api\Db\Exception\InvalidSql $e) catch (Api\Db\Exception\InvalidSql $e)
{ {
@ -548,7 +549,7 @@ class setup
* Check if an application has info in the db * Check if an application has info in the db
* *
* @param $appname Application 'name' with a matching $setup_info[$appname] array slice * @param $appname Application 'name' with a matching $setup_info[$appname] array slice
* @param $enabled optional, set to False to not enable this app * @return boolean|null null: autoinstalled app which got uninstalled
*/ */
function app_registered($appname) function app_registered($appname)
{ {
@ -563,13 +564,13 @@ class setup
// _debug_array($setup_info[$appname]); // _debug_array($setup_info[$appname]);
} }
if ($this->db->select($this->applications_table,'COUNT(*)',array('app_name' => $appname),__LINE__,__FILE__)->fetchColumn()) if (($enabled = $this->db->select($this->applications_table, 'app_enabled', ['app_name' => $appname], __LINE__,__FILE__)->fetchColumn()) !== false)
{ {
if(@$GLOBALS['DEBUG']) if(@$GLOBALS['DEBUG'])
{ {
echo '... app previously registered.'; echo '... app previously registered.';
} }
return True; return $enabled <= -1 ? null : true;
} }
if(@$GLOBALS['DEBUG']) if(@$GLOBALS['DEBUG'])
{ {
@ -676,10 +677,35 @@ class setup
$this->db->delete(Api\Config::TABLE, array('config_app'=>$appname),__LINE__,__FILE__); $this->db->delete(Api\Config::TABLE, array('config_app'=>$appname),__LINE__,__FILE__);
} }
//echo 'DELETING application: ' . $appname; //echo 'DELETING application: ' . $appname;
$this->db->delete($this->applications_table,array('app_name'=>$appname),__LINE__,__FILE__);
// when uninstalling an autoinstall app, we must mark it deleted in the DB, otherwise it will install again the next update
if (file_exists($file = EGW_SERVER_ROOT.'/'.$appname.'/setup/setup.inc.php'))
{
$setup_info = [];
include($file);
}
if (!empty($setup_info[$appname]['autoinstall']) && $setup_info[$appname]['autoinstall'] === true)
{
$this->db->update($this->applications_table, [
'app_enabled' => -1,
'app_tables' => '',
'app_version' => 'uninstalled',
'app_index' => null,
], [
'app_name' => $appname,
], __LINE__, __FILE__);
}
else
{
$this->db->delete($this->applications_table, ['app_name' => $appname], __LINE__, __FILE__);
}
Api\Egw\Applications::invalidate(); Api\Egw\Applications::invalidate();
// unregister hooks, before removing links
unset($GLOBALS['egw_info']['apps'][$appname]);
Api\Hooks::read(true);
// Remove links to the app // Remove links to the app
Link::unlink(0, $appname); Link::unlink(0, $appname);
} }
@ -1219,6 +1245,8 @@ class setup
{ {
static $table_names = False; static $table_names = False;
if(!is_object($this->db)) $this->loaddb();
if (!$table_names || $force_refresh) $table_names = $this->db->table_names(); if (!$table_names || $force_refresh) $table_names = $this->db->table_names();
if (!$table_names) return false; if (!$table_names) return false;

View File

@ -62,7 +62,7 @@ class setup_detection
/* one of these tables exists. checking for post/pre beta version */ /* one of these tables exists. checking for post/pre beta version */
if($GLOBALS['egw_setup']->applications_table != 'applications') if($GLOBALS['egw_setup']->applications_table != 'applications')
{ {
foreach($GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->applications_table,'*',false,__LINE__,__FILE__) as $row) foreach($GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->applications_table, '*', 'app_enabled != -1', __LINE__, __FILE__) as $row)
{ {
$app = $row['app_name']; $app = $row['app_name'];
if (!isset($setup_info[$app])) // app source no longer there if (!isset($setup_info[$app])) // app source no longer there

View File

@ -618,10 +618,10 @@ class setup_process
foreach($setup_info as $appname => &$appdata) foreach($setup_info as $appname => &$appdata)
{ {
// check if app is NOT installed // check if app is NOT installed
if(!$GLOBALS['egw_setup']->app_registered($appname)) if (!($registered = $GLOBALS['egw_setup']->app_registered($appname)))
{ {
// check if app wants to be automatically installed on update to version x or allways // check if app wants to be automatically installed on update to version x or always (unless uninstalled prior)
if (isset($appdata['autoinstall']) && ($appdata['autoinstall'] === true || if (isset($appdata['autoinstall']) && ($appdata['autoinstall'] === true && $registered !== null ||
$appdata['autoinstall'] === $this->api_version_target)) $appdata['autoinstall'] === $this->api_version_target))
{ {
$info_c = $this->current(array($appname => $appdata), $DEBUG); $info_c = $this->current(array($appname => $appdata), $DEBUG);