function uninstall(&$STACK, $addon) { $INSTALLED = array(); $STACK->rewind(); foreach ($STACK as $item) { $INSTALLED[] = $item; } // Check dependencies for this $addon - recurse if necessary $dependencies = SchemesManager::getUninstallDependencies($addon); if (!empty($dependencies)) { foreach ($dependencies as $shortcode => $name) { // print "$addon depends on $shortcode\n"; if (!in_array($shortcode, $INSTALLED)) { uninstall($STACK, $shortcode); } else { echo "warning: {$addon} already uninstalled\n"; } } } if (!isset($INSTALLED) || !in_array($addon, $INSTALLED)) { $result = fn_uninstall_addon($addon, true); if (empty($result)) { echo "could not uninstall '{$addon}' - aborting...\n\n"; echo "Re-installing previously uninstalled addons to restore system to good state\n"; foreach ($STACK as $item) { $addon = $STACK->pop(); fn_install_addon($addon, true, false); fn_update_addon_status($addon, 'A', true, false); print "INSTALL: {$addon}\n"; } exit; } echo "UNINSTALL: {$addon}\n"; $STACK->push($addon); } }
/** * Updates addon status * @param string $addon Addon to update status for * @param string $status Status to change to * @param bool $show_notification Display notification if set to true * @param bool $on_install If status was changed on after ionstall process * @return bool|string True on success, old status ID if status was not changed */ function fn_update_addon_status($addon, $status, $show_notification = true, $on_install = false) { $old_status = db_get_field("SELECT status FROM ?:addons WHERE addon = ?s", $addon); $new_status = $status; $scheme = SchemesManager::getScheme($addon); // Unmanaged addons can be enabled/disabled via console only if ($scheme->getUnmanaged() && !defined('CONSOLE')) { return false; } if ($old_status != $new_status) { // Check if addon can be enabled $conflicts = db_get_fields("SELECT addon FROM ?:addons WHERE status = 'A' AND FIND_IN_SET(?s, conflicts)", $addon); if ($new_status == 'A' && !empty($conflicts)) { $scheme = SchemesManager::getScheme($addon); fn_set_notification('W', __('warning'), __('text_addon_cannot_enable', array('[addons]' => implode(', ', SchemesManager::getNames($conflicts)), '[addon_name]' => $scheme->getName()))); return $old_status; } fn_get_schema('settings', 'actions.functions', 'php', true); $func = 'fn_settings_actions_addons_' . $addon; if (function_exists($func)) { $func($new_status, $old_status, $on_install); } // If status change is allowed, update it if ($old_status != $new_status) { if ($new_status != 'D') { // Check that addon have conflicts $scheme = SchemesManager::getScheme($addon); $conflicts = db_get_field("SELECT conflicts FROM ?:addons WHERE addon = ?s", $addon); if (!empty($conflicts)) { $conflicts = explode(',', $conflicts); $lang_var = 'text_addon_confclicts_on_install'; if (!$on_install) { foreach ($conflicts as $conflict) { fn_disable_addon($conflict, $scheme->getName(), $show_notification); } $lang_var = 'text_addon_confclicts'; } fn_set_notification('W', __('warning'), __($lang_var, array('[addons]' => implode(', ', SchemesManager::getNames($conflicts)), '[addon_name]' => $scheme->getName()))); // On install we cannot enable addon with conflicts automaticly if ($on_install) { return $old_status; } } } db_query("UPDATE ?:addons SET status = ?s WHERE addon = ?s", $status, $addon); $func = 'fn_settings_actions_addons_post_' . $addon; if (function_exists($func)) { $func($status); } if ($show_notification == true) { fn_set_notification('N', __('notice'), __('status_changed')); } // Enable/disable tabs for addon ProductTabs::instance()->updateAddonTabStatus($addon, $new_status); Registry::set('addons.' . $addon . '.status', $status); } else { return $old_status; } } // Clean cache fn_clear_cache(); if ($status == 'A') { foreach (fn_get_installed_themes() as $theme_name) { $theme = Themes::factory($theme_name); $theme_manifest = $theme->getManifest(); // Precompile addon LESS files if the theme has been converted to CSS if (!empty($theme_manifest['converted_to_css']) && !$theme->convertAddonToCss($addon)) { fn_update_addon_status($addon, 'D', $show_notification, $on_install); return $old_status; } } } return true; }
/** * Updates addon status * * @param string $addon Addon to update status for * @param string $status Status to change to * @param bool $show_notification Display notification if set to true * @param bool $on_install If status was changed right after install process * @param bool $allow_unmanaged Whether to allow change status for unmanaged addons in non-console environment * * @return bool|string True on success, old status ID if status was not changed */ function fn_update_addon_status($addon, $status, $show_notification = true, $on_install = false, $allow_unmanaged = false) { $old_status = db_get_field("SELECT status FROM ?:addons WHERE addon = ?s", $addon); $new_status = $status; $scheme = SchemesManager::getScheme($addon); // Unmanaged addons can be enabled/disabled via console only if ($scheme->getUnmanaged() && !($allow_unmanaged || defined('CONSOLE'))) { return false; } /** * Hook is executed before changing add-on status (i.e. before add-on enabling or disabling). * * @param string $addon Add-on name * @param string $status New addon status - "A" for enabled, "D" for disabled * @param bool $show_notification Display notification if set to true * @param bool $on_install If status was changed right after install process * @param bool $allow_unmanaged Whether to allow change status for unmanaged addons in non-console environment * @param string $old_status Previous addon status - "A" for enabled, "D" for disabled * @param \Tygh\Addons\AXmlScheme $scheme Add-on scheme */ fn_set_hook('update_addon_status_pre', $addon, $status, $show_notification, $on_install, $allow_unmanaged, $old_status, $scheme); if ($old_status != $new_status) { // Check if addon can be enabled $conflicts = db_get_fields("SELECT addon FROM ?:addons WHERE status = 'A' AND FIND_IN_SET(?s, conflicts)", $addon); if ($new_status == 'A' && !empty($conflicts)) { $scheme = SchemesManager::getScheme($addon); fn_set_notification('W', __('warning'), __('text_addon_cannot_enable', array('[addons]' => implode(', ', SchemesManager::getNames($conflicts)), '[addon_name]' => $scheme->getName()))); return $old_status; } fn_get_schema('settings', 'actions.functions', 'php', true); $func = 'fn_settings_actions_addons_' . $addon; if (function_exists($func)) { $func($new_status, $old_status, $on_install); } // If status change is allowed, update it if ($old_status != $new_status) { if ($new_status != 'D') { // Check that addon have conflicts $scheme = SchemesManager::getScheme($addon); $conflicts = db_get_field("SELECT conflicts FROM ?:addons WHERE addon = ?s", $addon); if (!empty($conflicts)) { $conflicts = explode(',', $conflicts); $conflicted_addons = db_get_fields("SELECT addon FROM ?:addons WHERE addon IN (?a) AND status = 'A'", $conflicts); if (!empty($conflicted_addons)) { $lang_var = 'text_addon_confclicts_on_install'; if (!$on_install) { foreach ($conflicts as $conflict) { fn_disable_addon($conflict, $scheme->getName(), $show_notification); } $lang_var = 'text_addon_confclicts'; } fn_set_notification('W', __('warning'), __($lang_var, array('[addons]' => implode(', ', SchemesManager::getNames($conflicts)), '[addon_name]' => $scheme->getName()))); // On install we cannot enable addon with conflicts automaticly if ($on_install) { return $old_status; } } } } db_query("UPDATE ?:addons SET status = ?s WHERE addon = ?s", $status, $addon); $func = 'fn_settings_actions_addons_post_' . $addon; if (function_exists($func)) { $func($status); } if ($show_notification == true) { fn_set_notification('N', __('notice'), __('status_changed')); } // Enable/disable tabs for addon ProductTabs::instance()->updateAddonTabStatus($addon, $new_status); Registry::set('addons.' . $addon . '.status', $status); } else { return $old_status; } } // Clean cache fn_clear_cache(); if ($status == 'A') { foreach (fn_get_installed_themes() as $theme_name) { $theme = Themes::factory($theme_name); $theme_manifest = $theme->getManifest(); // Precompile addon LESS files if the theme has been converted to CSS if (!empty($theme_manifest['converted_to_css']) && !$theme->convertAddonToCss($addon)) { fn_update_addon_status($addon, 'D', $show_notification, $on_install); return $old_status; } } } /** * Hook is executed after changing add-on status (i.e. after add-on enabling or disabling). * * @param string $addon Add-on name * @param string $status New addon status - "A" for enabled, "D" for disabled * @param bool $show_notification Display notification if set to true * @param bool $on_install If status was changed right after install process * @param bool $allow_unmanaged Whether to allow change status for unmanaged addons in non-console environment * @param string $old_status Previous addon status - "A" for enabled, "D" for disabled * @param \Tygh\Addons\AXmlScheme $scheme Add-on scheme */ fn_set_hook('update_addon_status_post', $addon, $status, $show_notification, $on_install, $allow_unmanaged, $old_status, $scheme); return true; }
exit; } } } } if (defined('AJAX_REQUEST')) { Tygh::$app['view']->display('views/addons/components/upload_addon.tpl'); exit; } } if ($mode == 'update_status') { $is_snapshot_correct = fn_check_addon_snapshot($_REQUEST['id']); if (!$is_snapshot_correct) { $status = false; } else { $status = fn_update_addon_status($_REQUEST['id'], $_REQUEST['status']); } if ($status !== true) { Tygh::$app['ajax']->assign('return_status', $status); } Registry::clearCachedKeyValues(); } if ($mode == 'install') { fn_install_addon($_REQUEST['addon']); Registry::clearCachedKeyValues(); } if ($mode == 'uninstall') { fn_uninstall_addon($_REQUEST['addon']); } return array(CONTROLLER_STATUS_OK, 'addons.manage'); }