Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Classes.php
Go to the documentation of this file.
1 <?php
9 
11 
12 class Classes
13 {
19  protected static $_virtualClasses = [];
20 
29  public static function getAllMatches($contents, $regex, &$result = [])
30  {
31  preg_match_all($regex, $contents, $matches);
32 
33  array_shift($matches);
34  foreach ($matches as $row) {
35  $result = array_merge($result, $row);
36  }
37  $result = array_filter(
38  array_unique($result),
39  function ($value) {
40  return !empty($value);
41  }
42  );
43  return $result;
44  }
45 
55  public static function getXmlNodeValues(\SimpleXMLElement $xml, $xPath)
56  {
57  $result = [];
58  $nodes = $xml->xpath($xPath) ?: [];
59  foreach ($nodes as $node) {
60  $result[] = (string)$node;
61  }
62  return $result;
63  }
64 
72  public static function getXmlNodeNames(\SimpleXMLElement $xml, $xpath)
73  {
74  $result = [];
75  $nodes = $xml->xpath($xpath) ?: [];
76  foreach ($nodes as $node) {
77  $result[] = $node->getName();
78  }
79  return $result;
80  }
81 
90  public static function getXmlAttributeValues(\SimpleXMLElement $xml, $xPath, $attributeName)
91  {
92  $result = [];
93  $nodes = $xml->xpath($xPath) ?: [];
94  foreach ($nodes as $node) {
95  $node = (array)$node;
96  if (isset($node['@attributes'][$attributeName])) {
97  $result[] = $node['@attributes'][$attributeName];
98  }
99  }
100  return $result;
101  }
102 
109  public static function getCallbackClass($callbackName)
110  {
111  $class = explode('::', $callbackName);
112  return $class[0];
113  }
114 
121  public static function collectClassesInConfig(\SimpleXMLElement $xml)
122  {
123  // @todo this method must be refactored after implementation of MAGETWO-7689 (valid configuration)
124  $classes = self::getXmlNodeValues(
125  $xml,
126  '
127  /config//resource_adapter | /config/*[not(name()="sections")]//class[not(ancestor::observers)]
128  | //model[not(parent::connection)] | //backend_model | //source_model | //price_model
129  | //model_token | //writer_model | //clone_model | //frontend_model | //working_model
130  | //admin_renderer | //renderer | /config/*/di/preferences/*'
131  );
132  $classes = array_merge($classes, self::getXmlAttributeValues($xml, '//@backend_model', 'backend_model'));
133  $classes = array_merge(
134  $classes,
135  self::getXmlNodeNames(
136  $xml,
137  '/logging/*/expected_models/* | /logging/*/actions/*/expected_models/* | /config/*/di/preferences/*'
138  )
139  );
140 
141  $classes = array_map([\Magento\Framework\App\Utility\Classes::class, 'getCallbackClass'], $classes);
142  $classes = array_map('trim', $classes);
143  $classes = array_unique($classes);
144  $classes = array_filter(
145  $classes,
146  function ($value) {
147  return !empty($value);
148  }
149  );
150 
151  return $classes;
152  }
153 
160  public static function collectLayoutClasses(\SimpleXMLElement $xml)
161  {
162  $classes = self::getXmlAttributeValues($xml, '/layout//block[@class]', 'class');
163  $classes = array_merge(
164  $classes,
165  self::getXmlNodeValues(
166  $xml,
167  '/layout//action/attributeType | /layout//action[@method="addTab"]/content
168  | /layout//action[@method="addMergeSettingsBlockType"
169  or @method="addInformationRenderer"
170  or @method="addDatabaseBlock"]/*[2]
171  | /layout//action[@method="setMassactionBlockName"]/name
172  | /layout//action[@method="setEntityModelClass"]/code'
173  )
174  );
175  return array_unique($classes);
176  }
177 
187  public static function collectModuleClasses($subTypePattern = '[A-Za-z]+')
188  {
190  $result = [];
191  foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $modulePath) {
192  $pattern = '/^' . preg_quote($modulePath, '/') . '\/(' . $subTypePattern . '\/.+)\.php$/';
193  foreach (Files::init()->getFiles([$modulePath], '*.php') as $file) {
194  if (preg_match($pattern, $file)) {
195  $partialFileName = substr($file, strlen($modulePath) + 1);
196  $partialFileName = substr($partialFileName, 0, strlen($partialFileName) - strlen('.php'));
197  $partialClassName = str_replace('/', '\\', $partialFileName);
198  $className = str_replace('_', '\\', $moduleName) . '\\' . $partialClassName;
199  $result[$className] = $moduleName;
200  }
201  }
202  }
203  return $result;
204  }
205 
211  public static function getVirtualClasses()
212  {
213  if (!empty(self::$_virtualClasses)) {
214  return self::$_virtualClasses;
215  }
216  $configFiles = Files::init()->getDiConfigs();
217  foreach ($configFiles as $fileName) {
218  $configDom = new \DOMDocument();
219  $configDom->load($fileName);
220  $xPath = new \DOMXPath($configDom);
221  $vTypes = $xPath->query('/config/virtualType');
223  foreach ($vTypes as $virtualType) {
224  $name = $virtualType->attributes->getNamedItem('name')->textContent;
225  if (!$virtualType->attributes->getNamedItem('type')) {
226  continue;
227  }
228  $type = $virtualType->attributes->getNamedItem('type')->textContent;
229  self::$_virtualClasses[$name] = $type;
230  }
231  }
232 
233  return self::$_virtualClasses;
234  }
235 
242  public static function isVirtual($className)
243  {
244  //init virtual classes if necessary
245  self::getVirtualClasses();
246 
247  return array_key_exists($className, self::$_virtualClasses);
248  }
249 
256  public static function resolveVirtualType($className)
257  {
258  if (false == self::isVirtual($className)) {
259  return $className;
260  }
261 
262  $resolvedName = self::$_virtualClasses[$className];
263  return self::resolveVirtualType($resolvedName);
264  }
265 
272  public static function isAutogenerated($className)
273  {
274  if (preg_match(
275  '/.*\\\\[a-zA-Z0-9]{1,}(Factory|SearchResults|DataBuilder|Extension|ExtensionInterface)$/',
276  $className
277  )
278  || preg_match('/Magento\\\\[\w]+\\\\(Test\\\\(Page|Fixture))\\\\/', $className)
279  || preg_match('/.*\\\\[a-zA-Z0-9]{1,}\\\\Proxy$/', $className)
280  ) {
281  return true;
282  }
283 
284  return false;
285  }
286 
294  public static function collectPhpCodeClasses($contents, &$classes = [])
295  {
297  $contents,
298  '/
299  # ::getModel ::getSingleton ::getResourceModel ::getResourceSingleton
300  \:\:get(?:Resource)?(?:Model | Singleton)\(\s*[\'"]([^\'"]+)[\'"]\s*[\),]
301 
302  # addBlock createBlock getBlockSingleton
303  | (?:addBlock | createBlock | getBlockSingleton)\(\s*[\'"]([^\'"]+)[\'"]\s*[\),]
304 
305  # various methods, first argument
306  | \->(?:initReport | setEntityModelClass
307  | setAttributeModel | setBackendModel | setFrontendModel | setSourceModel | setModel
308  )\(\s*[\'"]([^\'"]+)[\'"]\s*[\),]
309 
310  # various methods, second argument
311  | \->add(?:ProductConfigurationHelper | OptionsRenderCfg)\(.+,\s*[\'"]([^\'"]+)[\'"]\s*[\),]
312 
313  # models in install or setup
314  | [\'"](?:resource_model | attribute_model | entity_model | entity_attribute_collection
315  | source | backend | frontend | input_renderer | frontend_input_renderer
316  )[\'"]\s*=>\s*[\'"]([^\'"]+)[\'"]
317 
318  # misc
319  | function\s_getCollectionClass\(\)\s+{\s+return\s+[\'"]([a-z\d_\/]+)[\'"]
320  | (?:_parentResourceModelName | _checkoutType | _apiType)\s*=\s*\'([a-z\d_\/]+)\'
321  | \'renderer\'\s*=>\s*\'([a-z\d_\/]+)\'
322  | protected\s+\$_(?:form|info|backendForm|iframe)BlockType\s*=\s*[\'"]([^\'"]+)[\'"]
323 
324  /Uix',
325  $classes
326  );
327 
328  // check ->_init | parent::_init
329  $skipForInit = implode(
330  '|',
331  [
332  'id',
333  '[\w\d_]+_id',
334  'pk',
335  'code',
336  'status',
337  'serial_number',
338  'entity_pk_value',
339  'currency_code',
340  'unique_key'
341  ]
342  );
344  $contents,
345  '/
346  (?:parent\:\: | \->)_init\(\s*[\'"]([^\'"]+)[\'"]\s*\)
347  | (?:parent\:\: | \->)_init\(\s*[\'"]([^\'"]+)[\'"]\s*,\s*[\'"]((?!(' .
348  $skipForInit .
349  '))[^\'"]+)[\'"]\s*\)
350  /Uix',
351  $classes
352  );
353  return $classes;
354  }
355 
362  public static function getClassModuleName($class)
363  {
364  $parts = explode('\\', trim($class, '\\'));
365  return $parts[0] . '_' . $parts[1];
366  }
367 }
$contents
Definition: website.php:14
$componentRegistrar
Definition: bootstrap.php:23
static resolveVirtualType($className)
Definition: Classes.php:256
$pattern
Definition: website.php:22
static collectPhpCodeClasses($contents, &$classes=[])
Definition: Classes.php:294
static getCallbackClass($callbackName)
Definition: Classes.php:109
static collectClassesInConfig(\SimpleXMLElement $xml)
Definition: Classes.php:121
$type
Definition: item.phtml:13
static getXmlAttributeValues(\SimpleXMLElement $xml, $xPath, $attributeName)
Definition: Classes.php:90
static collectLayoutClasses(\SimpleXMLElement $xml)
Definition: Classes.php:160
$fileName
Definition: translate.phtml:15
$_option $_optionId $class
Definition: date.phtml:13
$value
Definition: gender.phtml:16
static collectModuleClasses($subTypePattern='[A-Za-z]+')
Definition: Classes.php:187
static getAllMatches($contents, $regex, &$result=[])
Definition: Classes.php:29
static isAutogenerated($className)
Definition: Classes.php:272
static getXmlNodeNames(\SimpleXMLElement $xml, $xpath)
Definition: Classes.php:72
static getXmlNodeValues(\SimpleXMLElement $xml, $xPath)
Definition: Classes.php:55
if($currentSelectedMethod==$_code) $className
Definition: form.phtml:31
if(!isset($_GET['name'])) $name
Definition: log.php:14