fix(analytics): Corregir URLs en analytics usando post_name desde BD
Problema: - URLs en analytics mostraban dominio incorrecto (HTTP_HOST) - URLs usaban formato /?p=ID en lugar de permalinks Solución: - class-search-engine.php: Agregar propiedad $prefix, incluir p.post_name en 5 queries fetch, agregar helpers getSiteUrlFromDb(), getPermalinkStructure() y buildPermalink() - search-endpoint.php: Obtener site_url y permalink_structure desde wp_options, construir URLs con post_name - click-endpoint.php: Fallback de dest usando post_name desde BD Archivos modificados: - includes/class-search-engine.php - api/search-endpoint.php - api/click-endpoint.php 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
248
roi-apu-search.php
Normal file
248
roi-apu-search.php
Normal file
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: ROI APU Search
|
||||
* Plugin URI: https://analisisdepreciosunitarios.com
|
||||
* Description: Motor de busqueda ultra-rapido para Analisis de Precios Unitarios con PDO persistente y scoring hibrido.
|
||||
* Version: 1.1.0
|
||||
* Author: ROI Theme
|
||||
* Author URI: https://analisisdepreciosunitarios.com
|
||||
* Text Domain: roi-apu-search
|
||||
* Domain Path: /languages
|
||||
* Requires at least: 6.0
|
||||
* Requires PHP: 8.0
|
||||
*
|
||||
* @package ROI_APU_Search
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
// Prevent direct access
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Plugin constants
|
||||
define('ROI_APU_SEARCH_VERSION', '1.1.0');
|
||||
define('ROI_APU_SEARCH_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||
define('ROI_APU_SEARCH_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||
define('ROI_APU_SEARCH_PLUGIN_BASENAME', plugin_basename(__FILE__));
|
||||
|
||||
/**
|
||||
* Main plugin class
|
||||
*/
|
||||
final class ROI_APU_Search_Plugin
|
||||
{
|
||||
private static ?self $instance = null;
|
||||
|
||||
/**
|
||||
* Get singleton instance
|
||||
*/
|
||||
public static function get_instance(): self
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
$this->load_dependencies();
|
||||
$this->init_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load required files
|
||||
*/
|
||||
private function load_dependencies(): void
|
||||
{
|
||||
require_once ROI_APU_SEARCH_PLUGIN_DIR . 'includes/class-db-connection.php';
|
||||
require_once ROI_APU_SEARCH_PLUGIN_DIR . 'includes/class-redis-cache.php';
|
||||
require_once ROI_APU_SEARCH_PLUGIN_DIR . 'includes/class-search-engine.php';
|
||||
require_once ROI_APU_SEARCH_PLUGIN_DIR . 'includes/class-shortcode.php';
|
||||
require_once ROI_APU_SEARCH_PLUGIN_DIR . 'includes/class-analytics.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize WordPress hooks
|
||||
*/
|
||||
private function init_hooks(): void
|
||||
{
|
||||
// Register shortcode
|
||||
add_action('init', [$this, 'register_shortcode']);
|
||||
|
||||
// Enqueue assets
|
||||
add_action('wp_enqueue_scripts', [$this, 'enqueue_assets']);
|
||||
|
||||
// AJAX handlers (for non-SHORTINIT fallback)
|
||||
add_action('wp_ajax_roi_apu_search', [$this, 'handle_ajax_search']);
|
||||
add_action('wp_ajax_nopriv_roi_apu_search', [$this, 'handle_ajax_search']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the shortcode
|
||||
*/
|
||||
public function register_shortcode(): void
|
||||
{
|
||||
$shortcode = new ROI_APU_Search_Shortcode();
|
||||
add_shortcode('roi_apu_search', [$shortcode, 'render']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue frontend assets
|
||||
*/
|
||||
public function enqueue_assets(): void
|
||||
{
|
||||
// Only load if shortcode is used
|
||||
global $post;
|
||||
if (!$post || !has_shortcode($post->post_content, 'roi_apu_search')) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_enqueue_style(
|
||||
'roi-apu-search',
|
||||
ROI_APU_SEARCH_PLUGIN_URL . 'assets/css/search-ui.css',
|
||||
[],
|
||||
ROI_APU_SEARCH_VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'roi-apu-search',
|
||||
ROI_APU_SEARCH_PLUGIN_URL . 'assets/js/search-handler.js',
|
||||
[],
|
||||
ROI_APU_SEARCH_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
// Obtener configuracion de AdSense del tema (si existe)
|
||||
// Verifica que la funcion exista para evitar errores si se usa otro tema
|
||||
$adsConfig = function_exists('roi_get_adsense_search_config')
|
||||
? roi_get_adsense_search_config()
|
||||
: ['enabled' => false];
|
||||
|
||||
// Localize script with AJAX URL, nonce, click tracking URL, and ads config
|
||||
wp_localize_script('roi-apu-search', 'roiApuSearch', [
|
||||
'ajaxUrl' => admin_url('admin-ajax.php'),
|
||||
'apiUrl' => ROI_APU_SEARCH_PLUGIN_URL . 'api/search-endpoint.php',
|
||||
'clickUrl' => ROI_APU_SEARCH_PLUGIN_URL . 'api/click-endpoint.php',
|
||||
'nonce' => wp_create_nonce('roi_apu_search'),
|
||||
'ads' => $adsConfig,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle AJAX search request (fallback if SHORTINIT doesn't work)
|
||||
*/
|
||||
public function handle_ajax_search(): void
|
||||
{
|
||||
// Verify nonce
|
||||
if (!check_ajax_referer('roi_apu_search', 'nonce', false)) {
|
||||
wp_send_json_error(['message' => 'Invalid security token'], 403);
|
||||
}
|
||||
|
||||
// Store raw term before sanitization
|
||||
$term_raw = isset($_POST['term']) ? (string) wp_unslash($_POST['term']) : '';
|
||||
$term = sanitize_text_field($term_raw);
|
||||
$page = isset($_POST['page']) ? absint($_POST['page']) : 1;
|
||||
$per_page = isset($_POST['per_page']) ? absint($_POST['per_page']) : 10;
|
||||
$categories = isset($_POST['categories']) ? sanitize_text_field(wp_unslash($_POST['categories'])) : '';
|
||||
|
||||
// Validate term
|
||||
$min_len = 3;
|
||||
$max_len = 250;
|
||||
|
||||
if (mb_strlen($term, 'UTF-8') < $min_len) {
|
||||
wp_send_json_error(['message' => "Minimo {$min_len} caracteres"], 400);
|
||||
}
|
||||
|
||||
if (mb_strlen($term, 'UTF-8') > $max_len) {
|
||||
$term = mb_substr($term, 0, $max_len, 'UTF-8');
|
||||
}
|
||||
|
||||
// Execute search
|
||||
try {
|
||||
$db = ROI_APU_Search_DB::get_instance();
|
||||
$pdo = $db->get_pdo();
|
||||
$prefix = $db->get_prefix();
|
||||
|
||||
$search = new ROI_APU_Search_Engine($pdo);
|
||||
|
||||
// Parse categories
|
||||
$category_ids = [];
|
||||
if (!empty($categories)) {
|
||||
$category_ids = $this->parse_categories($categories);
|
||||
}
|
||||
|
||||
$offset = ($page - 1) * $per_page;
|
||||
$results = $search->run($term, $per_page, $offset, $category_ids);
|
||||
|
||||
// Log search for analytics
|
||||
$analytics_cfg = ROI_APU_Search_Analytics::get_config();
|
||||
$search_id = ROI_APU_Search_Analytics::logSearch(
|
||||
$pdo,
|
||||
$prefix,
|
||||
$analytics_cfg,
|
||||
$term_raw,
|
||||
$term,
|
||||
$results,
|
||||
$page,
|
||||
$per_page
|
||||
);
|
||||
|
||||
// Add search_id to response for click tracking
|
||||
$results['search_id'] = $search_id;
|
||||
|
||||
wp_send_json_success($results);
|
||||
} catch (\Exception $e) {
|
||||
wp_send_json_error(['message' => 'Error en la busqueda'], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse categories string to array of IDs
|
||||
*/
|
||||
private function parse_categories(string $categories): array
|
||||
{
|
||||
$parts = array_filter(array_map('trim', explode(',', $categories)));
|
||||
$ids = [];
|
||||
|
||||
foreach ($parts as $part) {
|
||||
if (is_numeric($part)) {
|
||||
$ids[] = (int) $part;
|
||||
} else {
|
||||
// Try to get category by slug
|
||||
$term = get_term_by('slug', $part, 'category');
|
||||
if ($term) {
|
||||
$ids[] = (int) $term->term_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($ids);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize plugin
|
||||
add_action('plugins_loaded', function () {
|
||||
ROI_APU_Search_Plugin::get_instance();
|
||||
});
|
||||
|
||||
// Activation hook
|
||||
register_activation_hook(__FILE__, function () {
|
||||
// Check PHP version
|
||||
if (version_compare(PHP_VERSION, '8.0', '<')) {
|
||||
deactivate_plugins(plugin_basename(__FILE__));
|
||||
wp_die('ROI APU Search requiere PHP 8.0 o superior.');
|
||||
}
|
||||
|
||||
// Flush rewrite rules
|
||||
flush_rewrite_rules();
|
||||
});
|
||||
|
||||
// Deactivation hook
|
||||
register_deactivation_hook(__FILE__, function () {
|
||||
flush_rewrite_rules();
|
||||
});
|
||||
Reference in New Issue
Block a user