Geoposicionador de cosas
This commit is contained in:
@@ -0,0 +1,280 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user