Files
VITEC-website/migrations/rebuild_related_text_table.php
orasche f0b0694842 - New extension fe_comment (Evomedien, framework-agnostic): floating page
feedback widget served from /api/fe-comment/widget.js, note pad in
  localStorage, submissions mailed via /api/fe-comment/submit with
  recipients from the extension configuration; classic sites get the
  script injected via AssetCollector when the jsonOutput setting is off.
  An enabled master switch serves the widget EMPTY when off (no 404, no
  console errors) and rejects submissions - the go-live kill switch, no
  front-end build change needed
- URL swap finished: /_json prefix middleware, SPA fallback live with a
  dedicated root rule (REQUEST_FILENAME of / is a directory) and a
  query-string exception for the TYPO3 v14 install tool entry
  (?__typo3_install on the site root - the backend Settings/Environment
  modules depend on it); /api/ as a whole stays with TYPO3
- MailMessage::send() no longer exists in v14: fe_comment and the form
  EmailDelivery (latently broken since the core upgrade) now send through
  the Mailer service. Mail transport moved to SMTP against the local exim
  so delivery errors surface instead of bouncing into the blackhole -
  exim verifies the envelope sender, which therefore must be a routable
  existing address (transport config lives in the untracked settings.php)
- Related-product card texts editable on the product record (table rebuilt
  with uid/pid, TCA + inline field, one-time migration script); shared
  RteCompare for the module badge and the CLI comparison - batch dry-run
  now reports 0 writes instead of flagging every richtext field
- Workbook clarification cases executed: VisionIO-SD14, VisionSC-SD14 and
  both Diamond OG records imported (40 fields, live-verified); ArtioSign
  and ArtioView created hidden (uid 109/110) via
  create_artio_records.php - the product table has no sorting column;
  WallControl_10 mapping REVERTED and parked: the dry run revealed
  aetria-wallcontrol already carries its own agency workbook, which
  WallControl_10 would have overwritten. Manifest now 75 product /
  24 family / 1 open
2026-09-30 13:59:55 +02:00

83 lines
3.3 KiB
PHP

<?php
declare(strict_types=1);
/**
* One-time rebuild of tx_vitec_product_related_text (2026-09-28).
*
* The table stored the per-pair related-product card copy with a composite
* primary key and no uid/pid - fine for the import module, invisible to
* FormEngine. To surface the texts as an inline list on the product record
* the table needs a proper uid PK and a pid, and MySQL cannot grow an
* auto_increment PK onto an existing composite-key table through the TYPO3
* schema compare - hence this manual rebuild.
*
* Copies every row, backfilling:
* pid = the owning product's pid
* sorting = the pair's tx_vitec_product_related_mm sorting (0 when the
* relation has meanwhile been removed - such orphan texts are
* kept; they become active again if the relation returns)
* crdate = old tstamp
*
* Idempotent: exits when the uid column already exists.
*
* Usage: php migrations/rebuild_related_text_table.php
* (BEFORE vendor/bin/typo3 extension:setup)
*/
$root = null;
$dir = __DIR__;
for ($i = 0; $i < 5; $i++) {
if (is_file($dir . '/config/system/settings.php')) { $root = $dir; break; }
$dir = dirname($dir);
}
if ($root === null) { exit("Could not locate project root above " . __DIR__ . "\n"); }
$settings = require $root . '/config/system/settings.php';
$db = $settings['DB']['Connections']['Default'];
$pdo = new PDO(
sprintf('mysql:host=%s;port=%s;dbname=%s;charset=utf8mb4', $db['host'] ?? 'localhost', $db['port'] ?? 3306, $db['dbname'] ?? ''),
$db['user'] ?? '', $db['password'] ?? '',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
);
$table = 'tx_vitec_product_related_text';
$cols = $pdo->query('SHOW COLUMNS FROM `' . $table . '`')->fetchAll();
$names = array_column($cols, 'Field');
if (in_array('uid', $names, true)) {
exit("$table already has a uid column - nothing to do.\n");
}
$count = (int)$pdo->query('SELECT COUNT(*) FROM `' . $table . '`')->fetchColumn();
echo "Rebuilding $table ($count rows) ...\n";
$pdo->exec('DROP TABLE IF EXISTS `' . $table . '_new`');
$pdo->exec('CREATE TABLE `' . $table . '_new` (
uid int(11) NOT NULL auto_increment,
pid int(11) DEFAULT 0 NOT NULL,
product_uid int(11) DEFAULT 0 NOT NULL,
related_uid int(11) DEFAULT 0 NOT NULL,
sorting int(11) DEFAULT 0 NOT NULL,
cardtext text,
tstamp int(11) DEFAULT 0 NOT NULL,
crdate int(11) DEFAULT 0 NOT NULL,
PRIMARY KEY (uid),
UNIQUE KEY pair (product_uid, related_uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4');
$copied = $pdo->exec('INSERT INTO `' . $table . '_new`
(pid, product_uid, related_uid, sorting, cardtext, tstamp, crdate)
SELECT COALESCE(p.pid, 0), t.product_uid, t.related_uid,
COALESCE(mm.sorting, 0), t.cardtext, t.tstamp, t.tstamp
FROM `' . $table . '` t
LEFT JOIN tx_vitec_domain_model_product p ON p.uid = t.product_uid
LEFT JOIN tx_vitec_product_related_mm mm
ON mm.uid_local = t.product_uid AND mm.uid_foreign = t.related_uid');
$pdo->exec('RENAME TABLE `' . $table . '` TO `' . $table . '_old`, `' . $table . '_new` TO `' . $table . '`');
$pdo->exec('DROP TABLE `' . $table . '_old`');
echo "Done: $copied rows copied, old table dropped.\n";
echo "Next: vendor/bin/typo3 extension:setup && vendor/bin/typo3 cache:flush\n";