Completed
Branch dev (69a0d4)
by
unknown
18:27
created

uniteArraysRecursive()   D

Complexity

Conditions 9
Paths 10

Size

Total Lines 26
Code Lines 12

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 26
rs 4.9091
cc 9
eloc 12
nc 10
nop 2
1
<?php
2
/**
3
 * Admin Page Framework
4
 * 
5
 * http://en.michaeluno.jp/admin-page-framework/
6
 * Copyright (c) 2013-2015 Michael Uno; Licensed MIT
7
 * 
8
 */
9
10
/**
11
 * Provides utility methods dealing with PHP arrays which do not use WordPress functions.
12
 *
13
 * Listed methods are to modify array contents.
14
 * 
15
 * @since       DEVVER
16
 * @package     AdminPageFramework
17
 * @extends     AdminPageFramework_Utility_String
18
 * @subpackage  Utility
19
 * @internal
20
 */
21
abstract class AdminPageFramework_Utility_ArraySetter extends AdminPageFramework_Utility_ArrayGetter {
1 ignored issue
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
22
 
23
    /**
24
     * Calculates the subtraction of two values with the array key of `order`.
25
     * 
26
     * This is used to sort arrays.
27
     * 
28
     * @since       2.0.0
29
     * @since       3.0.0       Moved from the property class.
30
     * @since       3.3.1       Moved from `AdminPageFramework_Base`.
31
     * @since       3.6.0       Moved from `AdminPageFramework_Router`.
32
     * @since       DVVER       Moved from `AdminPageFramework_Utility`.
33
     * @remark      a callback method for `uasort()`.
34
     * @return      integer
35
     * @internal
36
     */        
37
    static public function sortArrayByKey( $a, $b, $sKey='order' ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
38
        return isset( $a[ $sKey ], $b[ $sKey ] )
39
            ? $a[ $sKey ] - $b[ $sKey ]
40
            : 1;
41
    }
42
 
43
    /**
44
     * Unsets an element of a multi-dimensional array by given keys.
45
     * 
46
     * <code>
47
     * $a = array(
48
     *  'a' => array(
49
     *      'b' => array(
50
     *          'c' => array(
51
     *              'd' => array(
52
     *                  'e' => 'eee',
53
     *              ),
54
     *          ),
55
     *      ),
56
     *  ),
57
     *  );
58
     *  $aKeys = array( 'a', 'b', 'c' );
59
     *  unsetDimensionalArrayElement( $a, $aKeys );
60
     *  var_dump( $a );
61
     * </code>
62
     * Will produce
63
     * <code>
64
     * array(
65
     *  'a' => array(
66
     *      'b' => array(
67
     *      )
68
     *  )
69
     * )
70
     * </code>
71
     * 
72
     * @remark      Introduced for resetting options with dimensional keys.
73
     * @since       3.5.3
74
     * @since       DVVER       Moved from `AdminPageFramework_Utility_Array`.
75
     * @return      void
76
     */
77
    static public function unsetDimensionalArrayElement( &$mSubject, array $aKeys ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
78
        
79
        $_sKey = array_shift( $aKeys );
80
        if ( ! empty( $aKeys ) ) {
81
            if ( isset( $mSubject[ $_sKey ] ) && is_array( $mSubject[ $_sKey ] ) ) {
82
                self::unsetDimensionalArrayElement( $mSubject[ $_sKey ], $aKeys );
83
            }
84
            return;            
85
        }
86
        if ( is_array( $mSubject ) ) {
87
            unset( $mSubject[ $_sKey ] );
88
        }
89
        
90
    }
91
    
92
    /**
93
     * Sets a dimensional array value by dimensional array key path.
94
     * @since       3.5.3
95
     * @since       DVVER       Moved from `AdminPageFramework_Utility_Array`.
96
     * @return      void
97
     */
98
    static public function setMultiDimensionalArray( &$mSubject, array $aKeys, $mValue ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
99
100
        $_sKey = array_shift( $aKeys );
101
        if ( ! empty( $aKeys ) ) {
102
            if( ! isset( $mSubject[ $_sKey ] ) || ! is_array( $mSubject[ $_sKey ] ) ) {
103
                $mSubject[ $_sKey ] = array();
104
            }
105
            self::setMultiDimensionalArray( $mSubject[ $_sKey ], $aKeys, $mValue );
106
            return;
107
            
108
        }
109
        $mSubject[ $_sKey ] = $mValue;
110
111
    }     
112
 
113
    /**
114
     * Reconstructs the given array by numerizing the keys. 
115
     * 
116
     * @since       3.0.0
117
     * @since       3.5.3       Added a type hint in the first parameter.
118
     * @since       DVVER       Moved from `AdminPageFramework_Utility_Array`.
119
     * @return      array       The passed array structure looks like this.
120
     * <code>
121
     *   array( 
122
     *      0 => array(
123
     *          'field_id_1' => array( ... ),
124
     *          'field_id_2' => array( ... ),
125
     *      ), 
126
     *      1 => array(
127
     *          'field_id_1' => array( ... ),
128
     *          'field_id_2' => array( ... ),
129
     *      ),
130
     *      'field_id_1' => array( ... ),
131
     *      'field_id_2' => array( ... ),
132
     *   )
133
     * </code>
134
     * It will be converted to to
135
     * <code>
136
     *   array(
137
     *      0 => array(
138
     *          'field_id_1' => array( ... ),
139
     *          'field_id_2' => array( ... ),
140
     *      ), 
141
     *      1 => array(
142
     *          'field_id_1' => array( ... ),
143
     *          'field_id_2' => array( ... ),
144
     *      ),     
145
     *      2 => array(
146
     *          'field_id_1' => array( ... ),
147
     *          'field_id_2' => array( ... ),
148
     *      ),
149
     *   )
150
     * </code>
151
     */
152
    static public function numerizeElements( array $aSubject ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
153
154
        $_aNumeric      = self::getIntegerKeyElements( $aSubject );
155
        $_aAssociative  = self::invertCastArrayContents( $aSubject, $_aNumeric );
156
        foreach( $_aNumeric as &$_aElem ) {
157
            $_aElem = self::uniteArrays( $_aElem, $_aAssociative );
158
        }
159
        if ( ! empty( $_aAssociative ) ) {
160
            array_unshift( $_aNumeric, $_aAssociative ); // insert the main section to the beginning of the array.
161
        }
162
        return $_aNumeric;
163
        
164
    }
165
 
166
    /**
167
     * Casts array contents into another while keeping the same key structure.
168
     * 
169
     * @since       3.0.0
170
     * @since       3.5.3       Added type hints to the parameter.
171
     * @since       DVVER       Moved from `AdminPageFramework_Utility_Array`.
172
     * @remark      It does not check key structure deeper than or equal to the second dimension.
173
     * @remark      If a key exists in the passed model array but does not exists in the subject array, 
174
     * a `null` value will be assigned to the resulting array.
175
     * @param       array       $aModel         the array that holds the necessary keys.
176
     * @param       array       $aSubject       the array from which the contents to be extracted.
177
     * @return      array       the extracted array contents with the keys of the model array.
178
     */
179
    public static function castArrayContents( array $aModel, array $aSubject ) {
180
        
181
        $_aCast = array();
182
        foreach( $aModel as $_isKey => $_v ) {
183
            $_aCast[ $_isKey ] = self::getElement(
184
                $aSubject,  // subject array
185
                $_isKey,    // key
186
                null        // default
187
            );                 
188
        }
189
        return $_aCast;
190
        
191
    }
192
    
193
    /**
194
     * Returns an array consisting of keys which don't exist in the other.
195
     * 
196
     * @since       3.0.0
197
     * @since       DVVER       Moved from `AdminPageFramework_Utility_Array`.
198
     * @remark      It won't check key structure deeper than or equal to the second dimension.
199
     * @param       array     $aModel       the array that holds the necessary keys.
200
     * @param       array     $aSubject     the array from which the contents to be extracted.
201
     * @return      array     the extracted array contents with the keys that do not exist in the model array.
202
     */
203
    public static function invertCastArrayContents( array $aModel, array $aSubject ) {
204
        
205
        $_aInvert = array();
206
        foreach( $aModel as $_isKey => $_v ) {
207
            if ( array_key_exists( $_isKey, $aSubject ) ) { 
208
                continue; 
209
            }
210
            $_aInvert[ $_isKey ] = $_v;
211
        }
212
        return $_aInvert;
213
        
214
    }
215
    
216
    /**
217
     * Merges multiple multi-dimensional arrays recursively.
218
     * 
219
     * The advantage of using this method over the array unite operator or `array_merge() is 
220
     * that it merges recursively and the null values of the preceding array will be overridden.
221
     * 
222
     * @since       2.1.2
223
     * @since       DVVER       Moved from `AdminPageFramework_Utility_Array`.
224
     * @static
225
     * @access      public
226
     * @remark      The parameters are variadic and can add arrays as many as necessary.
227
     * @return      array     the united array.
228
     */
229
    public static function uniteArrays( /* $aPrecedence, $aArray1, $aArray2, ... */ ) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
230
                
231
        $_aArray = array();
232
        foreach( array_reverse( func_get_args() ) as $_aArg ) {
233
            $_aArray = self::uniteArraysRecursive( 
234
                self::getAsArray( $_aArg ), 
235
                $_aArray 
236
            );
237
        }
238
        return $_aArray;
239
        
240
    }
