33namespace ToolboxBundle \Builder ;
44
55use Pimcore \Model \Document \Editable \Area \Info ;
6- use Pimcore \Model \Document \Editable \Checkbox ;
76use Pimcore \Templating \Renderer \EditableRenderer ;
87use Pimcore \Translation \Translator ;
8+ use ToolboxBundle \Document \Editable \ConfigParser ;
99use ToolboxBundle \Manager \AreaManagerInterface ;
10- use ToolboxBundle \Registry \StoreProviderRegistryInterface ;
1110use Twig \Environment ;
1211
1312abstract class AbstractConfigBuilder
1413{
1514 public function __construct (
1615 protected Translator $ translator ,
1716 protected Environment $ templating ,
18- protected StoreProviderRegistryInterface $ storeProvider ,
1917 protected AreaManagerInterface $ areaManager ,
18+ protected ConfigParser $ configParser ,
2019 protected EditableRenderer $ editableRenderer
2120 ) {
2221 }
@@ -47,8 +46,7 @@ protected function parseConfigElements(
4746
4847 $ editableNode = $ this ->parseConfigElement ($ info , $ configElementName , $ elementData , $ acStoreProcessed , $ brickId , $ themeOptions );
4948
50- //if element need's a store and store is empty: skip field
51- if ($ this ->needStore ($ elementData ['type ' ]) && $ this ->hasValidStore ($ editableNode ['config ' ]) === false ) {
49+ if ($ editableNode === null ) {
5250 continue ;
5351 }
5452
@@ -99,34 +97,14 @@ protected function parseConfigElements(
9997 return $ editableNodes ;
10098 }
10199
102- private function parseConfigElement (?Info $ info , string $ elementName , array $ elementData , bool $ acStoreProcessed , string $ brickId , array $ themeOptions ): array
100+ private function parseConfigElement (?Info $ info , string $ elementName , array $ elementData , bool $ acStoreProcessed , string $ brickId , array $ themeOptions ): ? array
103101 {
104- $ editableConfig = $ elementData ['config ' ];
105102 $ editableType = $ elementData ['type ' ];
106103
107- //set element config data
108- $ parsedNode = $ this ->parseElementNode ($ elementName , $ elementData , $ acStoreProcessed );
104+ $ parsedNode = $ this ->configParser ->parseConfigElement ($ info , $ elementName , $ elementData , $ acStoreProcessed );
109105
110- //set width
111- if ($ this ->canHaveDynamicWidth ($ editableType )) {
112- $ parsedNode ['width ' ] = $ parsedNode ['width ' ] ?? '100% ' ;
113- } else {
114- unset($ parsedNode ['width ' ]);
115- }
116-
117- //set height
118- if ($ this ->canHaveDynamicHeight ($ editableType )) {
119- $ parsedNode ['height ' ] = $ parsedNode ['height ' ] ?? 200 ;
120- } else {
121- unset($ parsedNode ['height ' ]);
122- }
123-
124- // set default
125- $ parsedNode ['config ' ]['defaultValue ' ] = $ this ->getSelectedValue ($ info , $ parsedNode , $ editableConfig ['default ' ] ?? null );
126-
127- // check store
128- if ($ this ->needStore ($ editableType ) && $ this ->hasValidStore ($ editableConfig )) {
129- $ parsedNode ['config ' ]['store ' ] = $ this ->buildStore ($ editableType , $ editableConfig );
106+ if ($ parsedNode === null ) {
107+ return null ;
130108 }
131109
132110 if ($ editableType === 'block ' && array_key_exists ('children ' , $ elementData ) && is_array ($ elementData ['children ' ]) && count ($ elementData ['children ' ]) > 0 ) {
@@ -136,105 +114,6 @@ private function parseConfigElement(?Info $info, string $elementName, array $ele
136114 return $ parsedNode ;
137115 }
138116
139- private function parseElementNode (string $ configElementName , array $ elementData , bool $ acStoreProcessed ): array
140- {
141- $ elementNode = [
142- 'type ' => $ elementData ['type ' ],
143- 'name ' => $ configElementName ,
144- 'tab ' => $ elementData ['tab ' ],
145- 'label ' => !empty ($ elementData ['title ' ]) ? $ elementData ['title ' ] : null ,
146- 'description ' => !empty ($ elementData ['description ' ]) ? $ elementData ['description ' ] : null ,
147- 'config ' => $ elementData ['config ' ] ?? [],
148- 'additional_classes_element ' => false ,
149- ];
150-
151- if ($ elementData ['type ' ] === 'additionalClasses ' ) {
152- if ($ acStoreProcessed === true ) {
153- throw new \Exception (
154- sprintf (
155- 'A element of type "additionalClasses" in element "%s" already has been defined. You can only add one field of type "%s" per area. Use "%s" instead. ' ,
156- $ configElementName ,
157- 'additionalClasses ' ,
158- 'additionalClassesChained '
159- )
160- );
161- }
162-
163- $ elementNode ['type ' ] = 'select ' ;
164- $ elementNode ['label ' ] = !empty ($ elementData ['title ' ]) ? $ elementData ['title ' ] : 'Additional ' ;
165- $ elementNode ['additional_classes_element ' ] = true ;
166- $ elementNode ['name ' ] = 'add_classes ' ;
167- } elseif ($ elementData ['type ' ] === 'additionalClassesChained ' ) {
168- if ($ acStoreProcessed === false ) {
169- throw new \Exception (
170- sprintf (
171- 'You need to add a element of type "%s" before adding a "%s" element. ' ,
172- 'additionalClasses ' ,
173- 'additionalClassesChained '
174- )
175- );
176- }
177-
178- if (!str_starts_with ($ configElementName , 'additional_classes_chain_ ' )) {
179- throw new \Exception (
180- sprintf (
181- 'Chained AC element name needs to start with "%s" followed by a numeric. "%s" given. ' ,
182- 'additional_classes_chain_ ' ,
183- $ configElementName
184- )
185- );
186- }
187-
188- $ chainedElementName = explode ('_ ' , $ configElementName );
189- $ chainedIncrementor = end ($ chainedElementName );
190- if (!is_numeric ($ chainedIncrementor )) {
191- throw new \Exception ('Chained AC element name must end with an numeric. " ' . $ chainedIncrementor . '" given. ' );
192- }
193-
194- $ elementNode ['type ' ] = 'select ' ;
195- $ elementNode ['label ' ] = !empty ($ elementData ['title ' ]) ? $ elementData ['title ' ] : 'Additional ' ;
196- $ elementNode ['additional_classes_element ' ] = true ;
197- $ elementNode ['name ' ] = 'add_cclasses_ ' . $ chainedIncrementor ;
198- }
199-
200- // translate title
201- if (!empty ($ elementNode ['label ' ])) {
202- $ elementNode ['label ' ] = $ this ->translator ->trans ($ elementNode ['label ' ], [], 'admin ' );
203- }
204-
205- // translate description
206- if (!empty ($ elementNode ['description ' ])) {
207- $ elementNode ['description ' ] = $ this ->translator ->trans ($ elementNode ['description ' ], [], 'admin ' );
208- }
209-
210- return $ elementNode ;
211- }
212-
213- private function getSelectedValue (?Info $ info , array $ config , mixed $ defaultConfigValue ): mixed
214- {
215- if (!$ info instanceof Info) {
216- return $ this ->castPimcoreEditableValue ($ config ['type ' ], $ defaultConfigValue );
217- }
218-
219- $ el = $ info ->getDocumentElement ($ config ['name ' ], $ config ['type ' ]);
220-
221- if ($ el === null ) {
222- return $ this ->castPimcoreEditableValue ($ config ['type ' ], $ defaultConfigValue );
223- }
224-
225- // force default (only if it returns false)
226- // checkboxes may return an empty string and are impossible to track into default mode
227- if (!empty ($ defaultConfigValue ) && (method_exists ($ el , 'isEmpty ' ) && $ el ->isEmpty () === true )) {
228- $ el ->setDataFromResource ($ defaultConfigValue );
229- }
230-
231- $ value = $ el instanceof Checkbox ? $ el ->isChecked () : $ el ->getData ();
232-
233- $ fallbackAwareValue = !empty ($ value ) ? $ value : $ defaultConfigValue ;
234-
235- return $ this ->castPimcoreEditableValue ($ config ['type ' ], $ fallbackAwareValue );
236- }
237-
238117 private function checkColumnAdjusterField (string $ brickId , ?string $ tab , array $ themeOptions , string $ configElementName , array $ editableNodes ): array
239118 {
240119 if ($ brickId !== 'columns ' ) {
@@ -261,107 +140,4 @@ private function checkColumnAdjusterField(string $brickId, ?string $tab, array $
261140 return $ editableNodes ;
262141 }
263142
264- private function buildStore ($ type , $ config ): array
265- {
266- $ storeValues = [];
267- if (isset ($ config ['store ' ])) {
268- $ storeValues = $ config ['store ' ];
269- } elseif (isset ($ config ['store_provider ' ])) {
270- $ storeProvider = $ this ->storeProvider ->get ($ config ['store_provider ' ]);
271- $ storeValues = $ storeProvider ->getValues ();
272- }
273-
274- if (count ($ storeValues ) === 0 ) {
275- throw new \Exception ($ type . ' has no valid configured store ' );
276- }
277-
278- $ store = [];
279- foreach ($ storeValues as $ k => $ v ) {
280- if (is_array ($ v )) {
281- $ v = $ v ['name ' ];
282- }
283- $ store [] = [$ k , $ this ->translator ->trans ($ v , [], 'admin ' )];
284- }
285-
286- return $ store ;
287- }
288-
289- private function hasValidStore ($ parsedConfig ): bool
290- {
291- if (isset ($ parsedConfig ['store ' ]) && is_array ($ parsedConfig ['store ' ]) && count ($ parsedConfig ['store ' ]) > 0 ) {
292- return true ;
293- }
294-
295- if (isset ($ parsedConfig ['store_provider ' ]) && $ this ->storeProvider ->has ($ parsedConfig ['store_provider ' ])) {
296- return true ;
297- }
298-
299- return false ;
300- }
301-
302- private function needStore ($ type ): bool
303- {
304- return in_array ($ type , ['select ' , 'multiselect ' , 'additionalClasses ' , 'additionalClassesChained ' ]);
305- }
306-
307- private function canHaveDynamicWidth ($ type ): bool
308- {
309- return in_array (
310- $ type ,
311- [
312- 'multihref ' ,
313- 'relations ' ,
314- 'href ' ,
315- 'relation ' ,
316- 'image ' ,
317- 'input ' ,
318- 'multiselect ' ,
319- 'numeric ' ,
320- 'embed ' ,
321- 'pdf ' ,
322- 'renderlet ' ,
323- 'select ' ,
324- 'snippet ' ,
325- 'table ' ,
326- 'textarea ' ,
327- 'video ' ,
328- 'wysiwyg ' ,
329- 'parallaximage ' ,
330- 'additionalClasses ' ,
331- 'additionalClassesChained '
332- ]
333- );
334- }
335-
336- private function canHaveDynamicHeight ($ type ): bool
337- {
338- return in_array ($ type , [
339- 'multihref ' ,
340- 'relations ' ,
341- 'image ' ,
342- 'multiselect ' ,
343- 'embed ' ,
344- 'pdf ' ,
345- 'renderlet ' ,
346- 'snippet ' ,
347- 'textarea ' ,
348- 'video ' ,
349- 'wysiwyg ' ,
350- 'parallaximage '
351- ]);
352- }
353-
354- private function castPimcoreEditableValue (string $ type , mixed $ value ): mixed
355- {
356- // pimcore numeric editable requires string type
357- if ($ type === 'numeric ' ) {
358- return $ value === null ? null : (string ) $ value ;
359- }
360-
361- if ($ type === 'areablock ' ) {
362- return $ value === null ? null : (is_string ($ value ) ? $ value : serialize ($ value ));
363- }
364-
365- return $ value ;
366- }
367143}
0 commit comments