Skip to content

Commit 87c1e35

Browse files
committed
Added: getBlockAtts mutation.
1 parent 9ea5d2b commit 87c1e35

2 files changed

Lines changed: 136 additions & 0 deletions

File tree

src/Request.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

tests/RequestTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,50 @@ public function testApplyMutation()
273273
$expected = '{"name":"John","age":30}';
274274
$result = $this->request->applyMutation($mutations, $value);
275275
$this->assertEquals($expected, $result);
276+
277+
// Test with multi-dimensional arrays.
278+
$array1 = [
279+
'name' => 'John',
280+
'age' => 30,
281+
'address' => [
282+
'city' => 'New York',
283+
'zip' => '10001',
284+
'street' => 'a street'
285+
]
286+
];
287+
288+
$array2 = [
289+
'name' => 'Doe',
290+
'email' => 'john@example.com',
291+
'address' => [
292+
'street' => '123 Main St',
293+
]
294+
];
295+
296+
$expected = [
297+
'name' => 'JohnDoe',
298+
'age' => 30,
299+
'email' => 'john@example.com',
300+
'address' => [
301+
'city' => 'New York',
302+
'zip' => '10001',
303+
'street' => 'a street123 Main St',
304+
]
305+
];
306+
307+
$result = $this->request->mergeArraysConcatenateValues($array1, $array2);
308+
$this->assertEquals($expected, $result);
309+
310+
// Test with non-array inputs, it should return an empty array
311+
$resultNonArray = $this->request->mergeArraysConcatenateValues('This is not an array', ['name' => 'John']);
312+
$this->assertEquals([], $resultNonArray);
313+
314+
// Test with arrays containing numeric keys
315+
$array3 = [1 => 'One', 2 => 'Two'];
316+
$array4 = [2 => 'Dos', 3 => 'Three'];
317+
$expectedNumericKeys = [1 => 'One', 2 => 'TwoDos', 3 => 'Three'];
318+
$resultNumericKeys = $this->request->mergeArraysConcatenateValues($array3, $array4);
319+
$this->assertEquals($expectedNumericKeys, $resultNumericKeys);
276320
}
277321

278322
public function testGetParameterValues()

0 commit comments

Comments
 (0)