* @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\Model; defined('_JEXEC') or die; use Joomla\CMS\Factory; use Joomla\CMS\Filter\OutputFilter; use Joomla\CMS\MVC\Model\AdminModel; class ServiceModel extends AdminModel { /** * Method to get the record form. * * @param array $data Data for the form * @param boolean $loadData True if the form is to load its own data * * @return \Joomla\CMS\Form\Form|boolean */ public function getForm($data = [], $loadData = true) { $form = $this->loadForm( 'com_mokosuitecross.service', 'service', ['control' => 'jform', 'load_data' => $loadData] ); if (empty($form)) { return false; } return $form; } /** * Method to get the data that should be injected in the form. * * Expands the JSON credentials column back into individual cred_* form fields * so they are populated when editing an existing service. * * @return mixed The data for the form */ protected function loadFormData() { $data = $this->getItem(); if ($data && !empty($data->credentials)) { $credentials = \Joomla\Component\MokoSuiteCross\Administrator\Helper\CredentialHelper::decrypt($data->credentials); $serviceType = $data->service_type ?? ''; foreach ($credentials as $key => $value) { // Map credential keys back to form field names. // The mode field has no service type prefix. if ($key === 'mode') { $data->cred_mode = $value; } else { $data->{'cred_' . $serviceType . '_' . $key} = $value; } } } return $data; } /** * Override save to collect cred_* form fields into the credentials JSON column. * * The service form has individual fields (cred_twitter_api_key, cred_facebook_page_id, etc.) * but the database stores them as a single JSON blob in the `credentials` column. * * @param array $data The form data * * @return boolean True on success */ public function save($data) { $serviceType = $data['service_type'] ?? ''; $credentials = []; $credPrefix = 'cred_'; // Collect all cred_* fields into the credentials array foreach ($data as $key => $value) { if (strpos($key, $credPrefix) !== 0) { continue; } $credKey = substr($key, strlen($credPrefix)); // The mode field is shared across service types (no service_type prefix) if ($credKey === 'mode') { $credentials['mode'] = $value; } elseif ($serviceType && strpos($credKey, $serviceType . '_') === 0) { // Strip the service_type prefix: cred_twitter_api_key -> api_key $strippedKey = substr($credKey, strlen($serviceType) + 1); $credentials[$strippedKey] = $value; } } // Store credentials encrypted $data['credentials'] = !empty($credentials) ? \Joomla\Component\MokoSuiteCross\Administrator\Helper\CredentialHelper::encrypt($credentials) : '{}'; // Remove individual cred_* fields so they don't cause column-not-found errors foreach (array_keys($data) as $key) { if (strpos($key, $credPrefix) === 0) { unset($data[$key]); } } return parent::save($data); } }