PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/sebastian/global-state/src/Snapshot.php

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