RLoader::getStatic()   A
last analyzed

Complexity

Conditions 6
Paths 4

Size

Total Lines 28
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 14
c 2
b 1
f 0
dl 0
loc 28
rs 9.2222
cc 6
nc 4
nop 1
1
<?php
2
/**
3
 * @package     Redcore
4
 * @subpackage  Loader
5
 *
6
 * @copyright   Copyright (C) 2008 - 2021 redWEB.dk. All rights reserved.
7
 * @license     GNU General Public License version 2 or later, see LICENSE.
8
 */
9
10
defined('JPATH_REDCORE') or die;
11
12
/**
13
 * Static class to handle loading of libraries.
14
 *
15
 * @package     Redcore
16
 * @subpackage  Loader
17
 * @since       1.0
18
 */
19
class RLoader extends JLoader
20
{
21
	/**
22
	 * Container for already imported library paths.
23
	 *
24
	 * @var    array
25
	 * @since  11.1
26
	 */
27
	protected static $rClasses = array();
28
29
	/**
30
	 * Container for already imported library paths.
31
	 *
32
	 * @var    array
33
	 * @since  11.1
34
	 */
35
	protected static $rImported = array();
36
37
	/**
38
	 * Container for registered library class prefixes and path lookups.
39
	 *
40
	 * @var    array
41
	 * @since  12.1
42
	 */
43
	protected static $rPrefixes = array();
44
45
	/**
46
	 * Holds proxy classes and the class names the proxy.
47
	 *
48
	 * @var    array
49
	 * @since  3.2
50
	 */
51
	protected static $rClassAliases = array();
52
53
	/**
54
	 * Holds the inverse lookup for proxy classes and the class names the proxy.
55
	 *
56
	 * @var    array
57
	 * @since  3.4
58
	 */
59
	protected static $rClassAliasesInverse = array();
60
61
	/**
62
	 * Container for namespace => path map.
63
	 *
64
	 * @var    array
65
	 * @since  12.3
66
	 */
67
	protected static $rNamespaces = array('psr0' => array(), 'psr4' => array());
68
69
	/**
70
	 * Holds a reference for all deprecated aliases (mainly for use by a logging platform).
71
	 *
72
	 * @var    array
73
	 * @since  3.6.3
74
	 */
75
	protected static $rDeprecatedAliases = array();
76
77
	/**
78
	 * Get static property
79
	 *
80
	 * @param   string  $name  Name of property
81
	 *
82
	 * @return mixed
83
	 */
84
	protected static function &getStatic($name)
85
	{
86
		// Try to use parent property if exists
87
		if (property_exists(get_called_class(), $name))
88
		{
89
			$variable = &static::${$name};
90
91
			if ($name == 'namespaces'
92
				&& (!array_key_exists('psr0', $variable) || !is_array($variable['psr0'])))
93
			{
94
				$variable               = &static::${'r' . ucfirst($name)};
95
				static $mergeNamespaces = false;
96
97
				if (!$mergeNamespaces)
98
				{
99
					// Merge together old and new namespaces approaches
100
					static::${$name}  = array_merge(static::${$name}, $variable['psr0']);
101
					$variable['psr0'] = &static::${$name};
102
					$mergeNamespaces  = true;
103
				}
104
			}
105
		}
106
		else
107
		{
108
			$variable = &static::${'r' . ucfirst($name)};
109
		}
110
111
		return $variable;
112
	}
113
114
	/**
115
	 * Method to discover classes of a given type in a given path.
116
	 *
117
	 * @param   string   $classPrefix  The class name prefix to use for discovery.
118
	 * @param   string   $parentPath   Full path to the parent folder for the classes to discover.
119
	 * @param   boolean  $force        True to overwrite the autoload path value for the class if it already exists.
120
	 * @param   boolean  $recurse      Recurse through all child directories as well as the parent path.
121
	 *
122
	 * @return  void
123
	 *
124
	 * @since   11.1
125
	 */
126
	public static function discover($classPrefix, $parentPath, $force = true, $recurse = false)
127
	{
128
		try
129
		{
130
			if ($recurse)
131
			{
132
				$iterator = new RecursiveIteratorIterator(
133
					new RecursiveDirectoryIterator($parentPath),
134
					RecursiveIteratorIterator::SELF_FIRST
135
				);
136
			}
137
			else
138
			{
139
				$iterator = new DirectoryIterator($parentPath);
140
			}
141
142
			/* @type  $file  DirectoryIterator */
143
			foreach ($iterator as $file)
144
			{
145
				$fileName = $file->getFilename();
146
147
				// Only load for php files.
148
				if ($file->isFile() && $file->getExtension() == 'php')
149
				{
150
					// Get the class name and full path for each file.
151
					$class = strtolower($classPrefix . preg_replace('#\.php$#', '', $fileName));
152
153
					// Register the class with the autoloader if not already registered or the force flag is set.
154
					if (empty(self::getStatic('classes')[$class]) || $force)
155
					{
156
						self::register($class, $file->getPath() . '/' . $fileName);
157
					}
158
				}
159
			}
160
		}
161
		catch (UnexpectedValueException $e)
162
		{
163
			// Exception will be thrown if the path is not a directory. Ignore it.
164
		}
165
	}
166
167
	/**
168
	 * Method to get the list of registered classes and their respective file paths for the autoloader.
169
	 *
170
	 * @return  array  The array of class => path values for the autoloader.
171
	 *
172
	 * @since   11.1
173
	 */
174
	public static function getClassList()
175
	{
176
		return self::getStatic('classes');
177
	}
178
179
	/**
180
	 * Method to get the list of deprecated class aliases.
181
	 *
182
	 * @return  array  An associative array with deprecated class alias data.
183
	 *
184
	 * @since   3.6.3
185
	 */
186
	public static function getDeprecatedAliases()
187
	{
188
		return self::getStatic('deprecatedAliases');
189
	}
190
191
	/**
192
	 * Method to get the list of registered namespaces.
193
	 *
194
	 * @param   string  $type  Defines the type of namespace, can be prs0 or psr4.
195
	 *
196
	 * @return  array  The array of namespace => path values for the autoloader.
197
	 *
198
	 * @since   12.3
199
	 */
200
	public static function getNamespaces($type = 'psr0')
201
	{
202
		if ($type !== 'psr0' && $type !== 'psr4')
203
		{
204
			throw new InvalidArgumentException('Type needs to be prs0 or psr4!');
205
		}
206
207
		return self::getStatic('namespaces')[$type];
208
	}
209
210
	/**
211
	 * Loads a class from specified directories.
212
	 *
213
	 * @param   string  $key   The class name to look for (dot notation).
214
	 * @param   string  $base  Search this directory for the class.
215
	 *
216
	 * @return  boolean  True on success.
217
	 *
218
	 * @since   11.1
219
	 */
220
	public static function import($key, $base = null)
221
	{
222
		// Only import the library if not already attempted.
223
		if (!isset(self::getStatic('imported')[$key]))
224
		{
225
			// Setup some variables.
226
			$success = false;
227
			$parts   = explode('.', $key);
228
			$class   = array_pop($parts);
229
			$base    = (!empty($base)) ? $base : __DIR__;
230
			$path    = str_replace('.', DIRECTORY_SEPARATOR, $key);
231
232
			// Handle special case for helper classes.
233
			if ($class == 'helper')
234
			{
235
				$class = ucfirst(array_pop($parts)) . ucfirst($class);
236
			}
237
			// Standard class.
238
			else
239
			{
240
				$class = ucfirst($class);
241
			}
242
243
			// If we are importing a library from the Joomla namespace set the class to autoload.
244
			if (strpos($path, 'joomla') === 0)
245
			{
246
				// Since we are in the Joomla namespace prepend the classname with J.
247
				$class = 'J' . $class;
248
249
				// Only register the class for autoloading if the file exists.
250
				if (is_file($base . '/' . $path . '.php'))
251
				{
252
					self::getStatic('classes')[strtolower($class)] = $base . '/' . $path . '.php';
253
					$success                                       = true;
254
				}
255
			}
256
			/*
257
			 * If we are not importing a library from the Joomla namespace directly include the
258
			 * file since we cannot assert the file/folder naming conventions.
259
			 */
260
			else
261
			{
262
				// If the file exists attempt to include it.
263
				if (is_file($base . '/' . $path . '.php'))
264
				{
265
					$success = (bool) include_once $base . '/' . $path . '.php';
266
				}
267
			}
268
269
			// Add the import key to the memory cache container.
270
			self::getStatic('imported')[$key] = $success;
271
		}
272
273
		return self::getStatic('imported')[$key];
274
	}
275
276
	/**
277
	 * Load the file for a class.
278
	 *
279
	 * @param   string  $class  The class to be loaded.
280
	 *
281
	 * @return  boolean  True on success
282
	 *
283
	 * @since   11.1
284
	 */
285
	public static function load($class)
286
	{
287
		// Sanitize class name.
288
		$class = strtolower($class);
289
290
		// If the class already exists do nothing.
291
		if (class_exists($class, false))
292
		{
293
			return true;
294
		}
295
296
		// If the class is registered include the file.
297
		if (isset(self::getStatic('classes')[$class]))
298
		{
299
			$found = (bool) include_once self::getStatic('classes')[$class];
300
301
			if ($found)
302
			{
303
				self::loadAliasForClass($class);
304
			}
305
306
			return true;
307
		}
308
309
		return false;
310
	}
311
312
	/**
313
	 * Directly register a class to the autoload list.
314
	 *
315
	 * @param   string   $class  The class name to register.
316
	 * @param   string   $path   Full path to the file that holds the class to register.
317
	 * @param   boolean  $force  True to overwrite the autoload path value for the class if it already exists.
318
	 *
319
	 * @return  void
320
	 *
321
	 * @since   11.1
322
	 */
323
	public static function register($class, $path, $force = true)
324
	{
325
		// Sanitize class name.
326
		$class = strtolower($class);
327
328
		// Only attempt to register the class if the name and file exist.
329
		if (!empty($class) && is_file($path))
330
		{
331
			// Register the class with the autoloader if not already registered or the force flag is set.
332
			if (empty(self::getStatic('classes')[$class]) || $force)
333
			{
334
				self::getStatic('classes')[$class] = $path;
335
			}
336
		}
337
	}
338
339
	/**
340
	 * Register a class prefix with lookup path.  This will allow developers to register library
341
	 * packages with different class prefixes to the system autoloader.  More than one lookup path
342
	 * may be registered for the same class prefix, but if this method is called with the reset flag
343
	 * set to true then any registered lookups for the given prefix will be overwritten with the current
344
	 * lookup path. When loaded, prefix paths are searched in a "last in, first out" order.
345
	 *
346
	 * @param   string   $prefix   The class prefix to register.
347
	 * @param   string   $path     Absolute file path to the library root where classes with the given prefix can be found.
348
	 * @param   boolean  $reset    True to reset the prefix with only the given lookup path.
349
	 * @param   boolean  $prepend  If true, push the path to the beginning of the prefix lookup paths array.
350
	 *
351
	 * @return  void
352
	 *
353
	 * @throws  RuntimeException
354
	 *
355
	 * @since   12.1
356
	 */
357
	public static function registerPrefix($prefix, $path, $reset = false, $prepend = false)
358
	{
359
		// Verify the library path exists.
360
		if (!file_exists($path))
361
		{
362
			$path = (str_replace(JPATH_ROOT, '', $path) == $path) ? basename($path) : str_replace(JPATH_ROOT, '', $path);
363
364
			throw new RuntimeException('Library path ' . $path . ' cannot be found.', 500);
365
		}
366
367
		// If the prefix is not yet registered or we have an explicit reset flag then set set the path.
368
		if (!isset(self::getStatic('prefixes')[$prefix]) || $reset)
369
		{
370
			self::getStatic('prefixes')[$prefix] = array($path);
371
		}
372
		// Otherwise we want to simply add the path to the prefix.
373
		else
374
		{
375
			if ($prepend)
376
			{
377
				array_unshift(self::getStatic('prefixes')[$prefix], $path);
378
			}
379
			else
380
			{
381
				self::getStatic('prefixes')[$prefix][] = $path;
382
			}
383
		}
384
	}
385
386
	/**
387
	 * Offers the ability for "just in time" usage of `class_alias()`.
388
	 * You cannot overwrite an existing alias.
389
	 *
390
	 * @param   string          $alias     The alias name to register.
391
	 * @param   string          $original  The original class to alias.
392
	 * @param   string|boolean  $version   The version in which the alias will no longer be present.
393
	 *
394
	 * @return  boolean  True if registration was successful. False if the alias already exists.
395
	 *
396
	 * @since   3.2
397
	 */
398
	public static function registerAlias($alias, $original, $version = false)
399
	{
400
		if (!isset(self::getStatic('classAliases')[$alias]))
401
		{
402
			self::getStatic('classAliases')[$alias] = $original;
403
404
			// Remove the root backslash if present.
405
			if ($original[0] == '\\')
406
			{
407
				$original = substr($original, 1);
408
			}
409
410
			if (!isset(self::getStatic('classAliasesInverse')[$original]))
411
			{
412
				self::getStatic('classAliasesInverse')[$original] = array($alias);
413
			}
414
			else
415
			{
416
				self::getStatic('classAliasesInverse')[$original][] = $alias;
417
			}
418
419
			// If given a version, log this alias as deprecated
420
			if ($version)
421
			{
422
				self::getStatic('deprecatedAliases')[] = array('old' => $alias, 'new' => $original, 'version' => $version);
423
			}
424
425
			return true;
426
		}
427
428
		return false;
429
	}
430
431
	/**
432
	 * Register a namespace to the autoloader. When loaded, namespace paths are searched in a "last in, first out" order.
433
	 *
434
	 * @param   string   $namespace  A case sensitive Namespace to register.
435
	 * @param   string   $path       A case sensitive absolute file path to the library root where classes of the given namespace can be found.
436
	 * @param   boolean  $reset      True to reset the namespace with only the given lookup path.
437
	 * @param   boolean  $prepend    If true, push the path to the beginning of the namespace lookup paths array.
438
	 * @param   string   $type       Defines the type of namespace, can be prs0 or psr4.
439
	 *
440
	 * @return  void
441
	 *
442
	 * @throws  RuntimeException
443
	 *
444
	 * @note    The default argument of $type will be changed in J4 to be 'psr4'
445
	 * @since   12.3
446
	 */
447
	public static function registerNamespace($namespace, $path, $reset = false, $prepend = false, $type = 'psr0')
448
	{
449
		if ($type !== 'psr0' && $type !== 'psr4')
450
		{
451
			throw new InvalidArgumentException('Type needs to be prs0 or psr4!');
452
		}
453
454
		// Verify the library path exists.
455
		if (!file_exists($path))
456
		{
457
			$path = (str_replace(JPATH_ROOT, '', $path) == $path) ? basename($path) : str_replace(JPATH_ROOT, '', $path);
458
459
			throw new RuntimeException('Library path ' . $path . ' cannot be found.', 500);
460
		}
461
462
		// If the namespace is not yet registered or we have an explicit reset flag then set the path.
463
		if (!isset(self::getStatic('namespaces')[$type][$namespace]) || $reset)
464
		{
465
			self::getStatic('namespaces')[$type][$namespace] = array($path);
466
		}
467
468
		// Otherwise we want to simply add the path to the namespace.
469
		else
470
		{
471
			if ($prepend)
472
			{
473
				array_unshift(self::getStatic('namespaces')[$type][$namespace], $path);
474
			}
475
			else
476
			{
477
				self::getStatic('namespaces')[$type][$namespace][] = $path;
478
			}
479
		}
480
	}
481
482
	/**
483
	 * Method to setup the autoloaders for the Joomla Platform.
484
	 * Since the SPL autoloaders are called in a queue we will add our explicit
485
	 * class-registration based loader first, then fall back on the autoloader based on conventions.
486
	 * This will allow people to register a class in a specific location and override platform libraries
487
	 * as was previously possible.
488
	 *
489
	 * @param   boolean  $enablePsr       True to enable autoloading based on PSR-0.
490
	 * @param   boolean  $enablePrefixes  True to enable prefix based class loading (needed to auto load the Joomla core).
491
	 * @param   boolean  $enableClasses   True to enable class map based class loading (needed to auto load the Joomla core).
492
	 *
493
	 * @return  void
494
	 *
495
	 * @since   12.3
496
	 */
497
	public static function setup($enablePsr = true, $enablePrefixes = true, $enableClasses = true)
498
	{
499
		// Since spl_autoload_register use here prepend position we need to use revert order to reproduce the same Joomla! loader order
500
		if ($enablePsr)
501
		{
502
			// Register the PSR-0 based autoloader.
503
			spl_autoload_register(array('RLoader', 'loadByAlias'), true, true);
504
			spl_autoload_register(array('RLoader', 'loadByPsr4'), true, true);
505
			spl_autoload_register(array('RLoader', 'loadByPsr0'), true, true);
506
		}
507
508
		if ($enablePrefixes)
509
		{
510
			// Register the J prefix and base path for Joomla platform libraries.
511
			self::registerPrefix('J', JPATH_PLATFORM . '/joomla');
512
513
			// Register the prefix autoloader.
514
			spl_autoload_register(array('RLoader', '_autoload'), true, true);
515
		}
516
517
		if ($enableClasses)
518
		{
519
			// Register the class map based autoloader.
520
			spl_autoload_register(array('RLoader', 'load'), true, true);
521
		}
522
	}
523
524
	/**
525
	 * Method to autoload classes that are namespaced to the PSR-4 standard.
526
	 *
527
	 * @param   string  $class  The fully qualified class name to autoload.
528
	 *
529
	 * @return  boolean  True on success, false otherwise.
530
	 *
531
	 * @since   3.7.0
532
	 */
533
	public static function loadByPsr4($class)
534
	{
535
		// Remove the root backslash if present.
536
		if ($class[0] == '\\')
537
		{
538
			$class = substr($class, 1);
539
		}
540
541
		// Find the location of the last NS separator.
542
		$pos = strrpos($class, '\\');
543
544
		// If one is found, we're dealing with a NS'd class.
545
		if ($pos !== false)
546
		{
547
			$classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR;
548
			$className = substr($class, $pos + 1);
549
		}
550
		// If not, no need to parse path.
551
		else
552
		{
553
			$classPath = null;
554
			$className = $class;
555
		}
556
557
		$classPath .= $className . '.php';
558
559
		// Loop through registered namespaces until we find a match.
560
		foreach (self::getStatic('namespaces')['psr4'] as $ns => $paths)
561
		{
562
			$nsPath = trim(str_replace('\\', DIRECTORY_SEPARATOR, $ns), DIRECTORY_SEPARATOR);
563
564
			if (strpos($class, $ns) === 0)
565
			{
566
				// Loop through paths registered to this namespace until we find a match.
567
				foreach ($paths as $path)
568
				{
569
					$classFilePath = $path . DIRECTORY_SEPARATOR . str_replace($nsPath, '', $classPath);
570
571
					// We check for class_exists to handle case-sensitive file systems
572
					if (file_exists($classFilePath) && !class_exists($class, false))
573
					{
574
						$found = (bool) include_once $classFilePath;
575
576
						if ($found)
577
						{
578
							self::loadAliasForClass($class);
579
						}
580
581
						return $found;
582
					}
583
				}
584
			}
585
		}
586
587
		return false;
588
	}
589
590
	/**
591
	 * Method to autoload classes that are namespaced to the PSR-0 standard.
592
	 *
593
	 * @param   string  $class  The fully qualified class name to autoload.
594
	 *
595
	 * @return  boolean  True on success, false otherwise.
596
	 *
597
	 * @since   13.1
598
	 *
599
	 * @deprecated 4.0 this method will be removed
600
	 */
601
	public static function loadByPsr0($class)
602
	{
603
		// Remove the root backslash if present.
604
		if ($class[0] == '\\')
605
		{
606
			$class = substr($class, 1);
607
		}
608
609
		// Find the location of the last NS separator.
610
		$pos = strrpos($class, '\\');
611
612
		// If one is found, we're dealing with a NS'd class.
613
		if ($pos !== false)
614
		{
615
			$classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR;
616
			$className = substr($class, $pos + 1);
617
		}
618
		// If not, no need to parse path.
619
		else
620
		{
621
			$classPath = null;
622
			$className = $class;
623
		}
624
625
		$classPath .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
626
627
		// Loop through registered namespaces until we find a match.
628
		foreach (self::getStatic('namespaces')['psr0'] as $ns => $paths)
629
		{
630
			if (strpos($class, $ns) === 0)
631
			{
632
				// Loop through paths registered to this namespace until we find a match.
633
				foreach ($paths as $path)
634
				{
635
					$classFilePath = $path . DIRECTORY_SEPARATOR . $classPath;
636
637
					// We check for class_exists to handle case-sensitive file systems
638
					if (file_exists($classFilePath) && !class_exists($class, false))
639
					{
640
						$found = (bool) include_once $classFilePath;
641
642
						if ($found)
643
						{
644
							self::loadAliasForClass($class);
645
						}
646
647
						return $found;
648
					}
649
				}
650
			}
651
		}
652
653
		return false;
654
	}
655
656
	/**
657
	 * Method to autoload classes that have been aliased using the registerAlias method.
658
	 *
659
	 * @param   string  $class  The fully qualified class name to autoload.
660
	 *
661
	 * @return  boolean  True on success, false otherwise.
662
	 *
663
	 * @since   3.2
664
	 */
665
	public static function loadByAlias($class)
666
	{
667
		// Remove the root backslash if present.
668
		if ($class[0] == '\\')
669
		{
670
			$class = substr($class, 1);
671
		}
672
673
		if (isset(self::getStatic('classAliases')[$class]))
674
		{
675
			// Force auto-load of the regular class
676
			class_exists(self::getStatic('classAliases')[$class], true);
677
678
			// Normally this shouldn't execute as the autoloader will execute applyAliasFor when the regular class is
679
			// auto-loaded above.
680
			if (!class_exists($class, false) && !interface_exists($class, false))
681
			{
682
				class_alias(self::getStatic('classAliases')[$class], $class);
683
			}
684
		}
685
	}
686
687
	/**
688
	 * Applies a class alias for an already loaded class, if a class alias was created for it.
689
	 *
690
	 * @param   string  $class  We'll look for and register aliases for this (real) class name
691
	 *
692
	 * @return  void
693
	 *
694
	 * @since   3.4
695
	 */
696
	public static function applyAliasFor($class)
697
	{
698
		// Remove the root backslash if present.
699
		if ($class[0] == '\\')
700
		{
701
			$class = substr($class, 1);
702
		}
703
704
		if (isset(self::getStatic('classAliasesInverse')[$class]))
705
		{
706
			foreach (self::getStatic('classAliasesInverse')[$class] as $alias)
707
			{
708
				class_alias($class, $alias);
709
			}
710
		}
711
	}
712
713
	/**
714
	 * Autoload a class based on name.
715
	 *
716
	 * @param   string  $class  The class to be loaded.
717
	 *
718
	 * @return  boolean  True if the class was loaded, false otherwise.
719
	 *
720
	 * @since   11.3
721
	 */
722
	public static function _autoload($class)
723
	{
724
		foreach (self::getStatic('prefixes') as $prefix => $lookup)
725
		{
726
			$chr = strlen($prefix) < strlen($class) ? $class[strlen($prefix)] : 0;
727
728
			if (strpos($class, $prefix) === 0 && ($chr === strtoupper($chr)))
729
			{
730
				return self::_load(substr($class, strlen($prefix)), $lookup);
731
			}
732
		}
733
734
		return false;
735
	}
736
737
	/**
738
	 * Load a class based on name and lookup array.
739
	 *
740
	 * @param   string  $class   The class to be loaded (wihtout prefix).
741
	 * @param   array   $lookup  The array of base paths to use for finding the class file.
742
	 *
743
	 * @return  boolean  True if the class was loaded, false otherwise.
744
	 *
745
	 * @since   12.1
746
	 */
747
	private static function _load($class, $lookup)
748
	{
749
		// Split the class name into parts separated by camelCase.
750
		$parts      = preg_split('/(?<=[a-z0-9])(?=[A-Z])/x', $class);
751
		$partsCount = count($parts);
752
753
		foreach ($lookup as $base)
754
		{
755
			// Generate the path based on the class name parts.
756
			$path = $base . '/' . implode('/', array_map('strtolower', $parts)) . '.php';
757
758
			// Load the file if it exists.
759
			if (file_exists($path))
760
			{
761
				$found = (bool) include_once $path;
762
763
				if ($found)
764
				{
765
					self::loadAliasForClass($class);
766
				}
767
768
				return $found;
769
			}
770
771
			// Backwards compatibility patch
772
773
			// If there is only one part we want to duplicate that part for generating the path.
774
			if ($partsCount === 1)
775
			{
776
				// Generate the path based on the class name parts.
777
				$path = $base . '/' . implode('/', array_map('strtolower', array($parts[0], $parts[0]))) . '.php';
778
779
				// Load the file if it exists.
780
				if (file_exists($path))
781
				{
782
					return include $path;
783
				}
784
			}
785
		}
786
787
		return false;
788
	}
789
790
	/**
791
	 * Loads the aliases for the given class.
792
	 *
793
	 * @param   string  $class  The class.
794
	 *
795
	 * @return  void
796
	 *
797
	 * @since   2.1.0
798
	 */
799
	private static function loadAliasForClass($class)
800
	{
801
		if (empty(self::$classAliasesInverse))
802
		{
803
			// Not supported in this version of joomla
804
			return;
805
		}
806
807
		if (!key_exists($class, self::$classAliasesInverse))
808
		{
809
			return;
810
		}
811
812
		foreach (self::$classAliasesInverse[$class] as $alias)
813
		{
814
			// Force auto-load of the alias class
815
			class_exists($alias, true);
816
		}
817
	}
818
}
819