Hero placeholder fieldname: vitec_hero_bgimage (content block prefix)
The vitec/herosection content block has prefixFields - the real column and sys_file_reference fieldname is vitec_hero_bgimage; the JSON merely strips the prefix. The first apply wrote the 20 references with the bare name, so they existed but never rendered (no herosection anywhere had an image, so there was no working example to catch it against). - BuildProductOverviews: attach/backfill/skip-check now use vitec_hero_bgimage - new migration fix_overview_hero_refs.php: renames the existing 20 references in place (no re-attach) and sets the counter column Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
77661bf0b6
commit
8e173b1a85
2 files changed
+117
-4
No files matched your search
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* fix_overview_hero_refs.php (2026-11-03)
|
||||
*
|
||||
* Repariert die Hero-Platzhalter-Referenzen der 20 Produkt-Übersichtsseiten:
|
||||
* vitec:build-product-overviews --apply hatte die sys_file_reference-Zeilen
|
||||
* mit fieldname 'hero_bgimage' angelegt - der Content-Block vitec/herosection
|
||||
* hat aber prefixFields, die echte Spalte/der echte Fieldname ist
|
||||
* 'vitec_hero_bgimage' (das JSON streift den Praefix nur ab). Ergebnis:
|
||||
* Referenzen existieren, rendern aber nicht.
|
||||
*
|
||||
* Dieses Skript biegt die vorhandenen Referenzen um (fieldname-Update) und
|
||||
* setzt das Zaehlfeld tt_content.vitec_hero_bgimage - KEIN Neuanlegen.
|
||||
*
|
||||
* php migrations/fix_overview_hero_refs.php # INSPECT (default)
|
||||
* php migrations/fix_overview_hero_refs.php --apply # schreibt
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$apply = in_array('--apply', $argv, true);
|
||||
|
||||
$settings = require __DIR__ . '/../config/system/settings.php';
|
||||
$db = $settings['DB']['Connections']['Default'];
|
||||
$pdo = new PDO(
|
||||
sprintf('mysql:host=%s;dbname=%s;charset=utf8mb4', $db['host'], $db['dbname']),
|
||||
$db['user'],
|
||||
$db['password'],
|
||||
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
|
||||
);
|
||||
|
||||
echo $apply ? "APPLY\n\n" : "INSPECT - nichts wird geschrieben (--apply zum Schreiben)\n\n";
|
||||
|
||||
// Zielspalte muss existieren, sonst stimmt die Diagnose nicht
|
||||
$col = (int)$pdo->query(
|
||||
"SELECT COUNT(*) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'tt_content' AND COLUMN_NAME = 'vitec_hero_bgimage'"
|
||||
)->fetchColumn();
|
||||
echo 'tt_content.vitec_hero_bgimage vorhanden: ' . ($col > 0 ? 'ja' : 'NEIN') . "\n";
|
||||
if ($col === 0) {
|
||||
echo "ABBRUCH: Zielspalte fehlt - Feldname im Content Block pruefen.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// die falsch benannten Referenzen, nur an vitec_herosection-Elementen
|
||||
$refs = $pdo->query(
|
||||
"SELECT r.uid AS ref_uid, r.uid_foreign AS content_uid, r.uid_local AS file_uid,
|
||||
c.pid, c.CType, f.identifier
|
||||
FROM sys_file_reference r
|
||||
JOIN tt_content c ON c.uid = r.uid_foreign
|
||||
LEFT JOIN sys_file f ON f.uid = r.uid_local
|
||||
WHERE r.deleted = 0 AND r.tablenames = 'tt_content' AND r.fieldname = 'hero_bgimage'
|
||||
AND c.deleted = 0 AND c.CType = 'vitec_herosection'
|
||||
ORDER BY c.pid"
|
||||
)->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
echo count($refs) . " Referenz(en) mit fieldname 'hero_bgimage' an vitec_herosection:\n";
|
||||
foreach ($refs as $ref) {
|
||||
printf(
|
||||
" ref #%d -> content #%d (pid %d) file %s\n",
|
||||
$ref['ref_uid'],
|
||||
$ref['content_uid'],
|
||||
$ref['pid'],
|
||||
(string)$ref['identifier']
|
||||
);
|
||||
}
|
||||
|
||||
// Sicherheitsnetz: Elemente, die BEIDE Varianten tragen (sollte es nicht geben)
|
||||
$both = $pdo->query(
|
||||
"SELECT uid_foreign FROM sys_file_reference
|
||||
WHERE deleted = 0 AND tablenames = 'tt_content' AND fieldname = 'vitec_hero_bgimage'
|
||||
AND uid_foreign IN (SELECT uid_foreign FROM sys_file_reference
|
||||
WHERE deleted = 0 AND tablenames = 'tt_content' AND fieldname = 'hero_bgimage')"
|
||||
)->fetchAll(PDO::FETCH_COLUMN);
|
||||
if ($both !== []) {
|
||||
echo "ACHTUNG: Elemente mit korrekter UND falscher Referenz: " . implode(', ', $both) . " - die falschen wuerden geloescht statt umbenannt.\n";
|
||||
}
|
||||
|
||||
if (!$apply) {
|
||||
echo "\nINSPECT-Ende.\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$renamed = 0;
|
||||
$deleted = 0;
|
||||
foreach ($refs as $ref) {
|
||||
if (in_array((string)$ref['content_uid'], array_map('strval', $both), true)) {
|
||||
$pdo->prepare('UPDATE sys_file_reference SET deleted = 1, tstamp = ? WHERE uid = ?')
|
||||
->execute([time(), (int)$ref['ref_uid']]);
|
||||
$deleted++;
|
||||
continue;
|
||||
}
|
||||
$pdo->prepare("UPDATE sys_file_reference SET fieldname = 'vitec_hero_bgimage', tstamp = ? WHERE uid = ?")
|
||||
->execute([time(), (int)$ref['ref_uid']]);
|
||||
$renamed++;
|
||||
}
|
||||
|
||||
// Zaehlfeld pro betroffenem Element nachziehen
|
||||
$contentUids = array_values(array_unique(array_map(static fn(array $r): int => (int)$r['content_uid'], $refs)));
|
||||
foreach ($contentUids as $uid) {
|
||||
$count = (int)$pdo->query(
|
||||
"SELECT COUNT(*) FROM sys_file_reference
|
||||
WHERE deleted = 0 AND tablenames = 'tt_content' AND fieldname = 'vitec_hero_bgimage' AND uid_foreign = " . $uid
|
||||
)->fetchColumn();
|
||||
$pdo->prepare('UPDATE tt_content SET vitec_hero_bgimage = ?, tstamp = ? WHERE uid = ?')
|
||||
->execute([$count, time(), $uid]);
|
||||
}
|
||||
|
||||
printf("\nFertig: %d Referenz(en) umbenannt, %d geloescht, %d Zaehlfeld(er) gesetzt.\n", $renamed, $deleted, count($contentUids));
|
||||
echo "Danach: vendor/bin/typo3 cache:flush\n";
|
||||
@@ -397,7 +397,9 @@ final class BuildProductOverviewsCommand extends Command
|
||||
'uid_local' => GeneralUtility::makeInstance(StorageRepository::class)
|
||||
->getDefaultStorage()->getFile($placeholder)->getUid(),
|
||||
];
|
||||
$this->datamap['tt_content'][$heroId]['hero_bgimage'] = $refId;
|
||||
// content block vitec/herosection has prefixFields - the real
|
||||
// column/fieldname is vitec_hero_bgimage (JSON strips the prefix)
|
||||
$this->datamap['tt_content'][$heroId]['vitec_hero_bgimage'] = $refId;
|
||||
$this->report[] = ' hero: attach ' . $placeholder;
|
||||
} else {
|
||||
$this->report[] = ' hero: would attach ' . $placeholder;
|
||||
@@ -462,7 +464,7 @@ final class BuildProductOverviewsCommand extends Command
|
||||
return;
|
||||
}
|
||||
$existing = (int)$pool->getConnectionForTable('sys_file_reference')->fetchOne(
|
||||
"SELECT COUNT(*) FROM sys_file_reference WHERE deleted = 0 AND tablenames = 'tt_content' AND fieldname = 'hero_bgimage' AND uid_foreign = ?",
|
||||
"SELECT COUNT(*) FROM sys_file_reference WHERE deleted = 0 AND tablenames = 'tt_content' AND fieldname = 'vitec_hero_bgimage' AND uid_foreign = ?",
|
||||
[$heroUid]
|
||||
);
|
||||
if ($existing > 0) {
|
||||
@@ -485,9 +487,9 @@ final class BuildProductOverviewsCommand extends Command
|
||||
->getDefaultStorage()->getFile($placeholder)->getUid(),
|
||||
'tablenames' => 'tt_content',
|
||||
'uid_foreign' => $heroUid,
|
||||
'fieldname' => 'hero_bgimage',
|
||||
'fieldname' => 'vitec_hero_bgimage',
|
||||
];
|
||||
$this->datamap['tt_content'][$heroUid]['hero_bgimage'] = 1;
|
||||
$this->datamap['tt_content'][$heroUid]['vitec_hero_bgimage'] = 1;
|
||||
$this->report[] = ' hero #' . $heroUid . ': attach ' . $placeholder;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user