fix: devolver valores como string en las lecturas (paridad mysql_* legacy)

PDO con prepares nativos devuelve tipos reales (depth=int 0) mientras que
mysql_* devolvia siempre strings. Los templates y codigo Acai comparan
estrictamente contra strings (is same as('0'), === '1'...) y con tipos
nativos esos filtros fallan en silencio — p.ej. el menu del header vacio
en webs importadas (impulse) porque el filtro depth is same as('0') no
matcheaba int(0). stringifyRows normaliza todos los escalares no-NULL a
string en los 5 paths de lectura que devuelven datos hacia fuera: get(),
uploads, cache de queries de relaciones, traducciones y pluginsConfig.
This commit is contained in:
Jordan Diaz
2026-07-22 11:14:55 +00:00
parent fe7e9ee2e6
commit 031ef33f9f

View File

@@ -495,6 +495,7 @@ class AcaiAPI
$rows = $db->executeS($sql, $pdoParams); $rows = $db->executeS($sql, $pdoParams);
if (!is_array($rows)) $rows = []; if (!is_array($rows)) $rows = [];
$rows = self::stringifyRows($rows); // paridad de tipos con mysql_* legacy
// ── Hydrate records ─────────────────────────────────────────────── // ── Hydrate records ───────────────────────────────────────────────
$firstTableName = trim(explode(' ', $tables[0])[0]); $firstTableName = trim(explode(' ', $tables[0])[0]);
@@ -743,7 +744,7 @@ class AcaiAPI
if (!self::$pluginsConfig) { if (!self::$pluginsConfig) {
$db = Db::getInstance(); $db = Db::getInstance();
$configTable = preg_replace("/[^a-zA-Z0-9_]/", "", (string) $table) ?: "aux_plg_config"; $configTable = preg_replace("/[^a-zA-Z0-9_]/", "", (string) $table) ?: "aux_plg_config";
$rows = $db->executeS("SELECT * FROM `".$configTable."` ORDER BY num DESC") ?: []; $rows = self::stringifyRows($db->executeS("SELECT * FROM `".$configTable."` ORDER BY num DESC") ?: []);
self::$pluginsConfig = []; self::$pluginsConfig = [];
foreach ($rows as $row) { foreach ($rows as $row) {
if (!isset(self::$pluginsConfig[$row['plugin']])) { if (!isset(self::$pluginsConfig[$row['plugin']])) {
@@ -811,6 +812,7 @@ class AcaiAPI
ORDER BY `order` ASC", ORDER BY `order` ASC",
$params $params
); );
$uploads = self::stringifyRows($uploads); // paridad de tipos con mysql_* legacy
if (empty($uploads)) return []; if (empty($uploads)) return [];
@@ -914,7 +916,7 @@ class AcaiAPI
$cacheKey = md5($query); $cacheKey = md5($query);
if (!isset(self::$queryCaches[$cacheKey])) { if (!isset(self::$queryCaches[$cacheKey])) {
$db = Db::getInstance(); $db = Db::getInstance();
self::$queryCaches[$cacheKey] = $db->executeS($query) ?: []; self::$queryCaches[$cacheKey] = self::stringifyRows($db->executeS($query) ?: []);
} }
// Extract table name from the query for tableName field // Extract table name from the query for tableName field
$tableQuery = null; $tableQuery = null;
@@ -1157,6 +1159,7 @@ class AcaiAPI
ORDER BY num ASC", ORDER BY num ASC",
$params $params
) ?: []; ) ?: [];
$rows = self::stringifyRows($rows); // paridad de tipos con mysql_* legacy
foreach ($rows as $row) { foreach ($rows as $row) {
$uploadNum = $row['tableName'] === 'uploads' $uploadNum = $row['tableName'] === 'uploads'
@@ -1317,6 +1320,30 @@ class AcaiAPI
* $params mixed[] positional values matching each `?` * $params mixed[] positional values matching each `?`
* $uploadFields array [fieldName => [urlPath, ...]] * $uploadFields array [fieldName => [urlPath, ...]]
*/ */
/**
* Devuelve las filas con TODOS los valores escalares como string (NULL se
* mantiene NULL) — la semantica exacta del mysql_* legacy. PDO con
* prepares nativos devuelve tipos reales (int/float) y 20 años de
* templates/codigo Acai comparan estrictamente contra strings
* ("depth is same as('0')", === "1"...): sin esta normalizacion los
* filtros estrictos fallan EN SILENCIO (p.ej. menu del header vacio en
* webs importadas). Se aplica en todos los paths de lectura que devuelven
* datos hacia fuera de la clase.
*/
private static function stringifyRows($rows)
{
if (!is_array($rows)) return [];
foreach ($rows as $i => $row) {
if (!is_array($row)) continue;
foreach ($row as $k => $v) {
if ($v !== null && is_scalar($v) && !is_string($v)) {
$rows[$i][$k] = (string) $v;
}
}
}
return $rows;
}
private static function buildSetClause( private static function buildSetClause(
array $record, array $record,
array $schema, array $schema,