- Docker Compose (WordPress + MariaDB) listo para Dokploy, con instalación automática por etapas: idiomas, páginas, menús y plugins recomendados. - Web bilingüe castellano / euskera con Polylang. - Tema propio «gure-ametsa»: diseño inspirado en Beargrass Animal Rescue, personalizable desde Apariencia → Personalizar (paletas, tipografías, secciones de portada ordenables) y patrones de bloques propios. - Plugin mu «gure-ametsa-core»: animales en adopción con ficha y filtros, carrusel y formulario de contacto/adopción. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
635 lines
24 KiB
PHP
635 lines
24 KiB
PHP
<?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
|
||
* 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 ( 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,
|
||
) );
|
||
|
||
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,
|
||
'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' );
|
||
}
|