timeTracker = GeneralUtility::makeInstance(TimeTracker::class); $this->cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('events_category'); } /** * Get child categories by calling recursive function * and using the caching framework to save some queries * * @param string $idList list of category ids to start * @param int $counter * @return string comma separated list of category ids */ public function getChildrenCategories($idList, int $counter = 0): string { $cacheIdentifier = sha1('children' . $idList); $entry = $this->cache->get($cacheIdentifier); if (!$entry || is_string($entry) === false) { $entry = $this->getChildrenCategoriesRecursive($idList, $counter); $this->cache->set($cacheIdentifier, $entry); } return $entry; } /** * Get child categories * * @param string $idList list of category ids to start * @param int $counter * @return string comma separated list of category ids */ protected function getChildrenCategoriesRecursive($idList, $counter = 0): string { $result = []; // add id list to the output if ($counter === 0) { $newList = $this->getUidListFromRecords($idList); if ($newList) { $result[] = $newList; } } $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('sys_category'); $res = $queryBuilder ->select('uid') ->from('sys_category') ->where($queryBuilder->expr()->in( 'parent', $queryBuilder->createNamedParameter(explode(',', $idList), Connection::PARAM_INT_ARRAY) )) ->execute(); while ($row = $res->fetch()) { if (is_array($row) === false) { continue; } $counter++; if ($counter > 10000) { $this->timeTracker->setTSlogMessage('EXT:dd_events: one or more recursive categories where found'); return implode(',', $result); } $subcategories = $this->getChildrenCategoriesRecursive($row['uid'], $counter); $result[] = $row['uid'] . ($subcategories ? ',' . $subcategories : ''); } $result = implode(',', $result); return $result; } /** * Fetch ids again from DB to avoid false positives * * @param string $idList * @return string */ protected function getUidListFromRecords(string $idList): string { $list = []; $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('sys_category'); $rows = $queryBuilder ->select('uid') ->from('sys_category') ->where($queryBuilder->expr()->in( 'uid', $queryBuilder->createNamedParameter(explode(',', $idList), Connection::PARAM_INT_ARRAY) )) ->execute() ->fetchAll(); foreach ($rows as $row) { if (is_array($row) === false) { continue; } $list[] = $row['uid']; } return implode(',', $list); } }