[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Joomla! Content Management System 5 * 6 * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> 7 * @license GNU General Public License version 2 or later; see LICENSE.txt 8 9 * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace 10 */ 11 12 use Joomla\CMS\Log\Log; 13 use Joomla\Filesystem\File; 14 use Joomla\Filesystem\Folder; 15 16 // phpcs:disable PSR1.Files.SideEffects 17 \defined('_JEXEC') or die; 18 // phpcs:enable PSR1.Files.SideEffects 19 20 /** 21 * Class JNamespacePsr4Map 22 * 23 * @since 4.0.0 24 */ 25 class JNamespacePsr4Map 26 { 27 /** 28 * Path to the autoloader 29 * 30 * @var string 31 * @since 4.0.0 32 */ 33 protected $file = JPATH_CACHE . '/autoload_psr4.php'; 34 35 /** 36 * @var array|null 37 * @since 4.0.0 38 */ 39 private $cachedMap = null; 40 41 /** 42 * Check if the file exists 43 * 44 * @return boolean 45 * 46 * @since 4.0.0 47 */ 48 public function exists() 49 { 50 return is_file($this->file); 51 } 52 53 /** 54 * Check if the namespace mapping file exists, if not create it 55 * 56 * @return void 57 * 58 * @since 4.0.0 59 */ 60 public function ensureMapFileExists() 61 { 62 if (!$this->exists()) { 63 $this->create(); 64 } 65 } 66 67 /** 68 * Create the namespace file 69 * 70 * @return boolean 71 * 72 * @since 4.0.0 73 */ 74 public function create() 75 { 76 $extensions = array_merge( 77 $this->getNamespaces('component'), 78 $this->getNamespaces('module'), 79 $this->getNamespaces('plugin'), 80 $this->getNamespaces('library') 81 ); 82 83 ksort($extensions); 84 85 $this->writeNamespaceFile($extensions); 86 87 return true; 88 } 89 90 /** 91 * Load the PSR4 file 92 * 93 * @return boolean 94 * 95 * @since 4.0.0 96 */ 97 public function load() 98 { 99 if (!$this->exists()) { 100 $this->create(); 101 } 102 103 $map = $this->cachedMap ?: require $this->file; 104 105 $loader = include JPATH_LIBRARIES . '/vendor/autoload.php'; 106 107 foreach ($map as $namespace => $path) { 108 $loader->setPsr4($namespace, $path); 109 } 110 111 return true; 112 } 113 114 /** 115 * Write the Namespace mapping file 116 * 117 * @param array $elements Array of elements 118 * 119 * @return void 120 * 121 * @since 4.0.0 122 */ 123 protected function writeNamespaceFile($elements) 124 { 125 $content = array(); 126 $content[] = "<?php"; 127 $content[] = 'defined(\'_JEXEC\') or die;'; 128 $content[] = 'return ['; 129 130 foreach ($elements as $namespace => $path) { 131 $content[] = "\t'" . $namespace . "'" . ' => [' . $path . '],'; 132 } 133 134 $content[] = '];'; 135 136 /** 137 * Backup the current error_reporting level and set a new level 138 * 139 * We do this because file_put_contents can raise a Warning if it cannot write the autoload_psr4.php file 140 * and this will output to the response BEFORE the session has started, causing the session start to fail 141 * and ultimately leading us to a 500 Internal Server Error page just because of the output warning, which 142 * we can safely ignore as we can use an in-memory autoload_psr4 map temporarily, and display real errors later. 143 */ 144 $error_reporting = error_reporting(0); 145 146 try { 147 File::write($this->file, implode("\n", $content)); 148 } catch (Exception $e) { 149 Log::add('Could not save ' . $this->file, Log::WARNING); 150 151 $map = []; 152 $constants = ['JPATH_ADMINISTRATOR', 'JPATH_API', 'JPATH_SITE', 'JPATH_PLUGINS']; 153 154 foreach ($elements as $namespace => $path) { 155 foreach ($constants as $constant) { 156 $path = preg_replace(['/^(' . $constant . ")\s\.\s\'/", '/\'$/'], [constant($constant), ''], $path); 157 } 158 159 $namespace = str_replace('\\\\', '\\', $namespace); 160 $map[$namespace] = [ $path ]; 161 } 162 163 $this->cachedMap = $map; 164 } 165 166 // Restore previous value of error_reporting 167 error_reporting($error_reporting); 168 } 169 170 /** 171 * Get an array of namespaces with their respective path for the given extension type. 172 * 173 * @param string $type The extension type 174 * 175 * @return array 176 * 177 * @since 4.0.0 178 */ 179 private function getNamespaces(string $type): array 180 { 181 if (!in_array($type, ['component', 'module', 'plugin', 'library'], true)) { 182 return []; 183 } 184 185 // Select directories containing extension manifest files. 186 if ($type === 'component') { 187 $directories = [JPATH_ADMINISTRATOR . '/components']; 188 } elseif ($type === 'module') { 189 $directories = [JPATH_SITE . '/modules', JPATH_ADMINISTRATOR . '/modules']; 190 } elseif ($type === 'plugin') { 191 try { 192 $directories = Folder::folders(JPATH_PLUGINS, '.', false, true); 193 } catch (Exception $e) { 194 $directories = []; 195 } 196 } else { 197 $directories = [JPATH_LIBRARIES]; 198 } 199 200 $extensions = []; 201 202 foreach ($directories as $directory) { 203 try { 204 $extensionFolders = Folder::folders($directory); 205 } catch (Exception $e) { 206 continue; 207 } 208 209 foreach ($extensionFolders as $extension) { 210 // Compile the extension path 211 $extensionPath = $directory . '/' . $extension . '/'; 212 213 // Strip the com_ from the extension name for components 214 $name = str_replace('com_', '', $extension, $count); 215 $file = $extensionPath . $name . '.xml'; 216 217 // If there is no manifest file, ignore. If it was a component check if the xml was named with the com_ prefix. 218 if (!is_file($file)) { 219 if (!$count) { 220 continue; 221 } 222 223 $file = $extensionPath . $extension . '.xml'; 224 225 if (!is_file($file)) { 226 continue; 227 } 228 } 229 230 // Load the manifest file 231 $xml = simplexml_load_file($file); 232 233 // When invalid, ignore 234 if (!$xml) { 235 continue; 236 } 237 238 // The namespace node 239 $namespaceNode = $xml->namespace; 240 241 // The namespace string 242 $namespace = (string) $namespaceNode; 243 244 // Ignore when the string is empty 245 if (!$namespace) { 246 continue; 247 } 248 249 // Normalize the namespace string 250 $namespace = str_replace('\\', '\\\\', $namespace) . '\\\\'; 251 $namespacePath = rtrim($extensionPath . $namespaceNode->attributes()->path, '/'); 252 253 if ($type === 'plugin' || $type === 'library') { 254 $baseDir = $type === 'plugin' ? 'JPATH_PLUGINS . \'' : 'JPATH_LIBRARIES . \''; 255 $path = str_replace($type === 'plugin' ? JPATH_PLUGINS : JPATH_LIBRARIES, '', $namespacePath); 256 257 // Set the namespace 258 $extensions[$namespace] = $baseDir . $path . '\''; 259 260 continue; 261 } 262 263 // Check if we need to use administrator path 264 $isAdministrator = strpos($namespacePath, JPATH_ADMINISTRATOR) === 0; 265 $path = str_replace($isAdministrator ? JPATH_ADMINISTRATOR : JPATH_SITE, '', $namespacePath); 266 267 // Add the site path when a component 268 if ($type === 'component') { 269 if (is_dir(JPATH_SITE . $path)) { 270 $extensions[$namespace . 'Site\\\\'] = 'JPATH_SITE . \'' . $path . '\''; 271 } 272 273 if (is_dir(JPATH_API . $path)) { 274 $extensions[$namespace . 'Api\\\\'] = 'JPATH_API . \'' . $path . '\''; 275 } 276 } 277 278 // Add the application specific segment when a component or module 279 $baseDir = $isAdministrator ? 'JPATH_ADMINISTRATOR . \'' : 'JPATH_SITE . \''; 280 $namespace .= $isAdministrator ? 'Administrator\\\\' : 'Site\\\\'; 281 282 // Set the namespace 283 $extensions[$namespace] = $baseDir . $path . '\''; 284 } 285 } 286 287 // Return the namespaces 288 return $extensions; 289 } 290 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |