[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/administrator/components/com_finder/src/Service/HTML/ -> Filter.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Administrator
   5   * @subpackage  com_finder
   6   *
   7   * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9   */
  10  
  11  namespace Joomla\Component\Finder\Administrator\Service\HTML;
  12  
  13  use Joomla\CMS\Factory;
  14  use Joomla\CMS\Filter\OutputFilter;
  15  use Joomla\CMS\HTML\HTMLHelper;
  16  use Joomla\CMS\Language\Multilanguage;
  17  use Joomla\CMS\Language\Text;
  18  use Joomla\Component\Finder\Administrator\Helper\LanguageHelper;
  19  use Joomla\Component\Finder\Administrator\Indexer\Query;
  20  use Joomla\Database\DatabaseAwareTrait;
  21  use Joomla\Registry\Registry;
  22  
  23  // phpcs:disable PSR1.Files.SideEffects
  24  \defined('_JEXEC') or die;
  25  // phpcs:enable PSR1.Files.SideEffects
  26  
  27  /**
  28   * Filter HTML Behaviors for Finder.
  29   *
  30   * @since  2.5
  31   */
  32  class Filter
  33  {
  34      use DatabaseAwareTrait;
  35  
  36      /**
  37       * Method to generate filters using the slider widget and decorated
  38       * with the FinderFilter JavaScript behaviors.
  39       *
  40       * @param   array  $options  An array of configuration options. [optional]
  41       *
  42       * @return  mixed  A rendered HTML widget on success, null otherwise.
  43       *
  44       * @since   2.5
  45       */
  46      public function slider($options = array())
  47      {
  48          $db     = $this->getDatabase();
  49          $query  = $db->getQuery(true);
  50          $user   = Factory::getUser();
  51          $groups = implode(',', $user->getAuthorisedViewLevels());
  52          $html   = '';
  53          $filter = null;
  54  
  55          // Get the configuration options.
  56          $filterId    = $options['filter_id'] ?? null;
  57          $activeNodes = array_key_exists('selected_nodes', $options) ? $options['selected_nodes'] : array();
  58          $classSuffix = array_key_exists('class_suffix', $options) ? $options['class_suffix'] : '';
  59  
  60          // Load the predefined filter if specified.
  61          if (!empty($filterId)) {
  62              $query->select('f.data, f.params')
  63                  ->from($db->quoteName('#__finder_filters') . ' AS f')
  64                  ->where('f.filter_id = ' . (int) $filterId);
  65  
  66              // Load the filter data.
  67              $db->setQuery($query);
  68  
  69              try {
  70                  $filter = $db->loadObject();
  71              } catch (\RuntimeException $e) {
  72                  return null;
  73              }
  74  
  75              // Initialize the filter parameters.
  76              if ($filter) {
  77                  $filter->params = new Registry($filter->params);
  78              }
  79          }
  80  
  81          // Build the query to get the branch data and the number of child nodes.
  82          $query->clear()
  83              ->select('t.*, count(c.id) AS children')
  84              ->from($db->quoteName('#__finder_taxonomy') . ' AS t')
  85              ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS c ON c.parent_id = t.id')
  86              ->where('t.parent_id = 1')
  87              ->where('t.state = 1')
  88              ->where('t.access IN (' . $groups . ')')
  89              ->group('t.id, t.parent_id, t.state, t.access, t.title, c.parent_id')
  90              ->order('t.lft, t.title');
  91  
  92          // Limit the branch children to a predefined filter.
  93          if ($filter) {
  94              $query->where('c.id IN(' . $filter->data . ')');
  95          }
  96  
  97          // Load the branches.
  98          $db->setQuery($query);
  99  
 100          try {
 101              $branches = $db->loadObjectList('id');
 102          } catch (\RuntimeException $e) {
 103              return null;
 104          }
 105  
 106          // Check that we have at least one branch.
 107          if (count($branches) === 0) {
 108              return null;
 109          }
 110  
 111          $branch_keys = array_keys($branches);
 112          $html .= HTMLHelper::_('bootstrap.startAccordion', 'accordion', array('active' => 'accordion-' . $branch_keys[0]));
 113  
 114          // Load plugin language files.
 115          LanguageHelper::loadPluginLanguage();
 116  
 117          // Iterate through the branches and build the branch groups.
 118          foreach ($branches as $bk => $bv) {
 119              // If the multi-lang plugin is enabled then drop the language branch.
 120              if ($bv->title === 'Language' && Multilanguage::isEnabled()) {
 121                  continue;
 122              }
 123  
 124              // Build the query to get the child nodes for this branch.
 125              $query->clear()
 126                  ->select('t.*')
 127                  ->from($db->quoteName('#__finder_taxonomy') . ' AS t')
 128                  ->where('t.lft > ' . (int) $bv->lft)
 129                  ->where('t.rgt < ' . (int) $bv->rgt)
 130                  ->where('t.state = 1')
 131                  ->where('t.access IN (' . $groups . ')')
 132                  ->order('t.lft, t.title');
 133  
 134              // Self-join to get the parent title.
 135              $query->select('e.title AS parent_title')
 136                  ->join('LEFT', $db->quoteName('#__finder_taxonomy', 'e') . ' ON ' . $db->quoteName('e.id') . ' = ' . $db->quoteName('t.parent_id'));
 137  
 138              // Load the branches.
 139              $db->setQuery($query);
 140  
 141              try {
 142                  $nodes = $db->loadObjectList('id');
 143              } catch (\RuntimeException $e) {
 144                  return null;
 145              }
 146  
 147              // Translate node titles if possible.
 148              $lang = Factory::getLanguage();
 149  
 150              foreach ($nodes as $nk => $nv) {
 151                  if (trim($nv->parent_title, '*') === 'Language') {
 152                      $title = LanguageHelper::branchLanguageTitle($nv->title);
 153                  } else {
 154                      $key = LanguageHelper::branchPlural($nv->title);
 155                      $title = $lang->hasKey($key) ? Text::_($key) : $nv->title;
 156                  }
 157  
 158                  $nodes[$nk]->title = $title;
 159              }
 160  
 161              // Adding slides
 162              $html .= HTMLHelper::_(
 163                  'bootstrap.addSlide',
 164                  'accordion',
 165                  Text::sprintf(
 166                      'COM_FINDER_FILTER_BRANCH_LABEL',
 167                      Text::_(LanguageHelper::branchSingular($bv->title)) . ' - ' . count($nodes)
 168                  ),
 169                  'accordion-' . $bk
 170              );
 171  
 172              // Populate the toggle button.
 173              $html .= '<button class="btn btn-secondary js-filter" type="button" data-id="tax-' . $bk . '"><span class="icon-square" aria-hidden="true"></span> '
 174                  . Text::_('JGLOBAL_SELECTION_INVERT') . '</button><hr>';
 175  
 176              // Populate the group with nodes.
 177              foreach ($nodes as $nk => $nv) {
 178                  // Determine if the node should be checked.
 179                  $checked = in_array($nk, $activeNodes) ? ' checked="checked"' : '';
 180  
 181                  // Build a node.
 182                  $html .= '<div class="form-check">';
 183                  $html .= '<label class="form-check-label">';
 184                  $html .= '<input type="checkbox" class="form-check-input selector filter-node' . $classSuffix
 185                      . ' tax-' . $bk . '" value="' . $nk . '" name="t[]"' . $checked . '> ' . str_repeat('&mdash;', $nv->level - 2) . $nv->title;
 186                  $html .= '</label>';
 187                  $html .= '</div>';
 188              }
 189  
 190              $html .= HTMLHelper::_('bootstrap.endSlide');
 191          }
 192  
 193          $html .= HTMLHelper::_('bootstrap.endAccordion');
 194  
 195          return $html;
 196      }
 197  
 198      /**
 199       * Method to generate filters using select box dropdown controls.
 200       *
 201       * @param   Query  $idxQuery  A Query object.
 202       * @param   array  $options   An array of options.
 203       *
 204       * @return  mixed  A rendered HTML widget on success, null otherwise.
 205       *
 206       * @since   2.5
 207       */
 208      public function select($idxQuery, $options)
 209      {
 210          $user   = Factory::getUser();
 211          $groups = implode(',', $user->getAuthorisedViewLevels());
 212          $filter = null;
 213  
 214          // Get the configuration options.
 215          $classSuffix = $options->get('class_suffix', null);
 216          $showDates   = $options->get('show_date_filters', false);
 217  
 218          // Try to load the results from cache.
 219          $cache   = Factory::getCache('com_finder', '');
 220          $cacheId = 'filter_select_' . serialize(array($idxQuery->filter, $options, $groups, Factory::getLanguage()->getTag()));
 221  
 222          // Check the cached results.
 223          if ($cache->contains($cacheId)) {
 224              $branches = $cache->get($cacheId);
 225          } else {
 226              $db    = $this->getDatabase();
 227              $query = $db->getQuery(true);
 228  
 229              // Load the predefined filter if specified.
 230              if (!empty($idxQuery->filter)) {
 231                  $query->select('f.data, ' . $db->quoteName('f.params'))
 232                      ->from($db->quoteName('#__finder_filters') . ' AS f')
 233                      ->where('f.filter_id = ' . (int) $idxQuery->filter);
 234  
 235                  // Load the filter data.
 236                  $db->setQuery($query);
 237  
 238                  try {
 239                      $filter = $db->loadObject();
 240                  } catch (\RuntimeException $e) {
 241                      return null;
 242                  }
 243  
 244                  // Initialize the filter parameters.
 245                  if ($filter) {
 246                      $filter->params = new Registry($filter->params);
 247                  }
 248              }
 249  
 250              // Build the query to get the branch data and the number of child nodes.
 251              $query->clear()
 252                  ->select('t.*, count(c.id) AS children')
 253                  ->from($db->quoteName('#__finder_taxonomy') . ' AS t')
 254                  ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS c ON c.parent_id = t.id')
 255                  ->where('t.parent_id = 1')
 256                  ->where('t.state = 1')
 257                  ->where('t.access IN (' . $groups . ')')
 258                  ->where('c.state = 1')
 259                  ->where('c.access IN (' . $groups . ')')
 260                  ->group($db->quoteName('t.id'))
 261                  ->group($db->quoteName('t.parent_id'))
 262                  ->group('t.title, t.state, t.access, t.lft')
 263                  ->order('t.lft, t.title');
 264  
 265              // Limit the branch children to a predefined filter.
 266              if (!empty($filter->data)) {
 267                  $query->where('c.id IN(' . $filter->data . ')');
 268              }
 269  
 270              // Load the branches.
 271              $db->setQuery($query);
 272  
 273              try {
 274                  $branches = $db->loadObjectList('id');
 275              } catch (\RuntimeException $e) {
 276                  return null;
 277              }
 278  
 279              // Check that we have at least one branch.
 280              if (count($branches) === 0) {
 281                  return null;
 282              }
 283  
 284              // Iterate through the branches and build the branch groups.
 285              foreach ($branches as $bk => $bv) {
 286                  // If the multi-lang plugin is enabled then drop the language branch.
 287                  if ($bv->title === 'Language' && Multilanguage::isEnabled()) {
 288                      continue;
 289                  }
 290  
 291                  // Build the query to get the child nodes for this branch.
 292                  $query->clear()
 293                      ->select('t.*')
 294                      ->from($db->quoteName('#__finder_taxonomy') . ' AS t')
 295                      ->where('t.lft > ' . (int) $bv->lft)
 296                      ->where('t.rgt < ' . (int) $bv->rgt)
 297                      ->where('t.state = 1')
 298                      ->where('t.access IN (' . $groups . ')')
 299                      ->order('t.title');
 300  
 301                  // Self-join to get the parent title.
 302                  $query->select('e.title AS parent_title')
 303                      ->join('LEFT', $db->quoteName('#__finder_taxonomy', 'e') . ' ON ' . $db->quoteName('e.id') . ' = ' . $db->quoteName('t.parent_id'));
 304  
 305                  // Limit the nodes to a predefined filter.
 306                  if (!empty($filter->data)) {
 307                      $query->where('t.id IN(' . $filter->data . ')');
 308                  }
 309  
 310                  // Load the branches.
 311                  $db->setQuery($query);
 312  
 313                  try {
 314                      $branches[$bk]->nodes = $db->loadObjectList('id');
 315                  } catch (\RuntimeException $e) {
 316                      return null;
 317                  }
 318  
 319                  // Translate branch nodes if possible.
 320                  $language = Factory::getLanguage();
 321  
 322                  foreach ($branches[$bk]->nodes as $node_id => $node) {
 323                      if (trim($node->parent_title, '*') === 'Language') {
 324                          $title = LanguageHelper::branchLanguageTitle($node->title);
 325                      } else {
 326                          $key = LanguageHelper::branchPlural($node->title);
 327                          $title = $language->hasKey($key) ? Text::_($key) : $node->title;
 328                      }
 329  
 330                      if ($node->level > 2) {
 331                          $branches[$bk]->nodes[$node_id]->title = str_repeat('-', $node->level - 2) . $title;
 332                      } else {
 333                          $branches[$bk]->nodes[$node_id]->title = $title;
 334                      }
 335                  }
 336  
 337                  // Add the Search All option to the branch.
 338                  array_unshift($branches[$bk]->nodes, array('id' => null, 'title' => Text::_('COM_FINDER_FILTER_SELECT_ALL_LABEL')));
 339              }
 340  
 341              // Store the data in cache.
 342              $cache->store($branches, $cacheId);
 343          }
 344  
 345          $html = '';
 346  
 347          // Add the dates if enabled.
 348          if ($showDates) {
 349              $html .= HTMLHelper::_('filter.dates', $idxQuery, $options);
 350          }
 351  
 352          $html .= '<div class="filter-branch' . $classSuffix . '">';
 353  
 354          // Iterate through all branches and build code.
 355          foreach ($branches as $bk => $bv) {
 356              // If the multi-lang plugin is enabled then drop the language branch.
 357              if ($bv->title === 'Language' && Multilanguage::isEnabled()) {
 358                  continue;
 359              }
 360  
 361              $active = null;
 362  
 363              // Check if the branch is in the filter.
 364              if (array_key_exists($bv->title, $idxQuery->filters)) {
 365                  // Get the request filters.
 366                  $temp   = Factory::getApplication()->input->request->get('t', array(), 'array');
 367  
 368                  // Search for active nodes in the branch and get the active node.
 369                  $active = array_intersect($temp, $idxQuery->filters[$bv->title]);
 370                  $active = count($active) === 1 ? array_shift($active) : null;
 371              }
 372  
 373              // Build a node.
 374              $html .= '<div class="control-group">';
 375              $html .= '<div class="control-label">';
 376              $html .= '<label for="tax-' . OutputFilter::stringURLSafe($bv->title) . '">';
 377              $html .= Text::sprintf('COM_FINDER_FILTER_BRANCH_LABEL', Text::_(LanguageHelper::branchSingular($bv->title)));
 378              $html .= '</label>';
 379              $html .= '</div>';
 380              $html .= '<div class="controls">';
 381              $html .= HTMLHelper::_(
 382                  'select.genericlist',
 383                  $branches[$bk]->nodes,
 384                  't[]',
 385                  'class="form-select advancedSelect"',
 386                  'id',
 387                  'title',
 388                  $active,
 389                  'tax-' . OutputFilter::stringURLSafe($bv->title)
 390              );
 391              $html .= '</div>';
 392              $html .= '</div>';
 393          }
 394  
 395          $html .= '</div>';
 396  
 397          return $html;
 398      }
 399  
 400      /**
 401       * Method to generate fields for filtering dates
 402       *
 403       * @param   Query  $idxQuery  A Query object.
 404       * @param   array  $options   An array of options.
 405       *
 406       * @return  mixed  A rendered HTML widget on success, null otherwise.
 407       *
 408       * @since   2.5
 409       */
 410      public function dates($idxQuery, $options)
 411      {
 412          $html = '';
 413  
 414          // Get the configuration options.
 415          $classSuffix = $options->get('class_suffix', null);
 416          $loadMedia   = $options->get('load_media', true);
 417          $showDates   = $options->get('show_date_filters', false);
 418  
 419          if (!empty($showDates)) {
 420              // Build the date operators options.
 421              $operators   = array();
 422              $operators[] = HTMLHelper::_('select.option', 'before', Text::_('COM_FINDER_FILTER_DATE_BEFORE'));
 423              $operators[] = HTMLHelper::_('select.option', 'exact', Text::_('COM_FINDER_FILTER_DATE_EXACTLY'));
 424              $operators[] = HTMLHelper::_('select.option', 'after', Text::_('COM_FINDER_FILTER_DATE_AFTER'));
 425  
 426              // Load the CSS/JS resources.
 427              if ($loadMedia) {
 428                  /** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
 429                  $wa = Factory::getApplication()->getDocument()->getWebAssetManager();
 430                  $wa->useStyle('com_finder.dates');
 431              }
 432  
 433              // Open the widget.
 434              $html .= '<ul id="finder-filter-select-dates">';
 435  
 436              // Start date filter.
 437              $attribs['class'] = 'input-medium';
 438              $html .= '<li class="filter-date float-start' . $classSuffix . '">';
 439              $html .= '<label for="filter_date1" class="hasTooltip" title ="' . Text::_('COM_FINDER_FILTER_DATE1_DESC') . '">';
 440              $html .= Text::_('COM_FINDER_FILTER_DATE1');
 441              $html .= '</label>';
 442              $html .= '<br>';
 443              $html .= HTMLHelper::_(
 444                  'select.genericlist',
 445                  $operators,
 446                  'w1',
 447                  'class="inputbox filter-date-operator advancedSelect form-select w-auto mb-2"',
 448                  'value',
 449                  'text',
 450                  $idxQuery->when1,
 451                  'finder-filter-w1'
 452              );
 453              $html .= HTMLHelper::_('calendar', $idxQuery->date1, 'd1', 'filter_date1', '%Y-%m-%d', $attribs);
 454              $html .= '</li>';
 455  
 456              // End date filter.
 457              $html .= '<li class="filter-date float-end' . $classSuffix . '">';
 458              $html .= '<label for="filter_date2" class="hasTooltip" title ="' . Text::_('COM_FINDER_FILTER_DATE2_DESC') . '">';
 459              $html .= Text::_('COM_FINDER_FILTER_DATE2');
 460              $html .= '</label>';
 461              $html .= '<br>';
 462              $html .= HTMLHelper::_(
 463                  'select.genericlist',
 464                  $operators,
 465                  'w2',
 466                  'class="inputbox filter-date-operator advancedSelect form-select w-auto mb-2"',
 467                  'value',
 468                  'text',
 469                  $idxQuery->when2,
 470                  'finder-filter-w2'
 471              );
 472              $html .= HTMLHelper::_('calendar', $idxQuery->date2, 'd2', 'filter_date2', '%Y-%m-%d', $attribs);
 473              $html .= '</li>';
 474  
 475              // Close the widget.
 476              $html .= '</ul>';
 477          }
 478  
 479          return $html;
 480      }
 481  }


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