vendor/sulu/sulu/src/Sulu/Component/Content/Compat/Structure/StructureBridge.php line 664

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\Compat\Structure;
  11. use Sulu\Bundle\DocumentManagerBundle\Bridge\DocumentInspector;
  12. use Sulu\Component\Content\Compat\StructureInterface;
  13. use Sulu\Component\Content\Compat\StructureType;
  14. use Sulu\Component\Content\Document\Behavior\ExtensionBehavior;
  15. use Sulu\Component\Content\Document\Behavior\NavigationContextBehavior;
  16. use Sulu\Component\Content\Document\Behavior\OrderBehavior;
  17. use Sulu\Component\Content\Document\Behavior\RedirectTypeBehavior;
  18. use Sulu\Component\Content\Document\Behavior\ResourceSegmentBehavior;
  19. use Sulu\Component\Content\Document\Behavior\ShadowLocaleBehavior;
  20. use Sulu\Component\Content\Document\Behavior\StructureBehavior;
  21. use Sulu\Component\Content\Document\Behavior\WorkflowStageBehavior;
  22. use Sulu\Component\Content\Document\LocalizationState;
  23. use Sulu\Component\Content\Document\RedirectType;
  24. use Sulu\Component\Content\Document\WorkflowStage;
  25. use Sulu\Component\Content\Metadata\StructureMetadata;
  26. /**
  27.  * @deprecated Should be replaced by a proper StructureInterface implementation
  28.  */
  29. class StructureBridge implements StructureInterface
  30. {
  31.     /**
  32.      * @var StructureMetadata
  33.      */
  34.     protected $structure;
  35.     /**
  36.      * @var object
  37.      */
  38.     protected $document;
  39.     /**
  40.      * @var DocumentInspector
  41.      */
  42.     protected $inspector;
  43.     /**
  44.      * @var LegacyPropertyFactory
  45.      */
  46.     private $propertyFactory;
  47.     /**
  48.      * @var array
  49.      */
  50.     private $loadedProperties = [];
  51.     /**
  52.      * Needed by structure extensions when the document has not been set..
  53.      *
  54.      * @var string
  55.      */
  56.     protected $locale;
  57.     /**
  58.      * @param object $document
  59.      */
  60.     public function __construct(
  61.         StructureMetadata $structure,
  62.         DocumentInspector $inspector,
  63.         LegacyPropertyFactory $propertyFactory,
  64.         $document null
  65.     ) {
  66.         $this->structure $structure;
  67.         $this->inspector $inspector;
  68.         $this->propertyFactory $propertyFactory;
  69.         $this->document $document;
  70.     }
  71.     public function setDocument(StructureBehavior $document)
  72.     {
  73.         $this->document $document;
  74.     }
  75.     public function setLanguageCode($locale)
  76.     {
  77.         $this->locale $locale;
  78.     }
  79.     public function getLanguageCode()
  80.     {
  81.         if (!$this->document) {
  82.             return $this->locale;
  83.         }
  84.         return $this->inspector->getLocale($this->getDocument());
  85.     }
  86.     public function setWebspaceKey($webspace)
  87.     {
  88.         $this->readOnlyException(__METHOD__);
  89.     }
  90.     public function getWebspaceKey()
  91.     {
  92.         if (!$this->document) {
  93.             return null;
  94.         }
  95.         return $this->inspector->getWebspace($this->getDocument());
  96.     }
  97.     public function getUuid()
  98.     {
  99.         return $this->getDocument()->getUuid();
  100.     }
  101.     public function setUuid($uuid)
  102.     {
  103.         $this->readOnlyException(__METHOD__);
  104.     }
  105.     public function getCreator()
  106.     {
  107.         return $this->getDocument()->getCreator();
  108.     }
  109.     public function setCreator($userId)
  110.     {
  111.         $this->readOnlyException(__METHOD__);
  112.     }
  113.     public function getChanger()
  114.     {
  115.         return $this->getDocument()->getChanger();
  116.     }
  117.     public function setChanger($userId)
  118.     {
  119.         $this->readOnlyException(__METHOD__);
  120.     }
  121.     public function getCreated()
  122.     {
  123.         return $this->getDocument()->getCreated();
  124.     }
  125.     public function setCreated(\DateTime $created)
  126.     {
  127.         $this->readOnlyException(__METHOD__);
  128.     }
  129.     public function getChanged()
  130.     {
  131.         return $this->getDocument()->getChanged();
  132.     }
  133.     public function setChanged(\DateTime $changed)
  134.     {
  135.         $this->readOnlyException(__METHOD__);
  136.     }
  137.     public function getKey()
  138.     {
  139.         return $this->structure->getName();
  140.     }
  141.     public function getInternal()
  142.     {
  143.         return $this->structure->isInternal();
  144.     }
  145.     public function getProperty($name)
  146.     {
  147.         if ($this->hasProperty($name)) {
  148.             $property $this->structure->getProperty($name);
  149.         } else {
  150.             $property $this->structure->getChild($name);
  151.         }
  152.         return $this->createLegacyPropertyFromItem($property);
  153.     }
  154.     public function hasProperty($name)
  155.     {
  156.         return $this->structure->hasProperty($name);
  157.     }
  158.     public function getProperties($flatten false)
  159.     {
  160.         if ($flatten) {
  161.             $items $this->structure->getProperties();
  162.         } else {
  163.             $items $this->structure->getChildren();
  164.         }
  165.         $propertyBridges = [];
  166.         foreach ($items as $property) {
  167.             $propertyBridges[$property->getName()] = $this->createLegacyPropertyFromItem($property);
  168.         }
  169.         return $propertyBridges;
  170.     }
  171.     public function getExt()
  172.     {
  173.         return $this->document->getExtensionsData();
  174.     }
  175.     public function setExt($data)
  176.     {
  177.         $this->readOnlyException(__METHOD__);
  178.     }
  179.     public function setHasChildren($hasChildren)
  180.     {
  181.         $this->readOnlyException(__METHOD__);
  182.     }
  183.     public function getHasChildren()
  184.     {
  185.         return $this->inspector->hasChildren($this->getDocument());
  186.     }
  187.     public function setChildren($children)
  188.     {
  189.         $this->readOnlyException(__METHOD__);
  190.     }
  191.     public function getChildren()
  192.     {
  193.         $children = [];
  194.         foreach ($this->getDocument()->getChildren() as $child) {
  195.             $children[] = $this->documentToStructure($child);
  196.         }
  197.         return $children;
  198.     }
  199.     /**
  200.      * @return $this
  201.      */
  202.     public function getParent()
  203.     {
  204.         return $this->documentToStructure($this->inspector->getParent($this->getDocument()));
  205.     }
  206.     public function getPublishedState()
  207.     {
  208.         return WorkflowStage::PUBLISHED === $this->getWorkflowDocument(__METHOD__)->getWorkflowStage();
  209.     }
  210.     public function setPublished($published)
  211.     {
  212.         $this->readOnlyException(__METHOD__);
  213.     }
  214.     public function getPublished()
  215.     {
  216.         return $this->getWorkflowDocument(__METHOD__)->getPublished();
  217.     }
  218.     public function getPropertyValue($name)
  219.     {
  220.         return $this->getProperty($name)->getValue();
  221.     }
  222.     public function getPropertyNames()
  223.     {
  224.         return \array_keys($this->structure->getChildren());
  225.     }
  226.     public function setType($type)
  227.     {
  228.         $this->readOnlyException(__METHOD__);
  229.     }
  230.     public function getType()
  231.     {
  232.         $document $this->getDocument();
  233.         $localizationState $this->inspector->getLocalizationState($document);
  234.         if (LocalizationState::GHOST === $localizationState) {
  235.             return StructureType::getGhost($this->getDocument()->getLocale());
  236.         }
  237.         if (LocalizationState::SHADOW === $this->inspector->getLocalizationState($document)) {
  238.             return StructureType::getShadow($this->getDocument()->getLocale());
  239.         }
  240.     }
  241.     public function getPath()
  242.     {
  243.         return $this->inspector->getContentPath($this->getDocument());
  244.     }
  245.     public function setPath($path)
  246.     {
  247.         $this->readOnlyException(__METHOD__);
  248.     }
  249.     public function setHasTranslation($hasTranslation)
  250.     {
  251.         $this->readOnlyException(__METHOD__);
  252.     }
  253.     public function getHasTranslation()
  254.     {
  255.         return $this->getTitle() ? true false;
  256.     }
  257.     public function toArray($complete true)
  258.     {
  259.         $document $this->getDocument();
  260.         $result = [
  261.             'id' => $this->inspector->getUuid($document),
  262.             'path' => $this->inspector->getContentPath($document),
  263.             'nodeType' => $this->getNodeType(),
  264.             'nodeState' => $this->getNodeState(),
  265.             'internal' => false,
  266.             'availableLocales' => $this->inspector->getLocales($document),
  267.             'contentLocales' => $this->inspector->getConcreteLocales($document),
  268.             'hasSub' => $this->getHasChildren(),
  269.             'title' => $document->getTitle(), // legacy system returns diffent fields for title depending on $complete
  270.         ];
  271.         if ($document instanceof OrderBehavior) {
  272.             $result['order'] = $document->getSuluOrder();
  273.         }
  274.         if ($document instanceof RedirectTypeBehavior) {
  275.             $redirectType $document->getRedirectType();
  276.             $result['linked'] = null;
  277.             if (RedirectType::INTERNAL == $redirectType && null !== $document->getRedirectTarget()) {
  278.                 $result['linked'] = 'internal';
  279.                 $result['internal_link'] = $document->getRedirectTarget()->getUuid();
  280.             } elseif (RedirectType::EXTERNAL == $redirectType) {
  281.                 $result['linked'] = 'external';
  282.                 $result['external'] = $document->getRedirectExternal();
  283.             }
  284.         }
  285.         if ($document instanceof WorkflowStageBehavior) {
  286.             $result['publishedState'] = WorkflowStage::PUBLISHED === $document->getWorkflowStage();
  287.             $result['published'] = $document->getPublished();
  288.         }
  289.         $result['navContexts'] = [];
  290.         if ($document instanceof NavigationContextBehavior) {
  291.             $result['navContexts'] = $document->getNavigationContexts();
  292.         }
  293.         if (null !== $this->getType()) {
  294.             $result['type'] = $this->getType()->toArray();
  295.         }
  296.         if ($complete) {
  297.             if ($document instanceof ShadowLocaleBehavior) {
  298.                 $result = \array_merge(
  299.                     $result,
  300.                     [
  301.                         'shadowLocales' => $this->inspector->getShadowLocales($document),
  302.                         'shadowOn' => $document->isShadowLocaleEnabled(),
  303.                         'shadowBaseLanguage' => $document->getShadowLocale(),
  304.                     ]
  305.                 );
  306.             }
  307.             $result = \array_merge(
  308.                 $result,
  309.                 [
  310.                     'template' => $this->structure->getName(),
  311.                     'originTemplate' => $this->structure->getName(),
  312.                     'creator' => $document->getCreator(),
  313.                     'changer' => $document->getChanger(),
  314.                     'created' => $document->getCreated(),
  315.                     'changed' => $document->getChanged(),
  316.                     'title' => $document->getTitle(),
  317.                     'url' => null,
  318.                 ]
  319.             );
  320.             if ($document instanceof ResourceSegmentBehavior) {
  321.                 $result['url'] = $document->getResourceSegment();
  322.             }
  323.             if ($document instanceof ExtensionBehavior) {
  324.                 $result['ext'] = $document->getExtensionsData();
  325.             }
  326.             $result = \array_merge($this->getDocument()->getStructure()->toArray(), $result);
  327.             return $result;
  328.         }
  329.         return $result;
  330.     }
  331.     #[\ReturnTypeWillChange]
  332.     public function jsonSerialize()
  333.     {
  334.     }
  335.     public function getPropertyByTagName($tagName$highest true)
  336.     {
  337.         return $this->createLegacyPropertyFromItem($this->structure->getPropertyByTagName($tagName$highest));
  338.     }
  339.     public function getPropertiesByTagName($tagName)
  340.     {
  341.         $properties = [];
  342.         foreach ($this->structure->getPropertiesByTagName($tagName) as $structureProperty) {
  343.             $properties[] = $this->createLegacyPropertyFromItem($structureProperty);
  344.         }
  345.         return $properties;
  346.     }
  347.     public function getPropertyValueByTagName($tagName)
  348.     {
  349.         return $this->getPropertyByTagName($tagName)->getValue();
  350.     }
  351.     public function hasTag($tag)
  352.     {
  353.         return $this->structure->hasPropertyWithTagName($tag);
  354.     }
  355.     public function getNodeType()
  356.     {
  357.         if ($this->getDocument() instanceof RedirectTypeBehavior) {
  358.             return $this->getDocument()->getRedirectType();
  359.         }
  360.         return RedirectType::NONE;
  361.     }
  362.     public function getNodeName()
  363.     {
  364.         if ($this->document instanceof RedirectTypeBehavior &&
  365.             RedirectType::INTERNAL == $this->document->getRedirectType() &&
  366.             null !== $this->document->getRedirectTarget()
  367.         ) {
  368.             return $this->getDocument()->getRedirectTarget()->getTitle();
  369.         }
  370.         return $this->getDocument()->getTitle();
  371.     }
  372.     public function getLocalizedTitle($languageCode)
  373.     {
  374.         return $this->structure->getTitle($languageCode);
  375.     }
  376.     public function getNodeState()
  377.     {
  378.         $document $this->getDocument();
  379.         if (!$document instanceof WorkflowStageBehavior) {
  380.             return WorkflowStage::PUBLISHED;
  381.         }
  382.         return $this->getDocument()->getWorkflowStage();
  383.     }
  384.     public function getTitle()
  385.     {
  386.         return $this->getDocument()->getTitle();
  387.     }
  388.     public function getUrl()
  389.     {
  390.         return $this->getDocument()->getResourceSegment();
  391.     }
  392.     public function copyFrom(StructureInterface $structure)
  393.     {
  394.         foreach ($this->getProperties(true) as $property) {
  395.             if ($structure->hasProperty($property->getName())) {
  396.                 $property->setValue($structure->getPropertyValue($property->getName()));
  397.             }
  398.         }
  399.         $this->setDocument($structure->getDocument());
  400.     }
  401.     /**
  402.      * Magic getter.
  403.      *
  404.      * @deprecated Do not use magic getters. Use ArrayAccess instead
  405.      */
  406.     public function __get($name)
  407.     {
  408.         return $this->getProperty($name)->getValue();
  409.     }
  410.     public function getShadowLocales()
  411.     {
  412.         return $this->inspector->getShadowLocales($this->getDocument());
  413.     }
  414.     public function getContentLocales()
  415.     {
  416.         return $this->inspector->getConcreteLocales($this->getDocument());
  417.     }
  418.     public function getIsShadow()
  419.     {
  420.         if (!$this->document) {
  421.             return false;
  422.         }
  423.         $document $this->getDocument();
  424.         if (!$document instanceof ShadowLocaleBehavior) {
  425.             return false;
  426.         }
  427.         return $document->isShadowLocaleEnabled();
  428.     }
  429.     public function getShadowBaseLanguage()
  430.     {
  431.         $document $this->getDocument();
  432.         if (!$document instanceof ShadowLocaleBehavior) {
  433.             return;
  434.         }
  435.         return $document->getShadowLocale();
  436.     }
  437.     public function getResourceLocator()
  438.     {
  439.         $document $this->getDocument();
  440.         if (RedirectType::EXTERNAL == $document->getRedirectType()) {
  441.             return $document->getRedirectExternal();
  442.         }
  443.         if (RedirectType::INTERNAL === $document->getRedirectType()) {
  444.             $target $document->getRedirectTarget();
  445.             if (!$target) {
  446.                 throw new \RuntimeException('Document is an internal redirect, but no redirect target has been set.');
  447.             }
  448.             return $target->getResourceSegment();
  449.         }
  450.         return $document->getResourceSegment();
  451.     }
  452.     /**
  453.      * Returns document.
  454.      *
  455.      * @return object
  456.      */
  457.     public function getDocument()
  458.     {
  459.         if (!$this->document) {
  460.             throw new \RuntimeException(
  461.                 'Document has not been applied to structure yet, cannot retrieve data from structure.'
  462.             );
  463.         }
  464.         return $this->document;
  465.     }
  466.     /**
  467.      * Returns structure metadata.
  468.      *
  469.      * @return StructureMetadata
  470.      */
  471.     public function getStructure()
  472.     {
  473.         return $this->structure;
  474.     }
  475.     protected function readOnlyException($method)
  476.     {
  477.         throw new \BadMethodCallException(
  478.             \sprintf(
  479.                 'Compatibility layer StructureBridge instances are readonly. Tried to call "%s"',
  480.                 $method
  481.             )
  482.         );
  483.     }
  484.     /**
  485.      * @param StructureBehavior $document The document to convert
  486.      *
  487.      * @return $this
  488.      */
  489.     protected function documentToStructure(StructureBehavior $document)
  490.     {
  491.         return new $this(
  492.             $this->inspector->getStructureMetadata($document),
  493.             $this->inspector,
  494.             $this->propertyFactory,
  495.             $document
  496.         );
  497.     }
  498.     private function getWorkflowDocument($method)
  499.     {
  500.         $document $this->getDocument();
  501.         if (!$document instanceof WorkflowStageBehavior) {
  502.             throw new \BadMethodCallException(
  503.                 \sprintf(
  504.                     'Cannot call "%s" on Document which does not implement PageInterface. Is "%s"',
  505.                     $method,
  506.                     \get_class($document)
  507.                 )
  508.             );
  509.         }
  510.         return $document;
  511.     }
  512.     private function notImplemented($method)
  513.     {
  514.         throw new \InvalidArgumentException(
  515.             \sprintf(
  516.                 'Method "%s" is not yet implemented',
  517.                 $method
  518.             )
  519.         );
  520.     }
  521.     private function normalizeData(array $data null)
  522.     {
  523.         if (null === $data) {
  524.             return;
  525.         }
  526.         if (false === \is_array($data)) {
  527.             return $this->normalizeValue($data);
  528.         }
  529.         foreach ($data as &$value) {
  530.             if (\is_array($value)) {
  531.                 foreach ($value as $childKey => $childValue) {
  532.                     $data[$childKey] = $this->normalizeData($childValue);
  533.                 }
  534.             }
  535.             $value $this->normalizeValue($value);
  536.         }
  537.         return $data;
  538.     }
  539.     private function normalizeValue($value)
  540.     {
  541.         if ($value instanceof StructureBehavior) {
  542.             return $this->documentToStructure($value);
  543.         }
  544.         return $value;
  545.     }
  546.     private function createLegacyPropertyFromItem($item)
  547.     {
  548.         $name $item->getName();
  549.         if (isset($this->loadedProperties[$name])) {
  550.             return $this->loadedProperties[$name];
  551.         }
  552.         $propertyBridge $this->propertyFactory->createProperty($item$this);
  553.         if ($this->document) {
  554.             $property $this->getDocument()->getStructure()->getProperty($name);
  555.             $propertyBridge->setPropertyValue($property);
  556.         }
  557.         $this->loadedProperties[$name] = $propertyBridge;
  558.         return $propertyBridge;
  559.     }
  560. }