- Add Schemas/theme-settings.json with analytics and custom_code groups - Add ThemeSettingsFormBuilder for Admin Panel UI - Add ThemeSettingsFieldMapper for AJAX field mapping - Add ThemeSettingsRenderer for injecting GA/CSS/JS - Add ThemeSettingsInjector for wp_head/wp_footer hooks - Register component in AdminDashboardRenderer::getComponents() - Register FieldMapper in FieldMapperProvider 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
166 lines
5.2 KiB
PHP
166 lines
5.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace ROITheme\Admin\Infrastructure\Ui;
|
|
|
|
use ROITheme\Admin\Domain\Contracts\DashboardRendererInterface;
|
|
use ROITheme\Shared\Application\UseCases\GetComponentSettings\GetComponentSettingsUseCase;
|
|
|
|
/**
|
|
* Renderiza el dashboard del panel de administración
|
|
*
|
|
* Infrastructure - Implementación con WordPress
|
|
*/
|
|
final class AdminDashboardRenderer implements DashboardRendererInterface
|
|
{
|
|
private const SUPPORTED_VIEWS = ['dashboard'];
|
|
|
|
/**
|
|
* @param GetComponentSettingsUseCase|null $getComponentSettingsUseCase
|
|
* @param array<string, mixed> $components Componentes disponibles
|
|
*/
|
|
public function __construct(
|
|
private readonly ?GetComponentSettingsUseCase $getComponentSettingsUseCase = null,
|
|
private readonly array $components = []
|
|
) {
|
|
}
|
|
|
|
public function render(): string
|
|
{
|
|
ob_start();
|
|
require __DIR__ . '/Views/dashboard.php';
|
|
return ob_get_clean();
|
|
}
|
|
|
|
public function supports(string $viewType): bool
|
|
{
|
|
return in_array($viewType, self::SUPPORTED_VIEWS, true);
|
|
}
|
|
|
|
/**
|
|
* Obtiene los componentes disponibles
|
|
*
|
|
* @return array<string, array<string, string>>
|
|
*/
|
|
public function getComponents(): array
|
|
{
|
|
return [
|
|
'top-notification-bar' => [
|
|
'id' => 'top-notification-bar',
|
|
'label' => 'TopBar',
|
|
'icon' => 'bi-megaphone-fill',
|
|
],
|
|
'navbar' => [
|
|
'id' => 'navbar',
|
|
'label' => 'Navbar',
|
|
'icon' => 'bi-list',
|
|
],
|
|
'cta-lets-talk' => [
|
|
'id' => 'cta-lets-talk',
|
|
'label' => "Let's Talk",
|
|
'icon' => 'bi-lightning-charge-fill',
|
|
],
|
|
'hero' => [
|
|
'id' => 'hero',
|
|
'label' => 'Hero Section',
|
|
'icon' => 'bi-image',
|
|
],
|
|
'featured-image' => [
|
|
'id' => 'featured-image',
|
|
'label' => 'Featured Image',
|
|
'icon' => 'bi-card-image',
|
|
],
|
|
'table-of-contents' => [
|
|
'id' => 'table-of-contents',
|
|
'label' => 'Table of Contents',
|
|
'icon' => 'bi-list-nested',
|
|
],
|
|
'cta-box-sidebar' => [
|
|
'id' => 'cta-box-sidebar',
|
|
'label' => 'CTA Sidebar',
|
|
'icon' => 'bi-megaphone',
|
|
],
|
|
'social-share' => [
|
|
'id' => 'social-share',
|
|
'label' => 'Social Share',
|
|
'icon' => 'bi-share',
|
|
],
|
|
'cta-post' => [
|
|
'id' => 'cta-post',
|
|
'label' => 'CTA Post',
|
|
'icon' => 'bi-megaphone-fill',
|
|
],
|
|
'related-post' => [
|
|
'id' => 'related-post',
|
|
'label' => 'Related Posts',
|
|
'icon' => 'bi-grid-3x3-gap',
|
|
],
|
|
'contact-form' => [
|
|
'id' => 'contact-form',
|
|
'label' => 'Contact Form',
|
|
'icon' => 'bi-envelope-paper',
|
|
],
|
|
'footer' => [
|
|
'id' => 'footer',
|
|
'label' => 'Footer',
|
|
'icon' => 'bi-layout-text-window-reverse',
|
|
],
|
|
'theme-settings' => [
|
|
'id' => 'theme-settings',
|
|
'label' => 'Theme Settings',
|
|
'icon' => 'bi-gear',
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Obtiene las configuraciones de un componente
|
|
*
|
|
* @param string $componentName Nombre del componente
|
|
* @return array<string, array<string, mixed>> Configuraciones agrupadas por grupo
|
|
*/
|
|
public function getComponentSettings(string $componentName): array
|
|
{
|
|
if ($this->getComponentSettingsUseCase === null) {
|
|
return [];
|
|
}
|
|
|
|
return $this->getComponentSettingsUseCase->execute($componentName);
|
|
}
|
|
|
|
/**
|
|
* Obtiene el valor de un campo de configuración
|
|
*
|
|
* @param string $componentName Nombre del componente
|
|
* @param string $groupName Nombre del grupo
|
|
* @param string $attributeName Nombre del atributo
|
|
* @param mixed $default Valor por defecto si no existe
|
|
* @return mixed
|
|
*/
|
|
public function getFieldValue(string $componentName, string $groupName, string $attributeName, mixed $default = null): mixed
|
|
{
|
|
$settings = $this->getComponentSettings($componentName);
|
|
|
|
return $settings[$groupName][$attributeName] ?? $default;
|
|
}
|
|
|
|
/**
|
|
* Obtiene la clase del FormBuilder para un componente
|
|
*
|
|
* @param string $componentId ID del componente en kebab-case (ej: 'top-notification-bar')
|
|
* @return string Namespace completo del FormBuilder
|
|
*/
|
|
public function getFormBuilderClass(string $componentId): string
|
|
{
|
|
// Convertir kebab-case a PascalCase
|
|
// 'top-notification-bar' → 'TopNotificationBar'
|
|
$className = str_replace('-', '', ucwords($componentId, '-'));
|
|
|
|
// Construir namespace completo
|
|
// ROITheme\Admin\TopNotificationBar\Infrastructure\Ui\TopNotificationBarFormBuilder
|
|
return "ROITheme\\Admin\\{$className}\\Infrastructure\\Ui\\{$className}FormBuilder";
|
|
}
|
|
|
|
}
|