Skip to content

[Bug] Double table_prefix in PR #271 defensive checks — seed migrations become silent no-op everywhere #276

@biz87

Description

@biz87

Проблема

В PR #271 (defensive checks for ms3_grid_fields table) во все seed-миграции добавлен защитный паттерн:

$prefix = $this->getAdapter()->getOption('table_prefix') ?? '';
if (!$this->hasTable($prefix . 'ms3_grid_fields')) {
    $this->output->writeln('<comment>Table ... does not exist, skipping ...</comment>');
    return;
}

Однако Phinx TablePrefixAdapter::hasTable($tableName) сам добавляет table_prefix внутри (getAdapterTableName($name)prefix . name . suffix). Передача $prefix . 'ms3_grid_fields' приводит к двойному префиксу — hasTable('modx_ms3_grid_fields') фактически ищет modx_modx_ms3_grid_fields, которой никогда не существует, и миграция всегда переходит в return (no-op).

Та же ошибка есть в $this->table($prefix . 'name') / hasColumn() — все Phinx API-методы автоматически префиксируют.

Где сломано

После PR #271 двойной префикс присутствует в 9 миграциях:

  • 20251127000002_seed_customers_grid_config.php
  • 20251204140000_seed_orders_grid_config.php
  • 20251215120000_seed_order_products_grid_config.php
  • 20251222120000_seed_deliveries_grid_config.php
  • 20251223130000_seed_vendors_grid_config.php
  • 20251231140000_seed_category_products_grid_config.php
  • 20260107120000_fix_orders_grid_filterable.php
  • 20260119220000_update_orders_grid_status_fields.php
  • 20260317120000_add_duplicate_publish_to_category_products_actions.php

Воздействие

  • Свежие установки MS3 ≥ 1.10.1: после initial_schema таблица ms3_grid_fields создаётся, но defensive checks воспринимают её как «отсутствует» (из-за двойного префикса) → seed-миграции не наполняют таблицу. В админке гриды (заказы, клиенты, доставки, оплаты, вендоры, позиции заказа, товары категории и т.д.) остаются без default-конфигурации.
  • Установки, прошедшие seed до PR fix(migrations): defensive checks for ms3_grid_fields table #271: уже отметили миграции в phinxlog, повторно не запускаются → последствий нет.
  • Установки, апгрейдящиеся с пред-fix(migrations): defensive checks for ms3_grid_fields table #271 версии с ещё не выполненным seed: после апгрейда seed пропустится из-за двойного префикса → данных не будет.

Связь с #270

Issue #270 (root cause Table ms3_grid_fields doesn't exist на установке) переоткрыта после мержа #271 — там обсуждалось, что defensive checks решают симптом, а не корневую причину. Сейчас выясняется, что и symptomatic fix работает неправильно: на сайтах, где таблица реально создалась, защита всё равно пропускает миграцию.

Решение

Во всех 9 миграциях убрать ручную конкатенацию префикса в Phinx API-вызовах:

// БЫЛО:
if (!$this->hasTable($prefix . 'ms3_grid_fields')) { return; }
$count = $this->fetchRow("SELECT COUNT(*) as cnt FROM {$prefix}ms3_grid_fields WHERE ...");

// СТАЛО:
if (!$this->hasTable('ms3_grid_fields')) { return; }
$count = $this->fetchRow("SELECT COUNT(*) as cnt FROM {$prefix}ms3_grid_fields WHERE ...");

Raw SQL через fetchRow / execute / fetchAll префикс не получает автоматически — там оставить {$prefix}name как есть. Префикс убираем только в Phinx-методах (hasTable, $this->table(), hasColumn, hasIndex).

Проверка после фикса

На dev-сайте, где ms3_grid_fields уже наполнена (миграции прошли до #271):

  1. Применить fix.
  2. Откатить любую из seed-миграций: phinx rollback -t 20260107120000.
  3. Снова запустить phinx migrate. Лог должен показать, что миграция реально выполняется (а не skipping), и данные восстановятся.

Связанное

Ссылка на источник проблемы

Phinx исходник: TablePrefixAdapter::hasTable() в vendor/robmorgan/phinx/src/Phinx/Db/Adapter/TablePrefixAdapter.php:48:

public function hasTable(string $tableName): bool
{
    $adapterTableName = $this->getAdapterTableName($tableName);  // prefix + name + suffix
    return parent::hasTable($adapterTableName);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions