| 148 |
lars |
1 |
<?php declare(strict_types=1);
|
|
|
2 |
/*
|
|
|
3 |
* This file is part of sebastian/global-state.
|
|
|
4 |
*
|
|
|
5 |
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
|
|
6 |
*
|
|
|
7 |
* For the full copyright and license information, please view the LICENSE
|
|
|
8 |
* file that was distributed with this source code.
|
|
|
9 |
*/
|
|
|
10 |
namespace SebastianBergmann\GlobalState;
|
|
|
11 |
|
|
|
12 |
use function array_diff;
|
|
|
13 |
use function array_key_exists;
|
|
|
14 |
use function array_keys;
|
|
|
15 |
use function array_merge;
|
|
|
16 |
use function function_exists;
|
|
|
17 |
use function get_defined_functions;
|
|
|
18 |
use function in_array;
|
|
|
19 |
use function is_array;
|
|
|
20 |
use ReflectionClass;
|
|
|
21 |
use ReflectionProperty;
|
|
|
22 |
|
|
|
23 |
/**
|
|
|
24 |
* Restorer of snapshots of global state.
|
|
|
25 |
*/
|
|
|
26 |
class Restorer
|
|
|
27 |
{
|
|
|
28 |
/**
|
|
|
29 |
* Deletes function definitions that are not defined in a snapshot.
|
|
|
30 |
*
|
|
|
31 |
* @throws RuntimeException when the uopz_delete() function is not available
|
|
|
32 |
*
|
|
|
33 |
* @see https://github.com/krakjoe/uopz
|
|
|
34 |
*/
|
|
|
35 |
public function restoreFunctions(Snapshot $snapshot): void
|
|
|
36 |
{
|
|
|
37 |
if (!function_exists('uopz_delete')) {
|
|
|
38 |
throw new RuntimeException('The uopz_delete() function is required for this operation');
|
|
|
39 |
}
|
|
|
40 |
|
|
|
41 |
$functions = get_defined_functions();
|
|
|
42 |
|
|
|
43 |
foreach (array_diff($functions['user'], $snapshot->functions()) as $function) {
|
|
|
44 |
uopz_delete($function);
|
|
|
45 |
}
|
|
|
46 |
}
|
|
|
47 |
|
|
|
48 |
/**
|
|
|
49 |
* Restores all global and super-global variables from a snapshot.
|
|
|
50 |
*/
|
|
|
51 |
public function restoreGlobalVariables(Snapshot $snapshot): void
|
|
|
52 |
{
|
|
|
53 |
$superGlobalArrays = $snapshot->superGlobalArrays();
|
|
|
54 |
|
|
|
55 |
foreach ($superGlobalArrays as $superGlobalArray) {
|
|
|
56 |
$this->restoreSuperGlobalArray($snapshot, $superGlobalArray);
|
|
|
57 |
}
|
|
|
58 |
|
|
|
59 |
$globalVariables = $snapshot->globalVariables();
|
|
|
60 |
|
|
|
61 |
foreach (array_keys($GLOBALS) as $key) {
|
|
|
62 |
if ($key !== 'GLOBALS' &&
|
|
|
63 |
!in_array($key, $superGlobalArrays, true) &&
|
|
|
64 |
!$snapshot->excludeList()->isGlobalVariableExcluded($key)) {
|
|
|
65 |
if (array_key_exists($key, $globalVariables)) {
|
|
|
66 |
$GLOBALS[$key] = $globalVariables[$key];
|
|
|
67 |
} else {
|
|
|
68 |
unset($GLOBALS[$key]);
|
|
|
69 |
}
|
|
|
70 |
}
|
|
|
71 |
}
|
|
|
72 |
}
|
|
|
73 |
|
|
|
74 |
/**
|
|
|
75 |
* Restores all static attributes in user-defined classes from this snapshot.
|
|
|
76 |
*/
|
|
|
77 |
public function restoreStaticAttributes(Snapshot $snapshot): void
|
|
|
78 |
{
|
|
|
79 |
$current = new Snapshot($snapshot->excludeList(), false, false, false, false, true, false, false, false, false);
|
|
|
80 |
$newClasses = array_diff($current->classes(), $snapshot->classes());
|
|
|
81 |
|
|
|
82 |
unset($current);
|
|
|
83 |
|
|
|
84 |
foreach ($snapshot->staticAttributes() as $className => $staticAttributes) {
|
|
|
85 |
foreach ($staticAttributes as $name => $value) {
|
|
|
86 |
$reflector = new ReflectionProperty($className, $name);
|
|
|
87 |
$reflector->setAccessible(true);
|
|
|
88 |
$reflector->setValue($value);
|
|
|
89 |
}
|
|
|
90 |
}
|
|
|
91 |
|
|
|
92 |
foreach ($newClasses as $className) {
|
|
|
93 |
$class = new ReflectionClass($className);
|
|
|
94 |
$defaults = $class->getDefaultProperties();
|
|
|
95 |
|
|
|
96 |
foreach ($class->getProperties() as $attribute) {
|
|
|
97 |
if (!$attribute->isStatic()) {
|
|
|
98 |
continue;
|
|
|
99 |
}
|
|
|
100 |
|
|
|
101 |
$name = $attribute->getName();
|
|
|
102 |
|
|
|
103 |
if ($snapshot->excludeList()->isStaticAttributeExcluded($className, $name)) {
|
|
|
104 |
continue;
|
|
|
105 |
}
|
|
|
106 |
|
|
|
107 |
if (!isset($defaults[$name])) {
|
|
|
108 |
continue;
|
|
|
109 |
}
|
|
|
110 |
|
|
|
111 |
$attribute->setAccessible(true);
|
|
|
112 |
$attribute->setValue($defaults[$name]);
|
|
|
113 |
}
|
|
|
114 |
}
|
|
|
115 |
}
|
|
|
116 |
|
|
|
117 |
/**
|
|
|
118 |
* Restores a super-global variable array from this snapshot.
|
|
|
119 |
*/
|
|
|
120 |
private function restoreSuperGlobalArray(Snapshot $snapshot, string $superGlobalArray): void
|
|
|
121 |
{
|
|
|
122 |
$superGlobalVariables = $snapshot->superGlobalVariables();
|
|
|
123 |
|
|
|
124 |
if (isset($GLOBALS[$superGlobalArray]) &&
|
|
|
125 |
is_array($GLOBALS[$superGlobalArray]) &&
|
|
|
126 |
isset($superGlobalVariables[$superGlobalArray])) {
|
|
|
127 |
$keys = array_keys(
|
|
|
128 |
array_merge(
|
|
|
129 |
$GLOBALS[$superGlobalArray],
|
|
|
130 |
$superGlobalVariables[$superGlobalArray]
|
|
|
131 |
)
|
|
|
132 |
);
|
|
|
133 |
|
|
|
134 |
foreach ($keys as $key) {
|
|
|
135 |
if (isset($superGlobalVariables[$superGlobalArray][$key])) {
|
|
|
136 |
$GLOBALS[$superGlobalArray][$key] = $superGlobalVariables[$superGlobalArray][$key];
|
|
|
137 |
} else {
|
|
|
138 |
unset($GLOBALS[$superGlobalArray][$key]);
|
|
|
139 |
}
|
|
|
140 |
}
|
|
|
141 |
}
|
|
|
142 |
}
|
|
|
143 |
}
|