241
    
242
    /**
243
     * Merges two multi-dimensional arrays recursively.
244
     * 
245
     * The first parameter array takes its precedence. This is useful to merge default option values. 
246
     * An alternative to `array_replace_recursive()` which is not available PHP 5.2.x or below.
247
     * 
248
     * @since       2.0.0
249
     * @since       2.1.5       Changed the visibility scope to `static`. 
250
     * @since       DVVER       Moved from `AdminPageFramework_Utility_Array`.
251
     * @access      public
252
     * @remark      null values will be overwritten.     
253
     * @param       array     the array that overrides the same keys.
254
     * @param       array     the array that is going to be overridden.
255
     * @return      array     the united array.
256
     */ 
257
    public static function uniteArraysRecursive( $aPrecedence, $aDefault ) {
258
                
259
        if ( is_null( $aPrecedence ) ) { 
260
            $aPrecedence = array(); 
261
        }
262
        
263
        if ( ! is_array( $aDefault ) || ! is_array( $aPrecedence ) ) { 
264
            return $aPrecedence; 
265
        }
266
            
267
        foreach( $aDefault as $sKey => $v ) {
268
            
269
            // If the precedence does not have the key, assign the default's value.
270
            if ( ! array_key_exists( $sKey, $aPrecedence ) || is_null( $aPrecedence[ $sKey ] ) ) {
271
                $aPrecedence[ $sKey ] = $v;
272
            } else {
273
                
274
                // if the both are arrays, do the recursive process.
275
                if ( is_array( $aPrecedence[ $sKey ] ) && is_array( $v ) ) {
276
                    $aPrecedence[ $sKey ] = self::uniteArraysRecursive( $aPrecedence[ $sKey ], $v );     
277
                }
278
            
279
            }
280
        }
281
        return $aPrecedence;     
282
    }
