fix(structure): Correct case-sensitivity for Linux compatibility
Rename folders to match PHP PSR-4 autoloading conventions: - schemas → Schemas - shared → Shared - Wordpress → WordPress (in all locations) Fixes deployment issues on Linux servers where filesystem is case-sensitive. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
180
Shared/Infrastructure/Services/CSSGeneratorService.php
Normal file
180
Shared/Infrastructure/Services/CSSGeneratorService.php
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ROITheme\Shared\Infrastructure\Services;
|
||||
|
||||
use ROITheme\Shared\Domain\Contracts\CSSGeneratorInterface;
|
||||
|
||||
/**
|
||||
* Class CSSGeneratorService
|
||||
*
|
||||
* Implementación concreta del generador de CSS.
|
||||
* Convierte arrays de configuración de estilos en reglas CSS válidas y formateadas.
|
||||
*
|
||||
* Responsabilidades:
|
||||
* - Generar string CSS a partir de selector y estilos
|
||||
* - Convertir propiedades snake_case → kebab-case
|
||||
* - Normalizar nombres de propiedades (text_color → color)
|
||||
* - Formatear reglas CSS con indentación legible
|
||||
* - Sanitizar valores para prevenir inyección
|
||||
*
|
||||
* @package ROITheme\Shared\Infrastructure\Services
|
||||
*/
|
||||
final class CSSGeneratorService implements CSSGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* Mapa de nombres de propiedades CSS normalizadas.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private const PROPERTY_MAP = [
|
||||
'text-color' => 'color',
|
||||
'bg-color' => 'background-color',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function generate(string $selector, array $styles): string
|
||||
{
|
||||
if (empty($styles)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Filtrar valores vacíos o null
|
||||
$styles = $this->filterEmptyValues($styles);
|
||||
|
||||
if (empty($styles)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Convertir array de estilos a propiedades CSS
|
||||
$cssProperties = $this->buildCSSProperties($styles);
|
||||
|
||||
// Formatear regla CSS completa
|
||||
return $this->formatCSSRule($selector, $cssProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filtra valores vacíos, null o que solo contienen espacios en blanco.
|
||||
*
|
||||
* @param array<string, mixed> $styles Array de estilos
|
||||
* @return array<string, string> Array filtrado
|
||||
*/
|
||||
private function filterEmptyValues(array $styles): array
|
||||
{
|
||||
return array_filter(
|
||||
$styles,
|
||||
fn($value) => $value !== null && $value !== '' && trim((string)$value) !== ''
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convierte array de estilos a propiedades CSS formateadas.
|
||||
*
|
||||
* @param array<string, string> $styles Array de estilos
|
||||
* @return array<int, string> Array de propiedades CSS formateadas
|
||||
*/
|
||||
private function buildCSSProperties(array $styles): array
|
||||
{
|
||||
$properties = [];
|
||||
|
||||
foreach ($styles as $property => $value) {
|
||||
// Convertir snake_case a kebab-case
|
||||
$cssProperty = $this->convertToKebabCase($property);
|
||||
|
||||
// Normalizar nombre de propiedad
|
||||
$cssProperty = $this->normalizePropertyName($cssProperty);
|
||||
|
||||
// Sanitizar valor
|
||||
$sanitizedValue = $this->sanitizeValue((string)$value);
|
||||
|
||||
// Agregar propiedad formateada
|
||||
$properties[] = sprintf('%s: %s;', $cssProperty, $sanitizedValue);
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convierte snake_case a kebab-case.
|
||||
*
|
||||
* Ejemplos:
|
||||
* - background_color → background-color
|
||||
* - font_size → font-size
|
||||
* - padding_top → padding-top
|
||||
*
|
||||
* @param string $property Nombre de propiedad en snake_case
|
||||
* @return string Nombre de propiedad en kebab-case
|
||||
*/
|
||||
private function convertToKebabCase(string $property): string
|
||||
{
|
||||
return str_replace('_', '-', strtolower($property));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normaliza nombres de propiedades CSS a su forma estándar.
|
||||
*
|
||||
* Mapea alias comunes a nombres de propiedades CSS estándar:
|
||||
* - text-color → color
|
||||
* - bg-color → background-color
|
||||
*
|
||||
* @param string $property Nombre de propiedad
|
||||
* @return string Nombre de propiedad normalizado
|
||||
*/
|
||||
private function normalizePropertyName(string $property): string
|
||||
{
|
||||
return self::PROPERTY_MAP[$property] ?? $property;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitiza valores CSS para prevenir inyección de código.
|
||||
*
|
||||
* Remueve tags HTML y caracteres potencialmente peligrosos,
|
||||
* manteniendo valores CSS válidos como colores, unidades, etc.
|
||||
*
|
||||
* @param string $value Valor CSS sin sanitizar
|
||||
* @return string Valor CSS sanitizado
|
||||
*/
|
||||
private function sanitizeValue(string $value): string
|
||||
{
|
||||
// Remover tags HTML
|
||||
$value = strip_tags($value);
|
||||
|
||||
// Remover caracteres de control excepto espacios
|
||||
$value = preg_replace('/[^\P{C}\s]/u', '', $value);
|
||||
|
||||
// Trim espacios
|
||||
$value = trim($value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatea la regla CSS completa con selector y propiedades.
|
||||
*
|
||||
* Genera CSS con formato legible:
|
||||
* ```css
|
||||
* .selector {
|
||||
* property: value;
|
||||
* property2: value2;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param string $selector Selector CSS
|
||||
* @param array<int, string> $properties Array de propiedades formateadas
|
||||
* @return string Regla CSS completa
|
||||
*/
|
||||
private function formatCSSRule(string $selector, array $properties): string
|
||||
{
|
||||
if (empty($properties)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
"%s {\n %s\n}",
|
||||
$selector,
|
||||
implode("\n ", $properties)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user