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 '
| '; switch ( $f['type'] ) { case 'select': echo ''; break; case 'checks': $current = array_filter( explode( ',', $value ) ); foreach ( $f['options'] as $v => $l ) { printf( '', esc_attr( $name ), esc_attr( $v ), checked( in_array( $v, $current, true ), true, false ), esc_html( $l ) ); } break; default: printf( '', 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 ' |
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.
'; echo 'Consejo: la foto principal aparece en los listados. Añade más fotos en el contenido con el bloque «Galería».
'; } 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 '' . esc_html( ga__( 'Ahora mismo no hay animales en esta sección. ¡Vuelve pronto!', 'Une honetan ez dago animaliarik atal honetan. Itzuli laster!' ) ) . '
'; } 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( '