feat: dynamic plugin version + plugin protection (no lock)
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Successful in 28s
Joomla: Repo Health / Release configuration (push) Has been cancelled
Joomla: Repo Health / Scripts governance (push) Has been cancelled
Joomla: Repo Health / Repository health (push) Has been cancelled
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Successful in 28s
Joomla: Repo Health / Release configuration (push) Has been cancelled
Joomla: Repo Health / Scripts governance (push) Has been cancelled
Joomla: Repo Health / Repository health (push) Has been cancelled
- Read plugin_version from manifest XML instead of hardcoding - Hide MokoWaaS from plugin/installer list for non-master users - Block non-master uninstall and disable attempts - No self-healing lock — master users can still disable if needed Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -65,6 +65,39 @@ class MokoWaaS extends CMSPlugin
|
||||
*/
|
||||
private const HEARTBEAT_KEY = 'moko-waas-hb-2026-x9k4m';
|
||||
|
||||
/**
|
||||
* Get the plugin version from the manifest XML.
|
||||
*
|
||||
* @return string Version string (e.g. '02.03.04')
|
||||
*
|
||||
* @since 02.03.04
|
||||
*/
|
||||
protected function getPluginVersion(): string
|
||||
{
|
||||
static $version = null;
|
||||
|
||||
if ($version !== null)
|
||||
{
|
||||
return $version;
|
||||
}
|
||||
|
||||
$manifestFile = JPATH_PLUGINS . '/system/mokowaas/mokowaas.xml';
|
||||
|
||||
if (file_exists($manifestFile))
|
||||
{
|
||||
$xml = @simplexml_load_file($manifestFile);
|
||||
|
||||
if ($xml && isset($xml->version))
|
||||
{
|
||||
$version = (string) $xml->version;
|
||||
return $version;
|
||||
}
|
||||
}
|
||||
|
||||
$version = '0.0.0';
|
||||
return $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the language file on instantiation.
|
||||
*
|
||||
@@ -869,6 +902,7 @@ class MokoWaaS extends CMSPlugin
|
||||
}
|
||||
|
||||
$this->enforceAdminRestrictions();
|
||||
$this->protectPlugin();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -902,6 +936,134 @@ class MokoWaaS extends CMSPlugin
|
||||
}
|
||||
|
||||
$this->injectFavicon($doc);
|
||||
|
||||
// Hide MokoWaaS from plugin list for non-master users
|
||||
if (!$this->isMasterUser())
|
||||
{
|
||||
$this->hidePluginFromList($doc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide MokoWaaS plugin and package from the extensions list via JS.
|
||||
*
|
||||
* @param \Joomla\CMS\Document\HtmlDocument $doc Document object
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 02.03.04
|
||||
*/
|
||||
protected function hidePluginFromList($doc)
|
||||
{
|
||||
$option = $this->app->input->get('option', '');
|
||||
$view = $this->app->input->get('view', '');
|
||||
|
||||
if ($option !== 'com_plugins' && $option !== 'com_installer')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$doc->addScriptDeclaration("
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.querySelectorAll('tr').forEach(function(row) {
|
||||
var text = row.textContent || '';
|
||||
if (text.indexOf('mokowaas') !== -1 || text.indexOf('MokoWaaS') !== -1) {
|
||||
row.style.display = 'none';
|
||||
}
|
||||
});
|
||||
});
|
||||
");
|
||||
}
|
||||
|
||||
/**
|
||||
* Protect the plugin from being disabled or uninstalled by non-master users.
|
||||
* Does NOT self-heal (no lock) — master users can still disable if needed.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 02.03.04
|
||||
*/
|
||||
protected function protectPlugin()
|
||||
{
|
||||
if ($this->isMasterUser())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$option = $this->app->input->get('option', '');
|
||||
$task = $this->app->input->get('task', '');
|
||||
|
||||
// Block non-master from disabling or uninstalling MokoWaaS
|
||||
if ($option === 'com_installer' && strpos($task, 'manage.remove') !== false)
|
||||
{
|
||||
$cid = $this->app->input->get('cid', [], 'array');
|
||||
|
||||
if ($this->isOurExtension($cid))
|
||||
{
|
||||
$this->app->enqueueMessage('MokoWaaS cannot be uninstalled.', 'error');
|
||||
$this->app->redirect('index.php?option=com_installer&view=manage');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any of the given extension IDs belong to MokoWaaS.
|
||||
*
|
||||
* @param array $ids Extension IDs to check
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 02.03.04
|
||||
*/
|
||||
protected function isOurExtension(array $ids): bool
|
||||
{
|
||||
if (empty($ids))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select('COUNT(*)')
|
||||
->from($db->quoteName('#__extensions'))
|
||||
->where($db->quoteName('extension_id') . ' IN (' . implode(',', array_map('intval', $ids)) . ')')
|
||||
->where('(' . $db->quoteName('element') . ' = ' . $db->quote('mokowaas')
|
||||
. ' OR ' . $db->quoteName('element') . ' = ' . $db->quote('pkg_mokowaas') . ')');
|
||||
|
||||
return (int) $db->setQuery($query)->loadResult() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent non-master users from disabling the plugin via save.
|
||||
*
|
||||
* @param string $context Extension context
|
||||
* @param object $table Extension table row
|
||||
* @param bool $isNew Whether this is a new record
|
||||
*
|
||||
* @return bool False to cancel save
|
||||
*
|
||||
* @since 02.03.04
|
||||
*/
|
||||
public function onExtensionBeforeSave($context, $table, $isNew)
|
||||
{
|
||||
if ($context !== 'com_plugins.plugin')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($table->element !== 'mokowaas' || $table->folder !== 'system')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Non-master users cannot disable the plugin
|
||||
if (!$this->isMasterUser() && (int) $table->enabled === 0)
|
||||
{
|
||||
$this->app->enqueueMessage('MokoWaaS cannot be disabled.', 'error');
|
||||
$table->enabled = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1301,7 +1463,7 @@ class MokoWaaS extends CMSPlugin
|
||||
'users' => $users,
|
||||
'extensions' => $extensions,
|
||||
'brand' => $this->params->get('brand_name', 'MokoWaaS'),
|
||||
'plugin_version' => '02.01.39',
|
||||
'plugin_version' => $this->getPluginVersion(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1455,7 +1617,7 @@ class MokoWaaS extends CMSPlugin
|
||||
|
||||
return [
|
||||
'brand' => $this->params->get('brand_name', 'MokoWaaS'),
|
||||
'plugin_version' => '02.01.22',
|
||||
'plugin_version' => $this->getPluginVersion(),
|
||||
'joomla_version' => JVERSION,
|
||||
'php_version' => PHP_VERSION,
|
||||
'server_name' => $config->get('sitename', ''),
|
||||
|
||||
Reference in New Issue
Block a user