Files
roi-theme/Inc/adsense-placement.php
FrankZamora 2acce34d9e fix(adsense): Disable Auto Ads when disable_auto_ads is enabled
- Add enable_page_level_ads: false to prevent Google from
  automatically inserting ads in unwanted locations
- This prevents ads from appearing inside table cells and
  other inappropriate places

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 15:29:16 -06:00

274 lines
7.7 KiB
PHP

<?php
/**
* AdSense Placement - Helper Functions
*
* Funciones para usar en templates:
* - roi_render_ad_slot('post-top')
* - roi_render_rail_ads() - Para los margenes laterales del viewport
* - roi_should_disable_auto_ads()
*/
if (!defined('ABSPATH')) {
exit;
}
/**
* Renderiza un slot de anuncio en una ubicacion
*
* NOTA DIP: El renderer se obtiene del DIContainer, NO se instancia directamente.
* Esto cumple con el Principio de Inversion de Dependencias.
*/
function roi_render_ad_slot(string $location): string
{
global $container;
if ($container === null) {
return '';
}
try {
$repository = $container->getComponentSettingsRepository();
$settings = $repository->getComponentSettings('adsense-placement');
if (empty($settings)) {
return '';
}
// Verificar exclusiones
if (roi_is_ad_excluded($settings)) {
return '';
}
// Obtener renderer desde DIContainer (DIP compliant)
$renderer = $container->getAdsensePlacementRenderer();
return $renderer->renderSlot($settings, $location);
} catch (\Throwable $e) {
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log('ROI AdSense: ' . $e->getMessage());
}
return '';
}
}
/**
* Verifica si el contenido actual esta excluido
*/
function roi_is_ad_excluded(array $settings): bool
{
$forms = $settings['forms'] ?? [];
// Excluir categorias
$excludeCats = array_filter(array_map('trim', explode(',', $forms['exclude_categories'] ?? '')));
if (!empty($excludeCats) && is_single()) {
$postCats = wp_get_post_categories(get_the_ID());
if (array_intersect($excludeCats, $postCats)) {
return true;
}
}
// Excluir tipos de post
$excludeTypes = array_filter(array_map('trim', explode(',', $forms['exclude_post_types'] ?? '')));
if (!empty($excludeTypes) && in_array(get_post_type(), $excludeTypes, true)) {
return true;
}
// Excluir posts especificos
$excludeIds = array_filter(array_map('trim', explode(',', $forms['exclude_post_ids'] ?? '')));
if (!empty($excludeIds) && in_array((string)get_the_ID(), $excludeIds, true)) {
return true;
}
return false;
}
/**
* Renderiza los Rail Ads (margenes laterales del viewport)
* Se llama desde wp_footer para inyectar al final del body
*
* NOTA DIP: El renderer se obtiene del DIContainer, NO se instancia directamente.
*/
function roi_render_rail_ads(): string
{
global $container;
if ($container === null) {
return '';
}
try {
$repository = $container->getComponentSettingsRepository();
$settings = $repository->getComponentSettings('adsense-placement');
if (empty($settings)) {
return '';
}
// Verificar exclusiones
if (roi_is_ad_excluded($settings)) {
return '';
}
// Obtener renderer desde DIContainer (DIP compliant)
$renderer = $container->getAdsensePlacementRenderer();
return $renderer->renderRailAds($settings);
} catch (\Throwable $e) {
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log('ROI AdSense Rail Ads: ' . $e->getMessage());
}
return '';
}
}
/**
* Hook para inyectar Rail Ads en el footer
*/
add_action('wp_footer', function() {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo roi_render_rail_ads();
}, 50);
/**
* Verifica si se debe deshabilitar Auto Ads
*/
function roi_should_disable_auto_ads(): bool
{
global $container;
if ($container === null) {
return false;
}
try {
$repository = $container->getComponentSettingsRepository();
$settings = $repository->getComponentSettings('adsense-placement');
$isEnabled = ($settings['visibility']['is_enabled'] ?? false) === true;
$disableAutoAds = ($settings['visibility']['disable_auto_ads'] ?? true) === true;
return $isEnabled && $disableAutoAds;
} catch (\Throwable $e) {
return false;
}
}
/**
* Carga el script principal de AdSense
*
* IMPORTANTE: Si disable_auto_ads está activo, se añade código para
* deshabilitar Auto Ads (page-level ads) de Google.
*/
function roi_enqueue_adsense_script(): void
{
global $container;
if ($container === null || is_admin()) {
return;
}
try {
$repository = $container->getComponentSettingsRepository();
$settings = $repository->getComponentSettings('adsense-placement');
if (!($settings['visibility']['is_enabled'] ?? false)) {
return;
}
$publisherId = $settings['content']['publisher_id'] ?? '';
if (empty($publisherId)) {
return;
}
$delayEnabled = ($settings['forms']['delay_enabled'] ?? true) === true;
$disableAutoAds = ($settings['visibility']['disable_auto_ads'] ?? true) === true;
// Script principal de AdSense
if ($delayEnabled) {
echo '<script type="text/plain" data-adsense-script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=' . esc_attr($publisherId) . '" crossorigin="anonymous"></script>' . "\n";
} else {
echo '<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=' . esc_attr($publisherId) . '" crossorigin="anonymous"></script>' . "\n";
}
// Deshabilitar Auto Ads (page-level ads) si está configurado
if ($disableAutoAds) {
echo '<script>
(adsbygoogle = window.adsbygoogle || []).push({
google_ad_client: "' . esc_js($publisherId) . '",
enable_page_level_ads: false
});
</script>' . "\n";
}
} catch (\Throwable $e) {
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log('ROI AdSense: ' . $e->getMessage());
}
}
}
add_action('wp_head', 'roi_enqueue_adsense_script', 5);
/**
* Registra el filtro the_content para inyectar anuncios
*/
add_filter('the_content', 'roi_inject_content_ads', 100);
function roi_inject_content_ads(string $content): string
{
global $container;
// Solo en posts individuales
if (!is_single() || !in_the_loop() || !is_main_query()) {
return $content;
}
if ($container === null) {
return $content;
}
try {
$repository = $container->getComponentSettingsRepository();
$settings = $repository->getComponentSettings('adsense-placement');
if (empty($settings) || !($settings['visibility']['is_enabled'] ?? false)) {
return $content;
}
// Verificar exclusiones
if (roi_is_ad_excluded($settings)) {
return $content;
}
$renderer = $container->getAdsensePlacementRenderer();
// Inyectar anuncio al inicio (post-top)
$postTopHtml = '';
if ($settings['behavior']['post_top_enabled'] ?? false) {
$postTopHtml = $renderer->renderSlot($settings, 'post-top');
}
// Inyectar anuncio al final (post-bottom)
$postBottomHtml = '';
if ($settings['behavior']['post_bottom_enabled'] ?? false) {
$postBottomHtml = $renderer->renderSlot($settings, 'post-bottom');
}
// Inyectar anuncios dentro del contenido
$injector = new \ROITheme\Public\AdsensePlacement\Infrastructure\Services\ContentAdInjector(
$settings,
$renderer
);
$content = $injector->inject($content);
return $postTopHtml . $content . $postBottomHtml;
} catch (\Throwable $e) {
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log('ROI AdSense Content: ' . $e->getMessage());
}
return $content;
}
}