feat(api): implement javascript-first architecture for cache compatibility
- Add REST endpoint GET /roi-theme/v1/adsense-placement/visibility - Add Domain layer: UserContext, VisibilityDecision, AdsenseSettings VOs - Add Application layer: CheckAdsenseVisibilityUseCase - Add Infrastructure: AdsenseVisibilityChecker, Controller, Enqueuer - Add JavaScript controller with localStorage caching - Add test plan for production validation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ROITheme\Public\AdsensePlacement\Infrastructure\Ui;
|
||||
|
||||
use ROITheme\Shared\Domain\Contracts\ComponentSettingsRepositoryInterface;
|
||||
use ROITheme\Public\AdsensePlacement\Infrastructure\Api\WordPress\AdsenseVisibilityController;
|
||||
|
||||
/**
|
||||
* Encola los assets JavaScript para el modo JavaScript-First de AdSense.
|
||||
*
|
||||
* Infrastructure Layer - Integra con WordPress asset system.
|
||||
*
|
||||
* @package ROITheme\Public\AdsensePlacement\Infrastructure\Ui
|
||||
*/
|
||||
final class AdsenseAssetsEnqueuer
|
||||
{
|
||||
private const COMPONENT_NAME = 'adsense-placement';
|
||||
private const SCRIPT_HANDLE = 'roi-adsense-visibility';
|
||||
private const SCRIPT_VERSION = '1.0.0';
|
||||
|
||||
public function __construct(
|
||||
private ComponentSettingsRepositoryInterface $settingsRepository
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Registra el hook para encolar scripts.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
add_action('wp_enqueue_scripts', [$this, 'enqueueScripts']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encola el script de visibilidad si el modo JS-First esta activo.
|
||||
*/
|
||||
public function enqueueScripts(): void
|
||||
{
|
||||
// Verificar si el modo JS-First esta activo
|
||||
if (!$this->isJavascriptFirstModeEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Solo en frontend, no en admin
|
||||
if (is_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scriptPath = $this->getScriptPath();
|
||||
|
||||
// Verificar que el archivo existe
|
||||
if (!file_exists($scriptPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scriptUrl = $this->getScriptUrl();
|
||||
|
||||
wp_enqueue_script(
|
||||
self::SCRIPT_HANDLE,
|
||||
$scriptUrl,
|
||||
[], // Sin dependencias
|
||||
self::SCRIPT_VERSION,
|
||||
true // En footer
|
||||
);
|
||||
|
||||
// Pasar configuracion al script
|
||||
wp_localize_script(self::SCRIPT_HANDLE, 'roiAdsenseConfig', $this->getScriptConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica si el modo JavaScript-First esta activo.
|
||||
*/
|
||||
private function isJavascriptFirstModeEnabled(): bool
|
||||
{
|
||||
$settings = $this->settingsRepository->getComponentSettings(self::COMPONENT_NAME);
|
||||
|
||||
$isEnabled = (bool) ($settings['visibility']['is_enabled'] ?? false);
|
||||
$jsFirstMode = (bool) ($settings['behavior']['javascript_first_mode'] ?? false);
|
||||
|
||||
return $isEnabled && $jsFirstMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene la ruta fisica del script.
|
||||
*/
|
||||
private function getScriptPath(): string
|
||||
{
|
||||
return get_template_directory() . '/Public/AdsensePlacement/Infrastructure/Ui/Assets/adsense-visibility.js';
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene la URL del script.
|
||||
*/
|
||||
private function getScriptUrl(): string
|
||||
{
|
||||
return get_template_directory_uri() . '/Public/AdsensePlacement/Infrastructure/Ui/Assets/adsense-visibility.js';
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene la configuracion para pasar al script.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function getScriptConfig(): array
|
||||
{
|
||||
$postId = $this->getCurrentPostId();
|
||||
$settings = $this->settingsRepository->getComponentSettings(self::COMPONENT_NAME);
|
||||
|
||||
return [
|
||||
'endpoint' => rest_url('roi-theme/v1/adsense-placement/visibility'),
|
||||
'postId' => $postId,
|
||||
'nonce' => wp_create_nonce(AdsenseVisibilityController::getNonceAction()),
|
||||
'settingsVersion' => $settings['_meta']['version'] ?? '1.0.0',
|
||||
'debug' => defined('WP_DEBUG') && WP_DEBUG,
|
||||
'featureEnabled' => true,
|
||||
'fallbackStrategy' => 'cached-or-show', // cached-or-show | cached-or-hide | always-show
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene el ID del post actual (0 si no es un post singular).
|
||||
*/
|
||||
private function getCurrentPostId(): int
|
||||
{
|
||||
if (is_singular()) {
|
||||
return get_the_ID() ?: 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user