Vervolg op v2.6.6: vier plekken lazen nog ruwe enabled_plugins zonder essential-forcering. handleDashboard(), handleContentFiles/Edit() en AdminPluginAPI::getEnabledPlugins() forceren nu essential plugins consistent met PluginManager. Dode functie countEnabledPlugins() verwijderd. AGENTS.md aangevuld met verplichte docblock-sectie.
254 lines
7.6 KiB
PHP
254 lines
7.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Lichtgewicht API-wrapper voor plugins in de admin-context.
|
|
*
|
|
* Biedt alleen-lezen toegang tot de site-config (zonder CMS-instance nodig).
|
|
*
|
|
* @since 2.6.5
|
|
*/
|
|
class AdminPluginAPI implements PluginAPIInterface
|
|
{
|
|
/**
|
|
* De site-configuratie als associatieve array.
|
|
*
|
|
* @since 2.6.5
|
|
* @var array<string,mixed>
|
|
*/
|
|
private array $config;
|
|
|
|
/**
|
|
* Het absolute pad naar de project-root.
|
|
*
|
|
* @since 2.6.5
|
|
* @var string
|
|
*/
|
|
private string $projectRoot;
|
|
|
|
/**
|
|
* De actieve admin-taalcode (bijv. 'nl', 'en').
|
|
*
|
|
* @since 2.6.5
|
|
* @var string
|
|
*/
|
|
private string $adminLanguage;
|
|
|
|
/**
|
|
* De admin PluginManager-instantie, optioneel via setPluginManager geïnjecteerd.
|
|
*
|
|
* @since 2.6.5
|
|
* @var PluginManager|null
|
|
*/
|
|
private ?PluginManager $pluginManager = null;
|
|
|
|
/**
|
|
* Construeer een AdminPluginAPI-instantie met de opgegeven site-config.
|
|
*
|
|
* @since 2.6.5
|
|
*
|
|
* @param array<string,mixed> $siteConfig De site-configuratie.
|
|
* @param string $projectRoot Optioneel absoluut pad naar de project-root.
|
|
*/
|
|
public function __construct(array $siteConfig, string $projectRoot = '')
|
|
{
|
|
$this->config = $siteConfig;
|
|
$this->projectRoot = $projectRoot !== '' ? $projectRoot : dirname(__DIR__, 3);
|
|
$this->adminLanguage = $siteConfig['admin_language']
|
|
?? ($siteConfig['language']['default'] ?? 'nl');
|
|
}
|
|
|
|
/**
|
|
* Injecteer de admin PluginManager zodat plugins hun eigen vertalingen
|
|
* via dezelfde fallback-keten kunnen resolven.
|
|
*
|
|
* @since 2.6.5
|
|
*
|
|
* @param PluginManager $pm De admin PluginManager-instantie.
|
|
* @return void
|
|
*/
|
|
public function setPluginManager(PluginManager $pm): void
|
|
{
|
|
$this->pluginManager = $pm;
|
|
}
|
|
|
|
/**
|
|
* Haal een configuratiewaarde op via dot-notatie.
|
|
*
|
|
* @since 2.6.5
|
|
*
|
|
* @param string $key Configuratie-sleutel in dot-notatie (bijv. 'language.default').
|
|
* @param mixed $default Standaardwaarde indien de sleutel niet bestaat.
|
|
* @return mixed De gevonden waarde of $default indien niet gevonden.
|
|
*/
|
|
public function getConfig(string $key, $default = null)
|
|
{
|
|
$keys = explode('.', $key);
|
|
$value = $this->config;
|
|
|
|
foreach ($keys as $k) {
|
|
if (!is_array($value) || !isset($value[$k])) {
|
|
return $default;
|
|
}
|
|
$value = $value[$k];
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* Haal de project-rootdirectory op.
|
|
*
|
|
* @since 2.6.5
|
|
*
|
|
* @return string Absoluut pad naar de project-root.
|
|
*/
|
|
public function getProjectRoot(): string
|
|
{
|
|
return $this->projectRoot;
|
|
}
|
|
|
|
/**
|
|
* Haal het pad naar de contentdirectory op als absoluut pad.
|
|
*
|
|
* Relatieve paden uit config.json (bijv. 'content') worden afgezet tegen
|
|
* de project-root, conform het gedrag van cms/core/config.php.
|
|
*
|
|
* @since 2.6.5
|
|
*
|
|
* @return string Absoluut pad naar de contentdirectory.
|
|
*/
|
|
public function getContentDir(): string
|
|
{
|
|
$dir = $this->config['content_dir'] ?? ($this->projectRoot . '/content');
|
|
if ($dir !== '' && $dir[0] !== DIRECTORY_SEPARATOR && !preg_match('#^[A-Za-z]:[/\\\\]#', $dir)) {
|
|
$dir = $this->projectRoot . '/' . $dir;
|
|
}
|
|
return rtrim($dir, '/');
|
|
}
|
|
|
|
/**
|
|
* Haal het pad naar de pluginsdirectory op.
|
|
*
|
|
* @since 2.6.5
|
|
*
|
|
* @return string Absoluut pad naar de pluginsdirectory.
|
|
*/
|
|
public function getPluginsDir(): string
|
|
{
|
|
return $this->projectRoot . '/plugins';
|
|
}
|
|
|
|
/**
|
|
* Haal de lijst met ingeschakelde plugins op.
|
|
*
|
|
* Essential plugins (plugin.json `essential: true`) worden altijd
|
|
* geretourneerd, ook als ze niet in config.enabled_plugins staan, en
|
|
* komen consistent met de PluginManager op de eerste positie. Als de
|
|
* PluginManager is geïnjecteerd wordt dien geautoriseerde lijst
|
|
* gebruikt (single source of truth); anders valt de methode terug op
|
|
* config.enabled_plugins aangevuld met een lokale essential-scan.
|
|
*
|
|
* @since 2.6.5
|
|
*
|
|
* @return array<int,string> Lijst met ingeschakelde plugin-namen.
|
|
*/
|
|
public function getEnabledPlugins(): array
|
|
{
|
|
if ($this->pluginManager !== null) {
|
|
return $this->pluginManager->getEnabledPlugins();
|
|
}
|
|
$enabled = $this->config['enabled_plugins'] ?? [];
|
|
if (!is_array($enabled)) {
|
|
$enabled = [];
|
|
}
|
|
// Fallback: essential plugins forceren als de PluginManager niet
|
|
// geïnjecteerd is (houdt de lijst consistent met loadPlugins()).
|
|
$pluginsDir = $this->projectRoot . '/plugins';
|
|
if (is_dir($pluginsDir)) {
|
|
foreach (glob($pluginsDir . '/*', GLOB_ONLYDIR) as $pluginDir) {
|
|
$pluginName = basename($pluginDir);
|
|
$pluginJsonFile = $pluginDir . '/plugin.json';
|
|
if (!file_exists($pluginJsonFile)) {
|
|
continue;
|
|
}
|
|
$data = json_decode(file_get_contents($pluginJsonFile), true);
|
|
if (is_array($data) && ($data['essential'] ?? false) === true
|
|
&& !in_array($pluginName, $enabled, true)
|
|
) {
|
|
$enabled[] = $pluginName;
|
|
}
|
|
}
|
|
}
|
|
return array_values($enabled);
|
|
}
|
|
|
|
/**
|
|
* Haal de versie-informatie uit version.php op.
|
|
*
|
|
* @since 2.6.5
|
|
*
|
|
* @return array<string,mixed> Versie-informatie met minimaal de sleutel 'version'.
|
|
*/
|
|
public function getVersionInfo(): array
|
|
{
|
|
$versionFile = $this->projectRoot . '/version.php';
|
|
if (file_exists($versionFile)) {
|
|
$data = include $versionFile;
|
|
if (is_array($data)) {
|
|
return $data;
|
|
}
|
|
}
|
|
return ['version' => '0.0.0'];
|
|
}
|
|
|
|
/**
|
|
* Haal de actieve admin-taalcode op (bijv. 'nl', 'en').
|
|
*
|
|
* System-plugins gebruiken deze om hun vertalingen te resolven.
|
|
*
|
|
* @since 2.6.5
|
|
*
|
|
* @return string De actieve admin-taalcode.
|
|
*/
|
|
public function getAdminLanguage(): string
|
|
{
|
|
return $this->adminLanguage;
|
|
}
|
|
|
|
/**
|
|
* Haal de vertalingen voor een plugin op in de admin-context.
|
|
*
|
|
* Fallback-keten (afgehandeld door PluginManager):
|
|
* aangevraagde taal -> default_language van de plugin -> lege array.
|
|
*
|
|
* @since 2.6.5
|
|
*
|
|
* @param string $pluginName Plugin-directorynaam.
|
|
* @param string|null $lang Override-taal; standaard de actieve admin-taal.
|
|
* @return array<string,string> Vertalingen als [key => value].
|
|
*/
|
|
public function getPluginTranslations(string $pluginName, ?string $lang = null): array
|
|
{
|
|
if ($this->pluginManager === null) {
|
|
return [];
|
|
}
|
|
$lang = $lang ?? $this->adminLanguage;
|
|
return $this->pluginManager->getPluginTranslations($pluginName, $lang, 'admin');
|
|
}
|
|
|
|
/**
|
|
* Vertaal een enkele sleutel voor een plugin in de admin-context.
|
|
*
|
|
* @since 2.6.5
|
|
*
|
|
* @param string $key Vertaalsleutel.
|
|
* @param string $pluginName Plugin-directorynaam.
|
|
* @param string|null $lang Override-taal; standaard de actieve admin-taal.
|
|
* @return string Vertaalde string, of $key indien niet gevonden.
|
|
*/
|
|
public function t(string $key, string $pluginName, ?string $lang = null): string
|
|
{
|
|
$t = $this->getPluginTranslations($pluginName, $lang);
|
|
return $t[$key] ?? $key;
|
|
}
|
|
} |