Files
roi-apu-search/includes/class-db-connection.php
FrankZamora 81d65c0f9a 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>
2025-12-03 10:59:56 -06:00

121 lines
2.8 KiB
PHP

<?php
/**
* Database Connection with PDO Persistent
*
* @package ROI_APU_Search
*/
declare(strict_types=1);
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
/**
* Singleton class for PDO database connection with persistent connections
*/
final class ROI_APU_Search_DB
{
private static ?self $instance = null;
private ?PDO $pdo = null;
/**
* Get singleton instance
*/
public static function get_instance(): self
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Private constructor
*/
private function __construct()
{
$this->connect();
}
/**
* Establish PDO connection with persistent connection enabled
*/
private function connect(): void
{
if ($this->pdo !== null) {
return;
}
// Get WordPress database credentials
$host = DB_HOST;
$name = DB_NAME;
$user = DB_USER;
$pass = DB_PASSWORD;
$charset = defined('DB_CHARSET') ? DB_CHARSET : 'utf8mb4';
// Handle port in host
$port = 3306;
if (strpos($host, ':') !== false) {
[$host, $port] = explode(':', $host);
$port = (int) $port;
}
$dsn = "mysql:host={$host};port={$port};dbname={$name};charset={$charset}";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => true, // Same as original buscar-apus (enables reusing :q placeholder)
PDO::ATTR_PERSISTENT => true, // Enable persistent connections
];
try {
$this->pdo = new PDO($dsn, $user, $pass, $options);
// Set MySQL specific options (same as original buscar-apus)
$this->pdo->exec("SET NAMES {$charset} COLLATE {$charset}_unicode_ci");
} catch (PDOException $e) {
// Log error but don't expose details
error_log('ROI APU Search DB Error: ' . $e->getMessage());
throw new RuntimeException('Database connection failed');
}
}
/**
* Get the PDO instance
*/
public function get_pdo(): PDO
{
if ($this->pdo === null) {
$this->connect();
}
return $this->pdo;
}
/**
* Get WordPress table prefix
*/
public function get_prefix(): string
{
global $table_prefix;
return $table_prefix ?? 'wp_';
}
/**
* Prevent cloning
*/
private function __clone()
{
}
/**
* Prevent unserialization
*/
public function __wakeup()
{
throw new RuntimeException('Cannot unserialize singleton');
}
}