[ 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) 2006 Open Source Matters, Inc. <https://www.joomla.org> 7 * @license GNU General Public License version 2 or later; see LICENSE.txt 8 */ 9 10 namespace Joomla\CMS\Component; 11 12 use Joomla\CMS\Access\Access; 13 use Joomla\CMS\Cache\CacheControllerFactoryInterface; 14 use Joomla\CMS\Cache\Controller\CallbackController; 15 use Joomla\CMS\Cache\Exception\CacheExceptionInterface; 16 use Joomla\CMS\Component\Exception\MissingComponentException; 17 use Joomla\CMS\Dispatcher\ApiDispatcher; 18 use Joomla\CMS\Dispatcher\ComponentDispatcher; 19 use Joomla\CMS\Factory; 20 use Joomla\CMS\Filter\InputFilter; 21 use Joomla\CMS\Language\Text; 22 use Joomla\CMS\Profiler\Profiler; 23 use Joomla\Registry\Registry; 24 25 // phpcs:disable PSR1.Files.SideEffects 26 \defined('JPATH_PLATFORM') or die; 27 // phpcs:enable PSR1.Files.SideEffects 28 29 /** 30 * Component helper class 31 * 32 * @since 1.5 33 */ 34 class ComponentHelper 35 { 36 /** 37 * The component list cache 38 * 39 * @var ComponentRecord[] 40 * @since 1.6 41 */ 42 protected static $components = array(); 43 44 /** 45 * Get the component information. 46 * 47 * @param string $option The component option. 48 * @param boolean $strict If set and the component does not exist, the enabled attribute will be set to false. 49 * 50 * @return ComponentRecord An object with the information for the component. 51 * 52 * @since 1.5 53 */ 54 public static function getComponent($option, $strict = false) 55 { 56 $components = static::getComponents(); 57 58 if (isset($components[$option])) { 59 return $components[$option]; 60 } 61 62 $result = new ComponentRecord(); 63 $result->enabled = $strict ? false : true; 64 $result->setParams(new Registry()); 65 66 return $result; 67 } 68 69 /** 70 * Checks if the component is enabled 71 * 72 * @param string $option The component option. 73 * 74 * @return boolean 75 * 76 * @since 1.5 77 */ 78 public static function isEnabled($option) 79 { 80 $components = static::getComponents(); 81 82 return isset($components[$option]) && $components[$option]->enabled; 83 } 84 85 /** 86 * Checks if a component is installed 87 * 88 * @param string $option The component option. 89 * 90 * @return integer 91 * 92 * @since 3.4 93 */ 94 public static function isInstalled($option) 95 { 96 $components = static::getComponents(); 97 98 return isset($components[$option]) ? 1 : 0; 99 } 100 101 /** 102 * Gets the parameter object for the component 103 * 104 * @param string $option The option for the component. 105 * @param boolean $strict If set and the component does not exist, false will be returned 106 * 107 * @return Registry A Registry object. 108 * 109 * @see Registry 110 * @since 1.5 111 */ 112 public static function getParams($option, $strict = false) 113 { 114 return static::getComponent($option, $strict)->getParams(); 115 } 116 117 /** 118 * Applies the global text filters to arbitrary text as per settings for current user groups 119 * 120 * @param string $text The string to filter 121 * 122 * @return string The filtered string 123 * 124 * @since 2.5 125 */ 126 public static function filterText($text) 127 { 128 // Punyencoding utf8 email addresses 129 $text = InputFilter::getInstance()->emailToPunycode($text); 130 131 // Filter settings 132 $config = static::getParams('com_config'); 133 $user = Factory::getUser(); 134 $userGroups = Access::getGroupsByUser($user->get('id')); 135 136 $filters = $config->get('filters'); 137 138 $forbiddenListTags = array(); 139 $forbiddenListAttributes = array(); 140 141 $customListTags = array(); 142 $customListAttributes = array(); 143 144 $allowedListTags = array(); 145 $allowedListAttributes = array(); 146 147 $allowedList = false; 148 $forbiddenList = false; 149 $customList = false; 150 $unfiltered = false; 151 152 // Cycle through each of the user groups the user is in. 153 // Remember they are included in the Public group as well. 154 foreach ($userGroups as $groupId) { 155 // May have added a group by not saved the filters. 156 if (!isset($filters->$groupId)) { 157 continue; 158 } 159 160 // Each group the user is in could have different filtering properties. 161 $filterData = $filters->$groupId; 162 $filterType = strtoupper($filterData->filter_type); 163 164 if ($filterType === 'NH') { 165 // Maximum HTML filtering. 166 } elseif ($filterType === 'NONE') { 167 // No HTML filtering. 168 $unfiltered = true; 169 } else { 170 // Forbidden list or allowed list. 171 // Preprocess the tags and attributes. 172 $tags = explode(',', $filterData->filter_tags); 173 $attributes = explode(',', $filterData->filter_attributes); 174 $tempTags = array(); 175 $tempAttributes = array(); 176 177 foreach ($tags as $tag) { 178 $tag = trim($tag); 179 180 if ($tag) { 181 $tempTags[] = $tag; 182 } 183 } 184 185 foreach ($attributes as $attribute) { 186 $attribute = trim($attribute); 187 188 if ($attribute) { 189 $tempAttributes[] = $attribute; 190 } 191 } 192 193 // Collect the forbidden list or allowed list tags and attributes. 194 // Each list is cumulative. 195 if ($filterType === 'BL') { 196 $forbiddenList = true; 197 $forbiddenListTags = array_merge($forbiddenListTags, $tempTags); 198 $forbiddenListAttributes = array_merge($forbiddenListAttributes, $tempAttributes); 199 } elseif ($filterType === 'CBL') { 200 // Only set to true if Tags or Attributes were added 201 if ($tempTags || $tempAttributes) { 202 $customList = true; 203 $customListTags = array_merge($customListTags, $tempTags); 204 $customListAttributes = array_merge($customListAttributes, $tempAttributes); 205 } 206 } elseif ($filterType === 'WL') { 207 $allowedList = true; 208 $allowedListTags = array_merge($allowedListTags, $tempTags); 209 $allowedListAttributes = array_merge($allowedListAttributes, $tempAttributes); 210 } 211 } 212 } 213 214 // Remove duplicates before processing (because the forbidden list uses both sets of arrays). 215 $forbiddenListTags = array_unique($forbiddenListTags); 216 $forbiddenListAttributes = array_unique($forbiddenListAttributes); 217 $customListTags = array_unique($customListTags); 218 $customListAttributes = array_unique($customListAttributes); 219 $allowedListTags = array_unique($allowedListTags); 220 $allowedListAttributes = array_unique($allowedListAttributes); 221 222 if (!$unfiltered) { 223 // Custom Forbidden list precedes Default forbidden list. 224 if ($customList) { 225 $filter = InputFilter::getInstance(array(), array(), 1, 1); 226 227 // Override filter's default forbidden tags and attributes 228 if ($customListTags) { 229 $filter->blockedTags = $customListTags; 230 } 231 232 if ($customListAttributes) { 233 $filter->blockedAttributes = $customListAttributes; 234 } 235 } elseif ($forbiddenList) { 236 // Forbidden list takes second precedence. 237 // Remove the allowed tags and attributes from the forbidden list. 238 $forbiddenListTags = array_diff($forbiddenListTags, $allowedListTags); 239 $forbiddenListAttributes = array_diff($forbiddenListAttributes, $allowedListAttributes); 240 241 $filter = InputFilter::getInstance( 242 $forbiddenListTags, 243 $forbiddenListAttributes, 244 InputFilter::ONLY_BLOCK_DEFINED_TAGS, 245 InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES 246 ); 247 248 // Remove the allowed tags from filter's default forbidden list. 249 if ($allowedListTags) { 250 $filter->blockedTags = array_diff($filter->blockedTags, $allowedListTags); 251 } 252 253 // Remove the allowed attributes from filter's default forbidden list. 254 if ($allowedListAttributes) { 255 $filter->blockedAttributes = array_diff($filter->blockedAttributes, $allowedListAttributes); 256 } 257 } elseif ($allowedList) { 258 // Allowed lists take third precedence. 259 // Turn off XSS auto clean 260 $filter = InputFilter::getInstance($allowedListTags, $allowedListAttributes, 0, 0, 0); 261 } else { 262 // No HTML takes last place. 263 $filter = InputFilter::getInstance(); 264 } 265 266 $text = $filter->clean($text, 'html'); 267 } 268 269 return $text; 270 } 271 272 /** 273 * Render the component. 274 * 275 * @param string $option The component option. 276 * @param array $params The component parameters 277 * 278 * @return string 279 * 280 * @since 1.5 281 * @throws MissingComponentException 282 */ 283 public static function renderComponent($option, $params = array()) 284 { 285 $app = Factory::getApplication(); 286 $lang = Factory::getLanguage(); 287 288 if (!$app->isClient('api')) { 289 // Load template language files. 290 $template = $app->getTemplate(true)->template; 291 $lang->load('tpl_' . $template, JPATH_BASE) 292 || $lang->load('tpl_' . $template, JPATH_THEMES . "/$template"); 293 } 294 295 if (empty($option)) { 296 throw new MissingComponentException(Text::_('JLIB_APPLICATION_ERROR_COMPONENT_NOT_FOUND'), 404); 297 } 298 299 if (JDEBUG) { 300 Profiler::getInstance('Application')->mark('beforeRenderComponent ' . $option); 301 } 302 303 // Record the scope 304 $scope = $app->scope; 305 306 // Set scope to component name 307 $app->scope = $option; 308 309 // Build the component path. 310 $option = preg_replace('/[^A-Z0-9_\.-]/i', '', $option); 311 312 // Define component path. 313 314 if (!\defined('JPATH_COMPONENT')) { 315 /** 316 * Defines the path to the active component for the request 317 * 318 * Note this constant is application aware and is different for each application (site/admin). 319 * 320 * @var string 321 * @since 1.5 322 * @deprecated 5.0 without replacement 323 */ 324 \define('JPATH_COMPONENT', JPATH_BASE . '/components/' . $option); 325 } 326 327 if (!\defined('JPATH_COMPONENT_SITE')) { 328 /** 329 * Defines the path to the site element of the active component for the request 330 * 331 * @var string 332 * @since 1.5 333 * @deprecated 5.0 without replacement 334 */ 335 \define('JPATH_COMPONENT_SITE', JPATH_SITE . '/components/' . $option); 336 } 337 338 if (!\defined('JPATH_COMPONENT_ADMINISTRATOR')) { 339 /** 340 * Defines the path to the admin element of the active component for the request 341 * 342 * @var string 343 * @since 1.5 344 * @deprecated 5.0 without replacement 345 */ 346 \define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR . '/components/' . $option); 347 } 348 349 // If component is disabled throw error 350 if (!static::isEnabled($option)) { 351 throw new MissingComponentException(Text::_('JLIB_APPLICATION_ERROR_COMPONENT_NOT_FOUND'), 404); 352 } 353 354 ob_start(); 355 $app->bootComponent($option)->getDispatcher($app)->dispatch(); 356 $contents = ob_get_clean(); 357 358 // Revert the scope 359 $app->scope = $scope; 360 361 if (JDEBUG) { 362 Profiler::getInstance('Application')->mark('afterRenderComponent ' . $option); 363 } 364 365 return $contents; 366 } 367 368 /** 369 * Load the installed components into the components property. 370 * 371 * @return boolean True on success 372 * 373 * @since 3.2 374 */ 375 protected static function load() 376 { 377 $loader = function () { 378 $db = Factory::getDbo(); 379 $query = $db->getQuery(true) 380 ->select($db->quoteName(['extension_id', 'element', 'params', 'enabled'], ['id', 'option', null, null])) 381 ->from($db->quoteName('#__extensions')) 382 ->where( 383 [ 384 $db->quoteName('type') . ' = ' . $db->quote('component'), 385 $db->quoteName('state') . ' = 0', 386 $db->quoteName('enabled') . ' = 1', 387 ] 388 ); 389 390 $components = []; 391 $db->setQuery($query); 392 393 foreach ($db->getIterator() as $component) { 394 $components[$component->option] = new ComponentRecord((array) $component); 395 } 396 397 return $components; 398 }; 399 400 /** @var CallbackController $cache */ 401 $cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class)->createCacheController('callback', ['defaultgroup' => '_system']); 402 403 try { 404 static::$components = $cache->get($loader, array(), __METHOD__); 405 } catch (CacheExceptionInterface $e) { 406 static::$components = $loader(); 407 } 408 409 return true; 410 } 411 412 /** 413 * Get installed components 414 * 415 * @return ComponentRecord[] The components property 416 * 417 * @since 3.6.3 418 */ 419 public static function getComponents() 420 { 421 if (empty(static::$components)) { 422 static::load(); 423 } 424 425 return static::$components; 426 } 427 428 /** 429 * Returns the component name (eg. com_content) for the given object based on the class name. 430 * If the object is not namespaced, then the alternative name is used. 431 * 432 * @param object $object The object controller or model 433 * @param string $alternativeName Mostly the value of getName() from the object 434 * 435 * @return string The name 436 * 437 * @since 4.0.0 438 */ 439 public static function getComponentName($object, string $alternativeName): string 440 { 441 $reflect = new \ReflectionClass($object); 442 443 if (!$reflect->getNamespaceName() || \get_class($object) === ComponentDispatcher::class || \get_class($object) === ApiDispatcher::class) { 444 return 'com_' . strtolower($alternativeName); 445 } 446 447 $from = strpos($reflect->getNamespaceName(), '\\Component'); 448 $to = strpos(substr($reflect->getNamespaceName(), $from + 11), '\\'); 449 450 return 'com_' . strtolower(substr($reflect->getNamespaceName(), $from + 11, $to)); 451 } 452 }
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 |