Skip to content

Commit

Permalink
Add uninstall option to modules
Browse files Browse the repository at this point in the history
  • Loading branch information
samerton committed Oct 1, 2023
1 parent 9ef6dd0 commit 832cfe9
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 5 deletions.
4 changes: 2 additions & 2 deletions core/classes/Core/Util.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ public static function cyrillicToLatin(string $string): string {
* @return bool Whether the action succeeded or not.
*/
public static function recursiveRemoveDirectory(string $directory): bool {
// safety precaution, only allow deleting files in "custom" directory
if (!str_contains($directory, 'custom')) {
// safety precaution, only allow deleting files in "custom" or "modules" directory
if (str_contains($directory, "Core") || !str_contains($directory, 'custom') || !str_contains($directory, 'modules')) {
return false;
}

Expand Down
4 changes: 4 additions & 0 deletions custom/languages/en_UK.json
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@
"admin/type": "Type",
"admin/type_required": "A type is required",
"admin/unable_to_delete_group": "Unable to delete a default group, or a group that can view the StaffCP. Please update the group settings first!",
"admin/unable_to_delete_module_files": "Unable to fully delete module. Please check file permissions.",
"admin/unable_to_delete_template": "Unable to fully delete template. Please check file permissions.",
"admin/unable_to_disable_module": "Unable to disable module - the module {{module}} depends on it.",
"admin/unable_to_enable_module": "Unable to enable incompatible module.",
Expand All @@ -687,7 +688,10 @@
"admin/unable_to_retrieve_modules": "Unable to retrieve modules",
"admin/unable_to_retrieve_nameless_news": "Unable to retrieve the latest news",
"admin/unable_to_retrieve_templates": "Unable to retrieve templates",
"admin/unable_to_uninstall_module": "Unable to uninstall module - the module {{module}} depends on it.",
"admin/unknown": "Unknown",
"admin/uninstall": "Uninstall",
"admin/uninstall_confirm": "Are you sure you want to uninstall {{item}}?",
"admin/unlink": "Unlink",
"admin/unlink_account_confirm": "Are you sure you want to forcibly unlink this provider from this user?",
"admin/unlink_account_success": "Successfully unlinked their account from {{provider}}.",
Expand Down
40 changes: 38 additions & 2 deletions custom/panel_templates/Default/core/modules.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
<div class="float-md-right">
{if $module.enabled}
{if $module.disable_link}
<form action="{$module.disable_link}" method="post">
<form action="{$module.disable_link}" method="post" style="display:inline">
<input type="hidden" name="token" value="{$TOKEN}" />
<input type="submit" class="btn btn-danger btn-sm"
value="{$DISABLE}" />
Expand All @@ -77,12 +77,17 @@
class="fa fa-lock"></i></a>
{/if}
{else}
<form action="{$module.enable_link}" method="post">
<form action="{$module.enable_link}" method="post" style="display:inline">
<input type="hidden" name="token" value="{$TOKEN}" />
<input type="submit" class="btn btn-primary btn-sm"
value="{$ENABLE}" />
</form>
{/if}
{if $module.uninstall_link}
<button class="btn btn-danger btn-sm" onclick="uninstallModule('{$module.uninstall_link}', '{$module.confirm_uninstall}')" style="display:inline">
{$UNINSTALL}
</button>
{/if}
</div>
</td>
</tr>
Expand Down Expand Up @@ -168,6 +173,29 @@
<!-- End Content Wrapper -->
</div>

<div class="modal fade" id="uninstallModuleModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{$UNINSTALL}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<form action="" method="post" id="uninstallModuleForm">
<div class="modal-body">
<p id="confirmUninstallModule"></p>
</div>
<div class="modal-footer">
<input type="hidden" name="token" value="{$TOKEN}">
<button type="button" class="btn btn-secondary" data-dismiss="modal">{$CANCEL}</button>
<input type="submit" class="btn btn-primary" value="{$UNINSTALL}">
</div>
</form>
</div>
</div>
</div>

<!-- End Wrapper -->
</div>

Expand All @@ -191,6 +219,14 @@
SetRatingStar();
</script>

<script type="text/javascript">
function uninstallModule(action, confirmationText) {
$('#uninstallModuleForm').attr('action', action);
$('#confirmUninstallModule').html(confirmationText);
$('#uninstallModuleModal').modal().show();
}
</script>

</body>

</html>
65 changes: 64 additions & 1 deletion modules/Core/pages/panel/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
}

try {
/** @var Module $module */
require_once ROOT_PATH . '/modules/' . $item->name . '/init.php';
} catch (Exception $e) {
$term = 'unable_to_load_module';
Expand Down Expand Up @@ -74,6 +75,8 @@
'actualVersion' => Text::bold(NAMELESS_VERSION)
]) : false,
'disable_link' => (($module->getName() != 'Core' && $item->enabled) ? URL::build('/panel/core/modules/', 'action=disable&m=' . urlencode($item->id)) : null),
'uninstall_link' => ($module->getName() != 'Core' ? URL::build('/panel/core/modules/', 'action=uninstall&m=' . urlencode($item->id)) : null),
'confirm_uninstall' => $language->get('admin', 'uninstall_confirm', ['item' => Output::getClean($module->getName())]),
'enable_link' => (($module->getName() != 'Core' && !$item->enabled) ? URL::build('/panel/core/modules/', 'action=enable&m=' . urlencode($item->id)) : null),
'enabled' => $item->enabled
];
Expand Down Expand Up @@ -133,6 +136,7 @@
'AUTHOR' => $language->get('admin', 'author'),
'ENABLE' => $language->get('admin', 'enable'),
'DISABLE' => $language->get('admin', 'disable'),
'UNINSTALL' => $language->get('admin', 'uninstall'),
'MODULE_LIST' => $template_array,
'FIND_MODULES' => $language->get('admin', 'find_modules'),
'WEBSITE_MODULES' => $all_modules,
Expand Down Expand Up @@ -333,6 +337,64 @@

