Files
feadulta/mu-plugins/fea-slider-sync.php
T

186 lines
6.8 KiB
PHP

<?php
/**
* Plugin Name: Fe Adulta — Slider home sync (filesystem → Smart Slider 3)
* Description: Sincroniza los slides del Smart Slider 3 id 2 ("Slider_home")
* con el contenido del directorio `wp-content/uploads/home/`.
* Imita el modelo Joomla mod_ariimageslider que leía
* `images/home/` automáticamente.
* Version: 1.0
*
* Operativa para el editor: subir/borrar ficheros en `uploads/home/`.
* El slider de la portada se actualiza solo al primer pageview.
*
* Ver issue rafa/feadulta#43.
*/
const FEA_SLIDER_ID = 2;
const FEA_SLIDER_DIRNAME = 'home';
const FEA_SLIDER_EXTS = ['jpg', 'jpeg', 'png', 'webp'];
const FEA_SLIDER_OPT_KEY = 'fea_slider_home_mtime';
/**
* Lista las imágenes del directorio uploads/home/, ordenadas por nombre.
*/
function fea_slider_home_files() {
$uploads = wp_upload_dir();
$dir = trailingslashit($uploads['basedir']) . FEA_SLIDER_DIRNAME;
if (!is_dir($dir)) return [];
$files = [];
foreach (scandir($dir) as $name) {
if ($name === '.' || $name === '..') continue;
$ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
if (!in_array($ext, FEA_SLIDER_EXTS, true)) continue;
$files[] = $name;
}
sort($files, SORT_NATURAL);
return $files;
}
/**
* mtime del directorio (cambia al añadir/borrar ficheros).
*/
function fea_slider_home_dir_mtime() {
$uploads = wp_upload_dir();
$dir = trailingslashit($uploads['basedir']) . FEA_SLIDER_DIRNAME;
if (!is_dir($dir)) return 0;
$m = (int) @filemtime($dir);
// Sumar mtime de cada fichero para detectar reemplazos del mismo nombre
foreach (fea_slider_home_files() as $f) {
$m = max($m, (int) @filemtime($dir . '/' . $f));
}
return $m;
}
/**
* Sincroniza la tabla wp_nextend2_smartslider3_slides para el slider 2
* con los ficheros del directorio. Idempotente.
*
* - Reusa slides existentes (manteniendo IDs) cuando coincide la imagen
* - Crea slides nuevos para imágenes nuevas
* - Borra slides cuya imagen ya no está
*/
function fea_slider_home_sync_now($force = false) {
global $wpdb;
$mtime = fea_slider_home_dir_mtime();
if (!$force) {
$last = (int) get_option(FEA_SLIDER_OPT_KEY, 0);
if ($last === $mtime && $mtime > 0) return false;
}
$files = fea_slider_home_files();
$uploads = wp_upload_dir();
$reldir = '$upload$/' . FEA_SLIDER_DIRNAME; // SS3 variable placeholder
// Leer slides actuales del slider 2 → mapeo imagen → row
$existing = $wpdb->get_results($wpdb->prepare(
"SELECT id, title, params, ordering FROM {$wpdb->prefix}nextend2_smartslider3_slides WHERE slider=%d ORDER BY ordering",
FEA_SLIDER_ID
), ARRAY_A);
$by_image = [];
foreach ($existing as $row) {
$p = json_decode($row['params'], true) ?: [];
$img = isset($p['backgroundImage']) ? basename($p['backgroundImage']) : null;
if ($img) $by_image[$img] = $row;
}
$keep_ids = [];
$ordering = 0;
foreach ($files as $file) {
$ordering++;
if (isset($by_image[$file])) {
// Reutilizar slide existente — actualizar params si fuera necesario
$row = $by_image[$file];
$p = json_decode($row['params'], true) ?: [];
$expected = $reldir . '/' . $file;
$needs_update = false;
if (($p['backgroundImage'] ?? '') !== $expected) { $p['backgroundImage'] = $expected; $needs_update = true; }
if (($p['background-type'] ?? '') !== 'image') { $p['background-type'] = 'image'; $needs_update = true; }
if ($needs_update) {
$wpdb->update(
$wpdb->prefix . 'nextend2_smartslider3_slides',
['params' => wp_json_encode($p), 'ordering' => $ordering],
['id' => $row['id']],
['%s','%d'], ['%d']
);
} else {
$wpdb->update(
$wpdb->prefix . 'nextend2_smartslider3_slides',
['ordering' => $ordering],
['id' => $row['id']],
['%d'], ['%d']
);
}
$keep_ids[] = (int) $row['id'];
} else {
// Crear slide nuevo
$title = pathinfo($file, PATHINFO_FILENAME);
$params = wp_json_encode([
'background-type' => 'image',
'backgroundImage' => $reldir . '/' . $file,
'version' => '3.5.1.32',
]);
$img_url = $reldir . '/' . $file;
$wpdb->insert(
$wpdb->prefix . 'nextend2_smartslider3_slides',
[
'slider' => FEA_SLIDER_ID,
'title' => $title,
'description' => '',
'params' => $params,
'slide' => '[]',
'thumbnail' => $img_url,
'publish_up' => '1970-01-01 00:00:00',
'publish_down' => '1970-01-01 00:00:00',
'published' => 1,
'first' => 0,
'generator_id' => 0,
'ordering' => $ordering,
],
['%d','%s','%s','%s','%s','%s','%s','%s','%d','%d','%d','%d']
);
$keep_ids[] = (int) $wpdb->insert_id;
}
}
// Borrar slides cuya imagen ya no está en el directorio
if ($keep_ids) {
$in = implode(',', array_map('intval', $keep_ids));
$wpdb->query($wpdb->prepare(
"DELETE FROM {$wpdb->prefix}nextend2_smartslider3_slides WHERE slider=%d AND id NOT IN ($in)",
FEA_SLIDER_ID
));
} else {
$wpdb->query($wpdb->prepare(
"DELETE FROM {$wpdb->prefix}nextend2_smartslider3_slides WHERE slider=%d",
FEA_SLIDER_ID
));
}
update_option(FEA_SLIDER_OPT_KEY, $mtime);
// Marcar slider como cambiado para que SS3 regenere su manifest
$wpdb->update(
$wpdb->prefix . 'nextend2_section_storage',
['value' => (string) $mtime],
['application' => 'smartslider', 'section' => 'sliderChanged', 'referenceKey' => (string) FEA_SLIDER_ID],
['%s'], ['%s','%s','%s']
);
return count($files);
}
// Ejecutar sync en cada carga de portada (la comprobación de mtime evita trabajo si nada cambió).
add_action('template_redirect', function() {
if (!is_front_page()) return;
fea_slider_home_sync_now();
}, 5);
// Sync también al entrar al admin (por si el editor sube ficheros desde wp-admin).
add_action('admin_init', function() {
fea_slider_home_sync_now();
});
// WP-CLI helper: `wp eval "fea_slider_home_sync_now(true);"` fuerza resync ignorando mtime.