- Adopción sin filtros ni etiquetas: acceso a Perros y Gatos, tarjetas de foto y nombre. - Ficha nueva: galería, vídeo, fecha de nacimiento o edad aproximada, carácter, necesidades, convivencia y hogar que buscamos (textos por idioma, datos compartidos). - Estados disponible / en proceso / adoptado y animales destacados. - Botón «Quiero conocerlo/la» con formulario breve (animal incluido) y confirmación. - Botones para compartir cada ficha (WhatsApp, Facebook, copiar enlace). - Portada corta según la propuesta del cliente; donaciones, cifras, etc. ocultas. - Páginas Acoge y Preguntas frecuentes, menú con submenús, sin hotel. - Aviso de cita previa y lista de ayuda material editables desde el panel. - Plugin núcleo dividido en módulos (i18n, animales, formularios, APIs). - Migración 5 idempotente: respeta las páginas editadas por el cliente. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
520 lines
21 KiB
PHP
520 lines
21 KiB
PHP
<?php
|
||
/**
|
||
* Animales en adopción: tipo de contenido, ficha, galería, consultas y listados.
|
||
*/
|
||
|
||
defined( 'ABSPATH' ) || exit;
|
||
|
||
/* -------------------------------------------------------------------------
|
||
* Tipos de contenido y taxonomías
|
||
* ---------------------------------------------------------------------- */
|
||
|
||
add_action( 'init', function () {
|
||
register_post_type( 'animal', array(
|
||
'labels' => array(
|
||
'name' => 'Animales',
|
||
'singular_name' => 'Animal',
|
||
'add_new' => 'Añadir animal',
|
||
'add_new_item' => 'Añadir nuevo animal',
|
||
'edit_item' => 'Editar animal',
|
||
'new_item' => 'Nuevo animal',
|
||
'view_item' => 'Ver ficha',
|
||
'search_items' => 'Buscar animales',
|
||
'not_found' => 'No hay animales',
|
||
'not_found_in_trash' => 'No hay animales en la papelera',
|
||
'all_items' => 'Todos los animales',
|
||
'featured_image' => 'Foto principal',
|
||
'set_featured_image' => 'Elegir foto principal',
|
||
'remove_featured_image' => 'Quitar foto principal',
|
||
'use_featured_image' => 'Usar como foto principal',
|
||
'excerpt' => 'Frase corta',
|
||
'menu_name' => 'Animales',
|
||
),
|
||
'public' => true,
|
||
'has_archive' => 'adopta',
|
||
'rewrite' => array( 'slug' => 'adopta', 'with_front' => false ),
|
||
'menu_icon' => 'dashicons-pets',
|
||
'menu_position' => 5,
|
||
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
|
||
'show_in_rest' => true,
|
||
'rest_base' => 'animales',
|
||
'show_in_graphql' => true,
|
||
'graphql_single_name' => 'animal',
|
||
'graphql_plural_name' => 'animales',
|
||
) );
|
||
|
||
register_taxonomy( 'especie', 'animal', array(
|
||
'labels' => array(
|
||
'name' => 'Especies',
|
||
'singular_name' => 'Especie',
|
||
'add_new_item' => 'Añadir especie',
|
||
),
|
||
'hierarchical' => true,
|
||
'show_admin_column' => true,
|
||
'show_in_rest' => true,
|
||
'rest_base' => 'especies',
|
||
'show_in_graphql' => true,
|
||
'graphql_single_name' => 'especie',
|
||
'graphql_plural_name' => 'especies',
|
||
'rewrite' => array( 'slug' => 'especie', 'with_front' => false ),
|
||
) );
|
||
|
||
register_post_type( 'ga_mensaje', array(
|
||
'labels' => array(
|
||
'name' => 'Mensajes',
|
||
'singular_name' => 'Mensaje',
|
||
'edit_item' => 'Mensaje',
|
||
'all_items' => 'Mensajes recibidos',
|
||
'not_found' => 'Aún no hay mensajes',
|
||
),
|
||
'public' => false,
|
||
'show_ui' => true,
|
||
'menu_icon' => 'dashicons-email-alt',
|
||
'menu_position' => 6,
|
||
'supports' => array( 'title', 'editor' ),
|
||
'capability_type' => 'post',
|
||
'capabilities' => array( 'create_posts' => 'do_not_allow' ),
|
||
'map_meta_cap' => true,
|
||
) );
|
||
|
||
foreach ( array_keys( ga_fields() ) as $key ) {
|
||
register_post_meta( 'animal', "_ga_$key", array(
|
||
'type' => 'string',
|
||
'single' => true,
|
||
'show_in_rest' => true,
|
||
'auth_callback' => fn() => current_user_can( 'edit_posts' ),
|
||
) );
|
||
}
|
||
} );
|
||
|
||
/* -------------------------------------------------------------------------
|
||
* Campos de la ficha
|
||
*
|
||
* 'shared' => true: el dato es común a la versión en castellano y en euskera.
|
||
* Los textos (carácter, necesidades…) se escriben en cada idioma.
|
||
* ---------------------------------------------------------------------- */
|
||
|
||
function ga_fields() {
|
||
return array(
|
||
'estado' => array( 'shared' => true, 'label' => ga__( 'Estado', 'Egoera' ), 'type' => 'select', 'options' => array(
|
||
'disponible' => ga__( 'Disponible', 'Eskuragarri' ),
|
||
'proceso' => ga__( 'En proceso', 'Prozesuan' ),
|
||
'adoptado' => ga__( 'Adoptado', 'Adoptatuta' ),
|
||
), 'help' => 'Los adoptados salen solos del listado.' ),
|
||
'destacado' => array( 'shared' => true, 'label' => ga__( 'Destacado', 'Nabarmendua' ), 'type' => 'checkbox', 'help' => 'Aparece en la portada. Útil para quien lleva más tiempo esperando o necesita un hogar especial.' ),
|
||
'sexo' => array( 'shared' => true, 'label' => ga__( 'Sexo', 'Sexua' ), 'type' => 'select', 'options' => array(
|
||
'macho' => ga__( 'Macho', 'Arra' ),
|
||
'hembra' => ga__( 'Hembra', 'Emea' ),
|
||
) ),
|
||
'nacimiento' => array( 'shared' => true, 'label' => ga__( 'Fecha de nacimiento', 'Jaiotze-data' ), 'type' => 'date', 'help' => 'Si no se conoce, deja la fecha vacía y rellena la edad aproximada.' ),
|
||
'edad' => array( 'shared' => true, 'label' => ga__( 'Edad aproximada', 'Gutxi gorabeherako adina' ), 'type' => 'number' ),
|
||
'edad_unidad' => array( 'shared' => true, 'label' => ga__( 'Edad en', 'Adina' ), 'type' => 'select', 'options' => array(
|
||
'anos' => ga__( 'Años', 'Urteak' ),
|
||
'meses' => ga__( 'Meses', 'Hilabeteak' ),
|
||
) ),
|
||
'tamano' => array( 'shared' => true, 'label' => ga__( 'Tamaño', 'Tamaina' ), 'type' => 'select', 'options' => array(
|
||
'pequeno' => ga__( 'Pequeño', 'Txikia' ),
|
||
'mediano' => ga__( 'Mediano', 'Ertaina' ),
|
||
'grande' => ga__( 'Grande', 'Handia' ),
|
||
), 'help' => 'Solo en perros.' ),
|
||
'llegada' => array( 'shared' => true, 'label' => ga__( 'En Bilagun desde', 'Bilagunen noiztik' ), 'type' => 'date', 'help' => 'Fecha de entrada, solo si está confirmada.' ),
|
||
'galeria' => array( 'shared' => true, 'label' => ga__( 'Más fotos', 'Argazki gehiago' ), 'type' => 'gallery' ),
|
||
'video' => array( 'shared' => true, 'label' => ga__( 'Vídeo', 'Bideoa' ), 'type' => 'url', 'help' => 'Enlace de YouTube, Vimeo o Instagram, o un vídeo subido a la biblioteca.' ),
|
||
|
||
'caracter' => array( 'label' => ga__( 'Cómo es', 'Nolakoa den' ), 'type' => 'textarea', 'help' => 'Su carácter, contado como en redes.' ),
|
||
'necesidades' => array( 'label' => ga__( 'Qué necesita', 'Zer behar duen' ), 'type' => 'textarea' ),
|
||
'convivencia' => array( 'label' => ga__( 'Convivencia con niños y otros animales', 'Haurrekin eta beste animaliekin bizikidetza' ), 'type' => 'textarea', 'help' => 'Solo lo observado, con contexto. Déjalo vacío si no lo sabemos.' ),
|
||
'hogar' => array( 'label' => ga__( 'El hogar que buscamos', 'Bilatzen dugun etxea' ), 'type' => 'textarea' ),
|
||
);
|
||
}
|
||
|
||
function ga_get( $post_id, $key ) {
|
||
return (string) get_post_meta( $post_id, "_ga_$key", true );
|
||
}
|
||
|
||
/** Estado normalizado (acepta valores antiguos). */
|
||
function ga_status( $post_id ) {
|
||
$estado = ga_get( $post_id, 'estado' );
|
||
return match ( $estado ) {
|
||
'adoptado' => 'adoptado',
|
||
'proceso', 'reservado' => 'proceso',
|
||
default => 'disponible',
|
||
};
|
||
}
|
||
|
||
/** Etiqueta legible de un campo de opciones. */
|
||
function ga_label( $post_id, $key ) {
|
||
$fields = ga_fields();
|
||
$value = 'estado' === $key ? ga_status( $post_id ) : ga_get( $post_id, $key );
|
||
if ( '' === $value || ! isset( $fields[ $key ] ) ) {
|
||
return '';
|
||
}
|
||
$field = $fields[ $key ];
|
||
if ( 'select' === $field['type'] ) {
|
||
return $field['options'][ $value ] ?? '';
|
||
}
|
||
if ( 'date' === $field['type'] ) {
|
||
return date_i18n( get_option( 'date_format' ), strtotime( $value ) );
|
||
}
|
||
return $value;
|
||
}
|
||
|
||
/** Edad legible: calculada desde la fecha de nacimiento o la aproximada. */
|
||
function ga_age( $post_id ) {
|
||
$birth = ga_get( $post_id, 'nacimiento' );
|
||
if ( $birth && strtotime( $birth ) ) {
|
||
$diff = date_diff( date_create( $birth ), date_create( 'today' ) );
|
||
$n = $diff->y ?: $diff->m;
|
||
$months = ! $diff->y;
|
||
if ( ! $n ) {
|
||
return ga__( 'Menos de un mes', 'Hilabete bat baino gutxiago' );
|
||
}
|
||
} else {
|
||
$n = ga_get( $post_id, 'edad' );
|
||
if ( '' === $n || ! is_numeric( $n ) ) {
|
||
return '';
|
||
}
|
||
$n = (float) $n + 0;
|
||
$months = 'meses' === ga_get( $post_id, 'edad_unidad' );
|
||
}
|
||
if ( 'eu' === ga_lang() ) {
|
||
return $n . ( $months ? ' hilabete' : ' urte' );
|
||
}
|
||
if ( $months ) {
|
||
return $n . ( 1 == $n ? ' mes' : ' meses' );
|
||
}
|
||
return $n . ( 1 == $n ? ' año' : ' años' );
|
||
}
|
||
|
||
/** ¿Es un perro? (el tamaño solo se muestra en perros) */
|
||
function ga_is_dog( $post_id ) {
|
||
$terms = get_the_terms( $post_id, 'especie' ) ?: array();
|
||
foreach ( $terms as $term ) {
|
||
if ( in_array( $term->slug, array( 'perro', 'txakurra' ), true ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/** IDs de las fotos: la principal primero y después la galería. */
|
||
function ga_gallery_ids( $post_id ) {
|
||
$ids = array_filter( array_map( 'absint', explode( ',', ga_get( $post_id, 'galeria' ) ) ) );
|
||
if ( has_post_thumbnail( $post_id ) ) {
|
||
array_unshift( $ids, (int) get_post_thumbnail_id( $post_id ) );
|
||
}
|
||
return array_values( array_unique( $ids ) );
|
||
}
|
||
|
||
/* -------------------------------------------------------------------------
|
||
* Ficha en el panel
|
||
* ---------------------------------------------------------------------- */
|
||
|
||
/* Editor clásico para los animales: la historia arriba y la ficha justo debajo, siempre a la vista. */
|
||
add_filter( 'use_block_editor_for_post_type', fn( $use, $type ) => 'animal' === $type ? false : $use, 10, 2 );
|
||
|
||
/* El cuadro de Yoast SEO va al final, debajo de la ficha. */
|
||
add_filter( 'wpseo_metabox_prio', fn() => 'low' );
|
||
|
||
add_action( 'add_meta_boxes_animal', function () {
|
||
add_meta_box( 'ga_ficha', 'Ficha del animal', 'ga_render_metabox', 'animal', 'normal', 'high' );
|
||
} );
|
||
|
||
function ga_render_metabox( $post ) {
|
||
wp_nonce_field( 'ga_ficha', 'ga_ficha_nonce' );
|
||
$fields = ga_fields();
|
||
$groups = array(
|
||
'Datos (comunes a castellano y euskera)' => array_filter( $fields, fn( $f ) => ! empty( $f['shared'] ) ),
|
||
'Textos de la ficha (en el idioma de esta página)' => array_filter( $fields, fn( $f ) => empty( $f['shared'] ) ),
|
||
);
|
||
echo '<p class="description">La historia se escribe en el editor principal. La «frase corta» (extracto) es opcional.</p>';
|
||
foreach ( $groups as $title => $group ) {
|
||
echo '<h3 style="margin:24px 0 4px">' . esc_html( $title ) . '</h3><table class="form-table" role="presentation"><tbody>';
|
||
foreach ( $group as $key => $f ) {
|
||
$name = "ga_$key";
|
||
$value = 'estado' === $key ? ga_status( $post->ID ) : ga_get( $post->ID, $key );
|
||
echo '<tr><th scope="row"><label for="' . esc_attr( $name ) . '">' . esc_html( $f['label'] ) . '</label></th><td>';
|
||
switch ( $f['type'] ) {
|
||
case 'select':
|
||
echo '<select id="' . esc_attr( $name ) . '" name="' . esc_attr( $name ) . '">';
|
||
if ( 'estado' !== $key ) {
|
||
echo '<option value="">—</option>';
|
||
}
|
||
foreach ( $f['options'] as $v => $l ) {
|
||
printf( '<option value="%s"%s>%s</option>', esc_attr( $v ), selected( $value, $v, false ), esc_html( $l ) );
|
||
}
|
||
echo '</select>';
|
||
break;
|
||
case 'checkbox':
|
||
printf( '<label><input type="checkbox" id="%1$s" name="%1$s" value="1"%2$s> Sí</label>', esc_attr( $name ), checked( $value, '1', false ) );
|
||
break;
|
||
case 'textarea':
|
||
printf( '<textarea id="%1$s" name="%1$s" rows="4" class="large-text">%2$s</textarea>', esc_attr( $name ), esc_textarea( $value ) );
|
||
break;
|
||
case 'gallery':
|
||
printf( '<input type="hidden" id="%1$s" name="%1$s" value="%2$s">', esc_attr( $name ), esc_attr( $value ) );
|
||
echo '<div class="ga-gallery-admin" data-input="' . esc_attr( $name ) . '">';
|
||
foreach ( array_filter( explode( ',', $value ) ) as $id ) {
|
||
$thumb = wp_get_attachment_image( (int) $id, array( 80, 80 ) );
|
||
if ( $thumb ) {
|
||
printf( '<span class="ga-gallery-admin__item" data-id="%d">%s<button type="button" aria-label="Quitar">×</button></span>', (int) $id, $thumb );
|
||
}
|
||
}
|
||
echo '</div><button type="button" class="button ga-gallery-add">Añadir fotos</button>';
|
||
break;
|
||
case 'number':
|
||
printf( '<input type="number" min="0" step="1" id="%1$s" name="%1$s" value="%2$s" class="small-text">', esc_attr( $name ), esc_attr( $value ) );
|
||
break;
|
||
default:
|
||
printf( '<input type="%1$s" id="%2$s" name="%2$s" value="%3$s" class="regular-text">', esc_attr( $f['type'] ), esc_attr( $name ), esc_attr( $value ) );
|
||
}
|
||
if ( ! empty( $f['help'] ) ) {
|
||
echo '<p class="description">' . esc_html( $f['help'] ) . '</p>';
|
||
}
|
||
echo '</td></tr>';
|
||
}
|
||
echo '</tbody></table>';
|
||
}
|
||
}
|
||
|
||
/* Selector de fotos de la galería */
|
||
add_action( 'admin_enqueue_scripts', function ( $hook ) {
|
||
if ( ! in_array( $hook, array( 'post.php', 'post-new.php' ), true ) || 'animal' !== get_current_screen()->post_type ) {
|
||
return;
|
||
}
|
||
wp_enqueue_media();
|
||
wp_add_inline_style( 'wp-admin', '.ga-gallery-admin{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}.ga-gallery-admin__item{position:relative;cursor:move}.ga-gallery-admin__item img{display:block;width:80px;height:80px;object-fit:cover;border-radius:6px}.ga-gallery-admin__item button{position:absolute;top:-6px;right:-6px;width:22px;height:22px;border-radius:50%;border:0;background:#b32d2e;color:#fff;cursor:pointer;line-height:1}' );
|
||
wp_add_inline_script( 'media-editor', <<<'JS'
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
document.querySelectorAll('.ga-gallery-admin').forEach(function (box) {
|
||
var input = document.getElementById(box.dataset.input);
|
||
var sync = function () {
|
||
input.value = Array.from(box.querySelectorAll('[data-id]')).map(function (el) { return el.dataset.id; }).join(',');
|
||
};
|
||
box.addEventListener('click', function (e) {
|
||
if (e.target.tagName === 'BUTTON') { e.target.parentNode.remove(); sync(); }
|
||
});
|
||
box.nextElementSibling.addEventListener('click', function () {
|
||
var frame = wp.media({ title: 'Fotos del animal', multiple: 'add', library: { type: 'image' }, button: { text: 'Añadir a la ficha' } });
|
||
frame.on('select', function () {
|
||
frame.state().get('selection').each(function (att) {
|
||
if (box.querySelector('[data-id="' + att.id + '"]')) return;
|
||
var src = (att.get('sizes') && att.get('sizes').thumbnail ? att.get('sizes').thumbnail.url : att.get('url'));
|
||
var item = document.createElement('span');
|
||
item.className = 'ga-gallery-admin__item';
|
||
item.dataset.id = att.id;
|
||
item.innerHTML = '<img src="' + src + '" alt=""><button type="button" aria-label="Quitar">×</button>';
|
||
box.appendChild(item);
|
||
});
|
||
sync();
|
||
});
|
||
frame.open();
|
||
});
|
||
});
|
||
});
|
||
JS
|
||
);
|
||
} );
|
||
|
||
add_action( 'save_post_animal', function ( $post_id ) {
|
||
if ( ! isset( $_POST['ga_ficha_nonce'] ) || ! wp_verify_nonce( $_POST['ga_ficha_nonce'], 'ga_ficha' ) ) {
|
||
return;
|
||
}
|
||
if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ! current_user_can( 'edit_post', $post_id ) ) {
|
||
return;
|
||
}
|
||
foreach ( ga_fields() as $key => $f ) {
|
||
$raw = wp_unslash( $_POST[ "ga_$key" ] ?? '' );
|
||
$value = match ( $f['type'] ) {
|
||
'select' => isset( $f['options'][ $raw ] ) ? $raw : '',
|
||
'checkbox' => $raw ? '1' : '',
|
||
'textarea' => sanitize_textarea_field( $raw ),
|
||
'gallery' => implode( ',', array_filter( array_map( 'absint', explode( ',', $raw ) ) ) ),
|
||
'url' => esc_url_raw( $raw ),
|
||
'number' => '' === $raw ? '' : (string) absint( $raw ),
|
||
'date' => preg_match( '/^\d{4}-\d{2}-\d{2}$/', $raw ) ? $raw : '',
|
||
default => sanitize_text_field( $raw ),
|
||
};
|
||
if ( ! empty( $f['shared'] ) ) {
|
||
ga_update_meta_all_languages( $post_id, "_ga_$key", $value );
|
||
} else {
|
||
update_post_meta( $post_id, "_ga_$key", $value );
|
||
}
|
||
}
|
||
} );
|
||
|
||
/** Guarda un campo común en el animal y en todas sus traducciones. */
|
||
function ga_update_meta_all_languages( $post_id, $meta_key, $value ) {
|
||
$ids = array( $post_id );
|
||
if ( function_exists( 'pll_get_post_translations' ) ) {
|
||
$ids = array_unique( array_merge( $ids, array_values( pll_get_post_translations( $post_id ) ) ) );
|
||
}
|
||
foreach ( $ids as $id ) {
|
||
update_post_meta( $id, $meta_key, $value );
|
||
}
|
||
}
|
||
|
||
/* Polylang: al crear o sincronizar traducciones, no copiar los textos (se escriben en cada idioma). */
|
||
add_filter( 'pll_copy_post_metas', function ( $metas, $sync ) {
|
||
$texts = array_map( fn( $k ) => "_ga_$k", array_keys( array_filter( ga_fields(), fn( $f ) => empty( $f['shared'] ) ) ) );
|
||
return $sync ? array_values( array_diff( $metas, $texts ) ) : $metas;
|
||
}, 10, 2 );
|
||
|
||
/* Columnas del listado del panel */
|
||
add_filter( 'manage_animal_posts_columns', function ( $cols ) {
|
||
$new = array();
|
||
foreach ( $cols as $k => $v ) {
|
||
if ( 'title' === $k ) {
|
||
$new['ga_foto'] = 'Foto';
|
||
}
|
||
$new[ $k ] = $v;
|
||
if ( 'title' === $k ) {
|
||
$new['ga_estado'] = 'Estado';
|
||
$new['ga_destacado'] = '★';
|
||
}
|
||
}
|
||
return $new;
|
||
} );
|
||
|
||
add_action( 'manage_animal_posts_custom_column', function ( $col, $post_id ) {
|
||
if ( 'ga_foto' === $col ) {
|
||
echo get_the_post_thumbnail( $post_id, array( 60, 60 ) );
|
||
} elseif ( 'ga_estado' === $col ) {
|
||
echo esc_html( ga_label( $post_id, 'estado' ) );
|
||
} elseif ( 'ga_destacado' === $col ) {
|
||
echo ga_get( $post_id, 'destacado' ) ? '★' : '';
|
||
}
|
||
}, 10, 2 );
|
||
|
||
/* Título de la pestaña del listado en el idioma actual */
|
||
add_filter( 'document_title_parts', function ( $parts ) {
|
||
if ( is_post_type_archive( 'animal' ) ) {
|
||
$parts['title'] = ga__( 'Adopta', 'Adoptatu' );
|
||
}
|
||
return $parts;
|
||
} );
|
||
|
||
/* -------------------------------------------------------------------------
|
||
* Consultas
|
||
* ---------------------------------------------------------------------- */
|
||
|
||
/** meta_query de los estados visibles en los listados. */
|
||
function ga_visible_meta_query() {
|
||
$hidden = array( 'adoptado' );
|
||
if ( ! ga_setting( 'adopcion', 'show_in_process', true ) ) {
|
||
$hidden = array_merge( $hidden, array( 'proceso', 'reservado' ) );
|
||
}
|
||
return array(
|
||
'relation' => 'OR',
|
||
array( 'key' => '_ga_estado', 'value' => $hidden, 'compare' => 'NOT IN' ),
|
||
array( 'key' => '_ga_estado', 'compare' => 'NOT EXISTS' ),
|
||
);
|
||
}
|
||
|
||
/** Orden de los listados según el ajuste «Orden». */
|
||
function ga_order_args() {
|
||
return 'antiguos' === ga_setting( 'adopcion', 'order', 'recientes' )
|
||
? array( 'orderby' => 'date', 'order' => 'ASC' )
|
||
: array( 'orderby' => 'date', 'order' => 'DESC' );
|
||
}
|
||
|
||
add_action( 'pre_get_posts', function ( $q ) {
|
||
if ( is_admin() || ! $q->is_main_query() || ! ( $q->is_post_type_archive( 'animal' ) || $q->is_tax( 'especie' ) ) ) {
|
||
return;
|
||
}
|
||
$q->set( 'meta_query', array( ga_visible_meta_query() ) );
|
||
$q->set( 'posts_per_page', 24 );
|
||
foreach ( ga_order_args() as $k => $v ) {
|
||
$q->set( $k, $v );
|
||
}
|
||
} );
|
||
|
||
/**
|
||
* Consulta reutilizable de animales (Polylang filtra por el idioma actual).
|
||
*
|
||
* @param array $args numero, especie (slugs), estado (lista o 'adoptado'), destacados (bool).
|
||
*/
|
||
function ga_query_animals( $args = array() ) {
|
||
$args = wp_parse_args( $args, array( 'numero' => 6, 'especie' => '', 'estado' => '', 'destacados' => false ) );
|
||
$query = array(
|
||
'post_type' => 'animal',
|
||
'posts_per_page' => (int) $args['numero'],
|
||
'no_found_rows' => true,
|
||
) + ga_order_args();
|
||
|
||
if ( $args['especie'] ) {
|
||
$query['tax_query'] = array( array(
|
||
'taxonomy' => 'especie',
|
||
'field' => 'slug',
|
||
'terms' => array_map( 'trim', explode( ',', $args['especie'] ) ),
|
||
) );
|
||
}
|
||
$meta = array();
|
||
if ( $args['estado'] ) {
|
||
$meta[] = array( 'key' => '_ga_estado', 'value' => array_map( 'trim', explode( ',', $args['estado'] ) ), 'compare' => 'IN' );
|
||
} else {
|
||
$meta[] = ga_visible_meta_query();
|
||
}
|
||
if ( $args['destacados'] ) {
|
||
$meta[] = array( 'key' => '_ga_destacado', 'value' => '1' );
|
||
}
|
||
$query['meta_query'] = $meta;
|
||
|
||
$q = new WP_Query( $query );
|
||
// Si no hay destacados marcados, se muestran los que llevan más tiempo esperando.
|
||
if ( $args['destacados'] && ! $q->have_posts() ) {
|
||
unset( $query['meta_query'][1] );
|
||
$query['orderby'] = 'date';
|
||
$query['order'] = 'ASC';
|
||
$q = new WP_Query( $query );
|
||
}
|
||
return $q;
|
||
}
|
||
|
||
/* [ga_animales numero="6" especie="perro" destacados="1" vista="carrusel"] */
|
||
add_shortcode( 'ga_animales', function ( $atts ) {
|
||
$atts = shortcode_atts( array( 'numero' => 6, 'especie' => '', 'estado' => '', 'destacados' => '', 'vista' => 'rejilla' ), $atts, 'ga_animales' );
|
||
$atts['destacados'] = in_array( $atts['destacados'], array( '1', 'si', 'true' ), true );
|
||
$q = ga_query_animals( $atts );
|
||
ob_start();
|
||
if ( $q->have_posts() ) {
|
||
$carousel = 'carrusel' === $atts['vista'];
|
||
$carousel ? ga_carousel_open() : print( '<div class="ga-grid">' );
|
||
while ( $q->have_posts() ) {
|
||
$q->the_post();
|
||
ga_animal_card();
|
||
}
|
||
$carousel ? ga_carousel_close() : print( '</div>' );
|
||
} else {
|
||
echo '<p class="ga-empty">' . esc_html( ga__( 'Ahora mismo no hay animales en esta sección. ¡Vuelve pronto!', 'Une honetan ez dago animaliarik atal honetan. Itzuli laster!' ) ) . '</p>';
|
||
}
|
||
wp_reset_postdata();
|
||
return ob_get_clean();
|
||
} );
|
||
|
||
/** Apertura y cierre de un carrusel accesible (el tema aporta el CSS y el JS). */
|
||
function ga_carousel_open( $label = '' ) {
|
||
printf(
|
||
'<div class="ga-carousel" data-ga-carousel role="region" aria-roledescription="%s" aria-label="%s"><div class="ga-carousel__track" tabindex="0">',
|
||
esc_attr( ga__( 'carrusel', 'karrusela' ) ),
|
||
esc_attr( $label ?: ga__( 'Animales', 'Animaliak' ) )
|
||
);
|
||
}
|
||
|
||
function ga_carousel_close() {
|
||
printf(
|
||
'</div><div class="ga-carousel__nav"><button type="button" class="ga-carousel__btn" data-dir="-1" aria-label="%s">←</button><button type="button" class="ga-carousel__btn" data-dir="1" aria-label="%s">→</button></div></div>',
|
||
esc_attr( ga__( 'Anteriores', 'Aurrekoak' ) ),
|
||
esc_attr( ga__( 'Siguientes', 'Hurrengoak' ) )
|
||
);
|
||
}
|
||
|
||
/** Tarjeta de un animal (dentro del loop). El tema la define en template-parts/animal-card.php. */
|
||
function ga_animal_card() {
|
||
if ( locate_template( 'template-parts/animal-card.php' ) ) {
|
||
get_template_part( 'template-parts/animal-card' );
|
||
return;
|
||
}
|
||
printf( '<article class="ga-card"><a href="%s">%s</a></article>', esc_url( get_permalink() ), esc_html( get_the_title() ) );
|
||
}
|