vendor/sulu/sulu/src/Sulu/Bundle/MediaBundle/Content/Types/MediaSelectionContentType.php line 150

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\Bundle\MediaBundle\Content\Types;
  11. use PHPCR\NodeInterface;
  12. use Sulu\Bundle\AdminBundle\Metadata\SchemaMetadata\AnyOfsMetadata;
  13. use Sulu\Bundle\AdminBundle\Metadata\SchemaMetadata\ArrayMetadata;
  14. use Sulu\Bundle\AdminBundle\Metadata\SchemaMetadata\EmptyArrayMetadata;
  15. use Sulu\Bundle\AdminBundle\Metadata\SchemaMetadata\NullMetadata;
  16. use Sulu\Bundle\AdminBundle\Metadata\SchemaMetadata\NumberMetadata;
  17. use Sulu\Bundle\AdminBundle\Metadata\SchemaMetadata\ObjectMetadata;
  18. use Sulu\Bundle\AdminBundle\Metadata\SchemaMetadata\PropertyMetadata;
  19. use Sulu\Bundle\AdminBundle\Metadata\SchemaMetadata\PropertyMetadataMapperInterface;
  20. use Sulu\Bundle\AdminBundle\Metadata\SchemaMetadata\PropertyMetadataMinMaxValueResolver;
  21. use Sulu\Bundle\AdminBundle\Metadata\SchemaMetadata\StringMetadata;
  22. use Sulu\Bundle\MediaBundle\Content\MediaSelectionContainer;
  23. use Sulu\Bundle\MediaBundle\Media\Manager\MediaManagerInterface;
  24. use Sulu\Bundle\WebsiteBundle\ReferenceStore\ReferenceStoreInterface;
  25. use Sulu\Component\Content\Compat\PropertyInterface;
  26. use Sulu\Component\Content\Compat\PropertyParameter;
  27. use Sulu\Component\Content\ComplexContentType;
  28. use Sulu\Component\Content\ContentTypeExportInterface;
  29. use Sulu\Component\Content\Metadata\PropertyMetadata as ContentPropertyMetadata;
  30. use Sulu\Component\Content\PreResolvableContentTypeInterface;
  31. use Sulu\Component\Security\Authorization\PermissionTypes;
  32. use Sulu\Component\Util\ArrayableInterface;
  33. use Sulu\Component\Webspace\Analyzer\RequestAnalyzerInterface;
  34. /**
  35. * content type for image selection.
  36. */
  37. class MediaSelectionContentType extends ComplexContentType implements ContentTypeExportInterface, PreResolvableContentTypeInterface, PropertyMetadataMapperInterface
  38. {
  39. /**
  40. * @var MediaManagerInterface
  41. */
  42. private $mediaManager;
  43. /**
  44. * @var ReferenceStoreInterface
  45. */
  46. private $referenceStore;
  47. /**
  48. * @var RequestAnalyzerInterface
  49. */
  50. private $requestAnalyzer;
  51. /**
  52. * @var ?array
  53. */
  54. private $permissions;
  55. /**
  56. * @var PropertyMetadataMinMaxValueResolver|null
  57. */
  58. private $propertyMetadataMinMaxValueResolver;
  59. public function __construct(
  60. MediaManagerInterface $mediaManager,
  61. ReferenceStoreInterface $referenceStore,
  62. ?RequestAnalyzerInterface $requestAnalyzer = null,
  63. $permissions = null,
  64. ?PropertyMetadataMinMaxValueResolver $propertyMetadataMinMaxValueResolver = null
  65. ) {
  66. $this->mediaManager = $mediaManager;
  67. $this->referenceStore = $referenceStore;
  68. $this->requestAnalyzer = $requestAnalyzer;
  69. $this->permissions = $permissions;
  70. $this->propertyMetadataMinMaxValueResolver = $propertyMetadataMinMaxValueResolver;
  71. }
  72. public function getDefaultParams(?PropertyInterface $property = null)
  73. {
  74. return [
  75. 'types' => new PropertyParameter('types', null),
  76. 'formats' => new PropertyParameter('formats', []),
  77. ];
  78. }
  79. /**
  80. * @param array $params
  81. *
  82. * @return PropertyParameter[]
  83. */
  84. public function getParams($params)
  85. {
  86. return \array_merge($this->getDefaultParams(), $params);
  87. }
  88. public function read(
  89. NodeInterface $node,
  90. PropertyInterface $property,
  91. $webspaceKey,
  92. $languageCode,
  93. $segmentKey
  94. ) {
  95. $data = \json_decode($node->getPropertyValueWithDefault($property->getName(), '{"ids": []}'), true);
  96. $property->setValue(isset($data['ids']) ? $data : null);
  97. }
  98. public function write(
  99. NodeInterface $node,
  100. PropertyInterface $property,
  101. $userId,
  102. $webspaceKey,
  103. $languageCode,
  104. $segmentKey
  105. ) {
  106. $value = $property->getValue();
  107. if ($value instanceof ArrayableInterface) {
  108. $value = $value->toArray();
  109. }
  110. // if whole smart-content container is pushed
  111. if (isset($value['data'])) {
  112. unset($value['data']);
  113. }
  114. // set value to node
  115. $node->setProperty($property->getName(), \json_encode($value));
  116. }
  117. public function remove(
  118. NodeInterface $node,
  119. PropertyInterface $property,
  120. $webspaceKey,
  121. $languageCode,
  122. $segmentKey
  123. ) {
  124. if ($node->hasProperty($property->getName())) {
  125. $node->getProperty($property->getName())->remove();
  126. }
  127. }
  128. public function getContentData(PropertyInterface $property)
  129. {
  130. $data = $property->getValue();
  131. $params = $this->getParams($property->getParams());
  132. $types = $params['types']->getValue();
  133. $webspace = $this->requestAnalyzer->getWebspace();
  134. $container = new MediaSelectionContainer(
  135. isset($data['config']) ? $data['config'] : [],
  136. isset($data['displayOption']) ? $data['displayOption'] : '',
  137. isset($data['ids']) ? $data['ids'] : [],
  138. $property->getStructure()->getLanguageCode(),
  139. $types,
  140. $this->mediaManager,
  141. $webspace && $webspace->hasWebsiteSecurity() ? $this->permissions[PermissionTypes::VIEW] : null
  142. );
  143. return $container->getData();
  144. }
  145. public function getViewData(PropertyInterface $property)
  146. {
  147. return $property->getValue();
  148. }
  149. public function exportData($propertyValue)
  150. {
  151. if (!\is_array($propertyValue)) {
  152. return '';
  153. }
  154. if (!empty($propertyValue)) {
  155. return \json_encode($propertyValue);
  156. }
  157. return '';
  158. }
  159. public function importData(
  160. NodeInterface $node,
  161. PropertyInterface $property,
  162. $value,
  163. $userId,
  164. $webspaceKey,
  165. $languageCode,
  166. $segmentKey = null
  167. ) {
  168. $property->setValue(\json_decode($value, true));
  169. $this->write($node, $property, $userId, $webspaceKey, $languageCode, $segmentKey);
  170. }
  171. public function preResolve(PropertyInterface $property)
  172. {
  173. $data = $property->getValue();
  174. if (!isset($data['ids']) || !\is_array($data['ids'])) {
  175. return;
  176. }
  177. foreach ($data['ids'] as $id) {
  178. $this->referenceStore->add($id);
  179. }
  180. }
  181. public function mapPropertyMetadata(ContentPropertyMetadata $propertyMetadata): PropertyMetadata
  182. {
  183. $mandatory = $propertyMetadata->isRequired();
  184. $minMaxValue = (object) [
  185. 'min' => null,
  186. 'max' => null,
  187. ];
  188. if (null !== $this->propertyMetadataMinMaxValueResolver) {
  189. $minMaxValue = $this->propertyMetadataMinMaxValueResolver->resolveMinMaxValue($propertyMetadata);
  190. }
  191. $idsMetadata = new ArrayMetadata(
  192. new NumberMetadata(),
  193. $minMaxValue->min,
  194. $minMaxValue->max,
  195. true
  196. );
  197. if (!$mandatory) {
  198. $idsMetadata = new AnyOfsMetadata([
  199. new EmptyArrayMetadata(),
  200. $idsMetadata,
  201. ]);
  202. }
  203. $mediaSelectionMetadata = new ObjectMetadata([
  204. new PropertyMetadata('ids', $mandatory, $idsMetadata),
  205. new PropertyMetadata('displayOption', false, new StringMetadata()),
  206. ]);
  207. if (!$mandatory) {
  208. $mediaSelectionMetadata = new AnyOfsMetadata([
  209. new NullMetadata(),
  210. $mediaSelectionMetadata,
  211. ]);
  212. }
  213. return new PropertyMetadata($propertyMetadata->getName(), $mandatory, $mediaSelectionMetadata);
  214. }
  215. }