Indicaciones del cliente: adopción solo Perros/Gatos, fichas nuevas y todo configurable
- 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>
This commit is contained in:
@@ -1,764 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: Gure Ametsa – Núcleo
|
||||
* Description: Animales en adopción, fichas, listados y formulario de contacto/adopción de Gure Ametsa Bi Lagun. Bilingüe castellano/euskera (con Polylang).
|
||||
* Version: 1.1.0
|
||||
* Plugin Name: Bilagun – Núcleo
|
||||
* Description: Animales en adopción (fichas, galería, vídeo, destacados), formularios de contacto y «Quiero conocerlo», ayuda material, APIs REST/GraphQL. Bilingüe castellano/euskera (con Polylang).
|
||||
* Version: 2.0.0
|
||||
* Author: Gure Ametsa Bi Lagun
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Idioma (castellano / euskera)
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Idioma actual: 'es' o 'eu'. El panel de administración siempre en castellano. */
|
||||
function ga_lang() {
|
||||
if ( isset( $GLOBALS['ga_forced_lang'] ) ) {
|
||||
return 'eu' === $GLOBALS['ga_forced_lang'] ? 'eu' : 'es';
|
||||
}
|
||||
if ( is_admin() && ! wp_doing_ajax() ) {
|
||||
return 'es';
|
||||
}
|
||||
$lang = function_exists( 'pll_current_language' ) ? pll_current_language() : '';
|
||||
return 'eu' === $lang ? 'eu' : 'es';
|
||||
}
|
||||
|
||||
/** Devuelve el texto en el idioma actual. */
|
||||
function ga__( $es, $eu ) {
|
||||
return 'eu' === ga_lang() ? $eu : $es;
|
||||
}
|
||||
|
||||
/** Imprime el texto escapado en el idioma actual. */
|
||||
function ga_e( $es, $eu ) {
|
||||
echo esc_html( ga__( $es, $eu ) );
|
||||
}
|
||||
|
||||
/** URL de una página por su slug en castellano, en el idioma actual. */
|
||||
function ga_page_url( $slug_es, $fragment = '' ) {
|
||||
$page = get_page_by_path( $slug_es );
|
||||
if ( ! $page ) {
|
||||
return home_url( "/$slug_es/" ) . $fragment;
|
||||
}
|
||||
$id = $page->ID;
|
||||
if ( function_exists( 'pll_get_post' ) ) {
|
||||
$id = pll_get_post( $id, ga_lang() ) ?: $id;
|
||||
}
|
||||
return get_permalink( $id ) . $fragment;
|
||||
}
|
||||
|
||||
/* Animales y especies son traducibles; los mensajes no. */
|
||||
add_filter( 'pll_get_post_types', function ( $types, $is_settings ) {
|
||||
$types['animal'] = 'animal';
|
||||
unset( $types['ga_mensaje'] );
|
||||
return $types;
|
||||
}, 10, 2 );
|
||||
|
||||
add_filter( 'pll_get_taxonomies', function ( $taxonomies ) {
|
||||
$taxonomies['especie'] = 'especie';
|
||||
return $taxonomies;
|
||||
} );
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Datos de la protectora
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
function ga_info( $key = null ) {
|
||||
$info = apply_filters( 'ga_info', array(
|
||||
'nombre' => 'Gure Ametsa Bi Lagun',
|
||||
'direccion' => 'Jaizubia, 44 · 20280 Hondarribia (Gipuzkoa)',
|
||||
'telefono' => '943 64 52 79',
|
||||
'email' => 'hola@gureametsabilagun.org',
|
||||
'horario' => ga__( 'Lunes a viernes: 10:00–13:00 y 14:00–19:00', 'Astelehenetik ostiralera: 10:00–13:00 eta 14:00–19:00' ),
|
||||
'instagram' => 'https://www.instagram.com/gureametsabilagun/',
|
||||
'facebook' => 'https://www.facebook.com/gureametsabilagun/',
|
||||
'maps' => 'https://www.google.com/maps/search/?api=1&query=Jaizubia+44+Hondarribia',
|
||||
) );
|
||||
return $key ? ( $info[ $key ] ?? '' ) : $info;
|
||||
}
|
||||
|
||||
function ga_contact_email() {
|
||||
$email = getenv( 'GA_CONTACT_EMAIL' );
|
||||
return is_email( $email ) ? $email : get_option( 'admin_email' );
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* 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',
|
||||
'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',
|
||||
// WPGraphQL
|
||||
'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' => function () { return current_user_can( 'edit_posts' ); },
|
||||
) );
|
||||
}
|
||||
} );
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Campos de la ficha (etiquetas en el idioma actual)
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
function ga_fields() {
|
||||
return array(
|
||||
'estado' => array( 'label' => ga__( 'Estado', 'Egoera' ), 'type' => 'select', 'options' => array(
|
||||
'disponible' => ga__( 'En adopción', 'Adopzioan' ),
|
||||
'urgente' => ga__( 'Adopción urgente', 'Adopzio premiazkoa' ),
|
||||
'acogida' => ga__( 'Busca casa de acogida', 'Harrera-etxe bila' ),
|
||||
'reservado' => ga__( 'Reservado', 'Erreserbatuta' ),
|
||||
'adoptado' => ga__( 'Adoptado', 'Adoptatuta' ),
|
||||
) ),
|
||||
'sexo' => array( 'label' => ga__( 'Sexo', 'Sexua' ), 'type' => 'select', 'options' => array(
|
||||
'macho' => ga__( 'Macho', 'Arra' ),
|
||||
'hembra' => ga__( 'Hembra', 'Emea' ),
|
||||
) ),
|
||||
'edad' => array( 'label' => ga__( 'Edad', 'Adina' ), 'type' => 'number', 'placeholder' => 'p. ej. 2' ),
|
||||
'edad_unidad' => array( 'label' => ga__( 'Edad en', 'Adina' ), 'type' => 'select', 'options' => array(
|
||||
'anos' => ga__( 'Años', 'Urteak' ),
|
||||
'meses' => ga__( 'Meses', 'Hilabeteak' ),
|
||||
) ),
|
||||
'tamano' => array( 'label' => ga__( 'Tamaño', 'Tamaina' ), 'type' => 'select', 'options' => array(
|
||||
'pequeno' => ga__( 'Pequeño', 'Txikia' ),
|
||||
'mediano' => ga__( 'Mediano', 'Ertaina' ),
|
||||
'grande' => ga__( 'Grande', 'Handia' ),
|
||||
) ),
|
||||
'raza' => array( 'label' => ga__( 'Raza', 'Arraza' ), 'type' => 'text', 'placeholder' => 'p. ej. Mestizo' ),
|
||||
'llegada' => array( 'label' => ga__( 'Fecha de llegada', 'Iritsiera-data' ), 'type' => 'date' ),
|
||||
'salud' => array( 'label' => ga__( 'Salud', 'Osasuna' ), 'type' => 'checks', 'options' => array(
|
||||
'chip' => ga__( 'Microchip', 'Mikrotxipa' ),
|
||||
'vacunado' => ga__( 'Vacunado', 'Txertatuta' ),
|
||||
'esterilizado' => ga__( 'Esterilizado', 'Antzututa' ),
|
||||
'desparasitado' => ga__( 'Desparasitado', 'Desparasitatuta' ),
|
||||
) ),
|
||||
'compatible' => array( 'label' => ga__( 'Se lleva bien con', 'Ondo moldatzen da hauekin' ), 'type' => 'checks', 'options' => array(
|
||||
'ninos' => ga__( 'Niños', 'Haurrak' ),
|
||||
'perros' => ga__( 'Perros', 'Txakurrak' ),
|
||||
'gatos' => ga__( 'Gatos', 'Katuak' ),
|
||||
) ),
|
||||
);
|
||||
}
|
||||
|
||||
/** Edad legible en el idioma actual: «3 años», «1 mes», «3 urte», «4 hilabete». */
|
||||
function ga_age( $post_id ) {
|
||||
$n = ga_get( $post_id, 'edad' );
|
||||
if ( '' === $n || ! is_numeric( $n ) ) {
|
||||
return $n; // Valores antiguos en texto libre.
|
||||
}
|
||||
$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' );
|
||||
}
|
||||
|
||||
function ga_get( $post_id, $key ) {
|
||||
return (string) get_post_meta( $post_id, "_ga_$key", true );
|
||||
}
|
||||
|
||||
/** Etiqueta legible de un campo select, o lista de etiquetas de un campo checks. */
|
||||
function ga_label( $post_id, $key ) {
|
||||
$fields = ga_fields();
|
||||
$value = ga_get( $post_id, $key );
|
||||
if ( '' === $value || ! isset( $fields[ $key ] ) ) {
|
||||
return '';
|
||||
}
|
||||
$field = $fields[ $key ];
|
||||
if ( 'select' === $field['type'] ) {
|
||||
return $field['options'][ $value ] ?? $value;
|
||||
}
|
||||
if ( 'checks' === $field['type'] ) {
|
||||
$labels = array();
|
||||
foreach ( explode( ',', $value ) as $v ) {
|
||||
if ( isset( $field['options'][ $v ] ) ) {
|
||||
$labels[] = $field['options'][ $v ];
|
||||
}
|
||||
}
|
||||
return $labels;
|
||||
}
|
||||
if ( 'date' === $field['type'] ) {
|
||||
return date_i18n( get_option( 'date_format' ), strtotime( $value ) );
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
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' );
|
||||
echo '<table class="form-table" role="presentation"><tbody>';
|
||||
foreach ( ga_fields() as $key => $f ) {
|
||||
$name = "ga_$key";
|
||||
$value = ga_get( $post->ID, $key );
|
||||
if ( 'estado' === $key && '' === $value ) {
|
||||
$value = 'disponible';
|
||||
}
|
||||
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 ) . '"><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 'checks':
|
||||
$current = array_filter( explode( ',', $value ) );
|
||||
foreach ( $f['options'] as $v => $l ) {
|
||||
printf(
|
||||
'<label style="margin-right:1em"><input type="checkbox" name="%s[]" value="%s"%s> %s</label>',
|
||||
esc_attr( $name ), esc_attr( $v ), checked( in_array( $v, $current, true ), true, false ), esc_html( $l )
|
||||
);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf(
|
||||
'<input type="%s" id="%s" name="%s" value="%s" class="%s" placeholder="%s"%s>',
|
||||
esc_attr( $f['type'] ), esc_attr( $name ), esc_attr( $name ), esc_attr( $value ),
|
||||
'number' === $f['type'] ? 'small-text' : 'regular-text',
|
||||
esc_attr( $f['placeholder'] ?? '' ),
|
||||
'number' === $f['type'] ? ' min="0" step="1"' : ''
|
||||
);
|
||||
}
|
||||
echo '</td></tr>';
|
||||
}
|
||||
echo '</tbody></table>';
|
||||
echo '<p class="description">La ficha se comparte entre la versión en castellano y en euskera: al guardar una, se copia a la otra. Solo el nombre y la descripción se traducen.</p>';
|
||||
echo '<p class="description">Consejo: la foto principal aparece en los listados. Añade más fotos en el contenido con el bloque «Galería».</p>';
|
||||
}
|
||||
|
||||
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 = $_POST[ "ga_$key" ] ?? '';
|
||||
if ( 'checks' === $f['type'] ) {
|
||||
$raw = array_intersect( (array) $raw, array_keys( $f['options'] ) );
|
||||
$value = implode( ',', $raw );
|
||||
} elseif ( 'select' === $f['type'] ) {
|
||||
$value = isset( $f['options'][ $raw ] ) ? $raw : '';
|
||||
} else {
|
||||
$value = sanitize_text_field( wp_unslash( $raw ) );
|
||||
}
|
||||
ga_update_meta_all_languages( $post_id, "_ga_$key", $value );
|
||||
}
|
||||
} );
|
||||
|
||||
/** Guarda un campo 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 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Columnas en el listado del admin */
|
||||
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_edad'] = 'Edad';
|
||||
}
|
||||
}
|
||||
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_edad' === $col ) {
|
||||
echo esc_html( ga_age( $post_id ) );
|
||||
}
|
||||
}, 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__( 'Animales en adopción', 'Animaliak adopzioan' );
|
||||
}
|
||||
return $parts;
|
||||
} );
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Consultas del listado público /adopta/
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
add_filter( 'query_vars', function ( $vars ) {
|
||||
return array_merge( $vars, array( 'tamano', 'sexo', 'edad', 'con' ) );
|
||||
} );
|
||||
|
||||
/** Grupos de edad para el filtro del listado. */
|
||||
function ga_age_groups() {
|
||||
return array(
|
||||
'joven' => ga__( 'Menos de 1 año', 'Urtebete baino gutxiago' ),
|
||||
'adulto' => ga__( 'Adulto', 'Heldua' ),
|
||||
'senior' => ga__( 'Mayor (8+)', 'Adinekoa (8+)' ),
|
||||
);
|
||||
}
|
||||
|
||||
/** meta_query para un grupo de edad (la edad se guarda como número + unidad). */
|
||||
function ga_age_meta_query( $group ) {
|
||||
$anos = array( 'key' => '_ga_edad_unidad', 'value' => 'anos' );
|
||||
switch ( $group ) {
|
||||
case 'joven':
|
||||
return array(
|
||||
'relation' => 'OR',
|
||||
array( 'key' => '_ga_edad_unidad', 'value' => 'meses' ),
|
||||
array( 'relation' => 'AND', $anos, array( 'key' => '_ga_edad', 'value' => 1, 'compare' => '<', 'type' => 'NUMERIC' ) ),
|
||||
);
|
||||
case 'adulto':
|
||||
return array( 'relation' => 'AND', $anos, array( 'key' => '_ga_edad', 'value' => array( 1, 7 ), 'compare' => 'BETWEEN', 'type' => 'NUMERIC' ) );
|
||||
case 'senior':
|
||||
return array( 'relation' => 'AND', $anos, array( 'key' => '_ga_edad', 'value' => 8, 'compare' => '>=', 'type' => 'NUMERIC' ) );
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
function ga_not_adopted_meta_query() {
|
||||
return array(
|
||||
'relation' => 'OR',
|
||||
array( 'key' => '_ga_estado', 'value' => 'adoptado', 'compare' => '!=' ),
|
||||
array( 'key' => '_ga_estado', 'compare' => 'NOT EXISTS' ),
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
$meta = array( ga_not_adopted_meta_query() );
|
||||
foreach ( array( 'tamano', 'sexo' ) as $key ) {
|
||||
$v = sanitize_key( (string) $q->get( $key ) );
|
||||
if ( $v && isset( ga_fields()[ $key ]['options'][ $v ] ) ) {
|
||||
$meta[] = array( 'key' => "_ga_$key", 'value' => $v );
|
||||
}
|
||||
}
|
||||
$edad = sanitize_key( (string) $q->get( 'edad' ) );
|
||||
if ( isset( ga_age_groups()[ $edad ] ) ) {
|
||||
$meta[] = ga_age_meta_query( $edad );
|
||||
}
|
||||
$con = sanitize_key( (string) $q->get( 'con' ) );
|
||||
if ( isset( ga_fields()['compatible']['options'][ $con ] ) ) {
|
||||
$meta[] = array( 'key' => '_ga_compatible', 'value' => $con, 'compare' => 'LIKE' );
|
||||
}
|
||||
$q->set( 'meta_query', $meta );
|
||||
$q->set( 'posts_per_page', 12 );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Consulta reutilizable de animales (Polylang filtra por el idioma actual).
|
||||
*/
|
||||
function ga_query_animals( $args = array() ) {
|
||||
$args = wp_parse_args( $args, array(
|
||||
'numero' => 6,
|
||||
'especie' => '',
|
||||
'estado' => '',
|
||||
) );
|
||||
|
||||
$query = array(
|
||||
'post_type' => 'animal',
|
||||
'posts_per_page' => (int) $args['numero'],
|
||||
'no_found_rows' => true,
|
||||
);
|
||||
if ( $args['especie'] ) {
|
||||
$query['tax_query'] = array( array(
|
||||
'taxonomy' => 'especie',
|
||||
'field' => 'slug',
|
||||
'terms' => array_map( 'trim', explode( ',', $args['especie'] ) ),
|
||||
) );
|
||||
}
|
||||
if ( $args['estado'] ) {
|
||||
$query['meta_query'] = array( array(
|
||||
'key' => '_ga_estado',
|
||||
'value' => array_map( 'trim', explode( ',', $args['estado'] ) ),
|
||||
'compare' => 'IN',
|
||||
) );
|
||||
} else {
|
||||
$query['meta_query'] = ga_not_adopted_meta_query();
|
||||
}
|
||||
return new WP_Query( $query );
|
||||
}
|
||||
|
||||
/* [ga_animales numero="6" especie="perro" estado="urgente" vista="carrusel"] */
|
||||
add_shortcode( 'ga_animales', function ( $atts ) {
|
||||
$atts = shortcode_atts( array( 'numero' => 6, 'especie' => '', 'estado' => '', 'vista' => 'rejilla' ), $atts, 'ga_animales' );
|
||||
$q = ga_query_animals( $atts );
|
||||
ob_start();
|
||||
if ( $q->have_posts() ) {
|
||||
$carousel = 'carrusel' === $atts['vista'];
|
||||
if ( $carousel ) {
|
||||
ga_carousel_open();
|
||||
} else {
|
||||
echo '<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 puede sobrescribirla con 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() ) );
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Formulario de contacto / solicitud de adopción [ga_contacto]
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
function ga_contact_reasons() {
|
||||
return array(
|
||||
'adopcion' => ga__( 'Adopción', 'Adopzioa' ),
|
||||
'acogida' => ga__( 'Casa de acogida', 'Harrera-etxea' ),
|
||||
'voluntario' => ga__( 'Voluntariado', 'Boluntariotza' ),
|
||||
'donaciones' => ga__( 'Donaciones', 'Dohaintzak' ),
|
||||
'hotel' => ga__( 'Hotel para perros y gatos', 'Txakur eta katuentzako hotela' ),
|
||||
'perdido' => ga__( 'He encontrado / perdido un animal', 'Animalia bat aurkitu / galdu dut' ),
|
||||
'otro' => ga__( 'Otro', 'Beste bat' ),
|
||||
);
|
||||
}
|
||||
|
||||
add_shortcode( 'ga_contacto', function () {
|
||||
$status = isset( $_GET['enviado'] ) ? sanitize_key( $_GET['enviado'] ) : '';
|
||||
$animal_id = isset( $_GET['adoptar'] ) ? absint( $_GET['adoptar'] ) : 0;
|
||||
$animal = $animal_id && 'animal' === get_post_type( $animal_id ) ? get_the_title( $animal_id ) : '';
|
||||
$preselect = $animal ? 'adopcion' : ( isset( $_GET['motivo'] ) ? sanitize_key( $_GET['motivo'] ) : '' );
|
||||
$privacy = ga_page_url( 'politica-de-privacidad' );
|
||||
|
||||
ob_start();
|
||||
if ( 'ok' === $status ) {
|
||||
echo '<div class="ga-notice ga-notice--ok" role="status"><strong>' . esc_html( ga__( '¡Eskerrik asko!', 'Eskerrik asko!' ) ) . '</strong> '
|
||||
. esc_html( ga__( 'Hemos recibido tu mensaje y te responderemos lo antes posible.', 'Zure mezua jaso dugu eta ahalik eta lasterren erantzungo dizugu.' ) ) . '</div>';
|
||||
} elseif ( 'error' === $status ) {
|
||||
echo '<div class="ga-notice ga-notice--error" role="alert">'
|
||||
. esc_html( ga__( 'No hemos podido enviar el mensaje. Revisa los campos obligatorios o escríbenos a ', 'Ezin izan dugu mezua bidali. Egiaztatu derrigorrezko eremuak edo idatzi iezaguzu helbide honetara: ' ) . ga_info( 'email' ) ) . '</div>';
|
||||
}
|
||||
?>
|
||||
<form class="ga-form" method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
|
||||
<input type="hidden" name="action" value="ga_contacto">
|
||||
<input type="hidden" name="idioma" value="<?php echo esc_attr( ga_lang() ); ?>">
|
||||
<input type="hidden" name="redirect" value="<?php echo esc_url( get_permalink() ); ?>">
|
||||
<?php wp_nonce_field( 'ga_contacto', 'ga_nonce' ); ?>
|
||||
<div class="ga-hp" aria-hidden="true"><label>No rellenar <input type="text" name="web" tabindex="-1" autocomplete="off"></label></div>
|
||||
|
||||
<div class="ga-form__row">
|
||||
<label><?php ga_e( 'Nombre', 'Izena' ); ?> *<input type="text" name="nombre" required autocomplete="name"></label>
|
||||
<label><?php ga_e( 'Email', 'Posta elektronikoa' ); ?> *<input type="email" name="email" required autocomplete="email"></label>
|
||||
</div>
|
||||
<div class="ga-form__row">
|
||||
<label><?php ga_e( 'Teléfono', 'Telefonoa' ); ?><input type="tel" name="telefono" autocomplete="tel"></label>
|
||||
<label><?php ga_e( 'Motivo', 'Arrazoia' ); ?>
|
||||
<select name="motivo">
|
||||
<?php foreach ( ga_contact_reasons() as $value => $label ) : ?>
|
||||
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $preselect, $value ); ?>><?php echo esc_html( $label ); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<label><?php ga_e( 'Animal por el que preguntas', 'Zein animaliari buruz galdetzen duzu' ); ?>
|
||||
<input type="text" name="animal" value="<?php echo esc_attr( $animal ); ?>" placeholder="<?php echo esc_attr( ga__( 'Opcional', 'Aukerakoa' ) ); ?>">
|
||||
</label>
|
||||
<label><?php ga_e( 'Mensaje', 'Mezua' ); ?> *
|
||||
<textarea name="mensaje" rows="6" required placeholder="<?php echo $animal ? esc_attr( ga__( 'Cuéntanos un poco sobre ti, tu casa y tu día a día…', 'Kontaiguzu zerbait zuri buruz, zure etxeari eta eguneroko bizitzari buruz…' ) ) : ''; ?>"></textarea>
|
||||
</label>
|
||||
<label class="ga-form__check">
|
||||
<input type="checkbox" name="privacidad" value="1" required>
|
||||
<span>
|
||||
<?php if ( 'eu' === ga_lang() ) : ?>
|
||||
<a href="<?php echo esc_url( $privacy ); ?>" target="_blank">Pribatutasun-politika</a> irakurri eta onartzen dut. *
|
||||
<?php else : ?>
|
||||
He leído y acepto la <a href="<?php echo esc_url( $privacy ); ?>" target="_blank">política de privacidad</a>. *
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</label>
|
||||
<button type="submit" class="ga-btn"><?php ga_e( 'Enviar mensaje', 'Mezua bidali' ); ?></button>
|
||||
</form>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
} );
|
||||
|
||||
add_action( 'admin_post_nopriv_ga_contacto', 'ga_handle_contact' );
|
||||
add_action( 'admin_post_ga_contacto', 'ga_handle_contact' );
|
||||
|
||||
function ga_handle_contact() {
|
||||
$redirect = wp_validate_redirect( esc_url_raw( wp_unslash( $_POST['redirect'] ?? '' ) ), home_url( '/' ) );
|
||||
$go = function ( $status ) use ( $redirect ) {
|
||||
wp_safe_redirect( add_query_arg( 'enviado', $status, $redirect ) . '#formulario' );
|
||||
exit;
|
||||
};
|
||||
|
||||
if ( ! isset( $_POST['ga_nonce'] ) || ! wp_verify_nonce( $_POST['ga_nonce'], 'ga_contacto' ) ) {
|
||||
$go( 'error' );
|
||||
}
|
||||
// Honeypot: los bots rellenan el campo oculto; fingimos éxito.
|
||||
if ( ! empty( $_POST['web'] ) ) {
|
||||
$go( 'ok' );
|
||||
}
|
||||
|
||||
$reasons = ga_contact_reasons(); // En castellano: el admin_post se ejecuta en contexto de administración.
|
||||
$reason = sanitize_key( $_POST['motivo'] ?? '' );
|
||||
$data = array(
|
||||
'nombre' => sanitize_text_field( wp_unslash( $_POST['nombre'] ?? '' ) ),
|
||||
'email' => sanitize_email( wp_unslash( $_POST['email'] ?? '' ) ),
|
||||
'telefono' => sanitize_text_field( wp_unslash( $_POST['telefono'] ?? '' ) ),
|
||||
'motivo' => $reasons[ $reason ] ?? $reasons['otro'],
|
||||
'animal' => sanitize_text_field( wp_unslash( $_POST['animal'] ?? '' ) ),
|
||||
'mensaje' => sanitize_textarea_field( wp_unslash( $_POST['mensaje'] ?? '' ) ),
|
||||
'idioma' => 'eu' === ( $_POST['idioma'] ?? '' ) ? 'Euskera' : 'Castellano',
|
||||
);
|
||||
if ( ! $data['nombre'] || ! is_email( $data['email'] ) || ! $data['mensaje'] || empty( $_POST['privacidad'] ) ) {
|
||||
$go( 'error' );
|
||||
}
|
||||
|
||||
$subject = sprintf( '[Web] %s – %s', $data['motivo'], $data['nombre'] );
|
||||
if ( $data['animal'] ) {
|
||||
$subject .= ' (' . $data['animal'] . ')';
|
||||
}
|
||||
$body = sprintf(
|
||||
"Nombre: %s\nEmail: %s\nTeléfono: %s\nMotivo: %s\nAnimal: %s\nIdioma: %s\n\n%s",
|
||||
$data['nombre'], $data['email'], $data['telefono'] ?: '-', $data['motivo'], $data['animal'] ?: '-', $data['idioma'], $data['mensaje']
|
||||
);
|
||||
|
||||
// Se guarda siempre en el panel, aunque falle el correo.
|
||||
wp_insert_post( array(
|
||||
'post_type' => 'ga_mensaje',
|
||||
'post_status' => 'private',
|
||||
'post_title' => $subject,
|
||||
'post_content' => $body,
|
||||
) );
|
||||
|
||||
wp_mail( ga_contact_email(), $subject, $body, array( 'Reply-To: ' . $data['nombre'] . ' <' . $data['email'] . '>' ) );
|
||||
|
||||
$go( 'ok' );
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* APIs: REST (/wp-json/wp/v2/animales) y GraphQL (/graphql)
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Ficha de un animal lista para las APIs: valores internos + textos legibles. */
|
||||
function ga_animal_api_data( $post_id ) {
|
||||
$lang = function_exists( 'pll_get_post_language' ) ? ( pll_get_post_language( $post_id ) ?: 'es' ) : 'es';
|
||||
$list = fn( $key ) => array_values( array_filter( explode( ',', ga_get( $post_id, $key ) ) ) );
|
||||
$data = array(
|
||||
'estado' => ga_get( $post_id, 'estado' ) ?: 'disponible',
|
||||
'sexo' => ga_get( $post_id, 'sexo' ),
|
||||
'edad' => '' === ga_get( $post_id, 'edad' ) ? null : (float) ga_get( $post_id, 'edad' ),
|
||||
'edad_unidad' => ga_get( $post_id, 'edad_unidad' ),
|
||||
'tamano' => ga_get( $post_id, 'tamano' ),
|
||||
'raza' => ga_get( $post_id, 'raza' ),
|
||||
'llegada' => ga_get( $post_id, 'llegada' ),
|
||||
'salud' => $list( 'salud' ),
|
||||
'compatible' => $list( 'compatible' ),
|
||||
'idioma' => $lang,
|
||||
);
|
||||
// Textos legibles en el idioma del animal.
|
||||
$labels = function () use ( $post_id ) {
|
||||
return array(
|
||||
'estado' => ga_label( $post_id, 'estado' ) ?: ga__( 'En adopción', 'Adopzioan' ),
|
||||
'sexo' => ga_label( $post_id, 'sexo' ),
|
||||
'edad' => ga_age( $post_id ),
|
||||
'tamano' => ga_label( $post_id, 'tamano' ),
|
||||
'salud' => ga_label( $post_id, 'salud' ) ?: array(),
|
||||
'compatible' => ga_label( $post_id, 'compatible' ) ?: array(),
|
||||
);
|
||||
};
|
||||
$data['textos'] = ga_with_lang( $lang, $labels );
|
||||
return $data;
|
||||
}
|
||||
|
||||
/** Ejecuta $callback como si el idioma actual fuera $lang (para las etiquetas). */
|
||||
function ga_with_lang( $lang, callable $callback ) {
|
||||
$GLOBALS['ga_forced_lang'] = $lang;
|
||||
try {
|
||||
return $callback();
|
||||
} finally {
|
||||
unset( $GLOBALS['ga_forced_lang'] );
|
||||
}
|
||||
}
|
||||
|
||||
/* REST: campo «ficha» de solo lectura en /wp/v2/animales */
|
||||
add_action( 'rest_api_init', function () {
|
||||
register_rest_field( 'animal', 'ficha', array(
|
||||
'get_callback' => fn( $post ) => ga_animal_api_data( $post['id'] ),
|
||||
'schema' => array(
|
||||
'description' => 'Ficha del animal (valores internos y textos legibles en su idioma).',
|
||||
'type' => 'object',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'properties' => array(
|
||||
'estado' => array( 'type' => 'string', 'enum' => array( 'disponible', 'urgente', 'acogida', 'reservado', 'adoptado' ) ),
|
||||
'sexo' => array( 'type' => 'string' ),
|
||||
'edad' => array( 'type' => array( 'number', 'null' ) ),
|
||||
'edad_unidad' => array( 'type' => 'string', 'enum' => array( '', 'anos', 'meses' ) ),
|
||||
'tamano' => array( 'type' => 'string' ),
|
||||
'raza' => array( 'type' => 'string' ),
|
||||
'llegada' => array( 'type' => 'string', 'format' => 'date' ),
|
||||
'salud' => array( 'type' => 'array', 'items' => array( 'type' => 'string' ) ),
|
||||
'compatible' => array( 'type' => 'array', 'items' => array( 'type' => 'string' ) ),
|
||||
'idioma' => array( 'type' => 'string' ),
|
||||
'textos' => array( 'type' => 'object' ),
|
||||
),
|
||||
),
|
||||
) );
|
||||
} );
|
||||
|
||||
/* GraphQL: tipo AnimalFicha y campo «ficha» en Animal */
|
||||
add_action( 'graphql_register_types', function () {
|
||||
register_graphql_object_type( 'AnimalFichaTextos', array(
|
||||
'description' => 'Textos legibles de la ficha, en el idioma del animal.',
|
||||
'fields' => array(
|
||||
'estado' => array( 'type' => 'String' ),
|
||||
'sexo' => array( 'type' => 'String' ),
|
||||
'edad' => array( 'type' => 'String' ),
|
||||
'tamano' => array( 'type' => 'String' ),
|
||||
'salud' => array( 'type' => array( 'list_of' => 'String' ) ),
|
||||
'compatible' => array( 'type' => array( 'list_of' => 'String' ) ),
|
||||
),
|
||||
) );
|
||||
register_graphql_object_type( 'AnimalFicha', array(
|
||||
'description' => 'Ficha del animal en adopción.',
|
||||
'fields' => array(
|
||||
'estado' => array( 'type' => 'String', 'description' => 'disponible, urgente, acogida, reservado o adoptado' ),
|
||||
'sexo' => array( 'type' => 'String' ),
|
||||
'edad' => array( 'type' => 'Float' ),
|
||||
'edadUnidad' => array( 'type' => 'String', 'description' => 'anos o meses' ),
|
||||
'tamano' => array( 'type' => 'String' ),
|
||||
'raza' => array( 'type' => 'String' ),
|
||||
'llegada' => array( 'type' => 'String' ),
|
||||
'salud' => array( 'type' => array( 'list_of' => 'String' ) ),
|
||||
'compatible' => array( 'type' => array( 'list_of' => 'String' ) ),
|
||||
'idioma' => array( 'type' => 'String' ),
|
||||
'textos' => array( 'type' => 'AnimalFichaTextos' ),
|
||||
),
|
||||
) );
|
||||
register_graphql_field( 'Animal', 'ficha', array(
|
||||
'type' => 'AnimalFicha',
|
||||
'resolve' => function ( $post ) {
|
||||
$data = ga_animal_api_data( $post->databaseId );
|
||||
$data['edadUnidad'] = $data['edad_unidad'];
|
||||
return $data;
|
||||
},
|
||||
) );
|
||||
} );
|
||||
|
||||
/* Documentación Swagger (/rest-api/docs/): solo para usuarios conectados, salvo API_DOCS_PUBLIC=true */
|
||||
add_action( 'template_redirect', function () {
|
||||
if ( 'docs' === get_query_var( 'swagger_api' ) && 'true' !== getenv( 'API_DOCS_PUBLIC' ) && ! is_user_logged_in() ) {
|
||||
auth_redirect();
|
||||
}
|
||||
}, 1 );
|
||||
|
||||
require_once __DIR__ . '/gure-ametsa/i18n.php';
|
||||
require_once __DIR__ . '/gure-ametsa/animals.php';
|
||||
require_once __DIR__ . '/gure-ametsa/forms.php';
|
||||
require_once __DIR__ . '/gure-ametsa/api.php';
|
||||
|
||||
519
wp-content/mu-plugins/gure-ametsa/animals.php
Normal file
519
wp-content/mu-plugins/gure-ametsa/animals.php
Normal file
@@ -0,0 +1,519 @@
|
||||
<?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() ) );
|
||||
}
|
||||
113
wp-content/mu-plugins/gure-ametsa/api.php
Normal file
113
wp-content/mu-plugins/gure-ametsa/api.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* APIs: REST (/wp-json/wp/v2/animales) y GraphQL (/graphql). Documentación Swagger protegida.
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/** Ficha de un animal lista para las APIs: valores internos + textos legibles en su idioma. */
|
||||
function ga_animal_api_data( $post_id ) {
|
||||
$lang = function_exists( 'pll_get_post_language' ) ? ( pll_get_post_language( $post_id ) ?: 'es' ) : 'es';
|
||||
$data = array(
|
||||
'estado' => ga_status( $post_id ),
|
||||
'destacado' => (bool) ga_get( $post_id, 'destacado' ),
|
||||
'sexo' => ga_get( $post_id, 'sexo' ),
|
||||
'nacimiento' => ga_get( $post_id, 'nacimiento' ),
|
||||
'edad' => '' === ga_get( $post_id, 'edad' ) ? null : (float) ga_get( $post_id, 'edad' ),
|
||||
'edad_unidad' => ga_get( $post_id, 'edad_unidad' ),
|
||||
'tamano' => ga_get( $post_id, 'tamano' ),
|
||||
'llegada' => ga_get( $post_id, 'llegada' ),
|
||||
'galeria' => array_map( fn( $id ) => wp_get_attachment_image_url( $id, 'large' ), ga_gallery_ids( $post_id ) ),
|
||||
'video' => ga_get( $post_id, 'video' ),
|
||||
'caracter' => ga_get( $post_id, 'caracter' ),
|
||||
'necesidades' => ga_get( $post_id, 'necesidades' ),
|
||||
'convivencia' => ga_get( $post_id, 'convivencia' ),
|
||||
'hogar' => ga_get( $post_id, 'hogar' ),
|
||||
'idioma' => $lang,
|
||||
);
|
||||
$data['textos'] = ga_with_lang( $lang, fn() => array(
|
||||
'estado' => ga_label( $post_id, 'estado' ),
|
||||
'sexo' => ga_label( $post_id, 'sexo' ),
|
||||
'edad' => ga_age( $post_id ),
|
||||
'tamano' => ga_label( $post_id, 'tamano' ),
|
||||
) );
|
||||
return $data;
|
||||
}
|
||||
|
||||
add_action( 'rest_api_init', function () {
|
||||
register_rest_field( 'animal', 'ficha', array(
|
||||
'get_callback' => fn( $post ) => ga_animal_api_data( $post['id'] ),
|
||||
'schema' => array(
|
||||
'description' => 'Ficha del animal (valores internos y textos legibles en su idioma).',
|
||||
'type' => 'object',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
'properties' => array(
|
||||
'estado' => array( 'type' => 'string', 'enum' => array( 'disponible', 'proceso', 'adoptado' ) ),
|
||||
'destacado' => array( 'type' => 'boolean' ),
|
||||
'sexo' => array( 'type' => 'string' ),
|
||||
'nacimiento' => array( 'type' => 'string' ),
|
||||
'edad' => array( 'type' => array( 'number', 'null' ) ),
|
||||
'edad_unidad' => array( 'type' => 'string' ),
|
||||
'tamano' => array( 'type' => 'string' ),
|
||||
'llegada' => array( 'type' => 'string' ),
|
||||
'galeria' => array( 'type' => 'array', 'items' => array( 'type' => 'string', 'format' => 'uri' ) ),
|
||||
'video' => array( 'type' => 'string' ),
|
||||
'caracter' => array( 'type' => 'string' ),
|
||||
'necesidades' => array( 'type' => 'string' ),
|
||||
'convivencia' => array( 'type' => 'string' ),
|
||||
'hogar' => array( 'type' => 'string' ),
|
||||
'idioma' => array( 'type' => 'string' ),
|
||||
'textos' => array( 'type' => 'object' ),
|
||||
),
|
||||
),
|
||||
) );
|
||||
} );
|
||||
|
||||
add_action( 'graphql_register_types', function () {
|
||||
register_graphql_object_type( 'AnimalFichaTextos', array(
|
||||
'description' => 'Textos legibles de la ficha, en el idioma del animal.',
|
||||
'fields' => array(
|
||||
'estado' => array( 'type' => 'String' ),
|
||||
'sexo' => array( 'type' => 'String' ),
|
||||
'edad' => array( 'type' => 'String' ),
|
||||
'tamano' => array( 'type' => 'String' ),
|
||||
),
|
||||
) );
|
||||
register_graphql_object_type( 'AnimalFicha', array(
|
||||
'description' => 'Ficha del animal en adopción.',
|
||||
'fields' => array(
|
||||
'estado' => array( 'type' => 'String', 'description' => 'disponible, proceso o adoptado' ),
|
||||
'destacado' => array( 'type' => 'Boolean' ),
|
||||
'sexo' => array( 'type' => 'String' ),
|
||||
'nacimiento' => array( 'type' => 'String' ),
|
||||
'edad' => array( 'type' => 'Float' ),
|
||||
'edadUnidad' => array( 'type' => 'String' ),
|
||||
'tamano' => array( 'type' => 'String' ),
|
||||
'llegada' => array( 'type' => 'String' ),
|
||||
'galeria' => array( 'type' => array( 'list_of' => 'String' ) ),
|
||||
'video' => array( 'type' => 'String' ),
|
||||
'caracter' => array( 'type' => 'String' ),
|
||||
'necesidades' => array( 'type' => 'String' ),
|
||||
'convivencia' => array( 'type' => 'String' ),
|
||||
'hogar' => array( 'type' => 'String' ),
|
||||
'idioma' => array( 'type' => 'String' ),
|
||||
'textos' => array( 'type' => 'AnimalFichaTextos' ),
|
||||
),
|
||||
) );
|
||||
register_graphql_field( 'Animal', 'ficha', array(
|
||||
'type' => 'AnimalFicha',
|
||||
'resolve' => function ( $post ) {
|
||||
$data = ga_animal_api_data( $post->databaseId );
|
||||
$data['edadUnidad'] = $data['edad_unidad'];
|
||||
return $data;
|
||||
},
|
||||
) );
|
||||
} );
|
||||
|
||||
/* Documentación Swagger (/rest-api/docs/): solo para usuarios conectados, salvo API_DOCS_PUBLIC=true */
|
||||
add_action( 'template_redirect', function () {
|
||||
if ( 'docs' === get_query_var( 'swagger_api' ) && 'true' !== getenv( 'API_DOCS_PUBLIC' ) && ! is_user_logged_in() ) {
|
||||
auth_redirect();
|
||||
}
|
||||
}, 1 );
|
||||
178
wp-content/mu-plugins/gure-ametsa/forms.php
Normal file
178
wp-content/mu-plugins/gure-ametsa/forms.php
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
/**
|
||||
* Formularios (contacto general y «Quiero conocerlo/la»), ayuda material y cita previa.
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/** Motivos del formulario general. */
|
||||
function ga_contact_reasons() {
|
||||
return array(
|
||||
'adopcion' => ga__( 'Adopción', 'Adopzioa' ),
|
||||
'acogida' => ga__( 'Casa de acogida', 'Harrera-etxea' ),
|
||||
'voluntario' => ga__( 'Voluntariado', 'Boluntariotza' ),
|
||||
'material' => ga__( 'Ayuda material', 'Laguntza materiala' ),
|
||||
'otro' => ga__( 'Otro', 'Beste bat' ),
|
||||
);
|
||||
}
|
||||
|
||||
/** Texto de confirmación tras enviar. */
|
||||
function ga_confirmation_text( $is_animal ) {
|
||||
return $is_animal
|
||||
? ga_setting( 'adopcion', 'confirm', ga__( 'Hemos recibido tu solicitud. Nos pondremos en contacto contigo para enviarte nuestro cuestionario y conoceros un poquito mejor.', 'Zure eskaera jaso dugu. Zurekin harremanetan jarriko gara gure galdetegia bidaltzeko eta elkar hobeto ezagutzeko.' ) )
|
||||
: ga_setting( 'adopcion', 'confirm_contact', ga__( '¡Gracias! Hemos recibido tu mensaje y te responderemos lo antes posible.', 'Eskerrik asko! Zure mezua jaso dugu eta ahalik eta lasterren erantzungo dizugu.' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* [ga_contacto] formulario general.
|
||||
* [ga_contacto animal="123"] formulario breve «Quiero conocerlo/la» (el animal va incluido).
|
||||
*/
|
||||
add_shortcode( 'ga_contacto', function ( $atts ) {
|
||||
$atts = shortcode_atts( array( 'animal' => 0 ), $atts, 'ga_contacto' );
|
||||
$animal_id = absint( $atts['animal'] ) ?: absint( $_GET['adoptar'] ?? 0 );
|
||||
$animal_id = $animal_id && 'animal' === get_post_type( $animal_id ) ? $animal_id : 0;
|
||||
$is_animal = absint( $atts['animal'] ) > 0; // Formulario breve dentro de la ficha.
|
||||
$status = sanitize_key( $_GET['enviado'] ?? '' );
|
||||
$preselect = $animal_id ? 'adopcion' : sanitize_key( $_GET['motivo'] ?? '' );
|
||||
$privacy = ga_page_url( 'politica-de-privacidad' );
|
||||
$anchor = $is_animal ? 'conocer' : 'formulario';
|
||||
|
||||
ob_start();
|
||||
if ( 'ok' === $status ) {
|
||||
echo '<div class="ga-notice ga-notice--ok" role="status">' . esc_html( ga_confirmation_text( (bool) $animal_id ) ) . '</div>';
|
||||
if ( $is_animal ) {
|
||||
return ob_get_clean();
|
||||
}
|
||||
} elseif ( 'error' === $status ) {
|
||||
echo '<div class="ga-notice ga-notice--error" role="alert">'
|
||||
. esc_html( ga__( 'No hemos podido enviar el mensaje. Revisa los campos obligatorios o escríbenos a ', 'Ezin izan dugu mezua bidali. Egiaztatu derrigorrezko eremuak edo idatzi iezaguzu helbide honetara: ' ) . ga_info( 'email' ) ) . '</div>';
|
||||
}
|
||||
?>
|
||||
<form class="ga-form" method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
|
||||
<input type="hidden" name="action" value="ga_contacto">
|
||||
<input type="hidden" name="idioma" value="<?php echo esc_attr( ga_lang() ); ?>">
|
||||
<input type="hidden" name="redirect" value="<?php echo esc_url( get_permalink() . '#' . $anchor ); ?>">
|
||||
<?php if ( $animal_id ) : ?>
|
||||
<input type="hidden" name="animal_id" value="<?php echo (int) $animal_id; ?>">
|
||||
<?php endif; ?>
|
||||
<?php wp_nonce_field( 'ga_contacto', 'ga_nonce' ); ?>
|
||||
<div class="ga-hp" aria-hidden="true"><label>No rellenar <input type="text" name="web" tabindex="-1" autocomplete="off"></label></div>
|
||||
|
||||
<div class="ga-form__row">
|
||||
<label><?php ga_e( 'Nombre', 'Izena' ); ?> *<input type="text" name="nombre" required autocomplete="name"></label>
|
||||
<label><?php ga_e( 'Correo electrónico', 'Posta elektronikoa' ); ?> *<input type="email" name="email" required autocomplete="email"></label>
|
||||
</div>
|
||||
<div class="ga-form__row">
|
||||
<label><?php ga_e( 'Teléfono', 'Telefonoa' ); ?><?php echo $is_animal ? ' *' : ''; ?><input type="tel" name="telefono" autocomplete="tel"<?php echo $is_animal ? ' required' : ''; ?>></label>
|
||||
<?php if ( ! $is_animal ) : ?>
|
||||
<label><?php ga_e( 'Motivo', 'Arrazoia' ); ?>
|
||||
<select name="motivo">
|
||||
<?php foreach ( ga_contact_reasons() as $value => $label ) : ?>
|
||||
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $preselect, $value ); ?>><?php echo esc_html( $label ); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</label>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ( $animal_id && ! $is_animal ) : ?>
|
||||
<p class="ga-form__animal"><?php echo esc_html( ga__( 'Animal: ', 'Animalia: ' ) . get_the_title( $animal_id ) ); ?></p>
|
||||
<?php endif; ?>
|
||||
<label><?php ga_e( 'Mensaje', 'Mezua' ); ?><?php echo $is_animal ? ' (' . esc_html( ga__( 'opcional', 'aukerakoa' ) ) . ')' : ' *'; ?>
|
||||
<textarea name="mensaje" rows="<?php echo $is_animal ? 4 : 6; ?>"<?php echo $is_animal ? '' : ' required'; ?>></textarea>
|
||||
</label>
|
||||
<label class="ga-form__check">
|
||||
<input type="checkbox" name="privacidad" value="1" required>
|
||||
<span>
|
||||
<?php if ( 'eu' === ga_lang() ) : ?>
|
||||
<a href="<?php echo esc_url( $privacy ); ?>" target="_blank">Pribatutasun-politika</a> irakurri eta onartzen dut. *
|
||||
<?php else : ?>
|
||||
He leído y acepto la <a href="<?php echo esc_url( $privacy ); ?>" target="_blank">política de privacidad</a>. *
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</label>
|
||||
<button type="submit" class="ga-btn"><?php echo esc_html( $is_animal ? ga__( 'Enviar solicitud', 'Eskaera bidali' ) : ga__( 'Enviar mensaje', 'Mezua bidali' ) ); ?></button>
|
||||
</form>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
} );
|
||||
|
||||
add_action( 'admin_post_nopriv_ga_contacto', 'ga_handle_contact' );
|
||||
add_action( 'admin_post_ga_contacto', 'ga_handle_contact' );
|
||||
|
||||
function ga_handle_contact() {
|
||||
$redirect = wp_validate_redirect( esc_url_raw( wp_unslash( $_POST['redirect'] ?? '' ) ), home_url( '/' ) );
|
||||
$go = function ( $status ) use ( $redirect ) {
|
||||
$parts = explode( '#', $redirect, 2 );
|
||||
wp_safe_redirect( add_query_arg( 'enviado', $status, $parts[0] ) . ( isset( $parts[1] ) ? '#' . $parts[1] : '' ) );
|
||||
exit;
|
||||
};
|
||||
|
||||
if ( ! isset( $_POST['ga_nonce'] ) || ! wp_verify_nonce( $_POST['ga_nonce'], 'ga_contacto' ) ) {
|
||||
$go( 'error' );
|
||||
}
|
||||
if ( ! empty( $_POST['web'] ) ) { // Honeypot: los bots rellenan el campo oculto.
|
||||
$go( 'ok' );
|
||||
}
|
||||
|
||||
$animal_id = absint( $_POST['animal_id'] ?? 0 );
|
||||
$animal = $animal_id && 'animal' === get_post_type( $animal_id ) ? get_the_title( $animal_id ) : '';
|
||||
$reasons = ga_contact_reasons();
|
||||
$reason = $animal ? 'adopcion' : sanitize_key( $_POST['motivo'] ?? '' );
|
||||
$data = array(
|
||||
'nombre' => sanitize_text_field( wp_unslash( $_POST['nombre'] ?? '' ) ),
|
||||
'email' => sanitize_email( wp_unslash( $_POST['email'] ?? '' ) ),
|
||||
'telefono' => sanitize_text_field( wp_unslash( $_POST['telefono'] ?? '' ) ),
|
||||
'motivo' => $reasons[ $reason ] ?? $reasons['otro'],
|
||||
'mensaje' => sanitize_textarea_field( wp_unslash( $_POST['mensaje'] ?? '' ) ),
|
||||
'idioma' => 'eu' === ( $_POST['idioma'] ?? '' ) ? 'Euskera' : 'Castellano',
|
||||
);
|
||||
$message_required = ! $animal;
|
||||
if ( ! $data['nombre'] || ! is_email( $data['email'] ) || ( $message_required && ! $data['mensaje'] ) || empty( $_POST['privacidad'] ) ) {
|
||||
$go( 'error' );
|
||||
}
|
||||
|
||||
$subject = $animal
|
||||
? sprintf( '[Web] Quiero conocer a %s – %s', $animal, $data['nombre'] )
|
||||
: sprintf( '[Web] %s – %s', $data['motivo'], $data['nombre'] );
|
||||
$body = sprintf(
|
||||
"Nombre: %s\nEmail: %s\nTeléfono: %s\nMotivo: %s\nAnimal: %s\nIdioma: %s\n\n%s",
|
||||
$data['nombre'], $data['email'], $data['telefono'] ?: '-', $data['motivo'],
|
||||
$animal ? $animal . ' — ' . get_permalink( $animal_id ) : '-',
|
||||
$data['idioma'], $data['mensaje'] ?: '(sin mensaje)'
|
||||
);
|
||||
|
||||
// Se guarda siempre en el panel, aunque falle el correo.
|
||||
wp_insert_post( array(
|
||||
'post_type' => 'ga_mensaje',
|
||||
'post_status' => 'private',
|
||||
'post_title' => $subject,
|
||||
'post_content' => $body,
|
||||
) );
|
||||
wp_mail( ga_contact_email(), $subject, $body, array( 'Reply-To: ' . $data['nombre'] . ' <' . $data['email'] . '>' ) );
|
||||
|
||||
$go( 'ok' );
|
||||
}
|
||||
|
||||
/* [ga_necesidades] lista de ayuda material (se edita en Personalizar → Colabora) */
|
||||
add_shortcode( 'ga_necesidades', function () {
|
||||
$items = array_filter( array_map( 'trim', explode( "\n", (string) ga_setting( 'material', 'list', '' ) ) ) );
|
||||
$note = ga_setting( 'material', 'note', '' );
|
||||
ob_start();
|
||||
if ( $items ) {
|
||||
echo '<ul class="ga-needs-list">';
|
||||
foreach ( $items as $item ) {
|
||||
echo '<li>' . esc_html( $item ) . '</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
if ( $note ) {
|
||||
echo '<p class="ga-needs-note">' . esc_html( $note ) . '</p>';
|
||||
}
|
||||
return ob_get_clean();
|
||||
} );
|
||||
|
||||
/* [ga_cita] aviso de cita previa */
|
||||
add_shortcode( 'ga_cita', function () {
|
||||
$text = ga_info( 'cita' );
|
||||
return $text ? '<p class="ga-cita">' . esc_html( $text ) . '</p>' : '';
|
||||
} );
|
||||
118
wp-content/mu-plugins/gure-ametsa/i18n.php
Normal file
118
wp-content/mu-plugins/gure-ametsa/i18n.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* Idioma (castellano / euskera), datos de la protectora y ajustes.
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/** Idioma actual: 'es' o 'eu'. El panel de administración siempre en castellano. */
|
||||
function ga_lang() {
|
||||
if ( isset( $GLOBALS['ga_forced_lang'] ) ) {
|
||||
return 'eu' === $GLOBALS['ga_forced_lang'] ? 'eu' : 'es';
|
||||
}
|
||||
if ( is_admin() && ! wp_doing_ajax() ) {
|
||||
return 'es';
|
||||
}
|
||||
$lang = function_exists( 'pll_current_language' ) ? pll_current_language() : '';
|
||||
return 'eu' === $lang ? 'eu' : 'es';
|
||||
}
|
||||
|
||||
/** Devuelve el texto en el idioma actual. */
|
||||
function ga__( $es, $eu ) {
|
||||
return 'eu' === ga_lang() ? $eu : $es;
|
||||
}
|
||||
|
||||
/** Imprime el texto escapado en el idioma actual. */
|
||||
function ga_e( $es, $eu ) {
|
||||
echo esc_html( ga__( $es, $eu ) );
|
||||
}
|
||||
|
||||
/** Ejecuta $callback como si el idioma actual fuera $lang. */
|
||||
function ga_with_lang( $lang, callable $callback ) {
|
||||
$previous = $GLOBALS['ga_forced_lang'] ?? null;
|
||||
$GLOBALS['ga_forced_lang'] = $lang;
|
||||
try {
|
||||
return $callback();
|
||||
} finally {
|
||||
if ( null === $previous ) {
|
||||
unset( $GLOBALS['ga_forced_lang'] );
|
||||
} else {
|
||||
$GLOBALS['ga_forced_lang'] = $previous;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** URL de una página por su slug en castellano, en el idioma actual. */
|
||||
function ga_page_url( $slug_es, $fragment = '' ) {
|
||||
$page = get_page_by_path( $slug_es );
|
||||
if ( ! $page ) {
|
||||
return home_url( "/$slug_es/" ) . $fragment;
|
||||
}
|
||||
$id = $page->ID;
|
||||
if ( function_exists( 'pll_get_post' ) ) {
|
||||
$id = pll_get_post( $id, ga_lang() ) ?: $id;
|
||||
}
|
||||
return get_permalink( $id ) . $fragment;
|
||||
}
|
||||
|
||||
/** URL del listado de una especie (slug en castellano: perro, gato) en el idioma actual. */
|
||||
function ga_species_url( $slug_es ) {
|
||||
$term = get_term_by( 'slug', $slug_es, 'especie' );
|
||||
if ( $term && function_exists( 'pll_get_term' ) ) {
|
||||
$translated = pll_get_term( $term->term_id, ga_lang() );
|
||||
$term = $translated ? get_term( $translated, 'especie' ) : $term;
|
||||
}
|
||||
$url = $term && ! is_wp_error( $term ) ? get_term_link( $term ) : '';
|
||||
return is_wp_error( $url ) || ! $url ? get_post_type_archive_link( 'animal' ) : $url;
|
||||
}
|
||||
|
||||
/* Animales y especies son traducibles; los mensajes no. */
|
||||
add_filter( 'pll_get_post_types', function ( $types ) {
|
||||
$types['animal'] = 'animal';
|
||||
unset( $types['ga_mensaje'] );
|
||||
return $types;
|
||||
} );
|
||||
|
||||
add_filter( 'pll_get_taxonomies', function ( $taxonomies ) {
|
||||
$taxonomies['especie'] = 'especie';
|
||||
return $taxonomies;
|
||||
} );
|
||||
|
||||
/**
|
||||
* Ajuste del personalizador del tema, con valor por defecto si el tema no está activo.
|
||||
*/
|
||||
function ga_setting( $section, $field, $default = '' ) {
|
||||
if ( function_exists( 'ga_opt' ) ) {
|
||||
$value = ga_opt( $section, $field );
|
||||
return null === $value ? $default : $value;
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Datos de la protectora (el tema los sustituye por los del personalizador)
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
function ga_info( $key = null ) {
|
||||
$info = apply_filters( 'ga_info', array(
|
||||
'nombre' => 'Bilagun',
|
||||
'direccion' => 'Jaizubia, 44 · 20280 Hondarribia (Gipuzkoa)',
|
||||
'telefono' => '943 64 52 79',
|
||||
'email' => 'hola@gureametsabilagun.org',
|
||||
'horario' => ga__( 'Lunes a viernes: 10:00–13:00 y 14:00–19:00', 'Astelehenetik ostiralera: 10:00–13:00 eta 14:00–19:00' ),
|
||||
'cita' => ga__( 'Atendemos con cita previa. Escríbenos o llámanos antes de venir.', 'Aurretiko hitzorduarekin artatzen dugu. Idatzi edo deitu iezaguzu etorri aurretik.' ),
|
||||
'instagram' => 'https://www.instagram.com/gureametsabilagun/',
|
||||
'facebook' => 'https://www.facebook.com/gureametsabilagun/',
|
||||
'maps' => 'https://www.google.com/maps/search/?api=1&query=Jaizubia+44+Hondarribia',
|
||||
) );
|
||||
return $key ? ( $info[ $key ] ?? '' ) : $info;
|
||||
}
|
||||
|
||||
/** Correo que recibe los formularios: ajuste del panel → variable GA_CONTACT_EMAIL → administrador. */
|
||||
function ga_contact_email() {
|
||||
$email = ga_setting( 'adopcion', 'form_email', '' );
|
||||
if ( ! is_email( $email ) ) {
|
||||
$email = getenv( 'GA_CONTACT_EMAIL' );
|
||||
}
|
||||
return is_email( $email ) ? $email : get_option( 'admin_email' );
|
||||
}
|
||||
Reference in New Issue
Block a user