@@ -200,6 +200,10 @@ public function applyMutation($mutations, $value)
200200 'getShortcodeAtts ' => [
201201 'args ' => [],
202202 'type ' => 'is_string '
203+ ],
204+ 'getBlockAtts ' => [
205+ 'args ' => [],
206+ 'type ' => 'is_string '
203207 ]
204208 ];
205209
@@ -223,6 +227,8 @@ public function applyMutation($mutations, $value)
223227 $ value = $ this ->getArrayValues ($ value );
224228 } elseif ($ mutation == 'getShortcodeAtts ' ) {
225229 $ value = $ this ->getShortcodeAtts ($ value );
230+ } elseif ($ mutation == 'getBlockAtts ' ) {
231+ $ value = $ this ->getBlockAtts ($ value );
226232 } else {
227233 $ value = call_user_func_array ($ mutation , array_merge ([$ value ], $ allowed [$ mutation ]['args ' ]));
228234 }
@@ -418,4 +424,90 @@ public function getShortcodeAtts($value)
418424
419425 return $ return ;
420426 }
427+
428+ /**
429+ * Given a string, fetch all blocks and its attributes.
430+ *
431+ * @param string $value
432+ * @return array
433+ */
434+ public function getBlockAtts ($ value )
435+ {
436+ // For rare cases where this may not be defined.
437+ if (!function_exists ('parse_blocks ' )) {
438+ return [];
439+ }
440+
441+ // Parse the blocks using the WordPress core function.
442+ $ blocks = @\parse_blocks ($ value );
443+ if (count ($ blocks ) === 0 ) {
444+ return [];
445+ }
446+
447+ // Get the inner blocks recursively.
448+ $ return = $ this ->getInnerBlocks ($ blocks , []);
449+
450+ // Return the blocks.
451+ return $ return ;
452+ }
453+
454+ /**
455+ * Given an array of inner blocks, fetch all of its attributes and merge together.
456+ *
457+ * @param array $innerBlocks
458+ * @return array
459+ */
460+ private function getInnerBlocks (array $ innerBlocks , array $ currentBlocks )
461+ {
462+ foreach ($ innerBlocks as $ block ) {
463+ // Essential values to have.
464+ if (!isset ($ block ['blockName ' ], $ block ['attrs ' ])) {
465+ continue ;
466+ }
467+
468+ // If the block already exists, merge all the atts together.
469+ if (isset ($ currentBlocks [$ block ['blockName ' ]])) {
470+ $ currentBlocks [$ block ['blockName ' ]] = $ this ->mergeArraysConcatenateValues ($ currentBlocks [$ block ['blockName ' ]], $ block ['attrs ' ]);
471+ } else {
472+ $ currentBlocks [$ block ['blockName ' ]] = $ block ['attrs ' ];
473+ }
474+
475+ // In case the block has innerblocks, we need to fetch them all and merge them together.
476+ if (isset ($ block ['innerBlocks ' ]) && is_array ($ block ['innerBlocks ' ]) && count ($ block ['innerBlocks ' ]) > 0 ) {
477+ $ currentBlocks = $ this ->getInnerBlocks ($ block ['innerBlocks ' ], $ currentBlocks );
478+ }
479+ }
480+
481+ return $ currentBlocks ;
482+ }
483+
484+ /**
485+ * Given 2 ararys, merge them together while concatenating its values.
486+ *
487+ * @param array $array1
488+ * @param array $array2
489+ * @return array
490+ */
491+ public function mergeArraysConcatenateValues ($ array1 , $ array2 ) {
492+ if (!is_array ($ array1 ) || !is_array ($ array2 )) {
493+ return [];
494+ }
495+
496+ foreach ($ array2 as $ key => $ value2 ) {
497+ if (array_key_exists ($ key , $ array1 )) {
498+ if (is_array ($ value2 ) && is_array ($ array1 [$ key ])) {
499+ // If both values are arrays, recursively merge them
500+ $ array1 [$ key ] = $ this ->mergeArraysConcatenateValues ($ array1 [$ key ], $ value2 );
501+ } else {
502+ // Concatenate values if keys are identical
503+ $ array1 [$ key ] .= $ value2 ;
504+ }
505+ } else {
506+ // If the key doesn't exist in array1, simply add it
507+ $ array1 [$ key ] = $ value2 ;
508+ }
509+ }
510+
511+ return $ array1 ;
512+ }
421513}
0 commit comments