Redirect::to(URL::build('/panel/core/modules'));
}

if ($_GET['action'] === 'uninstall') {
// Disable a module
if (!isset($_GET['m']) || !is_numeric($_GET['m']) || $_GET['m'] == 1) {
die('Invalid module!');
}

if (Token::check($_POST['token'])) {
// Get module name
$name = DB::getInstance()->get('modules', ['id', $_GET['m']])->results();
$name = Output::getClean($name[0]->name);

foreach (Module::getModules() as $item) {
if (in_array($name, $item->getLoadAfter())) {
// Unable to disable module
Session::flash('admin_modules_error', $language->get('admin', 'unable_to_uninstall_module', ['module' => Output::getClean($item->getName())]));
Redirect::to(URL::build('/panel/core/modules'));
}
}

DB::getInstance()->delete('modules', [
'id' => $_GET['m'],
]);

// Cache
$cache->setCache('modulescache');
$modules = [];

$order = Module::determineModuleOrder();

foreach ($order['modules'] as $key => $item) {
if ($item != $name) {
$modules[] = [
'name' => $item,
'priority' => $key
];
}
}

// Store
$cache->store('enabled_modules', $modules);

if (file_exists(ROOT_PATH . '/modules/' . $name . '/init.php')) {
/** @var Module $module */
require_once(ROOT_PATH . '/modules/' . $name . '/init.php');
$module->onUninstall();
}

if (!Util::recursiveRemoveDirectory(ROOT_PATH . '/modules/' . $name)) {
Session::flash('admin_modules_error', $language->get('admin', 'unable_to_delete_module_files'));
}

Session::flash('admin_modules', $language->get('admin', 'module_uninstalled'));

} else {
Session::flash('admin_modules_error', $language->get('general', 'invalid_token'));
}
}
}

if (Session::exists('admin_modules')) {
Expand Down Expand Up @@ -367,7 +429,8 @@
'MODULES' => $language->get('admin', 'modules'),
'PAGE' => PANEL_PAGE,
'TOKEN' => Token::get(),
'SUBMIT' => $language->get('general', 'submit')
'SUBMIT' => $language->get('general', 'submit'),
'CANCEL' => $language->get('general', 'cancel'),
]);

$template->onPageLoad();
Expand Down

0 comments on commit 832cfe9

Please sign in to comment.