- 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>
122 lines
3.9 KiB
PHP
122 lines
3.9 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace ROITheme\Public\AdsensePlacement\Infrastructure\Services;
|
|
|
|
use ROITheme\Public\AdsensePlacement\Domain\Contracts\AdsenseVisibilityCheckerInterface;
|
|
use ROITheme\Public\AdsensePlacement\Domain\ValueObjects\UserContext;
|
|
use ROITheme\Public\AdsensePlacement\Domain\ValueObjects\VisibilityDecision;
|
|
use ROITheme\Public\AdsensePlacement\Domain\ValueObjects\AdsenseSettings;
|
|
use ROITheme\Shared\Domain\Contracts\ComponentSettingsRepositoryInterface;
|
|
|
|
/**
|
|
* Implementacion del checker de visibilidad de AdSense.
|
|
*
|
|
* Infrastructure Layer - Accede a BD via repository.
|
|
*
|
|
* @package ROITheme\Public\AdsensePlacement\Infrastructure\Services
|
|
*/
|
|
final class AdsenseVisibilityChecker implements AdsenseVisibilityCheckerInterface
|
|
{
|
|
private const COMPONENT_NAME = 'adsense-placement';
|
|
private const CACHE_SECONDS_SHOW = 300; // 5 min cuando se muestran ads
|
|
private const CACHE_SECONDS_HIDE = 600; // 10 min cuando se ocultan (menos volatil)
|
|
|
|
public function __construct(
|
|
private ComponentSettingsRepositoryInterface $settingsRepository
|
|
) {
|
|
}
|
|
|
|
public function check(int $postId, UserContext $userContext): VisibilityDecision
|
|
{
|
|
// Cargar configuracion desde BD
|
|
$rawSettings = $this->settingsRepository->getComponentSettings(self::COMPONENT_NAME);
|
|
$settings = AdsenseSettings::fromArray($rawSettings);
|
|
|
|
// Evaluar reglas de visibilidad
|
|
$reasons = [];
|
|
|
|
// 1. AdSense desactivado globalmente
|
|
if (!$settings->isEnabled()) {
|
|
return VisibilityDecision::hide(['adsense_disabled'], self::CACHE_SECONDS_HIDE);
|
|
}
|
|
|
|
// 2. JavaScript-First Mode desactivado (usar PHP legacy)
|
|
if (!$settings->isJavascriptFirstMode()) {
|
|
return VisibilityDecision::hide(['javascript_first_disabled'], self::CACHE_SECONDS_HIDE);
|
|
}
|
|
|
|
// 3. Ocultar para usuarios logueados
|
|
if ($settings->hideForLoggedIn() && $userContext->isLoggedIn()) {
|
|
$reasons[] = 'user_logged_in';
|
|
}
|
|
|
|
// 4. Verificar dispositivo
|
|
if ($userContext->isMobile() && !$settings->showOnMobile()) {
|
|
$reasons[] = 'mobile_disabled';
|
|
}
|
|
|
|
if ($userContext->isDesktop() && !$settings->showOnDesktop()) {
|
|
$reasons[] = 'desktop_disabled';
|
|
}
|
|
|
|
// 5. Verificar exclusiones de post (solo si postId > 0)
|
|
if ($postId > 0) {
|
|
if ($settings->isPostExcluded($postId)) {
|
|
$reasons[] = 'post_excluded';
|
|
}
|
|
|
|
// Verificar categorias del post
|
|
$postCategories = $this->getPostCategoryIds($postId);
|
|
foreach ($postCategories as $catId) {
|
|
if ($settings->isCategoryExcluded($catId)) {
|
|
$reasons[] = 'category_excluded';
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Verificar post type
|
|
$postType = $this->getPostType($postId);
|
|
if ($postType !== '' && $settings->isPostTypeExcluded($postType)) {
|
|
$reasons[] = 'post_type_excluded';
|
|
}
|
|
}
|
|
|
|
// Decision final
|
|
if (count($reasons) > 0) {
|
|
return VisibilityDecision::hide($reasons, self::CACHE_SECONDS_HIDE);
|
|
}
|
|
|
|
return VisibilityDecision::show(self::CACHE_SECONDS_SHOW);
|
|
}
|
|
|
|
/**
|
|
* Obtiene IDs de categorias de un post.
|
|
*
|
|
* @return array<int>
|
|
*/
|
|
private function getPostCategoryIds(int $postId): array
|
|
{
|
|
$categories = get_the_category($postId);
|
|
|
|
if (!is_array($categories)) {
|
|
return [];
|
|
}
|
|
|
|
return array_map(
|
|
static fn($cat): int => (int) $cat->term_id,
|
|
$categories
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Obtiene el post type de un post.
|
|
*/
|
|
private function getPostType(int $postId): string
|
|
{
|
|
$postType = get_post_type($postId);
|
|
|
|
return $postType !== false ? $postType : '';
|
|
}
|
|
}
|