AcaiAPI data layer + CocoDB facade

AcaiAPI: PDO-based data access layer (prepared statements, JOIN relation
loading, batch upload fetching) developed on villagrancanaria.
CocoDB_alias declares the CocoDB facade delegating to AcaiAPI; the
legacy implementation stays available as CocoDB_old.
This commit is contained in:
Jordan Diaz
2026-07-21 17:29:51 +00:00
parent dd2657a5d3
commit 432130565b
3 changed files with 2068 additions and 1 deletions

1688
cms/lib/classes/AcaiAPI.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
<?php <?php
class CocoDB require_once __DIR__ . '/CocoDB_alias.php';
class CocoDB_old
{ {
public static $tableCache = []; public static $tableCache = [];
public static $uploadColumns = []; public static $uploadColumns = [];

View File

@@ -0,0 +1,378 @@
<?php
/**
* CocoDB_alias — Fachada sobre AcaiAPI con la misma firma pública que CocoDB.
*
* Uso:
* 1. Incluir este archivo además de AcaiAPI.php (o en su lugar).
* 2. Para migrar: copiar el contenido de este archivo, renombrar la clase a
* `CocoDB`, y TODA referencia anterior a CocoDB seguirá funcionando sin
* cambios en el código de llamada.
*
* Cómo funciona:
* - Declara las mismas propiedades estáticas públicas que CocoDB (force_redis,
* storeDebugData, etc.), de forma que el código externo pueda leerlas y
* escribirlas con la misma sintaxis.
* - Antes de cada llamada, sincroniza sus propiedades hacia AcaiAPI
* (syncToAcai). Después, lee de vuelta el estado acumulado (syncFromAcai).
* - Los métodos de la API pública delegan directamente a AcaiAPI manteniendo
* los mismos nombres y firmas que CocoDB.
*
* require_once 'CocoDB_alias.php';
* require_once 'AcaiAPI.php';
*
* CocoDB_alias::$force_redis = true;
* $result = CocoDB_alias::get('productos', 'visible=1', 'num ASC', 10);
*/
require_once __DIR__ . '/AcaiAPI.php';
class CocoDB {
// ──────────────────────────────────────────────────────────────────────
// Propiedades públicas — idénticas a CocoDB para compatibilidad directa
// ──────────────────────────────────────────────────────────────────────
/** Resultado raw de queries de debug */
public static $debugData = [];
/** Activa acumulación de debugData */
public static $storeDebugData = false;
/** Datos de tracking de rendimiento por request */
public static $trackData = [];
public static $backTracePoint = null;
/** Profundidad de relaciones por defecto */
public static $defaultRelationsDepth = 2;
/** Caché in-memory de resultados de get() */
public static $getCaches = [];
/** Caché de campos traducibles */
public static $allowedTranslateFields = null;
/** Caché de configuración de plugins */
public static $pluginsConfig = [];
/** Conexión Redis activa (null = sin Redis) */
public static $redis = null;
/** TTL Redis activo */
public static $redis_expireTime = 0;
/** Activar caché in-memory para TODOS los get() */
public static $force_load_cache = false;
/** Activar Redis para TODOS los get() */
public static $force_redis = false;
/** Consumido por la capa de caché de módulos del CMS */
public static $force_redis_module = false;
/** Consumido por la capa de caché de HTML del CMS */
public static $force_redis_html = false;
/** Activar caché JSON diario de uploads */
public static $force_json_cache_uploads = false;
/** URIs excluidas de caché (array de regex) */
public static $noCacheURIS = [];
/** Tablas excluidas de caché (nombre exacto) */
public static $noCacheTABLES = [];
// ──────────────────────────────────────────────────────────────────────
// Sincronización bidireccional de estado con AcaiAPI
// ──────────────────────────────────────────────────────────────────────
private static function syncToAcai() {
AcaiAPI::$storeDebugData = self::$storeDebugData;
AcaiAPI::$defaultRelationsDepth = self::$defaultRelationsDepth;
AcaiAPI::$getCaches = self::$getCaches;
AcaiAPI::$allowedTranslateFields = self::$allowedTranslateFields;
AcaiAPI::$pluginsConfig = self::$pluginsConfig;
AcaiAPI::$redis = self::$redis;
AcaiAPI::$redis_expireTime = self::$redis_expireTime;
AcaiAPI::$force_load_cache = self::$force_load_cache;
AcaiAPI::$force_redis = self::$force_redis;
AcaiAPI::$force_redis_module = self::$force_redis_module;
AcaiAPI::$force_redis_html = self::$force_redis_html;
AcaiAPI::$force_json_cache_uploads = self::$force_json_cache_uploads;
AcaiAPI::$noCacheURIS = self::$noCacheURIS;
AcaiAPI::$noCacheTABLES = self::$noCacheTABLES;
AcaiAPI::$backTracePoint = self::$backTracePoint;
AcaiAPI::$trackData = self::$trackData;
}
private static function syncFromAcai() {
self::$debugData = AcaiAPI::$debugData;
self::$trackData = AcaiAPI::$trackData;
self::$getCaches = AcaiAPI::$getCaches;
self::$allowedTranslateFields = AcaiAPI::$allowedTranslateFields;
self::$pluginsConfig = AcaiAPI::$pluginsConfig;
self::$redis = AcaiAPI::$redis;
self::$redis_expireTime = AcaiAPI::$redis_expireTime;
self::$force_load_cache = AcaiAPI::$force_load_cache;
self::$force_redis = AcaiAPI::$force_redis;
self::$force_redis_module = AcaiAPI::$force_redis_module;
self::$force_redis_html = AcaiAPI::$force_redis_html;
self::$force_json_cache_uploads = AcaiAPI::$force_json_cache_uploads;
}
// ──────────────────────────────────────────────────────────────────────
// API pública principal — mismos nombres y firmas que CocoDB
// ──────────────────────────────────────────────────────────────────────
/**
* Lee registros de una tabla.
* Firma idéntica a CocoDB::get().
*/
static function get($table, $where = null, $order = null, $limit = null, $options = []) {
self::syncToAcai();
$result = AcaiAPI::get($table, $where, $order, $limit, $options);
self::syncFromAcai();
return $result;
}
/**
* Inserta uno o varios registros.
* Firma idéntica a CocoDB::insertRecords().
*/
static function insertRecords($table, $records, $functions = [], $options = []) {
self::syncToAcai();
$result = AcaiAPI::insert($table, $records, $functions, $options);
self::syncFromAcai();
return $result;
}
/**
* Actualiza registros que cumplan $where.
* Firma idéntica a CocoDB::updateRecords().
*/
static function updateRecords($table, $records, $where, $functions = [], $options = []) {
self::syncToAcai();
$result = AcaiAPI::update($table, $records, $where, $functions, $options);
self::syncFromAcai();
return $result;
}
/**
* Elimina registros que cumplan $where.
* Firma idéntica a CocoDB::deleteRecords().
*/
static function deleteRecords($table, $where, $options = []) {
self::syncToAcai();
$result = AcaiAPI::delete($table, $where, $options);
self::syncFromAcai();
return $result;
}
/**
* Manejo de errores.
* Firma idéntica a CocoDB::error().
*/
static function error($array = []) {
return AcaiAPI::error($array);
}
// ──────────────────────────────────────────────────────────────────────
// Cache helpers — mismos nombres que CocoDB
// ──────────────────────────────────────────────────────────────────────
/** Activa caché in-memory para el siguiente get(). */
static function localCache() {
self::syncToAcai();
AcaiAPI::localCache();
self::syncFromAcai();
}
/** Activa Redis para el siguiente get(). */
static function fullCache($expireTime = 60) {
self::syncToAcai();
AcaiAPI::fullCache($expireTime);
self::syncFromAcai();
}
/** Limpia las cachés activas antes de la siguiente query. */
static function initCache() {
self::syncToAcai();
AcaiAPI::initCache();
self::syncFromAcai();
}
/** Genera el hash de caché para una query. Alias de cacheHash(). */
static function cacheGenerateHash($string) {
return AcaiAPI::cacheHash($string);
}
/** Guarda un valor en Redis o en $getCaches. */
static function cacheSet($hash, $data, $expireTime = null) {
self::syncToAcai();
$result = AcaiAPI::cacheSet($hash, $data, $expireTime);
self::syncFromAcai();
return $result;
}
/** Lee un valor de Redis o $getCaches. */
static function cacheGet($hash) {
self::syncToAcai();
$result = AcaiAPI::cacheGet($hash);
self::syncFromAcai();
return $result;
}
/** Comprueba si la URL actual está excluida de caché. */
static function bloquedCacheByURL($url) {
self::syncToAcai();
return AcaiAPI::bloquedCacheByURL($url);
}
/**
* En HTML cacheado, reemplaza el token CSRF con el de la sesión actual.
* Firma idéntica a CocoDB::replaceHooksToken().
*/
static function replaceHooksToken($html) {
self::syncToAcai();
return AcaiAPI::replaceHooksToken($html);
}
// ──────────────────────────────────────────────────────────────────────
// Debug y tracking
// ──────────────────────────────────────────────────────────────────────
/**
* Renderiza el panel de debug de queries.
* Firma idéntica a CocoDB::showDebug().
*/
static function showDebug($formated = false, $index = -1) {
self::syncToAcai();
return AcaiAPI::showDebug($formated, $index);
}
static function setBacktracePoint($string) {
self::syncToAcai();
$result = AcaiAPI::setBacktracePoint($string);
self::syncFromAcai();
return $result;
}
static function getTrackData() {
self::syncFromAcai();
return AcaiAPI::getTrackData();
}
static function setTrackData($init = false, $type = null, $id = null, $data = []) {
self::syncToAcai();
$result = AcaiAPI::setTrackData($init, $type, $id, $data);
self::syncFromAcai();
return $result;
}
// ──────────────────────────────────────────────────────────────────────
// Categorías
// ──────────────────────────────────────────────────────────────────────
/**
* Reconstruye el árbol de categorías (globalOrder, siblingOrder, depth,
* lineage, breadcrumb) para la tabla indicada.
* Firma idéntica a CocoDB::updateCategoryMetadata().
*/
static function updateCategoryMetadata($tableName = null, $where = '') {
self::syncToAcai();
$result = AcaiAPI::updateCategoryMetadata($tableName, $where);
self::syncFromAcai();
return $result;
}
// ──────────────────────────────────────────────────────────────────────
// Schema
// ──────────────────────────────────────────────────────────────────────
/**
* Carga y cachea el schema de una tabla.
* Equivalente a la función privada schema() de AcaiAPI, expuesta aquí
* para compatibilidad con código externo que llame a CocoDB::schema().
*/
static function schema($table) {
return AcaiAPI::schema($table);
}
// ──────────────────────────────────────────────────────────────────────
// Plugins
// ──────────────────────────────────────────────────────────────────────
static function getPluginsConfig($table, $where) {
self::syncToAcai();
$result = AcaiAPI::getPluginsConfig($table, $where);
self::syncFromAcai();
return $result;
}
// ──────────────────────────────────────────────────────────────────────
// Traducciones — mismo helper que CocoDB expone públicamente
// ──────────────────────────────────────────────────────────────────────
/**
* Aplica traducciones recursivamente a un registro.
* Firma idéntica a CocoDB::t_recursivo().
*/
static function t_recursivo($record, $idx = null) {
self::syncToAcai();
$result = AcaiAPI::t_recursivo($record, $idx);
self::syncFromAcai();
return $result;
}
// ──────────────────────────────────────────────────────────────────────
// Métodos internos de CocoDB — stubs para compatibilidad
//
// Estos métodos son "public static" en CocoDB por accidente histórico;
// ningún código externo debería llamarlos directamente. Si encuentras un
// uso externo, migra la llamada al equivalente de AcaiAPI o refactoriza.
// ──────────────────────────────────────────────────────────────────────
/** @deprecated Método interno de CocoDB. No disponible en AcaiAPI. */
static function insertOrUpdate($record, $sqlBase, &$result, $where = null, $table = null, $functions = null, $ignoreSchema = false, $schema = null, $options = []) {
trigger_error('CocoDB_alias::insertOrUpdate() es un método interno. Usa insertRecords() o updateRecords().', E_USER_WARNING);
}
/** @deprecated Método interno de CocoDB. */
static function prepareBaseSQL($prefix, $table, $schema = null, $update = false, $ignoreFields = [], $record = []) {
trigger_error('CocoDB_alias::prepareBaseSQL() es un método interno.', E_USER_WARNING);
}
/** @deprecated Método interno de CocoDB. */
static function parse_options($options) {
trigger_error('CocoDB_alias::parse_options() es un método interno.', E_USER_WARNING);
}
/** @deprecated Usa el schema directamente. */
static function column_exists($key, $schema, $table, $prefix = '') {
trigger_error('CocoDB_alias::column_exists() es un método interno.', E_USER_WARNING);
}
/** @deprecated Método interno de CocoDB. */
static function cache_column($table, $column, $exists) {
trigger_error('CocoDB_alias::cache_column() es un método interno.', E_USER_WARNING);
}
/** @deprecated Método interno de CocoDB. */
static function parse_value_schema($value, $schema, $key) {
trigger_error('CocoDB_alias::parse_value_schema() es un método interno.', E_USER_WARNING);
}
/** @deprecated Usa buildWhere() de AcaiAPI (privado). Pasa el where directamente a get(). */
static function parse_where($where, $table, $prefix = '') {
trigger_error('CocoDB_alias::parse_where() es un método interno. Pasa el $where directamente a get().', E_USER_WARNING);
}
/** @deprecated Método interno de CocoDB. */
static function unsetKeys($array, $keys) {
trigger_error('CocoDB_alias::unsetKeys() es un método interno.', E_USER_WARNING);
}
/** @deprecated Método interno de CocoDB. */
static function parseGetRecord(&$record, $firstTable, $schema, $options = [], $uploadsResult = []) {
trigger_error('CocoDB_alias::parseGetRecord() es un método interno.', E_USER_WARNING);
}
/** @deprecated Método interno de CocoDB. */
static function getUploadsResults($options) {
trigger_error('CocoDB_alias::getUploadsResults() es un método interno.', E_USER_WARNING);
}
/** @deprecated Método interno de CocoDB. */
static function getUploadsResultsFromRecord(&$record, $firstTable, $schema, $options) {
trigger_error('CocoDB_alias::getUploadsResultsFromRecord() es un método interno.', E_USER_WARNING);
}
}