setAliases(['ce']) ->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)) ?: ''; } }