Why-VITEC-Band auf den 3 alten Kategorieseiten (0106-FE, Entscheidung Harry)
migrations/why_band_unwrap_20261111.php: loest die vitec_cols-Container hinter dem Why-VITEC-Intro auf graphics-and-multi-display, infrastructure-and-accessories und video-capture auf, stellt die 12 Karten als icon_card top-level hinter das Intro und sortiert die Hauptspalte neu (Inspect default, --apply). Angewandt, Seiten gepurgt und gewaermt. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
086a178341
commit
8cdcd99eb3
1 file changed
+161
@@ -0,0 +1,161 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* why_band_unwrap_20261111.php (Ticket 0106-FE, Abschnitt "alte Seiten")
|
||||||
|
*
|
||||||
|
* Die drei 2026-10-Kategorieseiten ohne Menueplatz tragen ihre "Why VITEC?"-
|
||||||
|
* Karten noch als `vertical`-Karten IN vitec_cols_33_33_33-Containern
|
||||||
|
* (wrap-cards-grid vom 27.10.). Das Frontend baut das Icon-Band (0039-BE)
|
||||||
|
* aber nur aus `vitec_card` mit layout_variant icon_card DIREKT hinter dem
|
||||||
|
* Intro. Entscheidung Harry 2026-11-11: diese Seiten bekommen das Band auch.
|
||||||
|
*
|
||||||
|
* Umbau je Seite: Intro "Why VITEC?" finden, die direkt folgenden Container
|
||||||
|
* (nur solche, die ausschliesslich vitec_card enthalten) aufloesen - Karten
|
||||||
|
* nach colPos 0 / tx_container_parent 0 / icon_card, leere Container soft-
|
||||||
|
* loeschen, colPos 0 mit Stride 256 neu sortieren (Band direkt hinter dem
|
||||||
|
* Intro, Rest in bisheriger Folge). Direktes SQL -> Auto-Purge greift NICHT:
|
||||||
|
* danach cache:flush + vitec:ssr-purge/-warm mit den Pfaden.
|
||||||
|
*
|
||||||
|
* php migrations/why_band_unwrap_20261111.php # INSPECT (default)
|
||||||
|
* php migrations/why_band_unwrap_20261111.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;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]
|
||||||
|
);
|
||||||
|
|
||||||
|
echo $apply ? "APPLY\n\n" : "INSPECT - nichts wird geschrieben (--apply zum Schreiben)\n\n";
|
||||||
|
|
||||||
|
$slugs = [
|
||||||
|
'/products/graphics-and-multi-display',
|
||||||
|
'/products/infrastructure-and-accessories',
|
||||||
|
'/products/video-capture',
|
||||||
|
];
|
||||||
|
|
||||||
|
$norm = static fn(string $s): string => (string)preg_replace('/[^a-z0-9]+/', '', strtolower($s));
|
||||||
|
|
||||||
|
$done = 0;
|
||||||
|
foreach ($slugs as $slug) {
|
||||||
|
$st = $pdo->prepare('SELECT uid, title FROM pages WHERE deleted = 0 AND slug = ? AND sys_language_uid = 0');
|
||||||
|
$st->execute([$slug]);
|
||||||
|
$page = $st->fetch();
|
||||||
|
if (!$page) {
|
||||||
|
echo "$slug: Seite NICHT gefunden - uebersprungen\n\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$pid = (int)$page['uid'];
|
||||||
|
|
||||||
|
$st = $pdo->prepare(
|
||||||
|
'SELECT uid, CType, header, sorting, vitec_layout_variant FROM tt_content
|
||||||
|
WHERE pid = ? AND deleted = 0 AND colPos = 0 AND sys_language_uid = 0
|
||||||
|
AND (tx_container_parent IS NULL OR tx_container_parent = 0)
|
||||||
|
ORDER BY sorting, uid'
|
||||||
|
);
|
||||||
|
$st->execute([$pid]);
|
||||||
|
$top = $st->fetchAll();
|
||||||
|
|
||||||
|
echo "== $slug (pid $pid) \"{$page['title']}\" - " . count($top) . " Top-Level-Elemente in colPos 0\n";
|
||||||
|
|
||||||
|
// bereits umgebaut? (Band = Intro + direkt folgende Karten top-level)
|
||||||
|
$whyIdx = null;
|
||||||
|
foreach ($top as $i => $el) {
|
||||||
|
if ($el['CType'] === 'vitec_introparagraph' && str_starts_with($norm((string)$el['header']), 'whyvitec')) {
|
||||||
|
$whyIdx = $i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($whyIdx === null) {
|
||||||
|
echo " kein Why-VITEC-Intro gefunden - uebersprungen\n\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$intro = $top[$whyIdx];
|
||||||
|
if (isset($top[$whyIdx + 1]) && $top[$whyIdx + 1]['CType'] === 'vitec_card') {
|
||||||
|
echo " Band liegt bereits top-level hinter Intro #{$intro['uid']} - nichts zu tun\n\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// direkt folgende Container einsammeln, solange sie nur Karten enthalten
|
||||||
|
$containers = [];
|
||||||
|
$cards = [];
|
||||||
|
for ($i = $whyIdx + 1; $i < count($top); $i++) {
|
||||||
|
$el = $top[$i];
|
||||||
|
if (!str_starts_with((string)$el['CType'], 'vitec_cols')) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$kids = $pdo->query(
|
||||||
|
'SELECT uid, CType, header, colPos, sorting, vitec_layout_variant FROM tt_content
|
||||||
|
WHERE deleted = 0 AND tx_container_parent = ' . (int)$el['uid'] . ' ORDER BY colPos, sorting, uid'
|
||||||
|
)->fetchAll();
|
||||||
|
$onlyCards = $kids !== [] && count(array_filter($kids, static fn(array $k): bool => $k['CType'] !== 'vitec_card')) === 0;
|
||||||
|
if (!$onlyCards) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$containers[] = $el;
|
||||||
|
foreach ($kids as $k) {
|
||||||
|
$cards[] = $k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($cards === []) {
|
||||||
|
echo " Intro #{$intro['uid']} \"{$intro['header']}\" ohne folgende Karten-Container - uebersprungen\n\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" Intro #%d \"%s\"\n", $intro['uid'], $intro['header']);
|
||||||
|
printf(" %d Container (#%s) mit %d Karte(n):\n", count($containers), implode(', #', array_column($containers, 'uid')), count($cards));
|
||||||
|
foreach ($cards as $c) {
|
||||||
|
printf(" #%-6d %-14s \"%s\"\n", $c['uid'], (string)$c['vitec_layout_variant'], (string)$c['header']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// neue Reihenfolge: bis Intro, dann Karten, dann Rest ohne die Container
|
||||||
|
$containerUids = array_map('intval', array_column($containers, 'uid'));
|
||||||
|
$newOrder = [];
|
||||||
|
foreach ($top as $i => $el) {
|
||||||
|
if (in_array((int)$el['uid'], $containerUids, true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$newOrder[] = ['uid' => (int)$el['uid'], 'label' => $el['CType'] . ' ' . $el['header']];
|
||||||
|
if ($i === $whyIdx) {
|
||||||
|
foreach ($cards as $c) {
|
||||||
|
$newOrder[] = ['uid' => (int)$c['uid'], 'label' => 'vitec_card (icon_card) ' . $c['header']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo " Neue Reihenfolge colPos 0:\n";
|
||||||
|
$sorting = 0;
|
||||||
|
foreach ($newOrder as $el) {
|
||||||
|
$sorting += 256;
|
||||||
|
printf(" %5d #%-6d %s\n", $sorting, $el['uid'], $el['label']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($apply) {
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
$upCard = $pdo->prepare("UPDATE tt_content SET colPos = 0, tx_container_parent = 0, vitec_layout_variant = 'icon_card', tstamp = UNIX_TIMESTAMP() WHERE uid = ?");
|
||||||
|
foreach ($cards as $c) {
|
||||||
|
$upCard->execute([(int)$c['uid']]);
|
||||||
|
}
|
||||||
|
$pdo->exec('UPDATE tt_content SET deleted = 1, tstamp = UNIX_TIMESTAMP() WHERE uid IN (' . implode(',', $containerUids) . ')');
|
||||||
|
$upSort = $pdo->prepare('UPDATE tt_content SET sorting = ?, tstamp = UNIX_TIMESTAMP() WHERE uid = ?');
|
||||||
|
$sorting = 0;
|
||||||
|
foreach ($newOrder as $el) {
|
||||||
|
$sorting += 256;
|
||||||
|
$upSort->execute([$sorting, $el['uid']]);
|
||||||
|
}
|
||||||
|
$pdo->commit();
|
||||||
|
echo " GESCHRIEBEN\n";
|
||||||
|
}
|
||||||
|
$done++;
|
||||||
|
echo "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo ($apply ? 'FERTIG' : 'WUERDE') . ": $done Seite(n) umgebaut.\n";
|
||||||
|
if ($apply && $done > 0) {
|
||||||
|
echo "Danach: vendor/bin/typo3 cache:flush && vendor/bin/typo3 vitec:ssr-purge " . implode(' ', $slugs) . " && vendor/bin/typo3 vitec:ssr-warm " . implode(' ', $slugs) . "\n";
|
||||||
|
}
|
||||||
Reference in new issue
Block a user