getIdentity(); if (!$user->authorise('core.manage', 'com_plugins')) { $this->sendJson(403, ['error' => 'Not authorized']); return; } $db = Factory::getDbo(); $query = $db->getQuery(true) ->select([ $db->quoteName('extension_id'), $db->quoteName('name'), $db->quoteName('element'), $db->quoteName('folder'), $db->quoteName('type'), $db->quoteName('enabled'), $db->quoteName('protected'), $db->quoteName('manifest_cache'), ]) ->from($db->quoteName('#__extensions')) ->where([ '(' . '(' . $db->quoteName('type') . ' = ' . $db->quote('plugin') . ' AND ' . $db->quoteName('folder') . ' = ' . $db->quote('system') . ' AND (' . $db->quoteName('element') . ' = ' . $db->quote('mokosuiteclient') . ' OR ' . $db->quoteName('element') . ' LIKE ' . $db->quote('mokosuiteclient\\_%') . '))' . ' OR (' . $db->quoteName('type') . ' = ' . $db->quote('plugin') . ' AND ' . $db->quoteName('folder') . ' = ' . $db->quote('webservices') . ' AND ' . $db->quoteName('element') . ' = ' . $db->quote('mokosuiteclient') . ')' . ' OR (' . $db->quoteName('type') . ' = ' . $db->quote('plugin') . ' AND ' . $db->quoteName('folder') . ' = ' . $db->quote('task') . ' AND ' . $db->quoteName('element') . ' LIKE ' . $db->quote('mokosuiteclient%') . ')' . ')', ]) ->order($db->quoteName('folder') . ' ASC, ' . $db->quoteName('element') . ' ASC'); $db->setQuery($query); $rows = $db->loadObjectList() ?: []; $plugins = []; foreach ($rows as $row) { $manifest = json_decode($row->manifest_cache ?? '{}'); $plugins[] = [ 'extension_id' => (int) $row->extension_id, 'name' => $row->name, 'element' => $row->element, 'folder' => $row->folder, 'type' => $row->type, 'enabled' => (bool) $row->enabled, 'protected' => (bool) $row->protected, 'version' => $manifest->version ?? '', ]; } $this->sendJson(200, [ 'status' => 'ok', 'count' => \count($plugins), 'plugins' => $plugins, ]); } /** * Toggle a MokoSuiteClient feature plugin on or off. * * Expects JSON body: {"extension_id": 123, "enabled": true} * * @return void */ public function execute($task = 'plugins'): void { $app = Factory::getApplication(); $user = $app->getIdentity(); if (!$user->authorise('core.manage', 'com_plugins')) { $this->sendJson(403, ['error' => 'Not authorized']); return; } $input = json_decode(file_get_contents('php://input'), true); $extensionId = (int) ($input['extension_id'] ?? 0); $enabled = (bool) ($input['enabled'] ?? false); if (!$extensionId) { $this->sendJson(400, ['error' => 'Missing extension_id']); return; } $db = Factory::getDbo(); // Verify the extension exists and is a MokoSuiteClient plugin $query = $db->getQuery(true) ->select([$db->quoteName('element'), $db->quoteName('protected')]) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('extension_id') . ' = ' . $extensionId) ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')); $db->setQuery($query); $ext = $db->loadObject(); if (!$ext) { $this->sendJson(404, ['error' => 'Extension not found']); return; } // Don't allow disabling protected/core plugins if (!$enabled && ((int) $ext->protected || $ext->element === 'mokosuiteclient')) { $this->sendJson(409, ['error' => 'This plugin is protected and cannot be disabled']); return; } $query = $db->getQuery(true) ->update($db->quoteName('#__extensions')) ->set($db->quoteName('enabled') . ' = ' . ($enabled ? 1 : 0)) ->where($db->quoteName('extension_id') . ' = ' . $extensionId); $db->setQuery($query); $db->execute(); $this->sendJson(200, [ 'status' => 'ok', 'extension_id' => $extensionId, 'element' => $ext->element, 'enabled' => $enabled, ]); } private function sendJson(int $code, array $payload): void { $app = Factory::getApplication(); $app->setHeader('Content-Type', 'application/json', true); $app->setHeader('Status', (string) $code, true); echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); $app->close(); } }