ew_base/Classes/Command/ContentElementCommand.php
2024-12-26 21:44:19 +01:00

151 lines
5.2 KiB
PHP

<?php
declare(strict_types=1);
/*
* This file is developed by evoWeb.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*/
namespace Evoweb\EwBase\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class ContentElementCommand extends Command
{
protected ConnectionPool $connectionPool;
public function __construct(ConnectionPool $connectionPool)
{
$this->connectionPool = $connectionPool;
parent::__construct();
}
protected function configure(): void
{
$this
->setAliases(['kc-sitepackage'])
->addOption(
'pageId',
'-p',
InputOption::VALUE_REQUIRED,
'Page id to start query'
);
}
public function execute(InputInterface $input, OutputInterface $output): int
{
$pageIds = $input->getOption('pageId');
$pageIds = GeneralUtility::intExplode(',', $pageIds, true);
foreach ($pageIds as $pageId) {
$treeList = $this->getLocalTreeList($pageId, 999999, 0, '1=1');
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('tt_content');
$queryBuilder
->getRestrictions()
->removeByType(HiddenRestriction::class)
->removeByType(StartTimeRestriction::class)
->removeByType(EndTimeRestriction::class);
$result = $queryBuilder
->select('CType', 'list_type')
->from('tt_content')
->where(
$queryBuilder->expr()->in('pid', explode(',', $treeList))
)
->groupBy('CType', 'list_type')
->executeQuery()
->fetchAllAssociative();
(new Table($output))
->setHeaderTitle('Content in tree ' . $pageId)
->setHeaders(array_keys($result[0]))
->setRows($result)
->render();
$output->writeln($treeList);
}
return 0;
}
/**
* Recursively fetch all descendants of a given page
*/
public function getLocalTreeList(int $id, int $depth, int $begin = 0, string $permClause = ''): string
{
if ($id < 0) {
$id = abs($id);
}
if ($begin == 0) {
$theList = (string)$id;
} else {
$theList = '';
}
if ($id && $depth > 0) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
$queryBuilder
->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class));
$queryBuilder
->select('uid')
->from('pages')
->where(
$queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter($id, Connection::PARAM_INT)),
$queryBuilder->expr()->eq('sys_language_uid', 0)
)
->orderBy('uid');
if ($permClause !== '') {
$queryBuilder->andWhere($this->stripLogicalOperatorPrefix($permClause));
}
$statement = $queryBuilder->executeQuery();
while ($row = $statement->fetchAssociative()) {
if ($begin <= 0) {
$theList .= ',' . $row['uid'];
}
if ($depth > 1) {
$theSubList = $this->getLocalTreeList($row['uid'], $depth - 1, $begin - 1, $permClause);
if (!empty($theList) && !empty($theSubList) && ($theSubList[0] !== ',')) {
$theList .= ',';
}
$theList .= $theSubList;
}
}
}
return $theList;
}
/**
* Removes the prefixes AND/OR from the input string.
*
* This function should be used when you can't guarantee that the string
* that you want to use as a WHERE fragment is not prefixed.
*
* @param string $constraint The where part fragment with a possible leading AND / OR operator
* @return string The modified where part without leading operator
*/
public function stripLogicalOperatorPrefix(string $constraint): string
{
return preg_replace('/^(?:(AND|OR)[[:space:]]*)+/i', '', trim($constraint)) ?: '';
}
}