Añadir mu-plugins y scripts de feadulta
This commit is contained in:
@@ -0,0 +1,453 @@
|
||||
<?php
|
||||
/**
|
||||
* fea-pensamientos — Galerías Joomla y pausa aleatoria en artículos.
|
||||
*
|
||||
* Reutiliza /images de Joomla sin duplicar ficheros en WordPress.
|
||||
*/
|
||||
|
||||
if (!defined('FEA_JOOMLA_IMAGES_DIR')) {
|
||||
define('FEA_JOOMLA_IMAGES_DIR', file_exists('/web/images') ? '/web/images' : '/var/www/joomla-images');
|
||||
}
|
||||
|
||||
if (!defined('FEA_JOOMLA_IMAGES_URL')) {
|
||||
$fea_is_prod = (defined('ABSPATH') && strpos((string) ABSPATH, '/web/wp-nuevo/') === 0)
|
||||
|| (isset($_SERVER['HTTP_HOST']) && preg_match('/(^|\.)feadulta\.com$/', (string) $_SERVER['HTTP_HOST']))
|
||||
|| file_exists('/web/images');
|
||||
|
||||
define(
|
||||
'FEA_JOOMLA_IMAGES_URL',
|
||||
$fea_is_prod ? 'https://www.feadulta.com/images' : 'https://farmer.taild3aaf6.ts.net/joomla/images'
|
||||
);
|
||||
}
|
||||
|
||||
if (!defined('FEA_PENS_DIR')) {
|
||||
define('FEA_PENS_DIR', rtrim(FEA_JOOMLA_IMAGES_DIR, '/') . '/Pensamientos');
|
||||
}
|
||||
|
||||
if (!defined('FEA_PENS_URL')) {
|
||||
define('FEA_PENS_URL', rtrim(FEA_JOOMLA_IMAGES_URL, '/') . '/Pensamientos');
|
||||
}
|
||||
|
||||
if (!defined('FEA_GALLERY_PER_PAGE')) {
|
||||
define('FEA_GALLERY_PER_PAGE', 72);
|
||||
}
|
||||
|
||||
if (!defined('FEA_RANDOM_THOUGHT_EXCLUDED_CATS')) {
|
||||
// Categorías que NO muestran pensamiento aleatorio:
|
||||
// 1645 Lecturas bíblicas · 28 Evangelios y comentarios (textos del evangelio)
|
||||
// 20 Presentación colaboradores (fichas de colaboradores)
|
||||
// 1647 Comentarios al evangelio SÍ muestra pensamiento (decisión Rafa 2026-06-19).
|
||||
define('FEA_RANDOM_THOUGHT_EXCLUDED_CATS', '1645,28,20');
|
||||
}
|
||||
|
||||
if (!defined('FEA_RANDOM_THOUGHT_EXCLUDED_IDS')) {
|
||||
// Posts estructurales (páginas disfrazadas de post) que no deben llevar pensamiento.
|
||||
// 17563 = índice /colaboradores/ (está en «Sin categoría», no lo cubre la cat 20).
|
||||
define('FEA_RANDOM_THOUGHT_EXCLUDED_IDS', '17563');
|
||||
}
|
||||
|
||||
if (!defined('FEA_GALLERY_MANIFEST')) {
|
||||
define('FEA_GALLERY_MANIFEST', WP_CONTENT_DIR . '/uploads/fea-gallery-manifest.json');
|
||||
}
|
||||
|
||||
function fea_gallery_safe_dir(string $dir): string {
|
||||
$dir = trim($dir);
|
||||
$dir = trim($dir, "/\\ \t\n\r\0\x0B");
|
||||
return preg_replace('/[^A-Za-z0-9._-]/', '', $dir);
|
||||
}
|
||||
|
||||
function fea_gallery_base_dir(): string {
|
||||
return rtrim(FEA_JOOMLA_IMAGES_DIR, '/');
|
||||
}
|
||||
|
||||
function fea_gallery_base_url(): string {
|
||||
return rtrim(FEA_JOOMLA_IMAGES_URL, '/');
|
||||
}
|
||||
|
||||
function fea_gallery_manifest_files(string $dir, string $order = 'desc'): array {
|
||||
static $manifest = null;
|
||||
|
||||
if ($manifest === null) {
|
||||
$manifest = [];
|
||||
$path = (string) FEA_GALLERY_MANIFEST;
|
||||
if (is_readable($path)) {
|
||||
$decoded = json_decode((string) file_get_contents($path), true);
|
||||
if (is_array($decoded)) {
|
||||
$manifest = $decoded;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($manifest[$dir]) || !is_array($manifest[$dir])) return [];
|
||||
|
||||
$files = array_values(array_filter(array_map('strval', $manifest[$dir]), function ($file) {
|
||||
return preg_match('/\.(jpe?g|png|gif|webp)$/i', $file);
|
||||
}));
|
||||
natsort($files);
|
||||
$files = array_values($files);
|
||||
if ($order === 'desc') {
|
||||
$files = array_reverse($files);
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
function fea_gallery_files(string $dir, string $order = 'desc'): array {
|
||||
$dir = fea_gallery_safe_dir($dir);
|
||||
if ($dir === '') return [];
|
||||
|
||||
$path = fea_gallery_base_dir() . '/' . $dir;
|
||||
if (!is_dir($path) || !is_readable($path)) {
|
||||
return fea_gallery_manifest_files($dir, $order);
|
||||
}
|
||||
|
||||
$mtime = (int) @filemtime($path);
|
||||
$cache_key = 'fea_gallery_' . md5($path . '|' . $mtime . '|' . $order);
|
||||
$cached = get_transient($cache_key);
|
||||
if (is_array($cached)) return $cached;
|
||||
|
||||
$files = [];
|
||||
$entries = @scandir($path);
|
||||
if (!is_array($entries)) return [];
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry === '.' || $entry === '..') continue;
|
||||
if (!preg_match('/\.(jpe?g|png|gif|webp)$/i', $entry)) continue;
|
||||
if (!is_file($path . '/' . $entry)) continue;
|
||||
$files[] = $entry;
|
||||
}
|
||||
|
||||
natsort($files);
|
||||
$files = array_values($files);
|
||||
if ($order === 'desc') {
|
||||
$files = array_reverse($files);
|
||||
}
|
||||
|
||||
set_transient($cache_key, $files, 10 * MINUTE_IN_SECONDS);
|
||||
return $files;
|
||||
}
|
||||
|
||||
function fea_gallery_url(string $dir, string $file): string {
|
||||
return fea_gallery_base_url() . '/' . rawurlencode(fea_gallery_safe_dir($dir)) . '/' . rawurlencode($file);
|
||||
}
|
||||
|
||||
function fea_gallery_page_param(string $dir): string {
|
||||
return 'fea_gallery_' . substr(md5($dir), 0, 8);
|
||||
}
|
||||
|
||||
function fea_gallery_render(array $atts = []): string {
|
||||
$atts = shortcode_atts([
|
||||
'dir' => 'Pensamientos',
|
||||
'per_page' => (string) FEA_GALLERY_PER_PAGE,
|
||||
'order' => 'desc',
|
||||
], $atts, 'fea_galeria');
|
||||
|
||||
$dir = fea_gallery_safe_dir((string) $atts['dir']);
|
||||
if ($dir === '') return '';
|
||||
|
||||
$order = strtolower((string) $atts['order']) === 'asc' ? 'asc' : 'desc';
|
||||
$files = fea_gallery_files($dir, $order);
|
||||
if (!$files) {
|
||||
return '<p class="fea-gallery-empty">Galería no disponible.</p>';
|
||||
}
|
||||
|
||||
$per_page = max(12, min(144, (int) $atts['per_page']));
|
||||
$total = count($files);
|
||||
$pages = max(1, (int) ceil($total / $per_page));
|
||||
$param = fea_gallery_page_param($dir);
|
||||
$page = isset($_GET[$param]) ? max(1, (int) $_GET[$param]) : 1;
|
||||
$page = min($page, $pages);
|
||||
$offset = ($page - 1) * $per_page;
|
||||
$visible = array_slice($files, $offset, $per_page);
|
||||
|
||||
$html = '<div class="fea-gallery" data-fea-gallery="' . esc_attr($dir) . '">';
|
||||
$html .= '<div class="fea-gallery-grid">';
|
||||
foreach ($visible as $file) {
|
||||
$url = fea_gallery_url($dir, $file);
|
||||
$alt = preg_replace('/\.[^.]+$/', '', $file);
|
||||
$html .= '<a class="fea-gallery-item" href="' . esc_url($url) . '" data-fea-lightbox="1">';
|
||||
$html .= '<img src="' . esc_url($url) . '" alt="' . esc_attr($alt) . '" loading="lazy" decoding="async">';
|
||||
$html .= '</a>';
|
||||
}
|
||||
$html .= '</div>';
|
||||
|
||||
if ($pages > 1) {
|
||||
$html .= '<nav class="fea-gallery-pages" aria-label="Paginación de galería">';
|
||||
if ($page > 1) {
|
||||
$html .= '<a href="' . esc_url(add_query_arg($param, $page - 1)) . '">Anterior</a>';
|
||||
}
|
||||
$html .= '<span>Página ' . esc_html((string) $page) . ' de ' . esc_html((string) $pages) . '</span>';
|
||||
if ($page < $pages) {
|
||||
$html .= '<a href="' . esc_url(add_query_arg($param, $page + 1)) . '">Siguiente</a>';
|
||||
}
|
||||
$html .= '</nav>';
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
add_shortcode('fea_galeria', 'fea_gallery_render');
|
||||
|
||||
add_filter('the_content', function ($content) {
|
||||
if (is_admin() || stripos($content, '{gallery}') === false) return $content;
|
||||
|
||||
return preg_replace_callback(
|
||||
'/\{gallery\}\s*([^{}]+?)\s*\{\/gallery\}/i',
|
||||
function ($m) {
|
||||
return fea_gallery_render(['dir' => trim($m[1])]);
|
||||
},
|
||||
$content
|
||||
);
|
||||
}, 8);
|
||||
|
||||
function fea_random_thought_html(): string {
|
||||
$files = fea_gallery_files('Pensamientos', 'desc');
|
||||
if (!$files) return '';
|
||||
|
||||
$file = $files[array_rand($files)];
|
||||
$url = fea_gallery_url('Pensamientos', $file);
|
||||
|
||||
return '<aside class="fea-random-thought" aria-label="Una pausa">'
|
||||
. '<div class="fea-random-thought-title"><span></span><strong>Una pausa para el alma</strong><span></span></div>'
|
||||
. '<a href="' . esc_url($url) . '" data-fea-lightbox="1">'
|
||||
. '<img src="' . esc_url($url) . '" alt="Pensamiento aleatorio" loading="lazy" decoding="async">'
|
||||
. '</a></aside>';
|
||||
}
|
||||
|
||||
function fea_random_thought_excluded(): bool {
|
||||
if (!is_singular('post')) return true;
|
||||
|
||||
$post_id = get_the_ID();
|
||||
|
||||
$excluded_ids = array_filter(array_map('intval', explode(',', (string) FEA_RANDOM_THOUGHT_EXCLUDED_IDS)));
|
||||
if ($post_id && in_array((int) $post_id, $excluded_ids, true)) return true;
|
||||
|
||||
if ($post_id) {
|
||||
$raw = (string) get_post_field('post_content', $post_id);
|
||||
if (stripos($raw, '{gallery}') !== false || stripos($raw, '[fea_galeria') !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$ids = array_filter(array_map('intval', explode(',', (string) FEA_RANDOM_THOUGHT_EXCLUDED_CATS)));
|
||||
foreach ($ids as $id) {
|
||||
if ($id > 0 && has_category($id)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
add_shortcode('fea_reflexion_aleatoria', function () {
|
||||
return fea_random_thought_html();
|
||||
});
|
||||
|
||||
add_filter('the_content', function ($content) {
|
||||
if (is_admin() || !is_main_query() || !in_the_loop() || fea_random_thought_excluded()) {
|
||||
return $content;
|
||||
}
|
||||
if (strpos($content, 'fea-random-thought') !== false) return $content;
|
||||
|
||||
$thought = fea_random_thought_html();
|
||||
return $thought ? $content . $thought : $content;
|
||||
}, 18);
|
||||
|
||||
function fea_pensamientos_assets_needed(): bool {
|
||||
if (!is_singular()) return false;
|
||||
|
||||
$post_id = get_queried_object_id();
|
||||
$raw = $post_id ? (string) get_post_field('post_content', $post_id) : '';
|
||||
if (stripos($raw, '{gallery}') !== false || stripos($raw, '[fea_galeria') !== false || stripos($raw, '[fea_reflexion_aleatoria') !== false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !fea_random_thought_excluded();
|
||||
}
|
||||
|
||||
add_action('wp_head', function () {
|
||||
if (!fea_pensamientos_assets_needed()) return;
|
||||
|
||||
?>
|
||||
<style>
|
||||
.fea-gallery {
|
||||
width: min(1180px, 100%);
|
||||
max-width: none;
|
||||
margin: 1.5rem auto 2rem;
|
||||
}
|
||||
.fea-gallery .fea-gallery-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
|
||||
gap: 0.65rem !important;
|
||||
}
|
||||
.fea-gallery-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
aspect-ratio: 275 / 160;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(0,0,0,0.08);
|
||||
border-radius: 3px;
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.07);
|
||||
}
|
||||
.fea-gallery-item img {
|
||||
width: 98.5%;
|
||||
height: 96.5%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
transition: transform 0.16s ease;
|
||||
}
|
||||
.fea-gallery-item:hover img { transform: scale(1.02); }
|
||||
.fea-gallery-pages {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
margin-top: 1.25rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.fea-gallery-pages a {
|
||||
padding: 0.45rem 0.75rem;
|
||||
border: 1px solid currentColor;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.fea-random-thought {
|
||||
margin: 2.4rem auto 1.4rem;
|
||||
max-width: 720px;
|
||||
text-align: center;
|
||||
}
|
||||
.fea-random-thought-title {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #7f1d1d;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.fea-random-thought-title span {
|
||||
height: 1px;
|
||||
background: currentColor;
|
||||
opacity: 0.28;
|
||||
}
|
||||
.fea-random-thought a { display: inline-block; max-width: min(100%, 560px); }
|
||||
.fea-random-thought img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.14);
|
||||
}
|
||||
.fea-lightbox {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 99999;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4rem 5rem;
|
||||
background: rgba(0,0,0,0.86);
|
||||
}
|
||||
.fea-lightbox.is-open { display: flex; }
|
||||
.fea-lightbox-frame {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.fea-lightbox-frame img {
|
||||
max-width: min(100%, 1100px);
|
||||
max-height: calc(100vh - 8rem);
|
||||
width: auto;
|
||||
height: auto;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
box-shadow: 0 18px 60px rgba(0,0,0,0.45);
|
||||
}
|
||||
.fea-lightbox button {
|
||||
position: absolute;
|
||||
border: 0;
|
||||
border-radius: 999px;
|
||||
background: rgba(255,255,255,0.92);
|
||||
color: #111;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
.fea-lightbox-close {
|
||||
top: 0.75rem;
|
||||
right: 0.75rem;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
.fea-lightbox-prev,
|
||||
.fea-lightbox-next {
|
||||
top: 50%;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
font-size: 2rem;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.fea-lightbox-prev { left: 1rem; }
|
||||
.fea-lightbox-next { right: 1rem; }
|
||||
@media (max-width: 700px) {
|
||||
.fea-gallery { width: min(100%, calc(100vw - 1rem)); }
|
||||
.fea-gallery .fea-gallery-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
|
||||
.fea-lightbox { padding: 3.5rem 1rem; }
|
||||
.fea-lightbox-prev,
|
||||
.fea-lightbox-next {
|
||||
top: auto;
|
||||
bottom: 0.75rem;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var links = Array.prototype.slice.call(document.querySelectorAll('[data-fea-lightbox="1"]'));
|
||||
if (!links.length) return;
|
||||
|
||||
var box = document.createElement('div');
|
||||
box.className = 'fea-lightbox';
|
||||
box.innerHTML = '<button type="button" class="fea-lightbox-close" aria-label="Cerrar">×</button><button type="button" class="fea-lightbox-prev" aria-label="Anterior">‹</button><div class="fea-lightbox-frame"><img alt=""></div><button type="button" class="fea-lightbox-next" aria-label="Siguiente">›</button>';
|
||||
document.body.appendChild(box);
|
||||
|
||||
var img = box.querySelector('img');
|
||||
var closeButton = box.querySelector('.fea-lightbox-close');
|
||||
var prevButton = box.querySelector('.fea-lightbox-prev');
|
||||
var nextButton = box.querySelector('.fea-lightbox-next');
|
||||
var index = 0;
|
||||
|
||||
var show = function (nextIndex) {
|
||||
index = (nextIndex + links.length) % links.length;
|
||||
img.src = links[index].href;
|
||||
img.alt = links[index].querySelector('img') ? links[index].querySelector('img').alt : '';
|
||||
box.classList.add('is-open');
|
||||
};
|
||||
var close = function () {
|
||||
box.classList.remove('is-open');
|
||||
img.removeAttribute('src');
|
||||
};
|
||||
|
||||
box.addEventListener('click', function (event) {
|
||||
if (event.target === box) close();
|
||||
});
|
||||
closeButton.addEventListener('click', close);
|
||||
prevButton.addEventListener('click', function () { show(index - 1); });
|
||||
nextButton.addEventListener('click', function () { show(index + 1); });
|
||||
document.addEventListener('keydown', function (event) {
|
||||
if (!box.classList.contains('is-open')) return;
|
||||
if (event.key === 'Escape') close();
|
||||
if (event.key === 'ArrowLeft') show(index - 1);
|
||||
if (event.key === 'ArrowRight') show(index + 1);
|
||||
});
|
||||
links.forEach(function (link, linkIndex) {
|
||||
link.addEventListener('click', function (event) {
|
||||
event.preventDefault();
|
||||
show(linkIndex);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}, 30);
|
||||
Reference in New Issue
Block a user