vendor/sulu/sulu/src/Sulu/Component/Content/Types/ResourceLocator/Strategy/ResourceLocatorStrategy.php line 210

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of Sulu.
  4.  *
  5.  * (c) Sulu GmbH
  6.  *
  7.  * This source file is subject to the MIT license that is bundled
  8.  * with this source code in the file LICENSE.
  9.  */
  10. namespace Sulu\Component\Content\Types\ResourceLocator\Strategy;
  11. use Sulu\Bundle\DocumentManagerBundle\Bridge\DocumentInspector;
  12. use Sulu\Component\Content\Compat\StructureManagerInterface;
  13. use Sulu\Component\Content\ContentTypeManagerInterface;
  14. use Sulu\Component\Content\Document\Behavior\ResourceSegmentBehavior;
  15. use Sulu\Component\Content\Exception\ResourceLocatorAlreadyExistsException;
  16. use Sulu\Component\Content\Exception\ResourceLocatorGeneratorException;
  17. use Sulu\Component\Content\Exception\ResourceLocatorNotFoundException;
  18. use Sulu\Component\Content\Exception\ResourceLocatorNotValidException;
  19. use Sulu\Component\Content\Types\ResourceLocator\Mapper\ResourceLocatorMapperInterface;
  20. use Sulu\Component\DocumentManager\Behavior\Mapping\ParentBehavior;
  21. use Sulu\Component\DocumentManager\DocumentManagerInterface;
  22. use Sulu\Component\PHPCR\PathCleanupInterface;
  23. use Sulu\Component\Util\SuluNodeHelper;
  24. /**
  25.  * Basic implementation for resource-locator-strategies.
  26.  */
  27. abstract class ResourceLocatorStrategy implements ResourceLocatorStrategyInterface
  28. {
  29.     /**
  30.      * @var ResourceLocatorMapperInterface
  31.      */
  32.     protected $mapper;
  33.     /**
  34.      * @var PathCleanupInterface
  35.      */
  36.     protected $cleaner;
  37.     /**
  38.      * @var StructureManagerInterface
  39.      */
  40.     protected $structureManager;
  41.     /**
  42.      * @var ContentTypeManagerInterface
  43.      */
  44.     protected $contentTypeManager;
  45.     /**
  46.      * @var SuluNodeHelper
  47.      */
  48.     protected $nodeHelper;
  49.     /**
  50.      * @var DocumentInspector
  51.      */
  52.     protected $documentInspector;
  53.     /**
  54.      * @var DocumentManagerInterface
  55.      */
  56.     protected $documentManager;
  57.     /**
  58.      * @var ResourceLocatorGeneratorInterface
  59.      */
  60.     private $resourceLocatorGenerator;
  61.     public function __construct(
  62.         ResourceLocatorMapperInterface $mapper,
  63.         PathCleanupInterface $cleaner,
  64.         StructureManagerInterface $structureManager,
  65.         ContentTypeManagerInterface $contentTypeManager,
  66.         SuluNodeHelper $nodeHelper,
  67.         DocumentInspector $documentInspector,
  68.         DocumentManagerInterface $documentManager,
  69.         ResourceLocatorGeneratorInterface $resourceLocatorGenerator
  70.     ) {
  71.         $this->mapper $mapper;
  72.         $this->cleaner $cleaner;
  73.         $this->structureManager $structureManager;
  74.         $this->contentTypeManager $contentTypeManager;
  75.         $this->nodeHelper $nodeHelper;
  76.         $this->documentInspector $documentInspector;
  77.         $this->documentManager $documentManager;
  78.         $this->resourceLocatorGenerator $resourceLocatorGenerator;
  79.     }
  80.     public function generate($title$parentUuid$webspaceKey$languageCode$segmentKey null/*, $uuid = null*/)
  81.     {
  82.         $uuid null;
  83.         if (\func_num_args() >= 6) {
  84.             $uuid \func_get_arg(5);
  85.         }
  86.         // title should not have a slash
  87.         $title \str_replace('/''-'$title);
  88.         $parentPath $this->getClosestResourceLocator($parentUuid$webspaceKey$languageCode);
  89.         // get generated path from childClass
  90.         $path $this->resourceLocatorGenerator->generate($title$parentPath);
  91.         // cleanup path
  92.         $path $this->cleaner->cleanup($path$languageCode);
  93.         // if no path was added throw an except that no url could be generated for the given title
  94.         if (\substr($path0, -1) === $parentPath) {
  95.             throw new ResourceLocatorGeneratorException($title$parentPath);
  96.         }
  97.         // get unique path
  98.         $path $this->mapper->getUniquePath($path$webspaceKey$languageCode$segmentKey$uuid);
  99.         return $path;
  100.     }
  101.     /**
  102.      * Returns the closes resourcelocator possible. Skips pages without URLs as internal/external links or unpublished
  103.      * pages.
  104.      *
  105.      * @param string $uuid
  106.      * @param string $webspaceKey
  107.      * @param string $languageCode
  108.      *
  109.      * @return null|string
  110.      */
  111.     private function getClosestResourceLocator($uuid$webspaceKey$languageCode)
  112.     {
  113.         if (!$uuid) {
  114.             return null;
  115.         }
  116.         $document $this->documentManager->find($uuid$languageCode, ['load_ghost_content' => false]);
  117.         do {
  118.             try {
  119.                 return $this->loadByContentUuid($this->documentInspector->getUuid($document), $webspaceKey$languageCode);
  120.             } catch (ResourceLocatorNotFoundException $e) {
  121.                 $document $document->getParent();
  122.             }
  123.         } while ($document instanceof ParentBehavior);
  124.     }
  125.     public function save(ResourceSegmentBehavior $document$userId)
  126.     {
  127.         $path $document->getResourceSegment();
  128.         $webspaceKey $this->documentInspector->getWebspace($document);
  129.         $languageCode $this->documentInspector->getOriginalLocale($document);
  130.         try {
  131.             $treeValue $this->loadByContent($document);
  132.         } catch (ResourceLocatorNotFoundException $e) {
  133.             $treeValue null;
  134.         }
  135.         if ($treeValue === $path) {
  136.             return false;
  137.         }
  138.         if (!$this->isValid($path$webspaceKey$languageCode)) {
  139.             throw new ResourceLocatorNotValidException($path);
  140.         }
  141.         if (!$this->mapper->unique($path$webspaceKey$languageCode)) {
  142.             try {
  143.                 $treeContent $this->loadByResourceLocator($path$webspaceKey$languageCode);
  144.                 // FIXME Required because jackalope-doctrine-dbal does not return references which only exist in the current
  145.                 // session. If it would loadByContent would already return some value, which would make this check obsolete.
  146.                 if ($treeContent === $this->documentInspector->getUuid($document)) {
  147.                     return false;
  148.                 }
  149.                 throw new ResourceLocatorAlreadyExistsException($path$treeContent);
  150.             } catch (ResourceLocatorNotFoundException $exception) {
  151.                 // a node exists but is not a resource-locator.
  152.             }
  153.         }
  154.         $this->mapper->save($document);
  155.     }
  156.     public function loadByContent(ResourceSegmentBehavior $document)
  157.     {
  158.         // delegate to mapper
  159.         return $this->mapper->loadByContent(
  160.             $this->documentInspector->getNode($document),
  161.             $this->documentInspector->getWebspace($document),
  162.             $this->documentInspector->getOriginalLocale($document),
  163.             null
  164.         );
  165.     }
  166.     public function loadByContentUuid($uuid$webspaceKey$languageCode$segmentKey null)
  167.     {
  168.         // delegate to mapper
  169.         return $this->mapper->loadByContentUuid($uuid$webspaceKey$languageCode$segmentKey);
  170.     }
  171.     public function loadHistoryByContentUuid($uuid$webspaceKey$languageCode$segmentKey null)
  172.     {
  173.         return $this->mapper->loadHistoryByContentUuid($uuid$webspaceKey$languageCode$segmentKey);
  174.     }
  175.     public function loadByResourceLocator($resourceLocator$webspaceKey$languageCode$segmentKey null)
  176.     {
  177.         // delegate to mapper
  178.         return $this->mapper->loadByResourceLocator($resourceLocator$webspaceKey$languageCode$segmentKey);
  179.     }
  180.     public function isValid($path$webspaceKey$languageCode$segmentKey null)
  181.     {
  182.         return '/' !== $path && $this->cleaner->validate($path);
  183.     }
  184.     public function deleteById($id$languageCode$segmentKey null)
  185.     {
  186.         $this->mapper->deleteById($id$languageCode$segmentKey);
  187.     }
  188. }