* @param string $prefix
* @return array
*/
- public static function prefixKeys(array $collection, string $prefix) {
+ public static function prefixKeys(array $collection, string $prefix): array {
$result = [];
foreach ($collection as $key => $value) {
$result[$prefix . $key] = $value;
return $result;
}
+ /**
+ * Removes all items from an array whose keys have a given prefix, and returns them unprefixed.
+ *
+ * @param array $collection
+ * @param string $prefix
+ */
+ public static function filterByPrefix(array &$collection, string $prefix): array {
+ $filtered = [];
+ foreach (array_keys($collection) as $key) {
+ if (!$prefix || strpos($key, $prefix) === 0) {
+ $filtered[substr($key, strlen($prefix))] = $collection[$key];
+ unset($collection[$key]);
+ }
+ }
+ return $filtered;
+ }
+
}
namespace Civi\Api4\Action\Contact;
use Civi\Api4\Utils\CoreUtil;
-use Civi\Api4\Utils\FormattingUtil;
/**
* Code shared by Contact create/update/save actions
foreach (['Address', 'Email', 'Phone', 'IM'] as $entity) {
foreach (['primary', 'billing'] as $type) {
$prefix = strtolower($entity) . '_' . $type . '.';
- $item = FormattingUtil::filterByPrefix($params, $prefix . '*', '*');
+ $item = \CRM_Utils_Array::filterByPrefix($params, $prefix);
// Not allowed to update by id or alter primary or billing flags
unset($item['id'], $item['is_primary'], $item['is_billing']);
if ($item) {
// Use BAO::buildOptions if possible
if ($baoName) {
$fieldName = empty($field['custom_field_id']) ? $field['name'] : 'custom_' . $field['custom_field_id'];
- $options = $baoName::buildOptions($fieldName, $context, self::filterByPrefix($params, $fieldPath, $field['name']));
+ $options = $baoName::buildOptions($fieldName, $context, self::filterByPath($params, $fieldPath, $field['name']));
}
// Fallback for option lists that exist in the api but not the BAO
if (!isset($options) || $options === FALSE) {
* @param mixed $value
*/
private static function applyFormatters(array $result, string $fieldPath, array $field, &$value) {
- $row = self::filterByPrefix($result, $fieldPath, $field['name']);
+ $row = self::filterByPath($result, $fieldPath, $field['name']);
foreach ($field['output_formatters'] as $formatter) {
$formatter($value, $row, $field);
* Given a field belonging to either the main entity or a joined entity,
* and a values array of [path => value], this returns all values which share the same root path.
*
- * Works by filtering array keys to only include those with the same prefix as a given field,
- * stripping them of that prefix.
+ * Note: Unlike CRM_Utils_Array::filterByPrefix this does not mutate the original array.
*
* Ex:
* ```
* @param string $fieldName
* @return array
*/
- public static function filterByPrefix(array $values, string $fieldPath, string $fieldName): array {
- $filtered = [];
+ public static function filterByPath(array $values, string $fieldPath, string $fieldName): array {
$prefix = substr($fieldPath, 0, strpos($fieldPath, $fieldName));
- foreach ($values as $key => $val) {
- if (!$prefix || strpos($key, $prefix) === 0) {
- $filtered[substr($key, strlen($prefix))] = $val;
- }
- }
- return $filtered;
+ return \CRM_Utils_Array::filterByPrefix($values, $prefix);
}
}
'where' => [['name', '=', $fieldName]],
'select' => ['options'],
'loadOptions' => ['id', 'label'],
- 'values' => FormattingUtil::filterByPrefix($this->values, $this->fieldName, $fieldName),
+ 'values' => FormattingUtil::filterByPath($this->values, $this->fieldName, $fieldName),
], 0)['options'] ?: [];
}
$editable['value'] = $data[$editable['value_path']];
// Ensure field is appropriate to this entity sub-type
$field = $this->getField($column['key']);
- $entityValues = FormattingUtil::filterByPrefix($data, $editable['id_path'], $editable['id_key']);
+ $entityValues = FormattingUtil::filterByPath($data, $editable['id_path'], $editable['id_key']);
if (!$this->fieldBelongsToEntity($editable['entity'], $field['name'], $entityValues)) {
return NULL;
}