false, 'result' => self::RESULT_NO_PERMISSION]; } // Deep scan allowed here: we are committed to this migration, so it is // worth finding the plugin even under an unexpected folder name. $baseName = $source->resolveBaseName(true); if (!$baseName || !$source->isActive()) { return ['deactivated' => false, 'result' => self::RESULT_NOT_ACTIVE]; } require_once ABSPATH . 'wp-admin/includes/plugin.php'; // Silent: the source plugin's own deactivation hooks must not run, this // is a handover and not the user walking away from the product. deactivate_plugins($baseName, true); return ['deactivated' => true, 'result' => self::RESULT_DEACTIVATED]; } /** * Send the source plugin's admin page to Buttonizer. * * Bookmarks and old menu links keep working after the plugin is gone, * the same way the acquired plugin already redirects its own pre-Buttonizer * settings page. * * @param SourcePlugin $source Source plugin descriptor. */ public static function redirectSourcePage(SourcePlugin $source): void { $pageSlug = $source->pageSlug(); if (!$pageSlug || !isset($_GET['page']) || $_GET['page'] !== $pageSlug) { return; } // While the source plugin is still active it serves its own page if ($source->isActive()) { return; } wp_safe_redirect(admin_url('admin.php?page=' . \Buttonizer\Core\PluginConfig::pageSlug())); exit; } /** * May the current user activate/deactivate plugins? */ public static function currentUserCanManagePlugins(): bool { return current_user_can(is_multisite() ? 'manage_options' : 'activate_plugins'); } }