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 ;
3135use Pimcore \Model \DataObject \ClassDefinition \Data \Hotspotimage as HotspotImageData ;
3236use Pimcore \Model \DataObject \Concrete ;
3337use Pimcore \Model \DataObject \Data \Hotspotimage ;
38+ use Pimcore \Model \Document ;
3439use Pimcore \Model \Element \Data \MarkerHotspotItem ;
3540use Pimcore \Model \UserInterface ;
3641use Symfony \Component \DependencyInjection \Attribute \AutoconfigureTag ;
42+ use function get_class ;
3743use function in_array ;
3844use function is_array ;
3945
4349#[AutoconfigureTag(DataAdapterLoaderInterface::ADAPTER_TAG )]
4450final readonly class HotspotImageAdapter implements
4551 SetterDataInterface,
46- SearchPreviewDataInterface
52+ SearchPreviewDataInterface,
53+ DataNormalizerInterface
4754{
4855 use AssetPreviewDataTrait;
4956 use ElementProviderTrait;
@@ -104,6 +111,77 @@ public function normalizeImageData(MarkerHotspotItem $hotspotItem): array
104111 ];
105112 }
106113
114+ public function normalize (mixed $ value , Data $ fieldDefinition ): mixed
115+ {
116+ if (!($ fieldDefinition instanceof HotspotImageData)) {
117+ throw new InvalidDataTypeException (HotspotImageData::class, get_class ($ fieldDefinition ));
118+ }
119+
120+ $ value = $ fieldDefinition ->normalize ($ value );
121+ if (!is_array ($ value )) {
122+ return null ;
123+ }
124+
125+ $ id = $ value ['image ' ]['id ' ] ?? null ;
126+ $ type = $ value ['image ' ]['type ' ] ?? null ;
127+
128+ if ($ id === null || $ type === null ) {
129+ return $ value ;
130+ }
131+
132+ $ value ['image ' ] = [
133+ ... $ value ['image ' ],
134+ ...$ this ->normalizeElementData ($ id , $ type ),
135+ ];
136+ $ value ['hotspots ' ] = $ this ->normalizeHotSpotData ($ value ['hotspots ' ]);
137+
138+ return $ value ;
139+ }
140+
141+ private function normalizeElementData (int $ id , string $ type ): array
142+ {
143+ $ element = $ this ->getElementData ($ id , $ type );
144+ if ($ element instanceof AbstractObject || $ element instanceof Document) {
145+ $ elementData ['published ' ] = $ element ->isPublished ();
146+ }
147+ $ elementData ['subtype ' ] = $ element ->getType ();
148+ $ elementData ['fullPath ' ] = $ element ->getFullPath ();
149+
150+ return $ elementData ;
151+ }
152+
153+ private function normalizeHotSpotData (array $ hotSpotData ): array
154+ {
155+ foreach ($ hotSpotData as &$ hotSpot ) {
156+ $ data = $ hotSpot ['data ' ] ?? null ;
157+ if (!is_array ($ data )) {
158+ continue ;
159+ }
160+ foreach ($ data as $ item ) {
161+ if ($ item instanceof MarkerHotspotItem &&
162+ $ this ->isValidItem ($ item )
163+ ) {
164+ $ hotSpot ['data ' ] = [
165+ ... $ this ->normalizeImageData ($ item ),
166+ ... $ this ->normalizeElementData ($ item ->getValue (), $ item ->getType ()),
167+ ];
168+ }
169+ }
170+ }
171+
172+ return $ hotSpotData ;
173+ }
174+
175+ private function getElementData (int $ id , string $ type ): Asset |Document |AbstractObject
176+ {
177+ $ element = $ this ->serviceResolver ->getElementById ($ type , $ id );
178+ if ($ element === null ) {
179+ throw new NotFoundException ($ type , $ id );
180+ }
181+
182+ return $ element ;
183+ }
184+
107185 private function processData (array $ data ): array
108186 {
109187 if (empty ($ data )) {
@@ -123,15 +201,6 @@ private function processMetaData(array $metaData): array
123201 {
124202 foreach ($ metaData as &$ item ) {
125203 $ item = new MarkerHotspotItem ($ item );
126- if ($ this ->isValidItem ($ item )) {
127- try {
128- $ element = $ this ->getElement ($ this ->serviceResolver , $ item ['type ' ], $ item ->getValue ());
129- } catch (NotFoundException ) {
130- continue ;
131- }
132-
133- $ item ['value ' ] = $ element ;
134- }
135204 }
136205
137206 return $ metaData ;
0 commit comments