* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved. * @license GNU General Public License version 3 or later; see LICENSE * SPDX-License-Identifier: GPL-3.0-or-later */ namespace Joomla\Component\MokoSuiteCross\Administrator\Controller; defined('_JEXEC') or die; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Controller\FormController; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Response\JsonResponse; use Joomla\Component\MokoSuiteCross\Administrator\Service\MokoSuiteCrossServiceInterface; class ServiceController extends FormController { /** * Test connection to a service by validating its credentials. * * @return void */ public function testConnection(): void { $this->checkToken(); if (!$this->app->getIdentity()->authorise('core.manage', 'com_mokosuitecross')) { throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); } $app = $this->app; $id = (int) $this->input->getInt('id', 0); try { if ($id <= 0) { throw new \RuntimeException(Text::_('COM_MOKOSUITECROSS_TEST_CONNECTION_NO_SERVICE')); } // Load the service record $db = Factory::getDbo(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__mokosuitecross_services')) ->where($db->quoteName('id') . ' = ' . $id); $db->setQuery($query); $service = $db->loadObject(); if (!$service) { throw new \RuntimeException(Text::_('COM_MOKOSUITECROSS_TEST_CONNECTION_NOT_FOUND')); } // Get service plugins via dispatcher (Joomla 5+ Event ArrayAccess pattern) PluginHelper::importPlugin('mokosuitecross'); $servicePlugins = []; $event = new \Joomla\Event\Event('onMokoSuiteCrossGetServices', [$servicePlugins]); $app->getDispatcher()->dispatch('onMokoSuiteCrossGetServices', $event); $idx = 1; while (isset($event[$idx])) { $servicePlugins[] = $event[$idx]; $idx++; } // Find the matching plugin $plugin = null; foreach ($servicePlugins as $sp) { if ($sp instanceof MokoSuiteCrossServiceInterface && $sp->getServiceType() === $service->service_type) { $plugin = $sp; break; } } if (!$plugin) { throw new \RuntimeException(Text::sprintf('COM_MOKOSUITECROSS_TEST_CONNECTION_NO_PLUGIN', $service->service_type)); } // Decode credentials and validate $credentials = \Joomla\Component\MokoSuiteCross\Administrator\Helper\CredentialHelper::decrypt($service->credentials ?: ''); $result = $plugin->validateCredentials($credentials); $app->mimeType = 'application/json'; $app->setHeader('Content-Type', 'application/json; charset=utf-8'); echo new JsonResponse($result); } catch (\Throwable $e) { $app->mimeType = 'application/json'; $app->setHeader('Content-Type', 'application/json; charset=utf-8'); echo new JsonResponse(['error' => $e->getMessage()]); } $app->close(); } }