Elgg  Version master
ClassLoader.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
48 class ClassLoader {
49 
50  protected array $namespaces = [];
51 
52  protected array $prefixes = [];
53 
54  protected array $fallbacks = [];
55 
59  protected $map;
60 
64  protected array $missing = [];
65 
71  public function __construct(protected Config $config) {
72  $this->map = new \Elgg\ClassMap();
73 
74  $this->register();
75  }
76 
82  public function getClassMap() {
83  return $this->map;
84  }
85 
91  public function getNamespaces() {
92  return $this->namespaces;
93  }
94 
100  public function getPrefixes() {
101  return $this->prefixes;
102  }
103 
111  public function registerNamespaces(array $namespaces) {
112  foreach ($namespaces as $namespace => $locations) {
113  $this->namespaces[$namespace] = (array) $locations;
114  }
115  }
116 
125  public function registerNamespace($namespace, $paths) {
126  $this->namespaces[$namespace] = (array) $paths;
127  }
128 
136  public function registerPrefixes(array $classes) {
137  foreach ($classes as $prefix => $locations) {
138  $this->prefixes[$prefix] = (array) $locations;
139  }
140  }
141 
150  public function registerPrefix($prefix, $paths) {
151  $this->prefixes[$prefix] = (array) $paths;
152  }
153 
161  public function addFallback($path) {
162  $this->fallbacks[] = rtrim($path, '/\\');
163  }
164 
170  public function register() {
171  spl_autoload_register([$this, 'loadClass']);
172  }
173 
181  public function loadClass($class) {
182  // is missing? return
183  if (isset($this->missing[$class])) {
184  return;
185  }
186 
187  $file = $this->map->getPath($class);
188  if (!empty($file) && (!$this->config->class_loader_verify_file_existence || is_file($file))) {
189  require $file;
190  return;
191  }
192 
193  $file = $this->findFile($class);
194  if (!empty($file)) {
195  $this->map->setPath($class, $file);
196  $this->map->setAltered(true);
197  require $file;
198  }
199 
200  // add to missing
201  $this->missing[$class] = true;
202  }
203 
211  public function findFile($class) {
212  if ($class[0] === '\\') {
213  $class = substr($class, 1);
214  }
215 
216  $pos = strrpos($class, '\\');
217  if ($pos !== false) {
218  // namespaced class name
219  $namespace = substr($class, 0, $pos);
220  $className = substr($class, $pos + 1);
221  $normalizedClass = str_replace('\\', DIRECTORY_SEPARATOR, $namespace)
222  . DIRECTORY_SEPARATOR
223  . str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
224  foreach ($this->namespaces as $ns => $dirs) {
225  if (!str_starts_with($namespace, $ns)) {
226  continue;
227  }
228 
229  foreach ($dirs as $dir) {
230  $file = $dir . DIRECTORY_SEPARATOR . $normalizedClass;
231  if (is_file($file)) {
232  return $file;
233  }
234  }
235  }
236  } else {
237  // PEAR-like class name
238  $normalizedClass = str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
239  foreach ($this->prefixes as $prefix => $dirs) {
240  if (!str_starts_with($class, $prefix)) {
241  continue;
242  }
243 
244  foreach ($dirs as $dir) {
245  $file = $dir . DIRECTORY_SEPARATOR . $normalizedClass;
246  if (is_file($file)) {
247  return $file;
248  }
249  }
250  }
251  }
252 
253  foreach ($this->fallbacks as $dir) {
254  $file = $dir . DIRECTORY_SEPARATOR . $normalizedClass;
255  if (is_file($file)) {
256  return $file;
257  }
258  }
259  }
260 }
registerNamespaces(array $namespaces)
Registers an array of namespaces.
$paths
We handle here two possible locations of composer-generated autoload file.
Definition: autoloader.php:7
$classes
Definition: users.php:29
A class/interface/trait autoloader for PHP.
Definition: ClassLoader.php:48
loadClass($class)
Loads the given class or interface, possibly updating the class map.
addFallback($path)
Add a directory to search if no registered directory is found.
$class
Definition: summary.php:44
$config
Advanced site settings, debugging section.
Definition: debugging.php:6
$path
Definition: details.php:70
registerNamespace($namespace, $paths)
Registers a namespace.
$namespaces
Definition: default.php:32
getNamespaces()
Gets the configured namespaces.
Definition: ClassLoader.php:91
registerPrefix($prefix, $paths)
Registers a set of classes using the PEAR naming convention.
findFile($class)
Finds the path to the file where the class is defined.
__construct(protected Config $config)
Constructor.
Definition: ClassLoader.php:71
registerPrefixes(array $classes)
Registers an array of classes using the PEAR naming convention.
getPrefixes()
Gets the configured class prefixes.
getClassMap()
Get the class map.
Definition: ClassLoader.php:82