/** * Generates new full path and validates its uniqueness * @param PageLocalization $pageData * @return PageLocalization if changes were made */ protected function generatePath(PageLocalization $pageData, $force = false) { $page = $pageData->getMaster(); $oldPath = $pageData->getPath(); $changes = false; $oldPathEntity = $pageData->getPathEntity(); list($newPath, $active, $limited, $inSitemap) = $this->findPagePath($pageData); if (!$page->isRoot()) { if (!Path::compare($oldPath, $newPath) || $force) { $suffix = null; // Check duplicates only if path is not null if (!is_null($newPath)) { // Additional check for path length $pathString = $newPath->getPath(); if (mb_strlen($pathString) > 255) { throw new Exception\RuntimeException('Overall path length shouldn\'t be more than 255 symbols'); } $i = 2; $e = null; $pathPart = $pageData->getPathPart(); $pathValid = false; do { try { $this->checkForDuplicates($pageData, $newPath); $pathValid = true; } catch (DuplicatePagePathException $e) { if ($force) { // loop stoper if ($i > 101) { throw new Exception\RuntimeException("Couldn't find unique path for new page", null, $e); } // Will try adding unique suffix after 100 iterations if ($i > 100) { $suffix = uniqid(); } else { $suffix = $i; } $pageData->setPathPart($pathPart . '-' . $suffix); list($newPath, $active, $limited, $inSitemap) = $this->findPagePath($pageData); $i++; } } } while ($force && !$pathValid); if ($e instanceof DuplicatePagePathException && !$pathValid) { throw $e; } } // Validation passed, set the new path $pageData->setPathData($newPath, $active, $limited, $inSitemap); if (!is_null($suffix)) { $pageData->setTitle($pageData->getTitle() . " ({$suffix})"); } $changes = true; } } elseif ($page->getLeftValue() == 1) { $newPath = new Path(''); // Root page if (!$newPath->equals($oldPath)) { $changes = true; $pageData->setPathData($newPath, $active, $limited, $inSitemap); } // Another root page... } else { $newPath = null; $active = false; $pageData->setPathData($newPath, $active, $limited, $inSitemap); } if ($oldPathEntity->isActive() !== $active || $oldPathEntity->isVisibleInSitemap() != $inSitemap) { $pageData->setPathData($newPath, $active, $limited, $inSitemap); $changes = true; } if ($changes) { $pathEntity = $pageData->getPathEntity(); $pathMetaData = $this->em->getClassMetadata($pathEntity->CN()); $localizationMetaData = $this->em->getClassMetadata($pageData->CN()); if ($this->unitOfWork->getEntityState($pathEntity, UnitOfWork::STATE_NEW) === UnitOfWork::STATE_NEW) { $this->em->persist($pathEntity); // } elseif ($this->unitOfWork->getEntityState($pathEntity) === UnitOfWork::STATE_DETACHED) { // $pathEntity = $this->em->merge($pathEntity); } /* * Add the path changes to the changeset, must call different * methods depending on is the entity inside the unit of work * changeset */ if ($this->unitOfWork->getEntityChangeSet($pathEntity)) { $this->unitOfWork->recomputeSingleEntityChangeSet($pathMetaData, $pathEntity); } else { $this->unitOfWork->computeChangeSet($pathMetaData, $pathEntity); } if ($this->unitOfWork->getEntityChangeSet($pageData)) { $this->unitOfWork->recomputeSingleEntityChangeSet($localizationMetaData, $pageData); } else { $this->unitOfWork->computeChangeSet($localizationMetaData, $pageData); } return $pageData; } }