-08.png` when it exists (slot 08 =
* page media / menu tile; the number in the picture doubles as the image
* wish list towards the agency), otherwise the generic wide grey
* placeholder. A page that already has a media reference is NEVER touched -
* editors swap the placeholder for the real image in the page properties.
*
* vendor/bin/typo3 vitec:attach-page-media --root=/support
* vendor/bin/typo3 vitec:attach-page-media --root=/support --apply
*/
#[AsCommand(
name: 'vitec:attach-page-media',
description: 'Attach placeholder page media to the children of a root page (dry-run by default)'
)]
final class AttachPageMediaCommand extends Command
{
protected function configure(): void
{
$this->addOption('root', null, InputOption::VALUE_REQUIRED, 'Slug of the root page, e.g. /support');
$this->addOption('apply', null, InputOption::VALUE_NONE, 'Write changes (default: dry run)');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
Bootstrap::initializeBackendAuthentication();
$apply = (bool)$input->getOption('apply');
$rootSlug = '/' . trim((string)$input->getOption('root'), '/ ');
$pool = GeneralUtility::makeInstance(ConnectionPool::class);
$pages = $pool->getConnectionForTable('pages');
$root = $pages->fetchAssociative('SELECT uid, title FROM pages WHERE deleted = 0 AND slug = ? AND sys_language_uid IN (0,-1)', [$rootSlug]);
if ($root === null || $root === false) {
$output->writeln('Root page ' . $rootSlug . ' not found.');
return Command::FAILURE;
}
$children = $pages->fetchAllAssociative(
'SELECT uid, title FROM pages WHERE deleted = 0 AND hidden = 0 AND doktype = 1 AND pid = ? AND sys_language_uid IN (0,-1) ORDER BY sorting',
[(int)$root['uid']]
);
$output->writeln(($apply ? 'APPLY' : 'DRY-RUN') . sprintf(' · %s #%d · %d child page(s)', $rootSlug, (int)$root['uid'], count($children)));
$storage = GeneralUtility::makeInstance(StorageRepository::class)->getDefaultStorage();
$refs = $pool->getConnectionForTable('sys_file_reference');
$datamap = [];
$newIndex = 0;
foreach ($children as $child) {
$uid = (int)$child['uid'];
$existing = (int)$refs->fetchOne(
"SELECT COUNT(*) FROM sys_file_reference WHERE deleted = 0 AND tablenames = 'pages' AND fieldname = 'media' AND uid_foreign = ?",
[$uid]
);
if ($existing > 0) {
$output->writeln(sprintf(' = #%d "%s": has media (%d) - untouched', $uid, (string)$child['title'], $existing));
continue;
}
$identifier = 'placeholders/pages/' . $uid . '-08.png';
if (!$storage->hasFile($identifier)) {
$identifier = 'placeholders/placeholder-grey-wide.png';
if (!$storage->hasFile($identifier)) {
$output->writeln(sprintf(' ! #%d "%s": no placeholder file - skipped', $uid, (string)$child['title']));
continue;
}
}
$output->writeln(sprintf(' + #%d "%s": attach %s', $uid, (string)$child['title'], $identifier));
if (!$apply) {
continue;
}
$file = $storage->getFile($identifier);
$datamap['sys_file_reference']['NEWPM' . (++$newIndex)] = [
'pid' => $uid,
'table_local' => 'sys_file',
'uid_local' => $file->getUid(),
'tablenames' => 'pages',
'uid_foreign' => $uid,
'fieldname' => 'media',
];
$datamap['pages'][$uid] = ['media' => 1];
}
if (!$apply) {
$output->writeln("\nDRY RUN - nothing written. Add --apply to write.");
return Command::SUCCESS;
}
if ($datamap === []) {
$output->writeln('Nothing to attach.');
return Command::SUCCESS;
}
$dataHandler = GeneralUtility::makeInstance(DataHandler::class);
$dataHandler->start($datamap, []);
$dataHandler->process_datamap();
if ($dataHandler->errorLog !== []) {
$output->writeln('DataHandler: ' . implode(' | ', $dataHandler->errorLog) . '');
return Command::FAILURE;
}
$output->writeln('Done. Flush the frontend cache; the menu picks the images up.');
return Command::SUCCESS;
}
}