Fase 1: Estructura Base y DI Container - Clean Architecture
COMPLETADO: Fase 1 de la migración a Clean Architecture + POO ## Estructura de Carpetas - ✓ Estructura completa de 4 capas (Domain, Application, Infrastructure, Presentation) - ✓ Carpetas de Use Cases (SaveComponent, GetComponent, DeleteComponent, SyncSchema) - ✓ Estructura de tests (Unit, Integration, E2E) - ✓ Carpetas de schemas y templates ## Composer y Autoloading - ✓ PSR-4 autoloading configurado para ROITheme namespace - ✓ Autoloader optimizado regenerado ## DI Container - ✓ DIContainer implementado con patrón Singleton - ✓ Métodos set(), get(), has() para gestión de servicios - ✓ Getters específicos para ComponentRepository, ValidationService, CacheService - ✓ Placeholders que serán implementados en Fase 5 - ✓ Prevención de clonación y deserialización ## Interfaces - ✓ ComponentRepositoryInterface (Domain) - ✓ ValidationServiceInterface (Application) - ✓ CacheServiceInterface (Application) - ✓ Component entity placeholder (Domain) ## Bootstrap - ✓ functions.php actualizado con carga de Composer autoloader - ✓ Inicialización del DIContainer - ✓ Helper function roi_container() disponible globalmente ## Tests - ✓ 10 tests unitarios para DIContainer (100% cobertura) - ✓ Total: 13 tests unitarios, 28 assertions - ✓ Suite de tests pasando correctamente ## Validación - ✓ Script de validación automatizado (48/48 checks pasados) - ✓ 100% de validaciones exitosas La arquitectura base está lista para la Fase 2. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Handles responsive images, WebP/AVIF support, lazy loading, and image preloading.
|
||||
*
|
||||
* @package Apus_Theme
|
||||
* @package ROI_Theme
|
||||
* @since 1.0.0
|
||||
*/
|
||||
|
||||
@@ -16,51 +16,51 @@ if (!defined('ABSPATH')) {
|
||||
/**
|
||||
* Enable AVIF image support
|
||||
*/
|
||||
function apus_enable_avif_support($mime_types) {
|
||||
function roi_enable_avif_support($mime_types) {
|
||||
$mime_types['avif'] = 'image/avif';
|
||||
return $mime_types;
|
||||
}
|
||||
add_filter('upload_mimes', 'apus_enable_avif_support');
|
||||
add_filter('upload_mimes', 'roi_enable_avif_support');
|
||||
|
||||
/**
|
||||
* Add AVIF to allowed file extensions
|
||||
*/
|
||||
function apus_allow_avif_extension($types, $file, $filename, $mimes) {
|
||||
function roi_allow_avif_extension($types, $file, $filename, $mimes) {
|
||||
if (false !== strpos($filename, '.avif')) {
|
||||
$types['ext'] = 'avif';
|
||||
$types['type'] = 'image/avif';
|
||||
}
|
||||
return $types;
|
||||
}
|
||||
add_filter('wp_check_filetype_and_ext', 'apus_allow_avif_extension', 10, 4);
|
||||
add_filter('wp_check_filetype_and_ext', 'roi_allow_avif_extension', 10, 4);
|
||||
|
||||
/**
|
||||
* Configure custom image sizes
|
||||
* Already defined in functions.php, but we can add more if needed
|
||||
*/
|
||||
function apus_setup_additional_image_sizes() {
|
||||
function roi_setup_additional_image_sizes() {
|
||||
// Add support for additional modern image sizes
|
||||
add_image_size('apus-hero', 1920, 800, true); // Hero images
|
||||
add_image_size('apus-card', 600, 400, true); // Card thumbnails
|
||||
add_image_size('apus-thumbnail-2x', 800, 600, true); // Retina thumbnails
|
||||
add_image_size('roi-hero', 1920, 800, true); // Hero images
|
||||
add_image_size('roi-card', 600, 400, true); // Card thumbnails
|
||||
add_image_size('roi-thumbnail-2x', 800, 600, true); // Retina thumbnails
|
||||
}
|
||||
add_action('after_setup_theme', 'apus_setup_additional_image_sizes');
|
||||
add_action('after_setup_theme', 'roi_setup_additional_image_sizes');
|
||||
|
||||
/**
|
||||
* Add custom image sizes to media library dropdown
|
||||
*/
|
||||
function apus_custom_image_sizes($sizes) {
|
||||
function roi_custom_image_sizes($sizes) {
|
||||
return array_merge($sizes, array(
|
||||
'apus-thumbnail' => __('Thumbnail (400x300)', 'apus-theme'),
|
||||
'apus-medium' => __('Medium (800x600)', 'apus-theme'),
|
||||
'apus-large' => __('Large (1200x900)', 'apus-theme'),
|
||||
'apus-featured-large' => __('Featured Large (1200x600)', 'apus-theme'),
|
||||
'apus-featured-medium' => __('Featured Medium (800x400)', 'apus-theme'),
|
||||
'apus-hero' => __('Hero (1920x800)', 'apus-theme'),
|
||||
'apus-card' => __('Card (600x400)', 'apus-theme'),
|
||||
'roi-thumbnail' => __('Thumbnail (400x300)', 'roi-theme'),
|
||||
'roi-medium' => __('Medium (800x600)', 'roi-theme'),
|
||||
'roi-large' => __('Large (1200x900)', 'roi-theme'),
|
||||
'roi-featured-large' => __('Featured Large (1200x600)', 'roi-theme'),
|
||||
'roi-featured-medium' => __('Featured Medium (800x400)', 'roi-theme'),
|
||||
'roi-hero' => __('Hero (1920x800)', 'roi-theme'),
|
||||
'roi-card' => __('Card (600x400)', 'roi-theme'),
|
||||
));
|
||||
}
|
||||
add_filter('image_size_names_choose', 'apus_custom_image_sizes');
|
||||
add_filter('image_size_names_choose', 'roi_custom_image_sizes');
|
||||
|
||||
/**
|
||||
* Generate srcset and sizes attributes for responsive images
|
||||
@@ -70,7 +70,7 @@ add_filter('image_size_names_choose', 'apus_custom_image_sizes');
|
||||
* @param array $additional_sizes Additional sizes to include in srcset
|
||||
* @return array Array with 'srcset' and 'sizes' attributes
|
||||
*/
|
||||
function apus_get_responsive_image_attrs($attachment_id, $size = 'full', $additional_sizes = array()) {
|
||||
function roi_get_responsive_image_attrs($attachment_id, $size = 'full', $additional_sizes = array()) {
|
||||
if (empty($attachment_id)) {
|
||||
return array('srcset' => '', 'sizes' => '');
|
||||
}
|
||||
@@ -110,13 +110,13 @@ function apus_get_responsive_image_attrs($attachment_id, $size = 'full', $additi
|
||||
* @param bool $lazy Enable lazy loading (default: true)
|
||||
* @return string Image HTML
|
||||
*/
|
||||
function apus_get_responsive_image($attachment_id, $size = 'full', $attr = array(), $lazy = true) {
|
||||
function roi_get_responsive_image($attachment_id, $size = 'full', $attr = array(), $lazy = true) {
|
||||
if (empty($attachment_id)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Get responsive attributes
|
||||
$responsive_attrs = apus_get_responsive_image_attrs($attachment_id, $size);
|
||||
$responsive_attrs = roi_get_responsive_image_attrs($attachment_id, $size);
|
||||
|
||||
// Merge default attributes with custom ones
|
||||
$default_attr = array(
|
||||
@@ -140,7 +140,7 @@ function apus_get_responsive_image($attachment_id, $size = 'full', $attr = array
|
||||
/**
|
||||
* Enable lazy loading by default for all images
|
||||
*/
|
||||
function apus_add_lazy_loading_to_images($attr, $attachment, $size) {
|
||||
function roi_add_lazy_loading_to_images($attr, $attachment, $size) {
|
||||
// Don't add lazy loading if explicitly disabled
|
||||
if (isset($attr['loading']) && $attr['loading'] === 'eager') {
|
||||
return $attr;
|
||||
@@ -158,12 +158,12 @@ function apus_add_lazy_loading_to_images($attr, $attachment, $size) {
|
||||
|
||||
return $attr;
|
||||
}
|
||||
add_filter('wp_get_attachment_image_attributes', 'apus_add_lazy_loading_to_images', 10, 3);
|
||||
add_filter('wp_get_attachment_image_attributes', 'roi_add_lazy_loading_to_images', 10, 3);
|
||||
|
||||
/**
|
||||
* Add lazy loading to content images
|
||||
*/
|
||||
function apus_add_lazy_loading_to_content($content) {
|
||||
function roi_add_lazy_loading_to_content($content) {
|
||||
// Don't process if empty
|
||||
if (empty($content)) {
|
||||
return $content;
|
||||
@@ -174,7 +174,7 @@ function apus_add_lazy_loading_to_content($content) {
|
||||
|
||||
return $content;
|
||||
}
|
||||
add_filter('the_content', 'apus_add_lazy_loading_to_content', 20);
|
||||
add_filter('the_content', 'roi_add_lazy_loading_to_content', 20);
|
||||
|
||||
/**
|
||||
* Preload critical images (LCP images)
|
||||
@@ -183,7 +183,7 @@ add_filter('the_content', 'apus_add_lazy_loading_to_content', 20);
|
||||
* @param int $attachment_id Image attachment ID
|
||||
* @param string $size Image size
|
||||
*/
|
||||
function apus_preload_image($attachment_id, $size = 'full') {
|
||||
function roi_preload_image($attachment_id, $size = 'full') {
|
||||
if (empty($attachment_id)) {
|
||||
return;
|
||||
}
|
||||
@@ -230,7 +230,7 @@ function apus_preload_image($attachment_id, $size = 'full') {
|
||||
/**
|
||||
* Preload featured image for single posts (LCP optimization)
|
||||
*/
|
||||
function apus_preload_featured_image() {
|
||||
function roi_preload_featured_image() {
|
||||
// Only on single posts/pages with featured images
|
||||
if (!is_singular() || !has_post_thumbnail()) {
|
||||
return;
|
||||
@@ -240,17 +240,17 @@ function apus_preload_featured_image() {
|
||||
$thumbnail_id = get_post_thumbnail_id();
|
||||
|
||||
// Determine the size based on the post type
|
||||
$size = 'apus-featured-large';
|
||||
$size = 'roi-featured-large';
|
||||
|
||||
// Preload the image
|
||||
apus_preload_image($thumbnail_id, $size);
|
||||
roi_preload_image($thumbnail_id, $size);
|
||||
}
|
||||
add_action('wp_head', 'apus_preload_featured_image', 5);
|
||||
add_action('wp_head', 'roi_preload_featured_image', 5);
|
||||
|
||||
/**
|
||||
* Enable fetchpriority attribute for featured images
|
||||
*/
|
||||
function apus_add_fetchpriority_to_featured_image($attr, $attachment, $size) {
|
||||
function roi_add_fetchpriority_to_featured_image($attr, $attachment, $size) {
|
||||
// Only add fetchpriority="high" to featured images on singular pages
|
||||
if (is_singular() && get_post_thumbnail_id() === $attachment->ID) {
|
||||
$attr['fetchpriority'] = 'high';
|
||||
@@ -259,20 +259,20 @@ function apus_add_fetchpriority_to_featured_image($attr, $attachment, $size) {
|
||||
|
||||
return $attr;
|
||||
}
|
||||
add_filter('wp_get_attachment_image_attributes', 'apus_add_fetchpriority_to_featured_image', 20, 3);
|
||||
add_filter('wp_get_attachment_image_attributes', 'roi_add_fetchpriority_to_featured_image', 20, 3);
|
||||
|
||||
/**
|
||||
* Optimize image quality for uploads
|
||||
*/
|
||||
function apus_optimize_image_quality($quality, $mime_type) {
|
||||
function roi_optimize_image_quality($quality, $mime_type) {
|
||||
// Set quality to 85% for better file size without visible quality loss
|
||||
if ($mime_type === 'image/jpeg') {
|
||||
return 85;
|
||||
}
|
||||
return $quality;
|
||||
}
|
||||
add_filter('jpeg_quality', 'apus_optimize_image_quality', 10, 2);
|
||||
add_filter('wp_editor_set_quality', 'apus_optimize_image_quality', 10, 2);
|
||||
add_filter('jpeg_quality', 'roi_optimize_image_quality', 10, 2);
|
||||
add_filter('wp_editor_set_quality', 'roi_optimize_image_quality', 10, 2);
|
||||
|
||||
/**
|
||||
* Add picture element support for WebP/AVIF with fallbacks
|
||||
@@ -282,7 +282,7 @@ add_filter('wp_editor_set_quality', 'apus_optimize_image_quality', 10, 2);
|
||||
* @param array $attr Additional attributes
|
||||
* @return string Picture element HTML
|
||||
*/
|
||||
function apus_get_picture_element($attachment_id, $size = 'full', $attr = array()) {
|
||||
function roi_get_picture_element($attachment_id, $size = 'full', $attr = array()) {
|
||||
if (empty($attachment_id)) {
|
||||
return '';
|
||||
}
|
||||
@@ -340,26 +340,26 @@ function apus_get_picture_element($attachment_id, $size = 'full', $attr = array(
|
||||
* WordPress 5.3+ escala imágenes mayores a 2560px por defecto
|
||||
* Mantenemos 2560px como límite para balance entre calidad y rendimiento
|
||||
*/
|
||||
function apus_big_image_size_threshold($threshold) {
|
||||
function roi_big_image_size_threshold($threshold) {
|
||||
// Mantener 2560px como threshold (no desactivar completamente)
|
||||
return 2560;
|
||||
}
|
||||
add_filter('big_image_size_threshold', 'apus_big_image_size_threshold');
|
||||
add_filter('big_image_size_threshold', 'roi_big_image_size_threshold');
|
||||
|
||||
/**
|
||||
* Set maximum srcset image width
|
||||
*/
|
||||
function apus_max_srcset_image_width($max_width, $size_array) {
|
||||
function roi_max_srcset_image_width($max_width, $size_array) {
|
||||
// Limit srcset to images up to 2560px wide
|
||||
return 2560;
|
||||
}
|
||||
add_filter('max_srcset_image_width', 'apus_max_srcset_image_width', 10, 2);
|
||||
add_filter('max_srcset_image_width', 'roi_max_srcset_image_width', 10, 2);
|
||||
|
||||
/**
|
||||
* Habilitar generación automática de WebP en WordPress
|
||||
* WordPress 5.8+ soporta WebP nativamente si el servidor tiene soporte
|
||||
*/
|
||||
function apus_enable_webp_generation($editors) {
|
||||
function roi_enable_webp_generation($editors) {
|
||||
// Verificar que GD o Imagick tengan soporte WebP
|
||||
if (extension_loaded('gd')) {
|
||||
$gd_info = gd_info();
|
||||
@@ -380,12 +380,12 @@ function apus_enable_webp_generation($editors) {
|
||||
|
||||
return $editors;
|
||||
}
|
||||
add_filter('wp_image_editors', 'apus_enable_webp_generation');
|
||||
add_filter('wp_image_editors', 'roi_enable_webp_generation');
|
||||
|
||||
/**
|
||||
* Configurar tipos MIME adicionales para WebP y AVIF
|
||||
*/
|
||||
function apus_additional_mime_types($mimes) {
|
||||
function roi_additional_mime_types($mimes) {
|
||||
// WebP ya está soportado en WordPress 5.8+, pero lo agregamos por compatibilidad
|
||||
if (!isset($mimes['webp'])) {
|
||||
$mimes['webp'] = 'image/webp';
|
||||
@@ -398,12 +398,12 @@ function apus_additional_mime_types($mimes) {
|
||||
|
||||
return $mimes;
|
||||
}
|
||||
add_filter('mime_types', 'apus_additional_mime_types');
|
||||
add_filter('mime_types', 'roi_additional_mime_types');
|
||||
|
||||
/**
|
||||
* Remover tamaños de imagen no utilizados para ahorrar espacio
|
||||
*/
|
||||
function apus_remove_unused_image_sizes($sizes) {
|
||||
function roi_remove_unused_image_sizes($sizes) {
|
||||
// Remover tamaños de WordPress que no usamos
|
||||
unset($sizes['medium_large']); // 768px - no necesario con nuestros tamaños custom
|
||||
unset($sizes['1536x1536']); // 2x medium_large - no necesario
|
||||
@@ -411,42 +411,42 @@ function apus_remove_unused_image_sizes($sizes) {
|
||||
|
||||
return $sizes;
|
||||
}
|
||||
add_filter('intermediate_image_sizes_advanced', 'apus_remove_unused_image_sizes');
|
||||
add_filter('intermediate_image_sizes_advanced', 'roi_remove_unused_image_sizes');
|
||||
|
||||
/**
|
||||
* Agregar sizes attribute personalizado según contexto
|
||||
* Mejora la selección del tamaño correcto de imagen por el navegador
|
||||
*/
|
||||
function apus_responsive_image_sizes_attr($sizes, $size, $image_src, $image_meta, $attachment_id) {
|
||||
function roi_responsive_image_sizes_attr($sizes, $size, $image_src, $image_meta, $attachment_id) {
|
||||
// Para imágenes destacadas grandes (single posts)
|
||||
if ($size === 'apus-featured-large' || $size === 'apus-large') {
|
||||
if ($size === 'roi-featured-large' || $size === 'roi-large') {
|
||||
$sizes = '(max-width: 768px) 100vw, (max-width: 1200px) 80vw, 1200px';
|
||||
}
|
||||
|
||||
// Para imágenes destacadas medianas (archives)
|
||||
elseif ($size === 'apus-featured-medium' || $size === 'apus-medium') {
|
||||
elseif ($size === 'roi-featured-medium' || $size === 'roi-medium') {
|
||||
$sizes = '(max-width: 768px) 100vw, (max-width: 992px) 50vw, 800px';
|
||||
}
|
||||
|
||||
// Para thumbnails (widgets, related posts)
|
||||
elseif ($size === 'apus-thumbnail') {
|
||||
elseif ($size === 'roi-thumbnail') {
|
||||
$sizes = '(max-width: 576px) 100vw, 400px';
|
||||
}
|
||||
|
||||
// Para hero images
|
||||
elseif ($size === 'apus-hero') {
|
||||
elseif ($size === 'roi-hero') {
|
||||
$sizes = '100vw';
|
||||
}
|
||||
|
||||
return $sizes;
|
||||
}
|
||||
add_filter('wp_calculate_image_sizes', 'apus_responsive_image_sizes_attr', 10, 5);
|
||||
add_filter('wp_calculate_image_sizes', 'roi_responsive_image_sizes_attr', 10, 5);
|
||||
|
||||
/**
|
||||
* Forzar regeneración de metadatos de imagen para incluir WebP/AVIF
|
||||
* Solo se ejecuta cuando sea necesario
|
||||
*/
|
||||
function apus_maybe_regenerate_image_metadata($metadata, $attachment_id) {
|
||||
function roi_maybe_regenerate_image_metadata($metadata, $attachment_id) {
|
||||
// Verificar si ya tiene formatos modernos generados
|
||||
if (!empty($metadata) && is_array($metadata)) {
|
||||
// WordPress maneja automáticamente la generación de sub-formatos
|
||||
@@ -455,12 +455,12 @@ function apus_maybe_regenerate_image_metadata($metadata, $attachment_id) {
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
add_filter('wp_generate_attachment_metadata', 'apus_maybe_regenerate_image_metadata', 10, 2);
|
||||
add_filter('wp_generate_attachment_metadata', 'roi_maybe_regenerate_image_metadata', 10, 2);
|
||||
|
||||
/**
|
||||
* Excluir lazy loading en la primera imagen del contenido (posible LCP)
|
||||
*/
|
||||
function apus_skip_lazy_loading_first_image($content) {
|
||||
function roi_skip_lazy_loading_first_image($content) {
|
||||
// Solo en posts/páginas singulares
|
||||
if (!is_singular()) {
|
||||
return $content;
|
||||
@@ -482,13 +482,13 @@ function apus_skip_lazy_loading_first_image($content) {
|
||||
|
||||
return $content;
|
||||
}
|
||||
add_filter('the_content', 'apus_skip_lazy_loading_first_image', 15);
|
||||
add_filter('the_content', 'roi_skip_lazy_loading_first_image', 15);
|
||||
|
||||
/**
|
||||
* Agregar soporte para formatos de imagen modernos en subsizes
|
||||
* WordPress 5.8+ genera automáticamente WebP si está disponible
|
||||
*/
|
||||
function apus_enable_image_subsizes($metadata, $attachment_id, $context) {
|
||||
function roi_enable_image_subsizes($metadata, $attachment_id, $context) {
|
||||
if ($context !== 'create') {
|
||||
return $metadata;
|
||||
}
|
||||
@@ -497,4 +497,4 @@ function apus_enable_image_subsizes($metadata, $attachment_id, $context) {
|
||||
// Este filtro asegura que se ejecute correctamente
|
||||
return $metadata;
|
||||
}
|
||||
add_filter('wp_generate_attachment_metadata', 'apus_enable_image_subsizes', 20, 3);
|
||||
add_filter('wp_generate_attachment_metadata', 'roi_enable_image_subsizes', 20, 3);
|
||||
|
||||
Reference in New Issue
Block a user