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

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