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

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