2017-05-31 17:45:09 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @package Joomla.Libraries
|
|
|
|
*
|
2020-05-30 17:32:34 +00:00
|
|
|
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved.
|
2017-05-31 17:45:09 +00:00
|
|
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
|
|
|
*/
|
|
|
|
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
|
2018-07-11 11:28:27 +00:00
|
|
|
use Joomla\CMS\Filesystem\File;
|
2018-09-16 11:07:49 +00:00
|
|
|
use Joomla\CMS\Filesystem\Folder;
|
2018-06-19 19:00:00 +00:00
|
|
|
|
2017-05-31 17:45:09 +00:00
|
|
|
/**
|
|
|
|
* Class JNamespaceMap
|
|
|
|
*
|
2017-11-19 16:34:38 +00:00
|
|
|
* @since 4.0.0
|
2017-05-31 17:45:09 +00:00
|
|
|
*/
|
|
|
|
class JNamespacePsr4Map
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Path to the autoloader
|
|
|
|
*
|
|
|
|
* @var string
|
2017-11-19 16:34:38 +00:00
|
|
|
* @since 4.0.0
|
2017-05-31 17:45:09 +00:00
|
|
|
*/
|
2020-03-28 19:27:12 +00:00
|
|
|
protected $file = JPATH_CACHE . '/autoload_psr4.php';
|
2017-05-31 17:45:09 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if the file exists
|
|
|
|
*
|
2019-07-11 21:42:30 +00:00
|
|
|
* @return boolean
|
2017-05-31 17:45:09 +00:00
|
|
|
*
|
2017-11-19 16:34:38 +00:00
|
|
|
* @since 4.0.0
|
2017-05-31 17:45:09 +00:00
|
|
|
*/
|
2017-06-01 08:45:58 +00:00
|
|
|
public function exists()
|
2017-05-31 17:45:09 +00:00
|
|
|
{
|
2020-09-29 15:51:23 +00:00
|
|
|
return is_file($this->file);
|
2017-05-31 17:45:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if the namespace mapping file exists, if not create it
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*
|
2017-11-19 16:34:38 +00:00
|
|
|
* @since 4.0.0
|
2017-05-31 17:45:09 +00:00
|
|
|
*/
|
2017-06-01 08:45:58 +00:00
|
|
|
public function ensureMapFileExists()
|
2017-05-31 17:45:09 +00:00
|
|
|
{
|
2018-09-16 11:07:49 +00:00
|
|
|
if (!$this->exists())
|
2017-05-31 17:45:09 +00:00
|
|
|
{
|
2017-06-01 08:45:58 +00:00
|
|
|
$this->create();
|
2017-05-31 17:45:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create the namespace file
|
|
|
|
*
|
2019-07-11 21:42:30 +00:00
|
|
|
* @return boolean
|
2017-05-31 17:45:09 +00:00
|
|
|
*
|
2017-11-19 16:34:38 +00:00
|
|
|
* @since 4.0.0
|
2017-05-31 17:45:09 +00:00
|
|
|
*/
|
2017-06-01 08:45:58 +00:00
|
|
|
public function create()
|
2017-05-31 17:45:09 +00:00
|
|
|
{
|
2020-01-21 11:53:53 +00:00
|
|
|
$extensions = array_merge(
|
|
|
|
$this->getNamespaces('component'),
|
|
|
|
$this->getNamespaces('module'),
|
|
|
|
$this->getNamespaces('plugin'),
|
|
|
|
$this->getNamespaces('library')
|
|
|
|
);
|
2017-05-31 17:45:09 +00:00
|
|
|
|
2020-05-02 17:09:33 +00:00
|
|
|
ksort($extensions);
|
|
|
|
|
2018-09-16 11:07:49 +00:00
|
|
|
$this->writeNamespaceFile($extensions);
|
2017-05-31 17:45:09 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-06-15 11:38:44 +00:00
|
|
|
/**
|
|
|
|
* Load the PSR4 file
|
|
|
|
*
|
2019-07-11 21:42:30 +00:00
|
|
|
* @return boolean
|
2017-06-15 11:38:44 +00:00
|
|
|
*
|
2017-11-19 16:34:38 +00:00
|
|
|
* @since 4.0.0
|
2017-06-15 11:38:44 +00:00
|
|
|
*/
|
|
|
|
public function load()
|
|
|
|
{
|
|
|
|
if (!$this->exists())
|
|
|
|
{
|
|
|
|
$this->create();
|
|
|
|
}
|
|
|
|
|
|
|
|
$map = require $this->file;
|
|
|
|
|
|
|
|
$loader = include JPATH_LIBRARIES . '/vendor/autoload.php';
|
|
|
|
|
|
|
|
foreach ($map as $namespace => $path)
|
|
|
|
{
|
|
|
|
$loader->setPsr4($namespace, $path);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-31 17:45:09 +00:00
|
|
|
/**
|
|
|
|
* Write the Namespace mapping file
|
|
|
|
*
|
|
|
|
* @param array $elements Array of elements
|
|
|
|
*
|
|
|
|
* @return void
|
|
|
|
*
|
2017-11-19 16:34:38 +00:00
|
|
|
* @since 4.0.0
|
2017-05-31 17:45:09 +00:00
|
|
|
*/
|
2017-06-01 08:45:58 +00:00
|
|
|
protected function writeNamespaceFile($elements)
|
2017-05-31 17:45:09 +00:00
|
|
|
{
|
|
|
|
$content = array();
|
|
|
|
$content[] = "<?php";
|
2017-06-15 11:38:44 +00:00
|
|
|
$content[] = 'defined(\'_JEXEC\') or die;';
|
2018-09-16 11:07:49 +00:00
|
|
|
$content[] = 'return [';
|
2017-05-31 17:45:09 +00:00
|
|
|
|
2018-09-16 11:07:49 +00:00
|
|
|
foreach ($elements as $namespace => $path)
|
2017-05-31 17:45:09 +00:00
|
|
|
{
|
2019-06-10 22:56:44 +00:00
|
|
|
$content[] = "\t'" . $namespace . "'" . ' => [' . $path . '],';
|
2017-05-31 17:45:09 +00:00
|
|
|
}
|
|
|
|
|
2018-09-16 11:07:49 +00:00
|
|
|
$content[] = '];';
|
2017-05-31 17:45:09 +00:00
|
|
|
|
2018-07-11 11:28:27 +00:00
|
|
|
File::write($this->file, implode("\n", $content));
|
2017-05-31 17:45:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-01-21 11:53:53 +00:00
|
|
|
* Get an array of namespaces with their respective path for the given extension type.
|
2018-09-16 11:07:49 +00:00
|
|
|
*
|
2020-01-21 11:53:53 +00:00
|
|
|
* @param string $type The extension type
|
2017-05-31 17:45:09 +00:00
|
|
|
*
|
2018-09-16 11:07:49 +00:00
|
|
|
* @return array
|
2017-05-31 17:45:09 +00:00
|
|
|
*
|
2017-11-19 16:34:38 +00:00
|
|
|
* @since 4.0.0
|
2017-05-31 17:45:09 +00:00
|
|
|
*/
|
2020-01-21 11:53:53 +00:00
|
|
|
private function getNamespaces(string $type): array
|
2017-05-31 17:45:09 +00:00
|
|
|
{
|
2020-01-21 11:53:53 +00:00
|
|
|
if (!in_array($type, ['component', 'module', 'plugin', 'library'], true))
|
2018-09-16 11:07:49 +00:00
|
|
|
{
|
|
|
|
return [];
|
|
|
|
}
|
2017-05-31 17:45:09 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// Select directories containing extension manifest files.
|
|
|
|
if ($type === 'component')
|
|
|
|
{
|
|
|
|
$directories = [JPATH_ADMINISTRATOR . '/components'];
|
|
|
|
}
|
|
|
|
elseif ($type === 'module')
|
|
|
|
{
|
|
|
|
$directories = [JPATH_SITE . '/modules', JPATH_ADMINISTRATOR . '/modules'];
|
|
|
|
}
|
|
|
|
elseif ($type === 'plugin')
|
|
|
|
{
|
|
|
|
$directories = Folder::folders(JPATH_PLUGINS, '.', false, true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$directories = [JPATH_LIBRARIES];
|
|
|
|
}
|
|
|
|
|
2018-09-16 11:07:49 +00:00
|
|
|
$extensions = [];
|
2017-05-31 17:45:09 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
foreach ($directories as $directory)
|
2018-09-16 11:07:49 +00:00
|
|
|
{
|
2020-01-21 11:53:53 +00:00
|
|
|
foreach (Folder::folders($directory) as $extension)
|
2018-09-16 11:07:49 +00:00
|
|
|
{
|
2020-01-21 11:53:53 +00:00
|
|
|
// Compile the extension path
|
|
|
|
$extensionPath = $directory . '/' . $extension . '/';
|
2017-05-31 17:45:09 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// Strip the com_ from the extension name for components
|
|
|
|
$name = str_replace('com_', '', $extension, $count);
|
|
|
|
$file = $extensionPath . $name . '.xml';
|
2017-05-31 17:45:09 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// If there is no manifest file, ignore. If it was a component check if the xml was named with the com_ prefix.
|
2020-09-29 15:51:23 +00:00
|
|
|
if (!is_file($file))
|
2019-03-29 16:18:12 +00:00
|
|
|
{
|
2020-01-21 11:53:53 +00:00
|
|
|
if (!$count)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$file = $extensionPath . $extension . '.xml';
|
|
|
|
|
2020-09-29 15:51:23 +00:00
|
|
|
if (!is_file($file))
|
2020-01-21 11:53:53 +00:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2019-03-29 16:18:12 +00:00
|
|
|
}
|
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// Load the manifest file
|
|
|
|
$xml = simplexml_load_file($file);
|
2019-03-29 16:18:12 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// When invalid, ignore
|
|
|
|
if (!$xml)
|
2019-03-29 16:18:12 +00:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2018-09-16 11:07:49 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// The namespace node
|
|
|
|
$namespaceNode = $xml->namespace;
|
2018-09-16 11:07:49 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// The namespace string
|
|
|
|
$namespace = (string) $namespaceNode;
|
2018-09-16 11:07:49 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// Ignore when the string is empty
|
|
|
|
if (!$namespace)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2018-09-16 11:07:49 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// Normalize the namespace string
|
|
|
|
$namespace = str_replace('\\', '\\\\', $namespace) . '\\\\';
|
|
|
|
$namespacePath = rtrim($extensionPath . $namespaceNode->attributes()->path, '/');
|
2018-09-16 11:07:49 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
if ($type === 'plugin' || $type === 'library')
|
|
|
|
{
|
|
|
|
$baseDir = $type === 'plugin' ? 'JPATH_PLUGINS . \'' : 'JPATH_LIBRARIES . \'';
|
|
|
|
$path = str_replace($type === 'plugin' ? JPATH_PLUGINS : JPATH_LIBRARIES, '', $namespacePath);
|
2018-09-16 11:07:49 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// Set the namespace
|
|
|
|
$extensions[$namespace] = $baseDir . $path . '\'';
|
2018-09-16 11:07:49 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
continue;
|
|
|
|
}
|
2018-09-16 11:07:49 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// Check if we need to use administrator path
|
|
|
|
$isAdministrator = strpos($namespacePath, JPATH_ADMINISTRATOR) === 0;
|
|
|
|
$path = str_replace($isAdministrator ? JPATH_ADMINISTRATOR : JPATH_SITE, '', $namespacePath);
|
2019-03-29 16:18:12 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// Add the site path when a component
|
|
|
|
if ($type === 'component')
|
2019-03-29 16:18:12 +00:00
|
|
|
{
|
2020-01-21 11:53:53 +00:00
|
|
|
if (is_dir(JPATH_SITE . $path))
|
|
|
|
{
|
|
|
|
$extensions[$namespace . 'Site\\\\'] = 'JPATH_SITE . \'' . $path . '\'';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_dir(JPATH_API . $path))
|
|
|
|
{
|
|
|
|
$extensions[$namespace . 'Api\\\\'] = 'JPATH_API . \'' . $path . '\'';
|
|
|
|
}
|
2019-03-29 16:18:12 +00:00
|
|
|
}
|
2018-09-16 11:07:49 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// Add the application specific segment when a component or module
|
|
|
|
$baseDir = $isAdministrator ? 'JPATH_ADMINISTRATOR . \'' : 'JPATH_SITE . \'';
|
|
|
|
$namespace .= $isAdministrator ? 'Administrator\\\\' : 'Site\\\\';
|
2018-09-16 11:07:49 +00:00
|
|
|
|
2020-01-21 11:53:53 +00:00
|
|
|
// Set the namespace
|
|
|
|
$extensions[$namespace] = $baseDir . $path . '\'';
|
|
|
|
}
|
2018-09-16 11:07:49 +00:00
|
|
|
}
|
2017-05-31 17:45:09 +00:00
|
|
|
|
2018-09-16 11:07:49 +00:00
|
|
|
// Return the namespaces
|
2017-05-31 17:45:09 +00:00
|
|
|
return $extensions;
|
|
|
|
}
|
|
|
|
}
|