isEnabled($data)) { return ''; } $output = ''; // Google Analytics $gaOutput = $this->renderGoogleAnalytics($data); if (!empty($gaOutput)) { $output .= $gaOutput . "\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 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 ); } }