281 lines
8.7 KiB
PHP
281 lines
8.7 KiB
PHP
<?php
|
|
/**
|
|
* Proveedor de datos para el mapa
|
|
*
|
|
* @package FP_Geo_Content
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
class FP_Geo_Data_Provider {
|
|
|
|
/**
|
|
* Obtener marcadores para el mapa
|
|
*
|
|
* @param array $args Argumentos de configuración
|
|
* @return array
|
|
*/
|
|
public static function get_markers($args = []) {
|
|
$options = get_option('fp_geo_content_options', []);
|
|
|
|
$defaults = [
|
|
'post_types' => $options['post_types'] ?? [],
|
|
'lat_field' => $options['lat_field'] ?? 'latitud',
|
|
'lng_field' => $options['lng_field'] ?? 'longitud',
|
|
'taxonomies' => [],
|
|
'terms' => [],
|
|
'filter_combine' => $options['filter_combine'] ?? 'OR',
|
|
];
|
|
|
|
$args = wp_parse_args($args, $defaults);
|
|
|
|
if (empty($args['post_types'])) {
|
|
return [];
|
|
}
|
|
|
|
// Query args
|
|
$query_args = [
|
|
'post_type' => $args['post_types'],
|
|
'posts_per_page' => -1,
|
|
'post_status' => 'publish',
|
|
'meta_query' => [
|
|
'relation' => 'AND',
|
|
[
|
|
'key' => $args['lat_field'],
|
|
'compare' => 'EXISTS',
|
|
],
|
|
[
|
|
'key' => $args['lng_field'],
|
|
'compare' => 'EXISTS',
|
|
],
|
|
[
|
|
'key' => $args['lat_field'],
|
|
'value' => '',
|
|
'compare' => '!=',
|
|
],
|
|
[
|
|
'key' => $args['lng_field'],
|
|
'value' => '',
|
|
'compare' => '!=',
|
|
],
|
|
],
|
|
];
|
|
|
|
// Filtros por taxonomía
|
|
if (!empty($args['terms']) && is_array($args['terms'])) {
|
|
$tax_query = ['relation' => $args['filter_combine']];
|
|
|
|
foreach ($args['terms'] as $taxonomy => $term_slugs) {
|
|
if (!empty($term_slugs)) {
|
|
$tax_query[] = [
|
|
'taxonomy' => $taxonomy,
|
|
'field' => 'slug',
|
|
'terms' => (array) $term_slugs,
|
|
];
|
|
}
|
|
}
|
|
|
|
if (count($tax_query) > 1) {
|
|
$query_args['tax_query'] = $tax_query;
|
|
}
|
|
}
|
|
|
|
$query = new WP_Query($query_args);
|
|
$markers = [];
|
|
|
|
if ($query->have_posts()) {
|
|
while ($query->have_posts()) {
|
|
$query->the_post();
|
|
$post = get_post();
|
|
|
|
$marker = self::prepare_marker($post, $args);
|
|
if ($marker) {
|
|
$markers[] = $marker;
|
|
}
|
|
}
|
|
wp_reset_postdata();
|
|
}
|
|
|
|
return $markers;
|
|
}
|
|
|
|
/**
|
|
* Preparar datos de un marcador
|
|
*
|
|
* @param WP_Post $post
|
|
* @param array $args
|
|
* @return array|null
|
|
*/
|
|
private static function prepare_marker($post, $args) {
|
|
// Obtener coordenadas
|
|
$lat = get_field($args['lat_field'], $post->ID);
|
|
$lng = get_field($args['lng_field'], $post->ID);
|
|
|
|
// Si no hay coordenadas, intentar con get_post_meta
|
|
if (!$lat) {
|
|
$lat = get_post_meta($post->ID, $args['lat_field'], true);
|
|
}
|
|
if (!$lng) {
|
|
$lng = get_post_meta($post->ID, $args['lng_field'], true);
|
|
}
|
|
|
|
// Validar coordenadas
|
|
if (!$lat || !$lng || !is_numeric($lat) || !is_numeric($lng)) {
|
|
return null;
|
|
}
|
|
|
|
// Datos básicos
|
|
$marker = [
|
|
'id' => $post->ID,
|
|
'title' => html_entity_decode(get_the_title($post), ENT_QUOTES, 'UTF-8'),
|
|
'lat' => (float) $lat,
|
|
'lng' => (float) $lng,
|
|
'url' => get_permalink($post),
|
|
'post_type' => $post->post_type,
|
|
'excerpt' => wp_trim_words(get_the_excerpt($post), 20),
|
|
'thumbnail' => get_the_post_thumbnail_url($post, 'medium'),
|
|
];
|
|
|
|
// Obtener taxonomías
|
|
$options = get_option('fp_geo_content_options', []);
|
|
$filter_taxonomies = $options['filter_taxonomies'] ?? [];
|
|
|
|
$marker['taxonomies'] = [];
|
|
foreach ($filter_taxonomies as $taxonomy) {
|
|
$terms = wp_get_post_terms($post->ID, $taxonomy);
|
|
if (!is_wp_error($terms) && !empty($terms)) {
|
|
$marker['taxonomies'][$taxonomy] = [];
|
|
foreach ($terms as $term) {
|
|
$term_data = [
|
|
'id' => $term->term_id,
|
|
'name' => $term->name,
|
|
'slug' => $term->slug,
|
|
];
|
|
|
|
// Obtener campos ACF del término si existen (icono y color)
|
|
if (function_exists('get_field')) {
|
|
$icono = get_field('icono', $term);
|
|
$color = get_field('color', $term);
|
|
if ($icono) $term_data['icono'] = $icono;
|
|
if ($color) $term_data['color'] = $color;
|
|
}
|
|
|
|
$marker['taxonomies'][$taxonomy][] = $term_data;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Campo es_piloto del post (para actuaciones)
|
|
$es_piloto = get_field('es_piloto', $post->ID);
|
|
if (!$es_piloto) {
|
|
$es_piloto = get_post_meta($post->ID, 'es_piloto', true);
|
|
}
|
|
if ($es_piloto) {
|
|
$marker['es_piloto'] = true;
|
|
}
|
|
|
|
// Campos adicionales comunes
|
|
$additional_fields = ['direccion', 'localidad', 'telefono', 'email', 'web'];
|
|
foreach ($additional_fields as $field) {
|
|
$value = get_field($field, $post->ID);
|
|
if (!$value) {
|
|
$value = get_post_meta($post->ID, $field, true);
|
|
}
|
|
if ($value) {
|
|
$marker[$field] = $value;
|
|
}
|
|
}
|
|
|
|
// Permitir filtrar los datos del marcador
|
|
return apply_filters('fp_geo_marker_data', $marker, $post);
|
|
}
|
|
|
|
/**
|
|
* Handler AJAX para obtener marcadores
|
|
*/
|
|
public static function ajax_get_markers() {
|
|
check_ajax_referer('fp_geo_nonce', 'nonce');
|
|
|
|
$post_types = isset($_POST['post_types']) ? array_map('sanitize_text_field', (array) $_POST['post_types']) : [];
|
|
$terms = isset($_POST['terms']) ? $_POST['terms'] : [];
|
|
|
|
// Sanitizar términos
|
|
$sanitized_terms = [];
|
|
if (is_array($terms)) {
|
|
foreach ($terms as $taxonomy => $slugs) {
|
|
$taxonomy = sanitize_text_field($taxonomy);
|
|
$sanitized_terms[$taxonomy] = array_map('sanitize_text_field', (array) $slugs);
|
|
}
|
|
}
|
|
|
|
$markers = self::get_markers([
|
|
'post_types' => $post_types,
|
|
'terms' => $sanitized_terms,
|
|
]);
|
|
|
|
wp_send_json_success(['markers' => $markers]);
|
|
}
|
|
|
|
/**
|
|
* Obtener términos disponibles para filtros
|
|
*
|
|
* @param array $post_types
|
|
* @param array $taxonomies
|
|
* @return array
|
|
*/
|
|
public static function get_filter_terms($post_types = [], $taxonomies = []) {
|
|
$result = [];
|
|
|
|
foreach ($taxonomies as $taxonomy) {
|
|
$tax_obj = get_taxonomy($taxonomy);
|
|
if (!$tax_obj) continue;
|
|
|
|
// Verificar que la taxonomía está asociada a alguno de los post types
|
|
$associated = false;
|
|
foreach ($post_types as $pt) {
|
|
if (in_array($pt, $tax_obj->object_type)) {
|
|
$associated = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$associated) continue;
|
|
|
|
$terms = get_terms([
|
|
'taxonomy' => $taxonomy,
|
|
'hide_empty' => true,
|
|
]);
|
|
|
|
if (!is_wp_error($terms) && !empty($terms)) {
|
|
$result[$taxonomy] = [
|
|
'label' => $tax_obj->label,
|
|
'terms' => [],
|
|
];
|
|
|
|
foreach ($terms as $term) {
|
|
$term_data = [
|
|
'id' => $term->term_id,
|
|
'name' => $term->name,
|
|
'slug' => $term->slug,
|
|
'count' => $term->count,
|
|
];
|
|
|
|
// Campos ACF del término (icono y color)
|
|
if (function_exists('get_field')) {
|
|
$icono = get_field('icono', $term);
|
|
$color = get_field('color', $term);
|
|
if ($icono) $term_data['icono'] = $icono;
|
|
if ($color) $term_data['color'] = $color;
|
|
}
|
|
|
|
$result[$taxonomy]['terms'][] = $term_data;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
}
|