Completed
Branch dev (a5fbd1)
by Michael
05:49
created

AdminPageFramework_Debug_Base::_getCallableName()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 4
nop 1
dl 0
loc 15
rs 9.2
c 0
b 0
f 0
1
<?php
2
/**
3
 * Admin Page Framework
4
 * 
5
 * http://en.michaeluno.jp/admin-page-framework/
6
 * Copyright (c) 2013-2016 Michael Uno; Licensed MIT
7
 * 
8
 */
9
10
/**
11
 * A base class of the debug class.
12
 * 
13
 * Mainly provides methods for debug outputs.
14
 * 
15
 * @since           3.8.9
16
 * @extends         AdminPageFramework_FrameworkUtility
17
 * @package         AdminPageFramework
18
 * @subpackage      Common/Utility
19
 */
20
class AdminPageFramework_Debug_Base extends AdminPageFramework_FrameworkUtility {
21
22
    /**
23
     * Returns a legible value representation with value details.
24
     * @since       3.8.9
25
     * @return      string
26
     */
27
    static protected function _getLegibleDetails( $mValue ) {                
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
28
        if ( is_array( $mValue ) ) {            
29
            return '(array, length: ' . count( $mValue ).') ' 
30
                . print_r( self::_getLegibleArray( $mValue ) , true );
31
        }
32
        return print_r( self::_getLegibleValue( $mValue ), true );
33
    }
34
    
35
    /**
36
     * Returns a string representation of the given value.
37
     * @since       3.8.9
38
     * @return      string
39
     */
40
    static protected function _getLegible( $mValue ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
41
        
42
        $mValue = is_object( $mValue )
43
            ? ( method_exists( $mValue, '__toString' ) 
44
                ? ( string ) $mValue          // cast string
45
                : ( array ) $mValue           // cast array
46
            )
47
            : $mValue;
48
        $mValue = is_array( $mValue )
49
            ? self::_getArrayMappedRecursive( 
50
                self::_getSlicedByDepth( $mValue, 10 ), 
51
                array( __CLASS__, '_getObjectName' ) 
52
            )
53
            : $mValue;
54
        return self::_getArrayRepresentationSanitized( print_r( $mValue, true ) );
55
        
56
    }
57
    
58
        /**
59
         * Returns a object name if it is an object. Otherwise, the value itself.
60
         * This is used to convert objects into a string in array-walk functions 
61
         * as objects tent to get large when they are converted to a string representation.
62
         * @since       3.8.9
63
         */
64
        static private function _getObjectName( $mItem ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
65
            if ( is_object( $mItem ) ) {
66
                return '(object) ' . get_class( $mItem );
67
            }
68
            return $mItem;
69
        }
70
                
71
        /**
72
         * @since       3.8.9
73
         * @param       callable     $asoCallable
74
         * @return      string
75
         */
76
        static private function _getLegibleCallable( $asoCallable ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
77
            return '(callable) ' . self::_getCallableName( $asoCallable );    
78
        }       
79
            /**
80
             * @since       3.8.9
81
             * @param       callable     $asoCallable
82
             * @return      string
83
             */
84
            static public function _getCallableName( $asoCallable ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
85
                
86
                if ( is_string( $asoCallable ) ) {
87
                    return $asoCallable;
88
                }
89
                if ( is_object( $asoCallable ) ) {
90
                    return get_class( $asoCallable );
91
                }
92
                $_sSubject = is_object( $asoCallable[ 0 ] )
93
                    ? get_class( $asoCallable[ 0 ] )
94
                    : ( string ) $asoCallable[ 0 ];
95
96
                return $_sSubject . '::' . ( string ) $asoCallable[ 1 ];
97
                
98
            }
99
            
100
        /**
101
         * @since       3.8.9
102
         * @param       object      $oObject
103
         * @return      string
104
         */
105
        static public function _getLegibleObject( $oObject ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
106
                        
107
            if ( method_exists( $oObject, '__toString' ) ) {
108
                return ( string ) $oObject;
109
            }
110
            return '(object) ' . get_class( $oObject ) . ' ' 
111
                . count( get_object_vars( $oObject ) ) . ' properties.';
112
            
113
        } 
114
        /**
115
         * Returns an array representation with value types in each element.
116
         * The element deeper than 10 dimensions will be dropped.
117
         * @since       3.8.9
118
         * @return      array
119
         */
120
        static public function _getLegibleArray( array $aArray ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
121
            return self::_getArrayMappedRecursive( 
122
                self::_getSlicedByDepth( $aArray, 10 ), 
123
                array( __CLASS__, '_getLegibleValue' ) 
124
            );
125
        }
126
            /**
127
             * @since       3.8.9
128
             * @return      string
129
             */
130
            static private function _getLegibleValue( $mItem ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
131
                if ( is_callable( $mItem ) ) {
132
                    return self::_getLegibleCallable( $mItem );
133
                }
134
                return is_scalar( $mItem ) 
135
                    ? self::_getLegibleScalar( $mItem )
136
                    : self::_getLegibleNonScalar( $mItem );
137
            }
138
                /**
139
                 * @since       3.8.9
140
                 * @return      string
141
                 */
142
                static private function _getLegibleNonScalar( $mNonScalar ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
143
                    
144
                    $_sType = gettype( $mNonScalar );
145
                    if ( is_null( $mNonScalar ) ) {
146
                        return '(null)';
147
                    }                    
148
                    if ( is_object( $mNonScalar ) ) {
149
                        return '(' . $_sType . ') ' . get_class( $mNonScalar );
150
                    }
151
                    if ( is_array( $mNonScalar ) ) {
152
                        return '(' . $_sType . ') ' . count( $mNonScalar ) . ' elements';
153
                    }
154
                    return '(' . $_sType . ') ' . ( string ) $mNonScalar;
155
                    
156
                }
157
                /**
158
                 * @return      string
159
                 * @param       scalar      $sScalar        
160
                 * @since       3.8.9
161
                 */
162
                static private function _getLegibleScalar( $sScalar ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
163
                 
164
                    if ( is_bool( $sScalar ) ) {
165
                        return '(boolean) ' . ( $sScalar ? 'true' : 'false' );
166
                    }                 
167
                    return is_string( $sScalar )
168
                        ? self::_getLegibleString( $sScalar )
169
                        : '(' . gettype( $sScalar ) . ', length: ' . self::_getValueLength( $sScalar ) .  ') ' . $sScalar;
170
                }
171
                    /**
172
                     * Returns a length of a value.
173
                     * @since       3.5.3
174
                     * @internal
175
                     * @return      integer|null        For string or integer, the string length. For array, the element lengths. For other types, null.
176
                     */
177
                    static private function _getValueLength( $mValue ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
178
                        $_sVariableType = gettype( $mValue );
179
                        if ( in_array( $_sVariableType, array( 'string', 'integer' ) ) ) {
180
                            return strlen( $mValue );
181
                        }
182
                        if ( 'array' === $_sVariableType ) {
183
                            return count( $mValue );
184
                        }
185
                        return null;
186
                        
187
                    }                
188
                    /**
189
                     * @param       string      $sString        
190
                     * @param       integer     $iCharLimit     Character length limit to truncate.
191
                     * @return      string
192
                     */
193
                    static private function _getLegibleString( $sString, $iCharLimit=200 ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
194
                    
195
                        static $_iMBSupport;
196
                        $_iMBSupport    = isset( $_iMBSupport ) ? $_iMBSupport : ( integer ) function_exists( 'mb_strlen' );
197
                        $_aStrLenMethod = array( 'strlen', 'mb_strlen' );
198
                        $_aSubstrMethod = array( 'substr', 'mb_substr' );
199
                        
200
                        $_iCharLength   = call_user_func_array( $_aStrLenMethod[ $_iMBSupport ], array( $sString ) );
201
                        return $_iCharLength <= $iCharLimit
202
                            ? '(string, length: ' . $_iCharLength . ') ' . $sString
203
                            : '(string, length: ' . $_iCharLength . ') ' . call_user_func_array( $_aSubstrMethod[ $_iMBSupport ], array( $sString, 0, $iCharLimit ) )
204
                                . '...';
205
                        
206
                    }
207
208
    /**
209
     * @return      string
210
     * @since       3.8.9
211
     */
212
    static protected function _getArrayRepresentationSanitized( $sString ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
213
        
214
        // Fix extra line breaks after `Array()`
215
        $sString = preg_replace(
216
            '/\)(\r\n?|\n)(?=(\r\n?|\n)\s+[\[\)])/', // needle                   
217
            ')', // replacement
218
            $sString // subject
219
        );            
220
        
221
        // Fix empty array output 
222
        $sString = preg_replace(
223
            '/Array(\r\n?|\n)\s+\((\r\n?|\n)\s+\)/', // needle   
224
            'Array()', // replacement
225
            $sString // subject
226
        );
227
        return $sString;
228
        
229
    }
230
231
    /**
232
     * Slices an array by the given depth.
233
     * 
234
     * @since       3.4.4
235
     * @since       3.8.9       Changed it not to convert an object into an array. 
236
     * @since       3.8.9       Changed the scope to private.
237
     * @since       3.8.9       Renamed from `getSliceByDepth()`.
238
     * @return      array
239
     * @internal
240
     */
241
    static private function _getSlicedByDepth( array $aSubject, $iDepth=0 ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
242
243
        foreach ( $aSubject as $_sKey => $_vValue ) {
244
            if ( is_array( $_vValue ) ) {
245
                $_iDepth = $iDepth;
246
                if ( $iDepth > 0 ) {
247
                    $aSubject[ $_sKey ] = self::_getSlicedByDepth( $_vValue, --$iDepth );
248
                    $iDepth = $_iDepth;
249
                    continue;
250
                } 
251
                unset( $aSubject[ $_sKey ] );
252
            }
253
        }
254
        return $aSubject;
255
        
256
    }
257
            
258
    /**
259
     * Performs `array_map()` recursively.
260
     * @return      array
261
     * @since       3.8.9
262
     */
263
    static private function _getArrayMappedRecursive( array $aArray, $oCallable ) {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
264
        
265
        self::$_oCurrentCallableForArrayMapRecursive = $oCallable;
266
        $_aArray = array_map( array( __CLASS__, '_getArrayMappedNested' ), $aArray );
267
        self::$_oCurrentCallableForArrayMapRecursive = null;
268
        return $_aArray;
269
        
270
    }
271
        static private $_oCurrentCallableForArrayMapRecursive;
272
        /**
273
         * @internal
274
         * @return      mixed       A modified value.
275
         * @since       3.8.9
276
         */
277
        static private function _getArrayMappedNested( $mItem ) {            
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
278
            return is_array( $mItem ) 
279
                ? array_map( array( __CLASS__, '_getArrayMappedNested' ), $mItem ) 
280
                : call_user_func( self::$_oCurrentCallableForArrayMapRecursive, $mItem );            
281
        }   
282
 
283
}
284