[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Component/ -> ComponentHelper.php (source)

   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  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer