renderer); * $html .= $exclusionPartial->render($componentId, 'prefijo'); * ``` * * @package ROITheme\Admin\Shared\Infrastructure\Ui */ final class ExclusionFormPartial { private const GROUP_NAME = '_exclusions'; public function __construct( private readonly AdminDashboardRenderer $renderer ) {} /** * Renderiza la seccion de exclusiones * * @param string $componentId ID del componente (kebab-case) * @param string $prefix Prefijo para IDs de campos (ej: 'cta' genera 'ctaExclusionsEnabled') * @return string HTML de la seccion */ public function render(string $componentId, string $prefix): string { $html = ''; $html .= $this->buildExclusionHeader(); $html .= $this->buildExclusionToggle($componentId, $prefix); $html .= $this->buildExclusionRules($componentId, $prefix); return $html; } private function buildExclusionHeader(): string { $html = '
'; $html .= '

'; $html .= ' '; $html .= ' Reglas de exclusion avanzadas'; $html .= '

'; $html .= '

'; $html .= ' Excluir este componente de categorias, posts o URLs especificos.'; $html .= '

'; return $html; } private function buildExclusionToggle(string $componentId, string $prefix): string { $enabled = $this->renderer->getFieldValue( $componentId, self::GROUP_NAME, 'exclusions_enabled', false ); $checked = $this->toBool($enabled); $id = $prefix . 'ExclusionsEnabled'; $html = '
'; $html .= '
'; $html .= sprintf( ' ', esc_attr($id), $checked ? 'checked' : '' ); $html .= sprintf( ' '; $html .= '
'; $html .= '
'; return $html; } private function buildExclusionRules(string $componentId, string $prefix): string { $enabled = $this->renderer->getFieldValue( $componentId, self::GROUP_NAME, 'exclusions_enabled', false ); $display = $this->toBool($enabled) ? 'block' : 'none'; $html = sprintf( '
', esc_attr($prefix), $display ); $html .= $this->buildCategoryField($componentId, $prefix); $html .= $this->buildPostIdsField($componentId, $prefix); $html .= $this->buildUrlPatternsField($componentId, $prefix); $html .= '
'; return $html; } private function buildCategoryField(string $componentId, string $prefix): string { $value = $this->renderer->getFieldValue( $componentId, self::GROUP_NAME, 'exclude_categories', '[]' ); $categories = $this->jsonToCommaList($value); $id = $prefix . 'ExcludeCategories'; $html = '
'; $html .= sprintf( ' '; $html .= sprintf( ' ', esc_attr($id), esc_attr($categories) ); $html .= ' Slugs de categorias separados por comas'; $html .= '
'; return $html; } private function buildPostIdsField(string $componentId, string $prefix): string { $value = $this->renderer->getFieldValue( $componentId, self::GROUP_NAME, 'exclude_post_ids', '[]' ); $postIds = $this->jsonToCommaList($value); $id = $prefix . 'ExcludePostIds'; $html = '
'; $html .= sprintf( ' '; $html .= sprintf( ' ', esc_attr($id), esc_attr($postIds) ); $html .= ' IDs de posts o paginas separados por comas'; $html .= '
'; return $html; } private function buildUrlPatternsField(string $componentId, string $prefix): string { $value = $this->renderer->getFieldValue( $componentId, self::GROUP_NAME, 'exclude_url_patterns', '[]' ); $patterns = $this->jsonToLineList($value); $id = $prefix . 'ExcludeUrlPatterns'; $html = '
'; $html .= sprintf( ' '; $html .= sprintf( ' ', esc_attr($id), esc_textarea($patterns) ); $html .= ' Un patron por linea. Soporta texto simple o regex (ej: /^\/blog\/\d+$/)'; $html .= '
'; return $html; } /** * Convierte JSON array o array a lista separada por comas * * @param string|array $value Valor desde BD (puede ser JSON string o array ya deserializado) */ private function jsonToCommaList(string|array $value): string { // Si ya es array, usarlo directamente if (is_array($value)) { return empty($value) ? '' : implode(', ', $value); } // Si es string, intentar decodificar JSON $decoded = json_decode($value, true); if (!is_array($decoded) || empty($decoded)) { return ''; } return implode(', ', $decoded); } /** * Convierte JSON array o array a lista separada por lineas * * @param string|array $value Valor desde BD (puede ser JSON string o array ya deserializado) */ private function jsonToLineList(string|array $value): string { // Si ya es array, usarlo directamente if (is_array($value)) { return empty($value) ? '' : implode("\n", $value); } // Si es string, intentar decodificar JSON $decoded = json_decode($value, true); if (!is_array($decoded) || empty($decoded)) { return ''; } return implode("\n", $decoded); } private function toBool(mixed $value): bool { return $value === true || $value === '1' || $value === 1; } }