: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* @copyright Copyright (c) 2023, Code Atlantic LLC
if ( ! defined( 'ABSPATH' ) ) {
* Various functions to help manipulating arrays.
* Filters out null values.
public static function filter_null( $array = [] ) {
return array_filter( $array, [ __CLASS__, '_filter_null' ] );
public static function _filter_null( $val = null ) {
* Clean variables using sanitize_text_field.
public static function sanitize( $var ) {
if ( is_string( $var ) ) {
return sanitize_text_field( $var );
return array_map( [ __CLASS__, 'sanitize' ], (array) $var );
* Helper function to move or swap array keys in various ways.
* PUM_Utils_Array::move_item($arr, 'move me', 'up'); //move it one up
* PUM_Utils_Array::move_item($arr, 'move me', 'down'); //move it one down
* PUM_Utils_Array::move_item($arr, 'move me', 'top'); //move it to top
* PUM_Utils_Array::move_item($arr, 'move me', 'bottom'); //move it to bottom
* PUM_Utils_Array::move_item($arr, 'move me', -1); //move it one up
* PUM_Utils_Array::move_item($arr, 'move me', 1); //move it one down
* PUM_Utils_Array::move_item($arr, 'move me', 2); //move it two down
* PUM_Utils_Array::move_item($arr, 'move me', 'before', 'b'); //move it before ['b']
* PUM_Utils_Array::move_item($arr, 'move me', 'up', 'b'); //move it before ['b']
* PUM_Utils_Array::move_item($arr, 'move me', -1, 'b'); //move it before ['b']
* PUM_Utils_Array::move_item($arr, 'move me', 'after', 'b'); //move it after ['b']
* PUM_Utils_Array::move_item($arr, 'move me', 'down', 'b'); //move it after ['b']
* PUM_Utils_Array::move_item($arr, 'move me', 1, 'b'); //move it after ['b']
* PUM_Utils_Array::move_item($arr, 'move me', 2, 'b'); //move it two positions after ['b']
* Special syntax, to swap two elements:
* PUM_Utils_Array::move_item($arr, 'a', 0, 'd'); //Swap ['a'] with ['d']
* PUM_Utils_Array::move_item($arr, 'a', 'swap', 'd'); //Swap ['a'] with ['d']
* @param int|string $move
* @param string|null $key2
public static function move_item( &$ref_arr, $key1, $move, $key2 = null ) {
if ( ! isset( $arr[ $key1 ] ) || ! isset( $arr[ $key2 ] ) ) {
foreach ( $arr as &$val ) {
'sort' => ( ++ $i * 10 ),
// Add a quick keyword `swap` to make syntax simpler to remember.
if ( 'swap' === $move ) {
if ( is_numeric( $move ) ) {
if ( 0 === $move && $key1 === $key2 ) {
} elseif ( 0 === $move ) {
$tmp = $arr[ $key1 ]['sort'];
$arr[ $key1 ]['sort'] = $arr[ $key2 ]['sort'];
$arr[ $key2 ]['sort'] = $tmp;
$arr[ $key1 ]['sort'] = $arr[ $key2 ]['sort'] + ( $move * 10 + ( $key1 === $key2 ? ( $move < 0 ? - 5 : 5 ) : 0 ) );
$arr[ $key1 ]['sort'] = $arr[ $key2 ]['sort'] - ( $key1 === $key2 ? 15 : 5 );
$arr[ $key1 ]['sort'] = $arr[ $key2 ]['sort'] + ( $key1 === $key2 ? 15 : 5 );
$arr[ $key1 ]['sort'] = 5;
$arr[ $key1 ]['sort'] = $i * 10 + 5;
uasort( $arr, [ __CLASS__, 'sort_by_sort' ] );
foreach ( $arr as &$val ) {
* Pluck all array keys beginning with string.
* @param bool|string|array $strings
public static function pluck_keys_starting_with( $array, $strings = [] ) {
$to_be_removed = self::remove_keys_starting_with( $array, $strings );
return array_diff_key( $array, $to_be_removed );
* Pluck all array keys ending with string.
* @param bool|string|array $strings
public static function pluck_keys_ending_with( $array, $strings = [] ) {
$to_be_removed = self::remove_keys_ending_with( $array, $strings );
return array_diff_key( $array, $to_be_removed );
* Extract only allowed keys from an array.
* @param array $array Array to be extracted from.
* @param string[] $allowed_keys List of keys.
public static function allowed_keys( $array, $allowed_keys = [] ) {
return array_intersect_key( $array, array_flip( $allowed_keys ) );
* This works exactly the same as wp_parse_args, except we remove unused keys for sanitization.
* @param array $array Array to be parsed.
* @param array $allowed_args Array of key=>defaultValue pairs for each allowed argument.
public static function parse_allowed_args( $array, $allowed_args = [] ) {
$array = wp_parse_args( $array, $allowed_args );
return self::allowed_keys( $array, array_keys( $allowed_args ) );
* Pluck specified array keys.
public static function pluck( $array, $keys = [] ) {
return self::pluck_keys_containing( $array, $keys );
* Pluck all array keys containing a string or strings.
* @param string[] $strings
public static function pluck_keys_containing( $array, $strings = [] ) {
$to_be_removed = self::remove_keys_containing( $array, $strings );
return array_diff_key( $array, $to_be_removed );
* Remove all array keys beginning with string.
* @param string[] $strings
public static function remove_keys_starting_with( $array, $strings = [] ) {
if ( ! is_array( $strings ) ) {
foreach ( $array as $key => $value ) {
foreach ( $strings as $string ) {
if ( strpos( $key, $string ) === 0 ) {
* Remove all array keys ending with string.
* @param bool|string|array $strings
public static function remove_keys_ending_with( $array, $strings = [] ) {
if ( ! is_array( $strings ) ) {
foreach ( $array as $key => $value ) {
foreach ( $strings as $string ) {
$length = strlen( $string );
if ( substr( $key, - $length ) === $string ) {
* Remove all array keys containing string.
* @param bool|string|array $strings
public static function remove_keys_containing( $array, $strings = [] ) {
if ( ! is_array( $strings ) ) {
foreach ( $array as $key => $value ) {
foreach ( $strings as $string ) {
if ( strpos( $key, $string ) !== false ) {
* Remove all array keys containing string.
* @param string|array $keys
public static function remove_keys( $array, $keys = [] ) {
if ( is_string( $keys ) ) {
foreach ( (array) $keys as $key ) {
if ( is_string( $key ) && array_key_exists( $key, $array ) ) {
* Sort nested arrays with various options.
public static function sort( $array = [], $type = 'key', $reverse = false ) {
if ( ! is_array( $array ) ) {
uasort( $array, [ __CLASS__, 'sort_by_priority' ] );
uasort( $array, [ __CLASS__, 'rsort_by_priority' ] );
public static function sort_by_sort( $a, $b ) {
return $a['sort'] > $b['sort'];
* Sort array by priority value
public static function sort_by_priority( $a, $b ) {
$pri_a = isset( $a['pri'] ) ? $a['pri'] : ( isset( $a['priority'] ) ? $a['priority'] : false );
$pri_b = isset( $b['pri'] ) ? $b['pri'] : ( isset( $b['priority'] ) ? $b['priority'] : false );
if ( ! is_numeric( $pri_a ) || ! is_numeric( $pri_b ) || $pri_a === $pri_b ) {
return ( $pri_a < $pri_b ) ? - 1 : 1;
* Sort array in reverse by priority value
public static function rsort_by_priority( $a, $b ) {
$pri_a = isset( $a['pri'] ) ? $a['pri'] : ( isset( $a['priority'] ) ? $a['priority'] : false );
$pri_b = isset( $b['pri'] ) ? $b['pri'] : ( isset( $b['priority'] ) ? $b['priority'] : false );
if ( ! is_numeric( $pri_a ) || ! is_numeric( $pri_b ) || $pri_a === $pri_b ) {
return ( $pri_a < $pri_b ) ? 1 : - 1;
* Replace array key with new key name in same order
public static function replace_key( $array, $old_key, $new_key ) {
$keys = array_keys( $array );
if ( false === $index = array_search( $old_key, $keys, true ) ) {
// throw new \Exception( sprintf( 'Key "%s" does not exit', $old_key ) );
$keys[ $index ] = $new_key;
return array_combine( $keys, array_values( $array ) );
* Converts 'false' & 'true' string values in any array to proper boolean values.
* @param array|mixed $data
public static function fix_json_boolean_values( $data ) {
if ( is_array( $data ) ) {
foreach ( (array) $data as $key => $value ) {
if ( is_string( $value ) && in_array( $value, [ 'true', 'false' ] ) ) {
$data[ $key ] = json_decode( $value );
} elseif ( is_array( $value ) ) {
$data[ $key ] = self::fix_json_boolean_values( $value );
public static function from_object( $obj ) {
if ( is_object( $obj ) ) {
if ( is_array( $obj ) ) {
foreach ( $obj as $key => $val ) {
$new[ $key ] = self::from_object( $val );
public static function safe_json_decode( $array ) {