Batch of 2026-10-28/29 plus 2026-11-03: - NEW vitec:import-datapath-stories: 22 story packages from the agency dump (docx + Links/ assets) as usecase records with content, quotes, images, customer logos, download cards; --repair-quotes normalizes attribution lines; asset backfill for existing stories - /products grid incident repaired (fix_products_grid, fix_graphics_grid, check_grid_page): containers unhidden, 46 duplicate cards soft-deleted, section order restored; BuildProductPortfolio and ImportProductCategoryPages now GUARD against re-runs on pages that already carry vitec_cols_% containers - ' double-encoding fixed: render-pipeline importers write literal apostrophes (ENT_NOQUOTES), fix_double_entities literalizes existing rows - ticket quick wins (ticket_quickwins_20261028), broadcast market page cleanup, AttachCardImages market-card handling, SubmarketWorkbook META REPAIR, story content/video fixes (fix_story_*) - ProvideProductCatalog: transitional v1 fields removed (categories uid/link, legacyGroupFields, item products teaser) - pure v2 shape (ticket 0024-FE); search renderer keeps its teaser - BuildProductOverviews: heroes get the numbered placeholder background (placeholders/pages/<uid>-01.png, wide grey fallback) - backfill on existing pages with empty hero_bgimage, attached at creation for new pages; existing references always win (ticket 0026-FE); 40 placeholder PNGs shipped to fileadmin (not tracked) - AttachPageMedia: --depth=3 with sysfolders as pass-through parents for the overview pages' -08 menu tiles - NEW migrations/fec_isolation_test.sh: two-user live test proving fe_comment ticket isolation (backend verified tight, cross-user sighting traced to the FE page-JSON cache, ticket 0027-BE) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
148 lines
6.0 KiB
PHP
148 lines
6.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* Zwei Quick Wins aus Arnes Tickets (2026-10-28):
|
|
*
|
|
* A) 0012-FE Punkt 2: die Karte "Request access" auf /support (uid 11489)
|
|
* soll auf /support/login-to-helpdesk#form-helpdesk zeigen (Anker auf
|
|
* das HelpDesk-Formular; Schema form-<formKey>).
|
|
*
|
|
* B) 0009-FE Punkt 7: vitec_ctabanner auf Market-/Solution-Seiten haben
|
|
* Labels ("Contact our team" / "Request a demo"), aber keine Links.
|
|
* Leere primary_cta mit Contact-Label -> /contact, leere secondary_cta
|
|
* mit Demo-Label -> /contact/request-a-demo (als t3://page?uid=...).
|
|
* Gefuellte Links werden NIE angefasst.
|
|
*
|
|
* Plain PDO (Muster migrations/check_bg.php).
|
|
*
|
|
* Usage: php migrations/ticket_quickwins_20261028.php (inspect)
|
|
* php migrations/ticket_quickwins_20261028.php --apply
|
|
*/
|
|
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', '1');
|
|
|
|
const REQUEST_ACCESS_UID = 11489;
|
|
const ANCHOR = 'form-helpdesk';
|
|
|
|
$apply = in_array('--apply', $argv, true);
|
|
|
|
$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]
|
|
);
|
|
|
|
echo ($apply ? 'APPLY' : 'INSPECT') . "\n";
|
|
|
|
function pageUidBySlug(PDO $pdo, string $slug): int
|
|
{
|
|
$stmt = $pdo->prepare('SELECT uid FROM pages WHERE deleted = 0 AND slug = ? AND sys_language_uid IN (0,-1)');
|
|
$stmt->execute([$slug]);
|
|
return (int)$stmt->fetchColumn();
|
|
}
|
|
|
|
// --- A) Request-access-Karte -> Anker ---------------------------------------
|
|
echo "\n--- A) Request access -> #" . ANCHOR . " ---\n";
|
|
$stmt = $pdo->prepare('SELECT uid, header, vitec_primary_cta FROM tt_content WHERE deleted = 0 AND uid = ?');
|
|
$stmt->execute([REQUEST_ACCESS_UID]);
|
|
$card = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
if (!$card) {
|
|
echo "Karte #" . REQUEST_ACCESS_UID . " nicht gefunden - uebersprungen.\n";
|
|
} elseif (stripos((string)$card['header'], 'request access') === false) {
|
|
echo "Karte #" . REQUEST_ACCESS_UID . " heisst \"" . $card['header'] . "\" (erwartet: Request access) - NICHT angefasst.\n";
|
|
} else {
|
|
$cta = (string)$card['vitec_primary_cta'];
|
|
if (str_contains($cta, '#' . ANCHOR)) {
|
|
echo "Karte #" . REQUEST_ACCESS_UID . ": Anker bereits gesetzt ($cta) - nichts zu tun.\n";
|
|
} elseif ($cta === '') {
|
|
echo "Karte #" . REQUEST_ACCESS_UID . ": primary_cta ist LEER - erst klaeren, nicht angefasst.\n";
|
|
} else {
|
|
$new = $cta . '#' . ANCHOR;
|
|
echo "Karte #" . REQUEST_ACCESS_UID . " (\"" . $card['header'] . "\"): \"$cta\" -> \"$new\"\n";
|
|
if ($apply) {
|
|
$pdo->prepare('UPDATE tt_content SET vitec_primary_cta = ?, tstamp = UNIX_TIMESTAMP() WHERE uid = ?')
|
|
->execute([$new, REQUEST_ACCESS_UID]);
|
|
echo " geschrieben.\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
// --- B) CTA-Banner-Defaults auf Market-/Solution-Seiten ----------------------
|
|
echo "\n--- B) ctabanner-Links auf /markets + /solutions ---\n";
|
|
$contactUid = pageUidBySlug($pdo, '/contact');
|
|
$demoUid = pageUidBySlug($pdo, '/contact/request-a-demo');
|
|
$solutionsUid = pageUidBySlug($pdo, '/solutions');
|
|
if ($contactUid === 0 || $demoUid === 0 || $solutionsUid === 0) {
|
|
exit("Zielseiten nicht aufloesbar (/contact=#$contactUid, request-a-demo=#$demoUid, /solutions=#$solutionsUid) - Abbruch.\n");
|
|
}
|
|
echo "Ziele: /contact=#$contactUid, request-a-demo=#$demoUid, /solutions=#$solutionsUid\n";
|
|
|
|
$rows = $pdo->query(
|
|
"SELECT c.uid, p.slug, c.vitec_primary_cta, c.vitec_primary_cta_label,
|
|
c.vitec_secondary_cta, c.vitec_secondary_cta_label
|
|
FROM tt_content c JOIN pages p ON p.uid = c.pid AND p.deleted = 0
|
|
WHERE c.deleted = 0 AND c.CType = 'vitec_ctabanner'
|
|
AND (p.slug = '/markets' OR p.slug LIKE '/markets/%' OR p.slug = '/solutions' OR p.slug LIKE '/solutions/%')
|
|
ORDER BY p.slug"
|
|
)->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$setPrimary = 0;
|
|
$setSecondary = 0;
|
|
foreach ($rows as $row) {
|
|
$actions = [];
|
|
$pLabel = (string)$row['vitec_primary_cta_label'];
|
|
$sLabel = (string)$row['vitec_secondary_cta_label'];
|
|
// Sub-Solution-Variante: "Contact our team" / "Request a demo";
|
|
// Market-Variante (Fund 28.10.): "Talk to our team" / "Explore solutions"
|
|
if ((string)$row['vitec_primary_cta'] === '' && (stripos($pLabel, 'contact') !== false || stripos($pLabel, 'talk') !== false)) {
|
|
$actions['vitec_primary_cta'] = 't3://page?uid=' . $contactUid;
|
|
$setPrimary++;
|
|
}
|
|
if ((string)$row['vitec_secondary_cta'] === '') {
|
|
if (stripos($sLabel, 'demo') !== false) {
|
|
$actions['vitec_secondary_cta'] = 't3://page?uid=' . $demoUid;
|
|
$setSecondary++;
|
|
} elseif (stripos($sLabel, 'solution') !== false) {
|
|
$actions['vitec_secondary_cta'] = 't3://page?uid=' . $solutionsUid;
|
|
$setSecondary++;
|
|
}
|
|
}
|
|
if ($actions === []) {
|
|
continue;
|
|
}
|
|
echo "#" . $row['uid'] . " " . $row['slug'] . ": " . implode(', ', array_map(
|
|
static fn(string $field, string $value): string => $field . ' = ' . $value,
|
|
array_keys($actions), $actions
|
|
)) . "\n";
|
|
if ($apply) {
|
|
$set = implode(', ', array_map(static fn(string $f): string => "$f = ?", array_keys($actions)));
|
|
$pdo->prepare("UPDATE tt_content SET $set, tstamp = UNIX_TIMESTAMP() WHERE uid = ?")
|
|
->execute([...array_values($actions), (int)$row['uid']]);
|
|
}
|
|
}
|
|
echo "\n" . count($rows) . " Banner geprueft · $setPrimary primary + $setSecondary secondary " . ($apply ? 'gesetzt' : 'zu setzen') . ".\n";
|
|
if (!$apply) {
|
|
echo "Inspect only - mit --apply schreiben.\n";
|
|
} else {
|
|
echo "Danach: vendor/bin/typo3 cache:flush\n";
|
|
}
|