PHP 7.3 reaches end of support in December 2021 and Adobe Commerce 2.3.x reaches end of support in April 2022. You may want to consider planning your upgrade now to Adobe Commerce 2.4.x and PHP 7.4.x to help maintain PCI compliance.

Array Manager

Overview

The Magento\Framework\Stdlib\ArrayManager library provides the ability to manage deeply nested associative arrays. The library is primarily used to handle data from UI components within DataProviders and Modifiers, which are actually part of a complicated process of parsing XML files in associative arrays.

Usage

Method Description
exists Checks if the node exists in a given associative array
find Finds a node in a nested array and saves its index and parent node reference
findPaths Gets matching paths for elements with specified indexes.
get Returns the value of the key (or node) at the end of the path. null is returned if the node could not be found.
move Moves a value from one path to another
merge Merges a value with a node and returns the modified data.
populate Populates a nested array, if possible and necessary.
remove Removes a node and returns the modified array.
replace Updates the existing nodes and returns the modified array
set Sets the value into a node and returns modified data.
slicePath Retrieves a slice of the specified path.

Example 1

The following example shows how to add a custom field to the checkout billing address using the LayoutProcessor implementation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
/**
 * Process js Layout of block
 *
 * @param array $jsLayout
 *
 * @return array
 */
public function process($jsLayout)
{
    ...

    if (isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
        ['children']['shippingAddress']['children']['shipping-address-fieldset']['children'])
    ) {
        $fields = $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
        ['children']['shippingAddress']['children']['shipping-address-fieldset']['children'];

        ...
    }

    ...
}

For a cleaner implementation of the previous example, use the Magento\Framework\Stdlib\ArrayManager, library to eliminate duplicate checking and get the required array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php

use Magento\Framework\Stdlib\ArrayManager;

...
    /**
     * @var ArrayManager
     */
    private $arrayManager;

    /**
     * SomeClass constructor.
     *
     * @param ArrayManager $arrayManager
     */
    public function __construct(ArrayManager $arrayManager)
    {
        $this->arrayManager = $arrayManager;
    }

    /**
     * Process js Layout of block
     *
     * @param array $jsLayout
     *
     * @return array
     */
    public function process($jsLayout): array
    {
        $path = 'components/checkout/children/steps/children/shipping-step/children/shippingAddress/children/shipping-address-fieldset/children';

        if ($fields = $this->arrayManager->get($path, $jsLayout)) {
            ...
        }

        ...
    }

...

Example 2

Suppose you have the following nested array:

1
2
3
4
5
6
7
8
9
10
11
12
13
$data = [
    'response' => [
        'status' => 'OK',
        'result' => [
            'items' => [
                0 => 'First item',
                1 => 'Second item',
                ...
            ],
            ...
        ]
    ]
]

You can use the Magento\Framework\Stdlib\ArrayManager library to access items in the array:

1
2
3
4
5
6
7
8
9
10
11
...

if ($this->arrayManager->get('response/status', $data) === 'OK') {
    $items = $this->arrayManager->get('response/result/items', $data) ?? [];

    foreach ($items as $item) {
        ...
    }
}

...

You can use the Magento\Framework\Stdlib\ArrayManager library to populate an array from the given path:

1
2
3
4
5
...

$this->arrayManager->populate('response/result/items', $data)

...