vendor/sulu/sulu/src/Sulu/Component/Content/Types/BlockContentType.php line 384

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;
  11. use PHPCR\NodeInterface;
  12. use Sulu\Bundle\AudienceTargetingBundle\TargetGroup\TargetGroupStoreInterface;
  13. use Sulu\Component\Content\Compat\Block\BlockPropertyInterface;
  14. use Sulu\Component\Content\Compat\Block\BlockPropertyWrapper;
  15. use Sulu\Component\Content\Compat\Property;
  16. use Sulu\Component\Content\Compat\PropertyInterface;
  17. use Sulu\Component\Content\ComplexContentType;
  18. use Sulu\Component\Content\ContentTypeExportInterface;
  19. use Sulu\Component\Content\ContentTypeInterface;
  20. use Sulu\Component\Content\ContentTypeManagerInterface;
  21. use Sulu\Component\Content\Document\Subscriber\PHPCR\SuluNode;
  22. use Sulu\Component\Content\Exception\UnexpectedPropertyType;
  23. use Sulu\Component\Content\PreResolvableContentTypeInterface;
  24. use Sulu\Component\Content\Types\Block\BlockVisitorInterface;
  25. use Sulu\Component\Webspace\Analyzer\RequestAnalyzerInterface;
  26. /**
  27.  * content type for block.
  28.  */
  29. class BlockContentType extends ComplexContentType implements ContentTypeExportInterfacePreResolvableContentTypeInterface
  30. {
  31.     /**
  32.      * @var ContentTypeManagerInterface
  33.      */
  34.     private $contentTypeManager;
  35.     /**
  36.      * @var string
  37.      */
  38.     private $languageNamespace;
  39.     /**
  40.      * @var RequestAnalyzerInterface
  41.      *
  42.      * @deprecated This property is not needed anymore and will be removed in Sulu 3.0
  43.      */
  44.     private $requestAnalyzer;
  45.     /**
  46.      * @var ?TargetGroupStoreInterface
  47.      *
  48.      * @deprecated This property is not needed anymore and will be removed in Sulu 3.0
  49.      */
  50.     private $targetGroupStore;
  51.     /**
  52.      * @var BlockVisitorInterface[]
  53.      */
  54.     private $blockVisitors;
  55.     public function __construct(
  56.         ContentTypeManagerInterface $contentTypeManager,
  57.         $languageNamespace,
  58.         RequestAnalyzerInterface $requestAnalyzer,
  59.         ?TargetGroupStoreInterface $targetGroupStore null,
  60.         ?iterable $blockVisitors null
  61.     ) {
  62.         $this->contentTypeManager $contentTypeManager;
  63.         $this->languageNamespace $languageNamespace;
  64.         $this->requestAnalyzer $requestAnalyzer;
  65.         $this->targetGroupStore $targetGroupStore;
  66.         $this->blockVisitors $blockVisitors;
  67.         if (null === $this->blockVisitors) {
  68.             @trigger_deprecation('sulu/sulu''2.3''Instantiating BlockContentType without the $blockVisitors argument is deprecated.');
  69.             $this->blockVisitors = [];
  70.         }
  71.     }
  72.     public function read(
  73.         NodeInterface $node,
  74.         PropertyInterface $property,
  75.         $webspaceKey,
  76.         $languageCode,
  77.         $segmentKey
  78.     ) {
  79.         if ($property->getIsBlock()) {
  80.             /** @var BlockPropertyInterface $blockProperty */
  81.             $blockProperty $property;
  82.             while (!($blockProperty instanceof BlockPropertyInterface)) {
  83.                 $blockProperty $blockProperty->getProperty();
  84.             }
  85.             // init properties
  86.             $typeProperty = new Property('type''''text_line');
  87.             $settingsProperty = new Property('settings''''text_line');
  88.             $lengthProperty = new Property('length''''text_line');
  89.             // load length
  90.             $contentType $this->contentTypeManager->get($lengthProperty->getContentTypeName());
  91.             $contentType->read(
  92.                 $node,
  93.                 new BlockPropertyWrapper($lengthProperty$property),
  94.                 $webspaceKey,
  95.                 $languageCode,
  96.                 $segmentKey
  97.             );
  98.             $len $lengthProperty->getValue();
  99.             for ($i 0$i $len; ++$i) {
  100.                 // load type
  101.                 $contentType $this->contentTypeManager->get($typeProperty->getContentTypeName());
  102.                 $contentType->read(
  103.                     $node,
  104.                     new BlockPropertyWrapper($typeProperty$property$i),
  105.                     $webspaceKey,
  106.                     $languageCode,
  107.                     $segmentKey
  108.                 );
  109.                 if (!$blockProperty->hasType($typeProperty->getValue())) {
  110.                     continue;
  111.                 }
  112.                 $contentType $this->contentTypeManager->get($settingsProperty->getContentTypeName());
  113.                 $contentType->read(
  114.                     $node,
  115.                     new BlockPropertyWrapper($settingsProperty$property$i),
  116.                     $webspaceKey,
  117.                     $languageCode,
  118.                     $segmentKey
  119.                 );
  120.                 $blockPropertyType $blockProperty->initProperties($i$typeProperty->getValue());
  121.                 $settings \json_decode($settingsProperty->getValue(), true);
  122.                 $blockPropertyType->setSettings(!empty($settings) ? $settings : new \stdClass());
  123.                 /** @var PropertyInterface $subProperty */
  124.                 foreach ($blockPropertyType->getChildProperties() as $subProperty) {
  125.                     $contentType $this->contentTypeManager->get($subProperty->getContentTypeName());
  126.                     $contentType->read(
  127.                         $node,
  128.                         new BlockPropertyWrapper($subProperty$property$i),
  129.                         $webspaceKey,
  130.                         $languageCode,
  131.                         $segmentKey
  132.                     );
  133.                 }
  134.             }
  135.         } else {
  136.             throw new UnexpectedPropertyType($property$this);
  137.         }
  138.     }
  139.     public function hasValue(
  140.         NodeInterface $node,
  141.         PropertyInterface $property,
  142.         $webspaceKey,
  143.         $languageCode,
  144.         $segmentKey
  145.     ) {
  146.         if ($property->getIsBlock()) {
  147.             /** @var BlockPropertyInterface $blockProperty */
  148.             $blockProperty $property;
  149.             while (!($blockProperty instanceof BlockPropertyInterface)) {
  150.                 $blockProperty $blockProperty->getProperty();
  151.             }
  152.             // init properties
  153.             $lengthProperty = new Property('length''''text_line');
  154.             $lengthBlockProperty = new BlockPropertyWrapper($lengthProperty$property);
  155.             $contentType $this->contentTypeManager->get($lengthProperty->getContentTypeName());
  156.             return $contentType->hasValue($node$lengthBlockProperty$webspaceKey$languageCode$segmentKey);
  157.         }
  158.         return false;
  159.     }
  160.     public function write(
  161.         NodeInterface $node,
  162.         PropertyInterface $property,
  163.         $userId,
  164.         $webspaceKey,
  165.         $languageCode,
  166.         $segmentKey
  167.     ) {
  168.         return $this->doWrite($node$property$userId$webspaceKey$languageCode$segmentKeyfalse);
  169.     }
  170.     /**
  171.      * Save the value from given property.
  172.      *
  173.      * @param string $userId
  174.      * @param string $webspaceKey
  175.      * @param string $languageCode
  176.      * @param string $segmentKey
  177.      * @param bool $isImport
  178.      *
  179.      * @throws UnexpectedPropertyType
  180.      */
  181.     private function doWrite(
  182.         NodeInterface $node,
  183.         PropertyInterface $property,
  184.         $userId,
  185.         $webspaceKey,
  186.         $languageCode,
  187.         $segmentKey,
  188.         $isImport false
  189.     ) {
  190.         if ($property->getIsBlock()) {
  191.             /** @var BlockPropertyInterface $blockProperty */
  192.             $blockProperty $property;
  193.             while (!($blockProperty instanceof BlockPropertyInterface)) {
  194.                 $blockProperty $blockProperty->getProperty();
  195.             }
  196.             $data $blockProperty->getValue();
  197.             if (!$blockProperty->getIsMultiple()) {
  198.                 $data = [$data];
  199.             }
  200.             $data \array_filter($data);
  201.             $len \count($data);
  202.             // init properties
  203.             $typeProperty = new Property('type''''text_line');
  204.             $settingsProperty = new Property('settings''''text_line');
  205.             $lengthProperty = new Property('length''''text_line');
  206.             //save length
  207.             $lengthProperty->setValue($len);
  208.             $contentType $this->contentTypeManager->get($lengthProperty->getContentTypeName());
  209.             $contentType->write(
  210.                 $node,
  211.                 new BlockPropertyWrapper($lengthProperty$property),
  212.                 $userId,
  213.                 $webspaceKey,
  214.                 $languageCode,
  215.                 $segmentKey
  216.             );
  217.             for ($i 0$i $len; ++$i) {
  218.                 $blockPropertyType $blockProperty->getProperties($i);
  219.                 $this->writeProperty(
  220.                     $typeProperty,
  221.                     $property,
  222.                     $blockPropertyType->getName(),
  223.                     $i,
  224.                     $node,
  225.                     $userId,
  226.                     $webspaceKey,
  227.                     $languageCode,
  228.                     $segmentKey,
  229.                     $isImport
  230.                 );
  231.                 $this->writeProperty(
  232.                     $settingsProperty,
  233.                     $property,
  234.                     \json_encode($blockPropertyType->getSettings()),
  235.                     $i,
  236.                     $node,
  237.                     $userId,
  238.                     $webspaceKey,
  239.                     $languageCode,
  240.                     $segmentKey,
  241.                     $isImport
  242.                 );
  243.                 foreach ($blockProperty->getProperties($i)->getChildProperties() as $subProperty) {
  244.                     $this->writeProperty(
  245.                         $subProperty,
  246.                         $property,
  247.                         $subProperty->getValue(),
  248.                         $i,
  249.                         $node,
  250.                         $userId,
  251.                         $webspaceKey,
  252.                         $languageCode,
  253.                         $segmentKey,
  254.                         $isImport
  255.                     );
  256.                 }
  257.             }
  258.         } else {
  259.             throw new UnexpectedPropertyType($property$this);
  260.         }
  261.     }
  262.     /**
  263.      * write a property to node.
  264.      */
  265.     private function writeProperty(
  266.         PropertyInterface $property,
  267.         PropertyInterface $blockProperty,
  268.         $value,
  269.         $index,
  270.         NodeInterface $node,
  271.         $userId,
  272.         $webspaceKey,
  273.         $languageCode,
  274.         $segmentKey,
  275.         $isImport false
  276.     ) {
  277.         // save sub property
  278.         $contentType $this->contentTypeManager->get($property->getContentTypeName());
  279.         $blockPropertyWrapper = new BlockPropertyWrapper($property$blockProperty$index);
  280.         $blockPropertyWrapper->setValue($value);
  281.         if ($isImport && $contentType instanceof ContentTypeExportInterface) {
  282.             $contentType->importData(
  283.                 new SuluNode($node),
  284.                 $blockPropertyWrapper,
  285.                 $value,
  286.                 $userId,
  287.                 $webspaceKey,
  288.                 $languageCode,
  289.                 $segmentKey
  290.             );
  291.             return;
  292.         }
  293.         $contentType->write(
  294.             new SuluNode($node),
  295.             $blockPropertyWrapper,
  296.             $userId,
  297.             $webspaceKey,
  298.             $languageCode,
  299.             $segmentKey
  300.         );
  301.     }
  302.     public function remove(
  303.         NodeInterface $node,
  304.         PropertyInterface $property,
  305.         $webspaceKey,
  306.         $languageCode,
  307.         $segmentKey
  308.     ) {
  309.         foreach ($node->getProperties($property->getName() . '-*') as $nodeProperty) {
  310.             $node->getProperty($nodeProperty->getName())->remove();
  311.         }
  312.     }
  313.     public function getViewData(PropertyInterface $property)
  314.     {
  315.         return $this->prepareData(
  316.             $property,
  317.             function(ContentTypeInterface $contentType$property) {
  318.                 return $contentType->getViewData($property);
  319.             },
  320.             false
  321.         );
  322.     }
  323.     public function getContentData(PropertyInterface $property)
  324.     {
  325.         return $this->prepareData(
  326.             $property,
  327.             function(ContentTypeInterface $contentType$property) {
  328.                 return $contentType->getContentData($property);
  329.             }
  330.         );
  331.     }
  332.     /**
  333.      * Returns prepared data from property
  334.      * use callback to prepare data foreach property function($contentType, $property).
  335.      *
  336.      * @param bool $returnType
  337.      *
  338.      * @return array
  339.      */
  340.     private function prepareData(PropertyInterface $property, callable $dataCallback$returnType true)
  341.     {
  342.         /** @var BlockPropertyInterface $blockProperty */
  343.         $blockProperty $property;
  344.         while (!($blockProperty instanceof BlockPropertyInterface)) {
  345.             $blockProperty $blockProperty->getProperty();
  346.         }
  347.         $blockPropertyTypes = [];
  348.         for ($i 0$i $blockProperty->getLength(); ++$i) {
  349.             $blockPropertyType $blockProperty->getProperties($i);
  350.             foreach ($this->blockVisitors as $blockVisitor) {
  351.                 $blockPropertyType $blockVisitor->visit($blockPropertyType);
  352.                 if (!$blockPropertyType) {
  353.                     break;
  354.                 }
  355.             }
  356.             if ($blockPropertyType) {
  357.                 $blockPropertyTypes[] = $blockPropertyType;
  358.             }
  359.         }
  360.         $data = [];
  361.         foreach ($blockPropertyTypes as $blockPropertyType) {
  362.             $blockPropertyTypeSettings $blockPropertyType->getSettings();
  363.             $blockData = [];
  364.             if ($returnType) {
  365.                 $blockData['type'] = $blockPropertyType->getName();
  366.                 $blockData['settings'] = $blockPropertyTypeSettings;
  367.             }
  368.             foreach ($blockPropertyType->getChildProperties() as $childProperty) {
  369.                 $contentType $this->contentTypeManager->get($childProperty->getContentTypeName());
  370.                 $blockData[$childProperty->getName()] = $dataCallback($contentType$childProperty);
  371.             }
  372.             $data[] = $blockData;
  373.         }
  374.         if (!$property->getIsMultiple() && \count($data) > 0) {
  375.             $data $data[0];
  376.         }
  377.         return $data;
  378.     }
  379.     public function exportData($propertyValue)
  380.     {
  381.         return $propertyValue;
  382.     }
  383.     public function importData(
  384.         NodeInterface $node,
  385.         PropertyInterface $property,
  386.         $value,
  387.         $userId,
  388.         $webspaceKey,
  389.         $languageCode,
  390.         $segmentKey null
  391.     ) {
  392.         $property->setValue($value);
  393.         $this->doWrite($node$property$userId$webspaceKey$languageCode$segmentKeytrue);
  394.     }
  395.     public function preResolve(PropertyInterface $property)
  396.     {
  397.         $this->prepareData(
  398.             $property,
  399.             function(ContentTypeInterface $contentType$property) {
  400.                 if (!$contentType instanceof PreResolvableContentTypeInterface) {
  401.                     return;
  402.                 }
  403.                 return $contentType->preResolve($property);
  404.             },
  405.             false
  406.         );
  407.     }
  408. }