Merge pull request #16967 from wmortada/wp#46-2
[civicrm-core.git] / Civi / Api4 / Utils / ArrayInsertionUtil.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
6 | |
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
10 +--------------------------------------------------------------------+
11 */
12
13 /**
14 *
15 * @package CRM
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
17 * $Id$
18 *
19 */
20
21
22 namespace Civi\Api4\Utils;
23
24 class ArrayInsertionUtil {
25
26 /**
27 * If the values to be inserted contain a key _parent_id they will only be
28 * inserted if the parent node ID matches their ID
29 *
30 * @param $array
31 * The array to insert the value in
32 * @param array $parts
33 * Path to insertion point with structure:
34 * [[ name => is_multiple ], ..]
35 * @param mixed $values
36 * The value to be inserted
37 */
38 public static function insert(&$array, $parts, $values) {
39 $key = key($parts);
40 $isMulti = array_shift($parts);
41 if (!isset($array[$key])) {
42 $array[$key] = $isMulti ? [] : NULL;
43 }
44 if (empty($parts)) {
45 $values = self::filterValues($array, $isMulti, $values);
46 $array[$key] = $values;
47 }
48 else {
49 if ($isMulti) {
50 foreach ($array[$key] as &$subArray) {
51 self::insert($subArray, $parts, $values);
52 }
53 }
54 else {
55 self::insert($array[$key], $parts, $values);
56 }
57 }
58 }
59
60 /**
61 * @param $parentArray
62 * @param $isMulti
63 * @param $values
64 *
65 * @return array|mixed
66 */
67 private static function filterValues($parentArray, $isMulti, $values) {
68 $parentID = $parentArray['id'] ?? NULL;
69
70 if ($parentID) {
71 $values = array_filter($values, function ($value) use ($parentID) {
72 return ($value['_parent_id'] ?? NULL) == $parentID;
73 });
74 }
75
76 $unsets = ['_parent_id', '_base_id'];
77 array_walk($values, function (&$value) use ($unsets) {
78 foreach ($unsets as $unset) {
79 if (isset($value[$unset])) {
80 unset($value[$unset]);
81 }
82 }
83 });
84
85 if (!$isMulti) {
86 $values = array_shift($values);
87 }
88 return $values;
89 }
90
91 }