1717namespace Pimcore \Bundle \StudioBackendBundle \DataObject \Data \Adapter ;
1818
1919use Pimcore \Bundle \StaticResolverBundle \Models \Element \ServiceResolverInterface ;
20+ use Pimcore \Bundle \StudioBackendBundle \DataObject \Data \DataNormalizerInterface ;
2021use Pimcore \Bundle \StudioBackendBundle \DataObject \Data \Model \FieldContextData ;
2122use Pimcore \Bundle \StudioBackendBundle \DataObject \Data \SearchPreviewDataInterface ;
2223use Pimcore \Bundle \StudioBackendBundle \DataObject \Data \SetterDataInterface ;
2324use Pimcore \Bundle \StudioBackendBundle \DataObject \Service \DataAdapterLoaderInterface ;
2425use Pimcore \Bundle \StudioBackendBundle \DataObject \Service \DataServiceInterface ;
2526use Pimcore \Bundle \StudioBackendBundle \DataObject \Util \Trait \AssetPreviewDataTrait ;
27+ use Pimcore \Bundle \StudioBackendBundle \Exception \Api \InvalidDataTypeException ;
2628use Pimcore \Bundle \StudioBackendBundle \Exception \Api \NotFoundException ;
2729use Pimcore \Bundle \StudioBackendBundle \Util \Constant \ElementTypes ;
2830use Pimcore \Bundle \StudioBackendBundle \Util \Trait \ElementProviderTrait ;
31+ use Pimcore \Model \Asset ;
2932use Pimcore \Model \Asset \Image ;
33+ use Pimcore \Model \DataObject \AbstractObject ;
3034use Pimcore \Model \DataObject \ClassDefinition \Data ;
35+ use Pimcore \Model \DataObject \ClassDefinition \Data \Block ;
3136use Pimcore \Model \DataObject \ClassDefinition \Data \Hotspotimage as HotspotImageData ;
3237use Pimcore \Model \DataObject \Concrete ;
3338use Pimcore \Model \DataObject \Data \Hotspotimage ;
39+ use Pimcore \Model \Document ;
3440use Pimcore \Model \Element \Data \MarkerHotspotItem ;
3541use Pimcore \Model \UserInterface ;
3642use Symfony \Component \DependencyInjection \Attribute \AutoconfigureTag ;
4147 * @internal
4248 */
4349#[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG )]
44- final readonly class HotspotImageAdapter implements SetterDataInterface, SearchPreviewDataInterface
50+ final readonly class HotspotImageAdapter implements SetterDataInterface,
51+ SearchPreviewDataInterface,
52+ DataNormalizerInterface
4553{
4654 use AssetPreviewDataTrait;
4755 use ElementProviderTrait;
@@ -102,6 +110,76 @@ public function normalizeImageData(MarkerHotspotItem $hotspotItem): array
102110 ];
103111 }
104112
113+ public function normalize (mixed $ value , Data $ fieldDefinition ): mixed
114+ {
115+ if (!($ fieldDefinition instanceof HotspotImageData)) {
116+ throw new InvalidDataTypeException (HotspotImageData::class, get_class ($ fieldDefinition ));
117+ }
118+
119+ $ value = $ fieldDefinition ->normalize ($ value );
120+ if (!is_array ($ value )) {
121+ return null ;
122+ }
123+
124+ $ id = $ value ['image ' ]['id ' ] ?? null ;
125+ $ type = $ value ['image ' ]['type ' ] ?? null ;
126+
127+ if ($ id === null || $ type === null ) {
128+ return $ value ;
129+ }
130+
131+ $ value ['image ' ] = [
132+ ... $ value ['image ' ],
133+ ...$ this ->normalizeElementData ($ id , $ type )
134+ ];
135+ $ value ['hotspots ' ] = $ this ->normalizeHotSpotData ($ value ['hotspots ' ]);
136+
137+ return $ value ;
138+ }
139+
140+ private function normalizeElementData (int $ id , string $ type ): array
141+ {
142+ $ element = $ this ->getElementData ($ id , $ type );
143+ if ($ element instanceof AbstractObject || $ element instanceof Document) {
144+ $ elementData ['published ' ] = $ element ->isPublished ();
145+ }
146+ $ elementData ['subtype ' ] = $ element ->getType ();
147+ $ elementData ['fullPath ' ] = $ element ->getFullPath ();
148+
149+ return $ elementData ;
150+ }
151+
152+ private function normalizeHotSpotData (array $ hotSpotData ): array
153+ {
154+ foreach ($ hotSpotData as &$ hotSpot ) {
155+ $ data = $ hotSpot ['data ' ] ?? null ;
156+ if (!is_array ($ data )) {
157+ continue ;
158+ }
159+ foreach ($ data as $ item ) {
160+ if ($ item instanceof MarkerHotspotItem &&
161+ $ this ->isValidItem ($ item )
162+ ) {
163+ $ hotSpot ['data ' ] = [
164+ ... $ this ->normalizeImageData ($ item ),
165+ ... $ this ->normalizeElementData ($ item ->getValue (), $ item ->getType ())
166+ ];
167+ }
168+ }
169+ }
170+
171+ return $ hotSpotData ;
172+ }
173+
174+ private function getElementData (int $ id , string $ type ): Asset |Document |AbstractObject
175+ {
176+ $ element = $ this ->serviceResolver ->getElementById ($ type , $ id );
177+ if ($ element === null ) {
178+ throw new NotFoundException ($ type , $ id );
179+ }
180+ return $ element ;
181+ }
182+
105183 private function processData (array $ data ): array
106184 {
107185 if (empty ($ data )) {
@@ -121,15 +199,6 @@ private function processMetaData(array $metaData): array
121199 {
122200 foreach ($ metaData as &$ item ) {
123201 $ item = new MarkerHotspotItem ($ item );
124- if ($ this ->isValidItem ($ item )) {
125- try {
126- $ element = $ this ->getElement ($ this ->serviceResolver , $ item ['type ' ], $ item ->getValue ());
127- } catch (NotFoundException ) {
128- continue ;
129- }
130-
131- $ item ['value ' ] = $ element ;
132- }
133202 }
134203
135204 return $ metaData ;
0 commit comments