Completed
Push — master ( 95acd7...e70d94 )
by Naveen
13:02 queued 11:07
created

Snapshot::__construct()   F

Complexity

Conditions 12
Paths 1024

Size

Total Lines 45
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 45
rs 2.7855
cc 12
eloc 23
nc 1024
nop 10

How to fix   Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/*
3
 * This file is part of the GlobalState package.
4
 *
5
 * (c) Sebastian Bergmann <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace SebastianBergmann\GlobalState;
12
13
use ReflectionClass;
14
use Serializable;
15
16
/**
17
 * A snapshot of global state.
18
 */
19
class Snapshot
20
{
21
    /**
22
     * @var Blacklist
23
     */
24
    private $blacklist;
25
26
    /**
27
     * @var array
28
     */
29
    private $globalVariables = array();
30
31
    /**
32
     * @var array
33
     */
34
    private $superGlobalArrays = array();
35
36
    /**
37
     * @var array
38
     */
39
    private $superGlobalVariables = array();
40
41
    /**
42
     * @var array
43
     */
44
    private $staticAttributes = array();
45
46
    /**
47
     * @var array
48
     */
49
    private $iniSettings = array();
50
51
    /**
52
     * @var array
53
     */
54
    private $includedFiles = array();
55
56
    /**
57
     * @var array
58
     */
59
    private $constants = array();
60
61
    /**
62
     * @var array
63
     */
64
    private $functions = array();
65
66
    /**
67
     * @var array
68
     */
69
    private $interfaces = array();
70
71
    /**
72
     * @var array
73
     */
74
    private $classes = array();
75
76
    /**
77
     * @var array
78
     */
79
    private $traits = array();
80
81
    /**
82
     * Creates a snapshot of the current global state.
83
     *
84
     * @param Blacklist $blacklist
85
     * @param bool      $includeGlobalVariables
86
     * @param bool      $includeStaticAttributes
87
     * @param bool      $includeConstants
88
     * @param bool      $includeFunctions
89
     * @param bool      $includeClasses
90
     * @param bool      $includeInterfaces
91
     * @param bool      $includeTraits
92
     * @param bool      $includeIniSettings
93
     * @param bool      $includeIncludedFiles
94
     */
95
    public function __construct(Blacklist $blacklist = null, $includeGlobalVariables = true, $includeStaticAttributes = true, $includeConstants = true, $includeFunctions = true, $includeClasses = true, $includeInterfaces = true, $includeTraits = true, $includeIniSettings = true, $includeIncludedFiles = true)
96
    {
97
        if ($blacklist === null) {
98
            $blacklist = new Blacklist;
99
        }
100
101
        $this->blacklist = $blacklist;
102
103
        if ($includeConstants) {
104
            $this->snapshotConstants();
105
        }
106
107
        if ($includeFunctions) {
108
            $this->snapshotFunctions();
109
        }
110
111
        if ($includeClasses || $includeStaticAttributes) {
112
            $this->snapshotClasses();
113
        }
114
115
        if ($includeInterfaces) {
116
            $this->snapshotInterfaces();
117
        }
118
119
        if ($includeGlobalVariables) {
120
            $this->setupSuperGlobalArrays();
121
            $this->snapshotGlobals();
122
        }
123
124
        if ($includeStaticAttributes) {
125
            $this->snapshotStaticAttributes();
126
        }
127
128
        if ($includeIniSettings) {
129
            $this->iniSettings = ini_get_all(null, false);
130
        }
131
132
        if ($includeIncludedFiles) {
133
            $this->includedFiles = get_included_files();
134
        }
135
136
        if (function_exists('get_declared_traits')) {
137
            $this->traits = get_declared_traits();
138
        }
139
    }
140
141
    /**
142
     * @return Blacklist
143
     */
144
    public function blacklist()
145
    {
146
        return $this->blacklist;
147
    }
148
149
    /**
150
     * @return array
151
     */
152
    public function globalVariables()
153
    {
154
        return $this->globalVariables;
155
    }
156
157
    /**
158
     * @return array
159
     */
160
    public function superGlobalVariables()
161
    {
162
        return $this->superGlobalVariables;
163
    }
164
165
    /**
166
     * Returns a list of all super-global variable arrays.
167
     *
168
     * @return array
169
     */
170
    public function superGlobalArrays()
171
    {
172
        return $this->superGlobalArrays;
173
    }
174
175
    /**
176
     * @return array
177
     */
178
    public function staticAttributes()
179
    {
180
        return $this->staticAttributes;
181
    }
182
183
    /**
184
     * @return array
185
     */
186
    public function iniSettings()
187
    {
188
        return $this->iniSettings;
189
    }
190
191
    /**
192
     * @return array
193
     */
194
    public function includedFiles()
195
    {
196
        return $this->includedFiles;
197
    }
198
199
    /**
200
     * @return array
201
     */
202
    public function constants()
203
    {
204
        return $this->constants;
205
    }
206
207
    /**
208
     * @return array
209
     */
210
    public function functions()
211
    {
212
        return $this->functions;
213
    }
214
215
    /**
216
     * @return array
217
     */
218
    public function interfaces()
219
    {
220
        return $this->interfaces;
221
    }
222
223
    /**
224
     * @return array
225
     */
226
    public function classes()
227
    {
228
        return $this->classes;
229
    }
230
231
    /**
232
     * @return array
233
     */
234
    public function traits()
235
    {
236
        return $this->traits;
237
    }
238
239
    /**
240
     * Creates a snapshot user-defined constants.
241
     */
242
    private function snapshotConstants()
243
    {
244
        $constants = get_defined_constants(true);
245
246
        if (isset($constants['user'])) {
247
            $this->constants = $constants['user'];
248
        }
249
    }
250
251
    /**
252
     * Creates a snapshot user-defined functions.
253
     */
254
    private function snapshotFunctions()
255
    {
256
        $functions = get_defined_functions();
257
258
        $this->functions = $functions['user'];
259
    }
260
261
    /**
262
     * Creates a snapshot user-defined classes.
263
     */
264
    private function snapshotClasses()
265
    {
266
        foreach (array_reverse(get_declared_classes()) as $className) {
267
            $class = new ReflectionClass($className);
268
269
            if (!$class->isUserDefined()) {
270
                break;
271
            }
272
273
            $this->classes[] = $className;
274
        }
275
276
        $this->classes = array_reverse($this->classes);
277
    }
278
279
    /**
280
     * Creates a snapshot user-defined interfaces.
281
     */
282
    private function snapshotInterfaces()
283
    {
284
        foreach (array_reverse(get_declared_interfaces()) as $interfaceName) {
285
            $class = new ReflectionClass($interfaceName);
286
287
            if (!$class->isUserDefined()) {
288
                break;
289
            }
290
291
            $this->interfaces[] = $interfaceName;
292
        }
293
294
        $this->interfaces = array_reverse($this->interfaces);
295
    }
296
297
    /**
298
     * Creates a snapshot of all global and super-global variables.
299
     */
300
    private function snapshotGlobals()
301
    {
302
        $superGlobalArrays = $this->superGlobalArrays();
303
304
        foreach ($superGlobalArrays as $superGlobalArray) {
305
            $this->snapshotSuperGlobalArray($superGlobalArray);
306
        }
307
308
        foreach (array_keys($GLOBALS) as $key) {
309
            if ($key != 'GLOBALS' &&
310
                !in_array($key, $superGlobalArrays) &&
311
                $this->canBeSerialized($GLOBALS[$key]) &&
312
                !$this->blacklist->isGlobalVariableBlacklisted($key)) {
313
                $this->globalVariables[$key] = unserialize(serialize($GLOBALS[$key]));
314
            }
315
        }
316
    }
317
318
    /**
319
     * Creates a snapshot a super-global variable array.
320
     *
321
     * @param $superGlobalArray
322
     */
323
    private function snapshotSuperGlobalArray($superGlobalArray)
324
    {
325
        $this->superGlobalVariables[$superGlobalArray] = array();
326
327
        if (isset($GLOBALS[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
328
            foreach ($GLOBALS[$superGlobalArray] as $key => $value) {
329
                $this->superGlobalVariables[$superGlobalArray][$key] = unserialize(serialize($value));
330
            }
331
        }
332
    }
333
334
    /**
335
     * Creates a snapshot of all static attributes in user-defined classes.
336
     */
337
    private function snapshotStaticAttributes()
338
    {
339
        foreach ($this->classes as $className) {
340
            $class    = new ReflectionClass($className);
341
            $snapshot = array();
342
343
            foreach ($class->getProperties() as $attribute) {
344
                if ($attribute->isStatic()) {
345
                    $name = $attribute->getName();
346
347
                    if ($this->blacklist->isStaticAttributeBlacklisted($className, $name)) {
348
                        continue;
349
                    }
350
351
                    $attribute->setAccessible(true);
352
                    $value = $attribute->getValue();
353
354
                    if ($this->canBeSerialized($value)) {
355
                        $snapshot[$name] = unserialize(serialize($value));
356
                    }
357
                }
358
            }
359
360
            if (!empty($snapshot)) {
361
                $this->staticAttributes[$className] = $snapshot;
362
            }
363
        }
364
    }
365
366
    /**
367
     * Returns a list of all super-global variable arrays.
368
     *
369
     * @return array
370
     */
371
    private function setupSuperGlobalArrays()
372
    {
373
        $this->superGlobalArrays = array(
374
            '_ENV',
375
            '_POST',
376
            '_GET',
377
            '_COOKIE',
378
            '_SERVER',
379
            '_FILES',
380
            '_REQUEST'
381
        );
382
383
        if (ini_get('register_long_arrays') == '1') {
384
            $this->superGlobalArrays = array_merge(
385
                $this->superGlobalArrays,
386
                array(
387
                    'HTTP_ENV_VARS',
388
                    'HTTP_POST_VARS',
389
                    'HTTP_GET_VARS',
390
                    'HTTP_COOKIE_VARS',
391
                    'HTTP_SERVER_VARS',
392
                    'HTTP_POST_FILES'
393
                )
394
            );
395
        }
396
    }
397
398
    /**
399
     * @param  mixed $variable
400
     * @return bool
401
     * @todo   Implement this properly
402
     */
403
    private function canBeSerialized($variable)
404
    {
405
        if (!is_object($variable)) {
406
            return !is_resource($variable);
407
        }
408
409
        if ($variable instanceof \stdClass) {
410
            return true;
411
        }
412
413
        $class = new ReflectionClass($variable);
414
415
        do {
416
            if ($class->isInternal()) {
417
                return $variable instanceof Serializable;
418
            }
419
        } while ($class = $class->getParentClass());
420
421
        return true;
422
    }
423
}
424