Files
freepress-map/fp-geo-content/fp-geo-content.php
2026-02-13 13:14:41 +01:00

314 lines
8.2 KiB
PHP

<?php
/**
* Plugin Name: FP Geo Content
* Plugin URI: https://freepress.coop
* Description: Mapa interactivo genérico con Leaflet y OpenStreetMap para mostrar contenido geolocalizado de WordPress.
* Version: 1.0.0
* Author: Freepress Coop
* Author URI: https://freepress.coop
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
* Text Domain: fp-geo-content
* Domain Path: /languages
* Requires at least: 6.0
* Requires PHP: 8.0
*/
// Si se accede directamente, salir
if (!defined('ABSPATH')) {
exit;
}
// Constantes del plugin
define('FP_GEO_VERSION', '1.0.0');
define('FP_GEO_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('FP_GEO_PLUGIN_URL', plugin_dir_url(__FILE__));
define('FP_GEO_PLUGIN_BASENAME', plugin_basename(__FILE__));
/**
* Clase principal del plugin
*/
final class FP_Geo_Content {
/**
* Instancia única
*/
private static $instance = null;
/**
* Opciones del plugin
*/
private $options = [];
/**
* Obtener instancia única
*/
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
private function __construct() {
$this->load_dependencies();
$this->init_hooks();
$this->options = get_option('fp_geo_content_options', []);
}
/**
* Cargar dependencias
*/
private function load_dependencies() {
require_once FP_GEO_PLUGIN_DIR . 'includes/class-settings.php';
require_once FP_GEO_PLUGIN_DIR . 'includes/class-map-renderer.php';
require_once FP_GEO_PLUGIN_DIR . 'includes/class-data-provider.php';
}
/**
* Inicializar hooks
*/
private function init_hooks() {
// Activación
register_activation_hook(__FILE__, [$this, 'activate']);
register_deactivation_hook(__FILE__, [$this, 'deactivate']);
// Inicialización
add_action('init', [$this, 'init']);
add_action('plugins_loaded', [$this, 'load_textdomain']);
// Admin
if (is_admin()) {
add_action('admin_menu', [$this, 'add_admin_menu']);
add_action('admin_init', [$this, 'register_settings']);
add_action('admin_enqueue_scripts', [$this, 'admin_assets']);
}
// Frontend
add_action('wp_enqueue_scripts', [$this, 'register_frontend_assets']);
add_action('wp_head', [$this, 'output_custom_css'], 100);
// Shortcode
add_shortcode('fp-geo-map', [FP_Geo_Map_Renderer::class, 'render_shortcode']);
// AJAX
add_action('wp_ajax_fp_geo_get_markers', [FP_Geo_Data_Provider::class, 'ajax_get_markers']);
add_action('wp_ajax_nopriv_fp_geo_get_markers', [FP_Geo_Data_Provider::class, 'ajax_get_markers']);
}
/**
* Inicialización
*/
public function init() {
// Registrar settings
FP_Geo_Settings::register();
}
/**
* Cargar traducciones
*/
public function load_textdomain() {
load_plugin_textdomain(
'fp-geo-content',
false,
dirname(FP_GEO_PLUGIN_BASENAME) . '/languages/'
);
}
/**
* Añadir menú de administración
*/
public function add_admin_menu() {
add_options_page(
__('FP Geo Content', 'fp-geo-content'),
__('FP Geo Content', 'fp-geo-content'),
'manage_options',
'fp-geo-content',
[$this, 'render_settings_page']
);
}
/**
* Registrar ajustes
*/
public function register_settings() {
FP_Geo_Settings::register_settings();
}
/**
* Renderizar página de ajustes
*/
public function render_settings_page() {
include FP_GEO_PLUGIN_DIR . 'templates/settings-page.php';
}
/**
* Assets del admin
*/
public function admin_assets($hook) {
if ($hook !== 'settings_page_fp-geo-content') {
return;
}
// Cargar media uploader
wp_enqueue_media();
wp_enqueue_style(
'fp-geo-admin',
FP_GEO_PLUGIN_URL . 'assets/css/admin.css',
[],
FP_GEO_VERSION
);
wp_enqueue_script(
'fp-geo-admin',
FP_GEO_PLUGIN_URL . 'assets/js/admin.js',
['jquery', 'wp-media-utils'],
FP_GEO_VERSION,
true
);
}
/**
* Registrar assets del frontend (no cargar por defecto)
*/
public function register_frontend_assets() {
// Leaflet CSS
wp_register_style(
'leaflet',
'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css',
[],
'1.9.4'
);
// Leaflet MarkerCluster CSS
wp_register_style(
'leaflet-markercluster',
'https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.css',
['leaflet'],
'1.5.3'
);
wp_register_style(
'leaflet-markercluster-default',
'https://unpkg.com/leaflet.markercluster@1.5.3/dist/MarkerCluster.Default.css',
['leaflet-markercluster'],
'1.5.3'
);
// Plugin CSS
wp_register_style(
'fp-geo-content',
FP_GEO_PLUGIN_URL . 'assets/css/map.css',
['leaflet', 'leaflet-markercluster-default'],
FP_GEO_VERSION
);
// Leaflet JS
wp_register_script(
'leaflet',
'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js',
[],
'1.9.4',
true
);
// Leaflet MarkerCluster JS
wp_register_script(
'leaflet-markercluster',
'https://unpkg.com/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.js',
['leaflet'],
'1.5.3',
true
);
// Plugin JS
wp_register_script(
'fp-geo-content',
FP_GEO_PLUGIN_URL . 'assets/js/map.js',
['leaflet', 'leaflet-markercluster'],
FP_GEO_VERSION,
true
);
}
/**
* Output custom CSS in head
*/
public function output_custom_css() {
$options = get_option('fp_geo_content_options', []);
$custom_css = $options['custom_css'] ?? '';
if (!empty(trim($custom_css))) {
echo "\n<style id=\"fp-geo-custom-css\">\n";
echo wp_strip_all_tags($custom_css);
echo "\n</style>\n";
}
}
/**
* Activación
*/
public function activate() {
// Opciones por defecto
$defaults = [
'post_types' => [],
'lat_field' => 'latitud',
'lng_field' => 'longitud',
'default_lat' => '40.4168',
'default_lng' => '-3.7038',
'default_zoom' => 12,
'min_zoom' => 5,
'max_zoom' => 18,
'cluster_enabled' => true,
'detail_display' => 'sidebar', // sidebar | modal
'filter_combine' => 'OR', // OR | AND
'tile_provider' => 'carto_light',
// Nuevas opciones
'scroll_wheel_zoom' => 'ctrl', // ctrl | always | disabled
'marker_icon' => 0,
'marker_default_color' => '#F97316',
'use_category_colors' => true,
'show_legend' => true,
'legend_taxonomy' => '',
'sidebar_position' => 'right', // left | right
'show_detail_button' => true,
'detail_button_text' => 'Ver detalle',
];
if (!get_option('fp_geo_content_options')) {
add_option('fp_geo_content_options', $defaults);
}
update_option('fp_geo_content_version', FP_GEO_VERSION);
}
/**
* Desactivación
*/
public function deactivate() {
// Nada que hacer por ahora
}
/**
* Obtener opción
*/
public static function get_option($key, $default = null) {
$options = get_option('fp_geo_content_options', []);
return $options[$key] ?? $default;
}
}
/**
* Iniciar el plugin
*/
function fp_geo_content() {
return FP_Geo_Content::get_instance();
}
// Arrancar
fp_geo_content();