/** * @param EntityManager $em * @param ClassMetadata $class */ public function __construct(EntityManager $em, ClassMetadata $class) { parent::__construct($em, $class); // Bind additional conditions to the nested set repository $entities = array(Page::CN(), ApplicationPage::CN(), GroupPage::CN()); $orList = array(); foreach ($entities as $entityName) { $orList[] = "e INSTANCE OF {$entityName}"; } $additionalCondition = implode(' OR ', $orList); $additionalConditionSql = "discr IN ('page', 'application', 'group')"; $this->nestedSetRepository->setAdditionalCondition($additionalCondition, $additionalConditionSql); }
/** * Returns children page array data * @param string $entity * @param Localization $parentLocalization * @param string $filter * @param integer $levels * @param boolean $count * @return mixed */ private function gatherChildrenData($entity, $parentLocalization, $filter = null, $levels = null, $count = false) { $input = $this->getRequestInput(); $localeId = $this->getCurrentLocale()->getId(); // @TODO: existing_only flag is used for LinkManager, when it requests for available pages for linking. // should split that onto two separate methods. $existingOnly = $input->filter('existing_only', false, false, FILTER_VALIDATE_BOOLEAN); $customTitleQuery = $input->get('query', false); $entityManager = $this->getEntityManager(); $pageFinder = $entity === Page::CN() ? new PageFinder($entityManager) : new TemplateFinder($entityManager); // Reading by one level because need specific reading strategy for application pages if (empty($parentLocalization)) { $pageFinder->addLevelFilter(0, 0); } else { $rootNode = $parentLocalization->getMaster(); $pageFinder->addFilterByParent($rootNode, 1, 1); } $queryBuilder = $pageFinder->getQueryBuilder(); if ($existingOnly) { $queryBuilder->leftJoin('e.localizations', 'l_', 'WITH', 'l_.locale = :locale')->setParameter('locale', $localeId)->leftJoin('e.localizations', 'l')->andWhere('l_.id IS NOT NULL OR e INSTANCE OF ' . GroupPage::CN()); } else { $queryBuilder->leftJoin('e.localizations', 'l_', 'WITH', 'l_.locale = :locale')->setParameter('locale', $localeId)->leftJoin('e.localizations', 'l')->andWhere('l_.id IS NOT NULL OR e.global = true OR (e.level = 0 AND e.global = false)'); } if ($customTitleQuery) { $queryBuilder->andWhere('l_.title LIKE :customTitleQuery'); $queryBuilder->setParameter('customTitleQuery', $customTitleQuery . '%'); } $filterFolders = array(); $application = null; if ($parentLocalization instanceof ApplicationLocalization) { // This is bad solution for detecting where the sitemap has been requested from. // Should group by month if sitemap requested in the sidebar. //FIXME: JS should pass preference maybe if (empty($filter) && $existingOnly) { $filter = 'group'; } $application = $this->getPageApplicationManager()->createApplicationFor($parentLocalization, $this->getEntityManager()); $filterFolders = $application->getFilterFolders($queryBuilder, $filter); $application->applyFilters($queryBuilder, $filter); } $query = $queryBuilder->getQuery(); if ($input->has('offset')) { $offset = $input->getInt('offset'); $query->setFirstResult($offset); } if ($input->has('resultsPerRequest')) { $limit = $input->getInt('resultsPerRequest'); $query->setMaxResults($limit); } $paginator = new \Doctrine\ORM\Tools\Pagination\Paginator($query, true); // TODO: fix, shouldn't return mixed result depending on arguments if ($count) { // When only the count is needed... $count = count($filterFolders) + count($paginator); return $count; } else { $response = array(); // Prepend the filter folders $pages = array_merge($filterFolders, iterator_to_array($paginator)); if (!is_null($levels)) { $levels--; } foreach ($filterFolders as $filterFolder) { if (!$filterFolder instanceof TemporaryGroupPage) { throw new \LogicException("Application " . get_class($application) . ' returned invalid filter folders'); } } foreach ($pages as $page) { $pageData = $this->convertPageToArray($page, $localeId); // Skipping the page if (is_null($pageData)) { continue; } $pageData['children_count'] = 0; $localization = $page->getLocalization($localeId); if (!empty($localization)) { $filter = null; if ($page instanceof TemporaryGroupPage) { $filter = $page->getTitle(); $localization = $parentLocalization; // TODO: for now it's enabled for all filter folders $pageData['childrenListStyle'] = 'scrollList'; $pageData['selectable'] = false; $pageData['editable'] = false; $pageData['isDraggable'] = false; $pageData['isDropTarget'] = true; $pageData['new_children_first'] = true; } if ($levels === 0 && $page instanceof TemporaryGroupPage && $page->hasCalculatedNumberChildren()) { $pageData['children_count'] = $page->getNumberChildren(); } elseif ($levels === 0) { $pageData['children_count'] = $this->gatherChildrenData($entity, $localization, $filter, $levels, true); } else { $pageData['children'] = $this->gatherChildrenData($entity, $localization, $filter, $levels, false); $pageData['children_count'] = count($pageData['children']); } // // TODO: might be job for JS // if ($pageData['children_count'] > 0 // && ! empty($pageData['icon']) // && $pageData['icon'] === 'page') { // // $pageData['icon'] = 'folder'; // } } $response[] = $pageData; } return $response; } }