/** * @param DeepCopy $deepCopy * @param EntityManager $entityManager * @return DeepCopy */ private function addDeepCopyCommonFilters(DeepCopy $deepCopy, EntityManager $entityManager) { $keepFilter = new KeepFilter(); $nullifyFilter = new SetNullFilter(); // Matches RedirectTargetPage::$page property. // Keeps the $page property redirect target is referencing to. $deepCopy->addFilter($keepFilter, new PropertyMatcher(RedirectTargetPage::CN(), 'page')); // Matches PageLocalization::$template. // Prevents the template to be cloned. $deepCopy->addFilter($keepFilter, new PropertyMatcher(PageLocalization::CN(), 'template')); // Matches Localization::$path // Keeps the value since it is cloned manually (see PageLocalization::__clone()); $deepCopy->addFilter($keepFilter, new PropertyMatcher(Localization::CN(), 'path')); // Matches Block::$blockProperties collection. // Replaces with empty collection, since block properties can be obtained via Localization::$blockProperties. $deepCopy->addFilter(new DoctrineEmptyCollectionFilter(), new PropertyMatcher(Block::CN(), 'blockProperties')); // Matches Localization::$lock. // Nullifies editing lock entity. $deepCopy->addFilter($nullifyFilter, new PropertyMatcher(Localization::CN(), 'lock')); // Matches Localization::$publishedRevision. $deepCopy->addFilter($nullifyFilter, new PropertyMatcher(Localization::CN(), 'publishedRevision')); // Matches Localization::$publishTime. $deepCopy->addFilter($nullifyFilter, new PropertyMatcher(Localization::CN(), 'publishTime')); // Matches Entity Collection. // Creates Copy and persists the elements in it. $deepCopy->addFilter(new DoctrineCollectionFilter($entityManager), new PropertyTypeMatcher('Doctrine\\Common\\Collections\\Collection')); // Matches any Entity. // Creates copy and persists it. $deepCopy->addFilter(new DoctrineEntityFilter($entityManager), new PropertyTypeMatcher(Entity::CN())); }
/** * Handles block move(between multiple placeholders) request. */ public function moveBlocksAction() { $this->isPostRequest(); $this->checkLock(); $pageRequest = $this->createPageRequest(); $blockId = $this->getRequestInput()->get('block_id'); $block = $this->getEntityManager()->find(Block::CN(), $blockId); if ($block === null) { throw new CmsException(null, sprintf('Block with ID [%s] not found.', $blockId)); } $targetPlaceHolderName = $this->getRequestParameter('place_holder_id'); $targetPlaceHolder = $pageRequest->getPlaceHolderSet()->getFinalPlaceHolders()->offsetGet($targetPlaceHolderName); if ($targetPlaceHolder === null) { throw new \InvalidArgumentException(sprintf('Placeholder [%s] not found in placeholders set.', $targetPlaceHolderName)); } $currentPlaceHolder = $block->getPlaceHolder(); if ($currentPlaceHolder === $targetPlaceHolder) { // JS error or data spoofing throw new \LogicException('Current and new placeholders are the same.'); } $currentPlaceHolder->removeBlock($block); $targetPlaceHolder->addBlockLast($block); // @TODO: not quite sure that block will exists in collection already. // should be rewrited. $blockSet = $pageRequest->getBlockSet()->getPlaceHolderBlockSet($targetPlaceHolder); $blockPositionMap = array_values($this->getRequestParameter('order', array())); if ($blockSet->count() !== count($blockPositionMap)) { // JS error or data spoofing throw new \UnexpectedValueException('Ordered elements and actual blocks count does not match.'); } foreach ($blockPositionMap as $position => $id) { $block = $blockSet->findById($id); if ($block === null) { throw new \UnexpectedValueException(sprintf('Block [%s] not found.')); } $block->setPosition($position); } $this->getEntityManager()->flush(); return new SupraJsonResponse(); }
/** * @return Set\BlockSet */ public function getBlockSet() { if (isset($this->blockSet)) { return $this->blockSet; } $entityManager = $this->getEntityManager(); $this->blockSet = new Set\BlockSet(); $localFinalPlaceHolders = array(); $finalPlaceHolderIds = array(); $placeHolderSet = $this->getPlaceHolderSet(); // $allFinalPlaceHolderIds = $placeHolderSet->getFinalPlaceHolders() // ->collectIds(); // Filter out the locally managed placeholders (history) foreach ($placeHolderSet->getFinalPlaceHolders() as $placeHolder) { if ($this->isLocalResource($placeHolder)) { $localFinalPlaceHolders[] = $placeHolder; } else { $finalPlaceHolderIds[] = $placeHolder->getId(); } } $parentPlaceHolderIds = $placeHolderSet->getParentPlaceHolders()->collectIds(); $blocks = array(); // Just return empty array if no final/parent place holders have been found if (!empty($finalPlaceHolderIds) || !empty($parentPlaceHolderIds)) { // Here we find all 1) locked blocks from templates; 2) all blocks from final place holders $qb = $entityManager->createQueryBuilder(); $qb->select('b')->from(Block::CN(), 'b')->join('b.placeHolder', 'ph')->andWhere('b.inactive = FALSE')->orderBy('b.position', 'ASC'); $expr = $qb->expr(); $or = $expr->orX(); // final placeholder blocks if (!empty($finalPlaceHolderIds)) { $or->add($expr->in('ph.id', $finalPlaceHolderIds)); } // locked block condition if (!empty($parentPlaceHolderIds)) { $lockedBlocksCondition = $expr->andX($expr->in('ph.id', $parentPlaceHolderIds), 'b.locked = TRUE'); $or->add($lockedBlocksCondition); } $qb->where($or); // When specific ID is passed, limit by it $blockId = $this->getBlockRequestId(); if (!is_null($blockId)) { $qb->andWhere('b.id = :blockId OR b.componentClass = :blockId')->setParameter('blockId', $blockId); } // Execute block query $query = $qb->getQuery(); $this->prepareQueryResultCache($query); $blocks = $query->getResult(); } // Add blocks from locally managed placeholders foreach ($localFinalPlaceHolders as $placeHolder) { /* @var $placeHolder PlaceHolder */ $additionalBlocks = $placeHolder->getBlocks()->getValues(); $blocks = array_merge($blocks, $additionalBlocks); } // Skip temporary blocks for VIEW mode foreach ($blocks as $blockKey => $block) { if ($block instanceof TemplateBlock) { if ($block->getTemporary()) { unset($blocks[$blockKey]); } } } foreach ($blocks as $blockKey => $block) { if ($block instanceof PageBlock) { if ($block->isInactive()) { unset($blocks[$blockKey]); } } } /* * Collect locked blocks first, these are positioned as first blocks in * the placeholder if placeholder is not locked. * First locked blocs are taken from the top template. */ foreach ($placeHolderSet as $placeHolder) { foreach ($blocks as $key => $block) { /* @var $block Block */ if ($block->getLocked() && $block->getPlaceHolder()->equals($placeHolder)) { if (!$placeHolder->getLocked()) { $this->blockSet[] = $block; unset($blocks[$key]); } } } } // Collect all unlocked blocks /* @var $block Block */ foreach ($blocks as $block) { $this->blockSet[] = $block; } // Ordering the blocks by position in the layout $placeHolderNames = $this->getLayoutPlaceHolderNames(); $this->blockSet->orderByPlaceHolderNameArray($placeHolderNames); return $this->blockSet; }