57b48520af
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 9s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 9s
Universal: PR Check / Branch Policy (pull_request) Successful in 3s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 19s
Universal: PR Check / Validate PR (pull_request) Failing after 12s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Successful in 18s
Generic: Project CI / Lint & Validate (pull_request) Successful in 48s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 51s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 54s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 19s
Universal: Auto Version Bump / Version Bump (push) Successful in 14s
- registerGuidedTours() in script.php postflight registers Welcome and Firewall tours via Joomla's #__guidedtours/#__guidedtour_steps tables - Tours use com_mokosuiteclient.* UIDs, auto-update on package update - DevTools: reset_tour_prompts one-shot toggle clears all guided tour completion flags from #__user_profiles on save - Language keys added for tour reset field
222 lines
5.6 KiB
PHP
222 lines
5.6 KiB
PHP
<?php
|
|
/**
|
|
* @package MokoSuiteClient
|
|
* @subpackage plg_system_mokosuiteclient_devtools
|
|
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
|
* @license GNU General Public License version 3 or later; see LICENSE
|
|
*/
|
|
|
|
namespace Moko\Plugin\System\MokoSuiteClientDevTools\Extension;
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
use Joomla\CMS\Factory;
|
|
use Joomla\CMS\Log\Log;
|
|
use Joomla\CMS\Plugin\CMSPlugin;
|
|
use Joomla\Event\SubscriberInterface;
|
|
|
|
/**
|
|
* MokoSuiteClient Developer Tools Plugin
|
|
*
|
|
* Provides development mode (disables caching, enables debug), hit counter
|
|
* reset, and content version cleanup.
|
|
*
|
|
* @since 02.32.00
|
|
*/
|
|
class DevTools extends CMSPlugin implements SubscriberInterface
|
|
{
|
|
protected $autoloadLanguage = true;
|
|
|
|
public static function getSubscribedEvents(): array
|
|
{
|
|
return [
|
|
'onAfterInitialise' => 'onAfterInitialise',
|
|
'onExtensionAfterSave' => 'onExtensionAfterSave',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Apply dev mode settings at runtime.
|
|
*/
|
|
public function onAfterInitialise(): void
|
|
{
|
|
if (!$this->params->get('dev_mode', 0))
|
|
{
|
|
return;
|
|
}
|
|
|
|
$config = Factory::getConfig();
|
|
$config->set('caching', 0);
|
|
$config->set('debug', 1);
|
|
|
|
// Show offline page on primary domain
|
|
$primaryDomain = $this->params->get('primary_domain', '');
|
|
$currentHost = $_SERVER['HTTP_HOST'] ?? '';
|
|
|
|
if (!empty($primaryDomain) && $currentHost === $primaryDomain)
|
|
{
|
|
$config->set('offline', 1);
|
|
}
|
|
|
|
// Suppress hit recording via com_content's native parameter
|
|
try
|
|
{
|
|
$contentParams = \Joomla\CMS\Component\ComponentHelper::getParams('com_content');
|
|
$contentParams->set('record_hits', 0);
|
|
}
|
|
catch (\Throwable $e) {}
|
|
}
|
|
|
|
/**
|
|
* Handle maintenance actions when this plugin's params are saved.
|
|
*/
|
|
public function onExtensionAfterSave($event): void
|
|
{
|
|
// Joomla 6: single event object; Joomla 5: individual args
|
|
if (is_object($event) && method_exists($event, 'getArgument'))
|
|
{
|
|
$context = $event->getArgument('context', $event->getArgument(0, ''));
|
|
$table = $event->getArgument('subject', $event->getArgument(1, null));
|
|
}
|
|
else
|
|
{
|
|
$context = $event;
|
|
$table = func_get_arg(1);
|
|
}
|
|
|
|
if ($context !== 'com_plugins.plugin' || !$table)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Only process saves to this plugin
|
|
if (($table->element ?? '') !== 'mokosuiteclient_devtools' || ($table->folder ?? '') !== 'system')
|
|
{
|
|
return;
|
|
}
|
|
|
|
$params = new \Joomla\Registry\Registry($table->params ?? '{}');
|
|
|
|
// Reset hits on save if toggled on
|
|
if ($params->get('reset_hits', 0))
|
|
{
|
|
$this->resetAllHits();
|
|
$params->set('reset_hits', 0);
|
|
}
|
|
|
|
// Delete versions on save if toggled on
|
|
if ($params->get('delete_versions', 0))
|
|
{
|
|
$this->deleteAllVersions();
|
|
$params->set('delete_versions', 0);
|
|
}
|
|
|
|
// Reset download keys on save if toggled on
|
|
if ($params->get('reset_download_keys', 0))
|
|
{
|
|
$this->resetDownloadKeys();
|
|
$params->set('reset_download_keys', 0);
|
|
}
|
|
|
|
// Reset tour prompts on save if toggled on
|
|
if ($params->get('reset_tour_prompts', 0))
|
|
{
|
|
$this->resetTourPrompts();
|
|
$params->set('reset_tour_prompts', 0);
|
|
}
|
|
|
|
// Reset the one-shot toggles
|
|
if ($table->params !== $params->toString())
|
|
{
|
|
$db = Factory::getDbo();
|
|
$db->setQuery(
|
|
$db->getQuery(true)
|
|
->update($db->quoteName('#__extensions'))
|
|
->set($db->quoteName('params') . ' = ' . $db->quote($params->toString()))
|
|
->where($db->quoteName('extension_id') . ' = ' . (int) $table->extension_id)
|
|
)->execute();
|
|
}
|
|
}
|
|
|
|
private function resetAllHits(): int
|
|
{
|
|
$db = Factory::getDbo();
|
|
$db->setQuery(
|
|
$db->getQuery(true)
|
|
->update($db->quoteName('#__content'))
|
|
->set($db->quoteName('hits') . ' = 0')
|
|
->where($db->quoteName('hits') . ' > 0')
|
|
)->execute();
|
|
|
|
$count = $db->getAffectedRows();
|
|
$this->getApplication()->enqueueMessage(\sprintf('Reset hits on %d articles.', $count), 'message');
|
|
|
|
return $count;
|
|
}
|
|
|
|
private function deleteAllVersions(): int
|
|
{
|
|
$db = Factory::getDbo();
|
|
$db->setQuery(
|
|
$db->getQuery(true)->delete($db->quoteName('#__history'))
|
|
)->execute();
|
|
|
|
$count = $db->getAffectedRows();
|
|
$this->getApplication()->enqueueMessage(\sprintf('Deleted %d version history records.', $count), 'message');
|
|
|
|
return $count;
|
|
}
|
|
|
|
private function resetTourPrompts(): int
|
|
{
|
|
$db = Factory::getDbo();
|
|
$db->setQuery(
|
|
$db->getQuery(true)
|
|
->delete($db->quoteName('#__user_profiles'))
|
|
->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('guidedtours.tour%'))
|
|
)->execute();
|
|
|
|
$count = $db->getAffectedRows();
|
|
$this->getApplication()->enqueueMessage(\sprintf('Reset %d guided tour completion flags.', $count), 'message');
|
|
|
|
return $count;
|
|
}
|
|
|
|
private function resetDownloadKeys(): int
|
|
{
|
|
$db = Factory::getDbo();
|
|
|
|
// Find update sites that have a dlid in extra_query
|
|
$db->setQuery(
|
|
$db->getQuery(true)
|
|
->select([$db->quoteName('update_site_id'), $db->quoteName('extra_query')])
|
|
->from($db->quoteName('#__update_sites'))
|
|
->where($db->quoteName('extra_query') . ' LIKE ' . $db->quote('%dlid=%'))
|
|
);
|
|
|
|
$sites = $db->loadObjectList();
|
|
$count = 0;
|
|
|
|
foreach ($sites as $site)
|
|
{
|
|
// Parse the query string, remove dlid, rebuild
|
|
parse_str($site->extra_query, $parsed);
|
|
unset($parsed['dlid']);
|
|
$newQuery = http_build_query($parsed);
|
|
|
|
$db->setQuery(
|
|
$db->getQuery(true)
|
|
->update($db->quoteName('#__update_sites'))
|
|
->set($db->quoteName('extra_query') . ' = ' . $db->quote($newQuery))
|
|
->where($db->quoteName('update_site_id') . ' = ' . (int) $site->update_site_id)
|
|
)->execute();
|
|
|
|
$count++;
|
|
}
|
|
|
|
$this->getApplication()->enqueueMessage(\sprintf('Cleared download keys from %d update sites.', $count), 'message');
|
|
|
|
return $count;
|
|
}
|
|
}
|