isEnabled($data)) {
return '';
}
$output = '';
// Google Analytics
$gaOutput = $this->renderGoogleAnalytics($data);
if (!empty($gaOutput)) {
$output .= $gaOutput . "\n";
}
// Google AdSense Auto Ads
$adsenseOutput = $this->renderAdSenseAutoAds($data);
if (!empty($adsenseOutput)) {
$output .= $adsenseOutput . "\n";
}
// Custom CSS
$cssOutput = $this->renderCustomCSS($data);
if (!empty($cssOutput)) {
$output .= $cssOutput . "\n";
}
// Custom JS Header
$jsHeaderOutput = $this->renderCustomJSHeader($data);
if (!empty($jsHeaderOutput)) {
$output .= $jsHeaderOutput . "\n";
}
return $output;
}
/**
* Genera contenido para wp_footer
*
* Incluye:
* - Custom JS Footer (si configurado)
*
* @param array $data Datos del componente desde BD
* @return string Contenido para wp_footer
*/
public function renderFooterContent(array $data): string
{
// Validar visibilidad general
if (!$this->isEnabled($data)) {
return '';
}
return $this->renderCustomJSFooter($data);
}
/**
* Verifica si el componente esta habilitado
*
* NOTA: Theme Settings es un componente de configuracion global
* que siempre esta activo. No tiene grupo visibility.
* Si el usuario no quiere GA o CSS custom, simplemente deja
* los campos vacios.
*
* @param array $data Datos del componente (no usado)
* @return bool Siempre true
*/
private function isEnabled(array $data): bool
{
// Theme Settings siempre esta activo (configuraciones globales)
// Los campos individuales se validan en sus metodos respectivos
return true;
}
/**
* Genera el script de Google Analytics
*
* @param array $data Datos del componente
* @return string Script de GA o vacio si no configurado
*/
private function renderGoogleAnalytics(array $data): string
{
$trackingId = trim($data['analytics']['ga_tracking_id'] ?? '');
if (empty($trackingId)) {
return '';
}
// Verificar si GA ya esta cargado por otro plugin
if ($this->isGoogleAnalyticsLoaded()) {
return '';
}
$anonymizeIp = ($data['analytics']['ga_anonymize_ip'] ?? true) === true;
// Detectar tipo de ID (GA4 vs Universal Analytics)
if (strpos($trackingId, 'G-') === 0) {
// Google Analytics 4
return $this->renderGA4Script($trackingId, $anonymizeIp);
} elseif (strpos($trackingId, 'UA-') === 0) {
// Universal Analytics (legacy)
return $this->renderUniversalAnalyticsScript($trackingId, $anonymizeIp);
}
return '';
}
/**
* Genera script de Google Analytics 4
*
* @param string $trackingId ID de GA4 (G-XXXXXXXXXX)
* @param bool $anonymizeIp Si anonimizar IP
* @return string Script HTML
*/
private function renderGA4Script(string $trackingId, bool $anonymizeIp): string
{
$config = $anonymizeIp ? "{ 'anonymize_ip': true }" : '{}';
return sprintf(
'
',
esc_attr($trackingId),
$config
);
}
/**
* Genera script de Universal Analytics (legacy)
*
* @param string $trackingId ID de UA (UA-XXXXXXXX-X)
* @param bool $anonymizeIp Si anonimizar IP
* @return string Script HTML
*/
private function renderUniversalAnalyticsScript(string $trackingId, bool $anonymizeIp): string
{
$anonymizeConfig = $anonymizeIp ? "ga('set', 'anonymizeIp', true);" : '';
return sprintf(
'
',
esc_attr($trackingId),
$anonymizeConfig
);
}
/**
* Verifica si Google Analytics ya esta cargado
*
* @return bool True si ya esta cargado por otro plugin
*/
private function isGoogleAnalyticsLoaded(): bool
{
// Verificar plugins comunes de GA
if (function_exists('gtag')) {
return true;
}
// Verificar si MonsterInsights esta activo
if (class_exists('MonsterInsights_Lite') || class_exists('MonsterInsights')) {
return true;
}
// Verificar si Site Kit de Google esta activo
if (class_exists('Google\Site_Kit\Plugin')) {
return true;
}
return false;
}
/**
* Genera el script de Google AdSense Auto Ads
*
* @param array $data Datos del componente
* @return string Script de AdSense o vacio si no configurado
*/
private function renderAdSenseAutoAds(array $data): string
{
$publisherId = trim($data['adsense']['adsense_publisher_id'] ?? '');
$autoAdsEnabled = ($data['adsense']['adsense_auto_ads'] ?? false) === true;
// Solo mostrar si tiene publisher ID y auto ads esta activado
if (empty($publisherId) || !$autoAdsEnabled) {
return '';
}
// Validar formato del publisher ID (ca-pub-XXXXXXXXXX)
if (!preg_match('/^ca-pub-\d+$/', $publisherId)) {
return '';
}
return sprintf(
'
',
esc_attr($publisherId)
);
}
/**
* Genera el CSS personalizado
*
* @param array $data Datos del componente
* @return string Bloque style o vacio si no hay CSS
*/
private function renderCustomCSS(array $data): string
{
$css = trim($data['custom_code']['custom_css'] ?? '');
if (empty($css)) {
return '';
}
return sprintf(
'
',
$css // No escapar CSS - usuario avanzado responsable
);
}
/**
* Genera el JavaScript personalizado para header
*
* @param array $data Datos del componente
* @return string Bloque script o vacio si no hay JS
*/
private function renderCustomJSHeader(array $data): string
{
$js = trim($data['custom_code']['custom_js_header'] ?? '');
if (empty($js)) {
return '';
}
return sprintf(
'
',
$js // No escapar JS - usuario avanzado responsable
);
}
/**
* Genera el JavaScript personalizado para footer
*
* @param array $data Datos del componente
* @return string Bloque script o vacio si no hay JS
*/
private function renderCustomJSFooter(array $data): string
{
$js = trim($data['custom_code']['custom_js_footer'] ?? '');
if (empty($js)) {
return '';
}
return sprintf(
'
',
$js // No escapar JS - usuario avanzado responsable
);
}
}