Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
FileClassScanner.php
Go to the documentation of this file.
1 <?php
8 
10 {
16  private $filename;
17 
23  private $classNames = false;
24 
28  private $tokens;
29 
35  public function __construct($filename)
36  {
37  $filename = realpath($filename);
38  if (!file_exists($filename) || !\is_file($filename)) {
39  throw new InvalidFileException(
40  sprintf(
41  'The file "%s" does not exist or is not a file',
42  $filename
43  )
44  );
45  }
46  $this->filename = $filename;
47  }
48 
54  public function getFileContents()
55  {
56  return file_get_contents($this->filename);
57  }
58 
70  private function extract()
71  {
72  $allowedOpenBraces = [T_CURLY_OPEN, T_DOLLAR_OPEN_CURLY_BRACES, T_STRING_VARNAME];
73  $classes = [];
74  $namespace = '';
75  $class = '';
76  $triggerClass = false;
77  $triggerNamespace = false;
78  $braceLevel = 0;
79  $bracedNamespace = false;
80 
81  $this->tokens = token_get_all($this->getFileContents());
82  foreach ($this->tokens as $index => $token) {
83  // Is either a literal brace or an interpolated brace with a variable
84  if ($token == '{' || (is_array($token) && in_array($token[0], $allowedOpenBraces))) {
85  $braceLevel++;
86  } else if ($token == '}') {
87  $braceLevel--;
88  }
89  // The namespace keyword was found in the last loop
90  if ($triggerNamespace) {
91  // A string ; or a discovered namespace that looks like "namespace name { }"
92  if (!is_array($token) || ($namespace && $token[0] == T_WHITESPACE)) {
93  $triggerNamespace = false;
94  $namespace .= '\\';
95  continue;
96  }
97  $namespace .= $token[1];
98 
99  // The class keyword was found in the last loop
100  } else if ($triggerClass && $token[0] == T_STRING) {
101  $triggerClass = false;
102  $class = $token[1];
103  }
104 
105  switch ($token[0]) {
106  case T_NAMESPACE:
107  // Current loop contains the namespace keyword. Between this and the semicolon is the namespace
108  $triggerNamespace = true;
109  $namespace = '';
110  $bracedNamespace = $this->isBracedNamespace($index);
111  break;
112  case T_CLASS:
113  // Current loop contains the class keyword. Next loop will have the class name itself.
114  if ($braceLevel == 0 || ($bracedNamespace && $braceLevel == 1)) {
115  $triggerClass = true;
116  }
117  break;
118  }
119 
120  // We have a class name, let's concatenate and store it!
121  if ($class != '') {
122  $namespace = trim($namespace);
123  $fqClassName = $namespace . trim($class);
124  $classes[] = $fqClassName;
125  $class = '';
126  }
127  }
128  return $classes;
129  }
130 
137  private function isBracedNamespace($index)
138  {
139  $len = count($this->tokens);
140  while ($index++ < $len) {
141  if (!is_array($this->tokens[$index])) {
142  if ($this->tokens[$index] == ';') {
143  return false;
144  } else if ($this->tokens[$index] == '{') {
145  return true;
146  }
147  continue;
148  }
149 
150  if (!in_array($this->tokens[$index][0], [T_WHITESPACE, T_STRING, T_NS_SEPARATOR])) {
151  throw new InvalidFileException('Namespace not defined properly');
152  }
153  }
154  throw new InvalidFileException('Could not find namespace termination');
155  }
156 
163  public function getClassNames()
164  {
165  if ($this->classNames === false) {
166  $this->classNames = $this->extract();
167  }
168  return $this->classNames;
169  }
170 }
$_option $_optionId $class
Definition: date.phtml:13
$index
Definition: list.phtml:44