Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
StaticProperties.php
Go to the documentation of this file.
1 <?php
11 
14 
16 {
24  protected static $_cleanableFolders = [
25  '/dev/tests/integration/framework' => [],
26  ];
27 
28  protected static $backupStaticVariables = [];
29 
35  protected static $_classesToSkip = [
36  \Magento\Framework\App\ObjectManager::class,
37  \Magento\TestFramework\Helper\Bootstrap::class,
38  \Magento\TestFramework\Event\Magento::class,
39  \Magento\TestFramework\Event\PhpUnit::class,
40  \Magento\TestFramework\Annotation\AppIsolation::class,
41  \Magento\TestFramework\Workaround\Cleanup\StaticProperties::class,
42  \Magento\Framework\Phrase::class,
43  ];
44 
48  public function __construct()
49  {
52  foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
53  $key = $moduleDir . '/';
54  $value = $key . 'Test/Unit/';
55  self::$_cleanableFolders[$key] = [$value];
56  }
57  foreach ($componentRegistrar->getPaths(ComponentRegistrar::LIBRARY) as $libraryDir) {
58  $key = $libraryDir . '/';
59  $valueRootFolder = $key . '/Test/Unit/';
60  $valueSubFolder = $key . '/*/Test/Unit/';
61  self::$_cleanableFolders[$key] = [$valueSubFolder, $valueRootFolder];
62  }
63  }
64 
71  protected static function _isClassCleanable(\ReflectionClass $reflectionClass)
72  {
73  // do not process blacklisted classes from integration framework
74  foreach (self::$_classesToSkip as $notCleanableClass) {
75  if ($reflectionClass->getName() == $notCleanableClass || is_subclass_of(
76  $reflectionClass->getName(),
77  $notCleanableClass
78  )
79  ) {
80  return false;
81  }
82  }
83  return true;
84  }
85 
92  protected static function _isClassInCleanableFolders($classFile)
93  {
94  $classFile = str_replace('\\', '/', $classFile);
95  foreach (self::$_cleanableFolders as $include => $excludeSet) {
96  if (stripos($classFile, $include) !== false) {
97  foreach ($excludeSet as $exclude) {
98  $excludeExp = '#' . str_replace('*', '[\w]+', $exclude) . '#';
99  if (preg_match($excludeExp, $classFile)) {
100  return false; // File is in an "include" directory, but also an "exclude" subdirectory of it
101  }
102  }
103  return true; // File is in an "include" directory, and not in an "exclude" subdirectory of it
104  }
105  }
106  return false; // File is not in an "include" directory
107  }
108 
112  protected static $classes = [];
113 
118  private static function getReflectionClass($class)
119  {
120  if (!isset(self::$classes[$class])) {
121  self::$classes[$class] = new \ReflectionClass($class);
122  }
123  return self::$classes[$class];
124  }
125 
130  public static function restoreStaticVariables()
131  {
132  foreach (array_keys(self::$backupStaticVariables) as $class) {
133  $reflectionClass = self::getReflectionClass($class);
134  $staticProperties = $reflectionClass->getProperties(\ReflectionProperty::IS_STATIC);
135  foreach ($staticProperties as $staticProperty) {
136  $staticProperty->setAccessible(true);
137  $staticProperty->setValue(self::$backupStaticVariables[$class][$staticProperty->getName()]);
138  }
139  }
140  }
141 
146  public static function backupStaticVariables()
147  {
148  if (count(self::$backupStaticVariables) > 0) {
149  return;
150  }
151  $classFiles = array_filter(
152  Files::init()->getPhpFiles(
156  ),
157  function ($classFile) {
159  && strpos(file_get_contents($classFile), ' static ') > 0;
160  }
161  );
162  $namespacePattern = '/namespace [a-zA-Z0-9\\\\]+;/';
163  $classPattern = '/\nclass [a-zA-Z0-9_]+/';
164  foreach ($classFiles as $classFile) {
165  $code = file_get_contents($classFile);
166  preg_match($namespacePattern, $code, $namespace);
167  preg_match($classPattern, $code, $class);
168  if (!isset($namespace[0]) || !isset($class[0])) {
169  continue;
170  }
171  // trim namespace and class name
172  $namespace = substr($namespace[0], 10, strlen($namespace[0]) - 11);
173  $class = substr($class[0], 7, strlen($class[0]) - 7);
174  $className = $namespace . '\\' . $class;
175 
176  try {
177  $reflectionClass = self::getReflectionClass($className);
178  } catch (\Exception $e) {
179  continue;
180  }
181  if (self::_isClassCleanable($reflectionClass)) {
182  $staticProperties = $reflectionClass->getProperties(\ReflectionProperty::IS_STATIC);
183  foreach ($staticProperties as $staticProperty) {
184  $staticProperty->setAccessible(true);
185  $value = $staticProperty->getValue();
186  self::$backupStaticVariables[$className][$staticProperty->getName()] = $value;
187  }
188  }
189  }
190  }
191 
196  public function startTestSuite()
197  {
198  if (empty(self::$backupStaticVariables)) {
200  }
201  }
202 
208  public function endTestSuite(\PHPUnit\Framework\TestSuite $suite)
209  {
210  $clearStatics = false;
211  foreach ($suite->tests() as $test) {
212  if ($test instanceof \Magento\TestFramework\TestCase\AbstractController) {
213  $clearStatics = true;
214  break;
215  }
216  }
217  if ($clearStatics) {
219  }
220  }
221 }
$componentRegistrar
Definition: bootstrap.php:23
is_subclass_of($obj, $className)
$_option $_optionId $class
Definition: date.phtml:13
$value
Definition: gender.phtml:16
$reflectionClass
Definition: categories.php:25
static _isClassCleanable(\ReflectionClass $reflectionClass)
$code
Definition: info.phtml:12
if($currentSelectedMethod==$_code) $className
Definition: form.phtml:31