Sub-solution workbook pipeline on layout 5, fix element order in both importers
- New, deliberately separate pipeline for sub-solutions (markets and solutions must never break each other): generator vitec:generate-subsolution-workbooks (list from the page tree below /solutions, 39 workbooks, every sub-solution matched to its record), SubsolutionWorkbookImporter + CLI vitec:import-subsolution-workbooks, and a "Sub-Solutions" tab in the VITEC Import module with its own inbox migrations/subsolutions_xlsx_in/ - Targets the existing template 5 "Solution Detail" without changing it: hero element in colPos 1, the remaining sections in fixed order in colPos 0, found again by CType on re-import; existing empty sub-solution pages are switched to layout 5, missing ones created hidden; detail_page set on the solution record - Workbook per the Figma "07 Solution Detail page": hero without video teaser, intro with headline and without learn-more/portfolio, extended icon list, own page-layout reference image - Shared content elements: market hero/intro/insights relabelled "Market/Solution", market intro gains the optional intro_headline field (new column, requires extension:setup) - Fix: DataHandler puts every NEW record with a positive pid at the top of its column, so pages built in one run came out reversed. Both importers now track the page order per colPos and write tt_content.sorting explicitly after the DataHandler run; re-applying repairs pages imported earlier (verified on the control-room sub-solution and sub-market page 443) - migrations/fill_test_subsolution.php: realistic test content from vitec.com copy and images for the control-room sub-solution - Docs section 5z
This commit is contained in:
1 parent
3d5459b8d2
commit
8e67f5db23
84 files changed
+1772
-35
No files matched your search
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* Test data for the sub-solution pipeline: fills the generated workbook
|
||||
* "Control Room Platforms SOC NOC Command Centres" with realistic copy
|
||||
* (based on vitec.com product content) and real vitec.com images, and
|
||||
* drops it into the import inbox.
|
||||
*
|
||||
* Starts from the FRESH generated file (named ranges intact), never from
|
||||
* an Excel-saved copy. Stories/products are picked from the workbook's own
|
||||
* dropdown lists, so every value is a valid DB title.
|
||||
*
|
||||
* php migrations/fill_test_subsolution.php
|
||||
*/
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
|
||||
$source = __DIR__ . '/subsolutions_xlsx_out/Control Room & Command Centre Solutions/Control Room Platforms SOC NOC Command Centres.xlsx';
|
||||
$target = __DIR__ . '/subsolutions_xlsx_in/Control Room Platforms SOC NOC Command Centres.xlsx';
|
||||
|
||||
if (!is_file($source)) {
|
||||
fwrite(STDERR, "Source workbook not found: $source\n(run vendor/bin/typo3 vitec:generate-subsolution-workbooks first)\n");
|
||||
exit(1);
|
||||
}
|
||||
if (is_file($target)) {
|
||||
copy($target, $target . '.bak');
|
||||
echo "Backup of the existing inbox file: " . basename($target) . ".bak\n";
|
||||
}
|
||||
|
||||
$spreadsheet = IOFactory::load($source);
|
||||
|
||||
// ---- dropdown lists from the workbook itself ------------------------------
|
||||
$lists = $spreadsheet->getSheetByName('Lists');
|
||||
$column = static function (string $col) use ($lists): array {
|
||||
$values = [];
|
||||
for ($r = 1; $r <= $lists->getHighestRow(); $r++) {
|
||||
$v = trim((string)$lists->getCell($col . $r)->getValue());
|
||||
if ($v !== '') {
|
||||
$values[] = $v;
|
||||
}
|
||||
}
|
||||
return $values;
|
||||
};
|
||||
$stories = $column('A');
|
||||
$products = $column('B');
|
||||
|
||||
/** First list entry matching each keyword, in keyword order, no duplicates. */
|
||||
$pick = static function (array $list, array $keywords, int $max) : array {
|
||||
$chosen = [];
|
||||
foreach ($keywords as $keyword) {
|
||||
foreach ($list as $entry) {
|
||||
if (stripos($entry, $keyword) !== false && !in_array($entry, $chosen, true)) {
|
||||
$chosen[] = $entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count($chosen) >= $max) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $chosen;
|
||||
};
|
||||
|
||||
$storyPicks = $pick($stories, ['National Defense', 'Defense Visual', 'ISR Video Mission', 'Disease Control', 'Parliament', 'Police', 'Government'], 3);
|
||||
$productPicks = $pick($products, ['VSN V3', 'VSNMicro', 'VSNMini', 'Aligo', 'QTX100', 'WallControl', 'Fx4'], 4);
|
||||
$featured = array_shift($productPicks) ?? '';
|
||||
|
||||
// ---- content ----------------------------------------------------------------
|
||||
$values = [
|
||||
'hero_subline' => 'Unified, low-latency video visualisation for security, network and command operations - built for 24/7 reliability.',
|
||||
'hero_cta_label' => 'Talk to an expert',
|
||||
'hero_cta_url' => '/contact',
|
||||
'hero_bgimage_url' => 'https://www.vitec.com/fileadmin/user_upload/gov_16-9.jpg',
|
||||
|
||||
'intro_headline' => 'Every source, every screen, one operational picture',
|
||||
'intro_text' => 'Security operations centres, network operations centres and command centres all face the same challenge: operators must see and act on many live sources at once - CCTV, IP streams, dashboards, sensor data and broadcast feeds - without delay and without interruption. VITEC control room platforms bring these sources together on configurable video walls and operator workstations. VSN Series controllers render any mix of HDMI, DisplayPort, SDI and IP inputs, Aligo extends the wall to remote positions with visually lossless 4K and sub-millisecond latency, and WallControl 10 lets operators rearrange layouts in seconds as situations evolve.',
|
||||
'intro_image_url' => 'https://www.vitec.com/fileadmin/user_upload/control-room_control-launch.png',
|
||||
|
||||
'flow_headline' => 'Built for mission-critical operations',
|
||||
'flow_subtext' => 'VITEC control room platforms are designed for environments where every second counts and downtime is not an option. Key advantages include:',
|
||||
|
||||
'flow_card1_icon' => 'capture',
|
||||
'flow_card1_title' => 'Ingest',
|
||||
'flow_card1_front' => 'Bring every source onto the wall: HDMI, DisplayPort, SDI and IP streams.',
|
||||
'flow_card1_back' => 'Vision and ActiveSQX capture cards ingest local and networked sources side by side, so CCTV, PCs, dashboards and broadcast feeds share one display surface.',
|
||||
|
||||
'flow_card2_icon' => 'view',
|
||||
'flow_card2_title' => 'Visualise',
|
||||
'flow_card2_front' => 'Build any wall layout and change it in seconds with WallControl 10.',
|
||||
'flow_card2_back' => 'Operators drag and drop sources, recall saved layouts per shift or incident, and scale from a single screen to walls of 24 displays and beyond.',
|
||||
|
||||
'flow_card3_icon' => 'distribute',
|
||||
'flow_card3_title' => 'Extend',
|
||||
'flow_card3_front' => 'Take the wall to every operator position with Aligo AVoIP.',
|
||||
'flow_card3_back' => 'Visually lossless 4K60 over 10Gb networks with sub-millisecond latency, plus KVM control of remote sources - ideal for supervisor desks and overflow rooms.',
|
||||
|
||||
'flow_card4_icon' => 'respond',
|
||||
'flow_card4_title' => 'Stay resilient',
|
||||
'flow_card4_front' => 'Rack-mounted VSN V3 controllers with dual-redundant power for 24/7 duty.',
|
||||
'flow_card4_back' => 'Hardware-based rendering keeps playback smooth and synchronised, while redundant power supplies keep the picture up when it matters most.',
|
||||
|
||||
'testi_headline' => 'Trusted in control rooms worldwide',
|
||||
|
||||
'prod_featured' => $featured,
|
||||
|
||||
'insights_text1' => 'Modern control rooms are moving from fixed matrix switching to flexible, IP-based visualisation - for faster situational awareness, simpler expansion and lower operating costs.',
|
||||
'insights_text2' => 'See how organisations in defense, government and critical infrastructure use VITEC technology to keep operators informed and in control:',
|
||||
'insights_cta_label' => 'Explore success stories',
|
||||
'insights_cta_target' => '/success-stories',
|
||||
|
||||
'seo_title' => 'Control Room Platforms for SOC, NOC & Command Centres | VITEC',
|
||||
'seo_description' => 'Unify CCTV, IP streams and data on resilient video walls: VITEC VSN controllers, Aligo AVoIP and WallControl 10 for SOC, NOC and command centres.',
|
||||
];
|
||||
foreach ($storyPicks as $i => $story) {
|
||||
$values['testi_story_' . ($i + 1)] = $story;
|
||||
}
|
||||
foreach ($productPicks as $i => $product) {
|
||||
$values['prod_card_' . ($i + 1)] = $product;
|
||||
}
|
||||
|
||||
// ---- write via named ranges -------------------------------------------------
|
||||
$missing = [];
|
||||
foreach ($values as $name => $value) {
|
||||
$range = $spreadsheet->getNamedRange($name);
|
||||
if ($range === null || $range->getWorksheet() === null) {
|
||||
$missing[] = $name;
|
||||
continue;
|
||||
}
|
||||
$cell = str_replace('$', '', (string)$range->getValue());
|
||||
$cell = str_contains($cell, '!') ? substr($cell, strpos($cell, '!') + 1) : $cell;
|
||||
$range->getWorksheet()->getCell($cell)->setValue($value);
|
||||
}
|
||||
|
||||
@mkdir(dirname($target), 0775, true);
|
||||
(new Xlsx($spreadsheet))->save($target);
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
@chmod($target, 0664);
|
||||
|
||||
echo "Written: " . $target . "\n";
|
||||
echo "Featured product: " . ($featured !== '' ? $featured : '(none found!)') . "\n";
|
||||
echo "Product cards: " . ($productPicks !== [] ? implode(' | ', $productPicks) : '(none found)') . "\n";
|
||||
echo "Case studies: " . ($storyPicks !== [] ? implode(' | ', $storyPicks) : '(none found)') . "\n";
|
||||
if ($missing !== []) {
|
||||
echo "WARNING - named ranges not found: " . implode(', ', $missing) . "\n";
|
||||
}
|
||||
Reference in new issue
Block a user