283
 
284
    /**
285
     * Removes array elements by the specified type.
286
     * 
287
     * @since       3.3.1
288
     * @since       DVVER       Moved from `AdminPageFramework_Utility_Array`.
289
     * @param       array       $aArray     The subject array to parse.
290
     * @param       array       $aTypes     The value types to drop. The supported types are the followings.
291
     *  - boolean
292
     *  - integer
293
     *  - double
294
     *  - string
295
     *  - array 
296
     *  - object
297
     *  - resource
298
     *  - NULL
299
     * @return      array       The modified array.
300
     */
301
    static public function dropElementsByType( array $aArray, $aTypes=array( 'array' ) ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
302
        
303
        foreach( $aArray as $isKey => $vValue ) {
304
            if ( in_array( gettype( $vValue ), $aTypes ) ) {
305
                unset( $aArray[ $isKey ] );
306
            }
307
        }
308
        return $aArray;
309
    }
310
    
311
    /**
312
     * Removes an array element(s) by the given value.
313
     * @since       3.4.0
314
     * @since       DVVER       Moved from `AdminPageFramework_Utility_Array`.
315
     * @return      array       The modified array.
316
     */
317
    static public function dropElementByValue( array $aArray, $vValue ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
318
         
319
        foreach( self::getAsArray( $vValue, true ) as $_vValue ) {
320
            $_sKey = array_search( $_vValue, $aArray, true );
321
            if ( $_sKey === false ) {
322
                continue;
323
            }
324
            unset( $aArray[ $_sKey ] );
325
        }
326
        return $aArray;
327
        
328
    }
329
    
330
    /**
331
     * Removes given keys from the array.
332
     * 
333
     * This is used to drop unnecessary keys for a multidimensional array as multidimensinal arrays can cause PHP warnings used with `array_diff()`.
334
     * 
335
     * @since       3.4.6
336
     * @since       DVVER       Moved from `AdminPageFramework_Utility_Array`.
337
     * @return      array       The modified array.
338
     */
339
    static public function dropElementsByKey( array $aArray, $asKeys ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
340
        
341
        foreach( self::getAsArray( $asKeys, true ) as $_isKey ) {
342
            unset( $aArray[ $_isKey ] );
343
        }
344
        return $aArray;
345
        
346
    }  
347
   
348
}