primo commit
This commit is contained in:
		
							
								
								
									
										530
									
								
								administrator/components/com_finder/src/Service/HTML/Filter.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										530
									
								
								administrator/components/com_finder/src/Service/HTML/Filter.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,530 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_finder | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Finder\Administrator\Service\HTML; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\HTML\HTMLHelper; | ||||
| use Joomla\CMS\Language\Multilanguage; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\Component\Finder\Administrator\Helper\LanguageHelper; | ||||
| use Joomla\Component\Finder\Administrator\Indexer\Query; | ||||
| use Joomla\Database\DatabaseAwareTrait; | ||||
| use Joomla\Database\ParameterType; | ||||
| use Joomla\Filter\OutputFilter; | ||||
| use Joomla\Registry\Registry; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Filter HTML Behaviors for Finder. | ||||
|  * | ||||
|  * @since  2.5 | ||||
|  */ | ||||
| class Filter | ||||
| { | ||||
|     use DatabaseAwareTrait; | ||||
|  | ||||
|     /** | ||||
|      * Method to generate filters using the slider widget and decorated | ||||
|      * with the FinderFilter JavaScript behaviors. | ||||
|      * | ||||
|      * @param   array  $options  An array of configuration options. [optional] | ||||
|      * | ||||
|      * @return  mixed  A rendered HTML widget on success, null otherwise. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function slider($options = []) | ||||
|     { | ||||
|         $db     = $this->getDatabase(); | ||||
|         $query  = $db->getQuery(true); | ||||
|         $user   = Factory::getUser(); | ||||
|         $groups = implode(',', $user->getAuthorisedViewLevels()); | ||||
|         $html   = ''; | ||||
|         $filter = null; | ||||
|  | ||||
|         // Get the configuration options. | ||||
|         $filterId    = $options['filter_id'] ?? null; | ||||
|         $activeNodes = \array_key_exists('selected_nodes', $options) ? $options['selected_nodes'] : []; | ||||
|         $classSuffix = \array_key_exists('class_suffix', $options) ? $options['class_suffix'] : ''; | ||||
|  | ||||
|         // Load the predefined filter if specified. | ||||
|         if (!empty($filterId)) { | ||||
|             $query->select('f.data, f.params') | ||||
|                 ->from($db->quoteName('#__finder_filters') . ' AS f') | ||||
|                 ->where('f.filter_id = ' . (int) $filterId); | ||||
|  | ||||
|             // Load the filter data. | ||||
|             $db->setQuery($query); | ||||
|  | ||||
|             try { | ||||
|                 $filter = $db->loadObject(); | ||||
|             } catch (\RuntimeException $e) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             // Initialize the filter parameters. | ||||
|             if ($filter) { | ||||
|                 $filter->params = new Registry($filter->params); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Build the query to get the branch data and the number of child nodes. | ||||
|         $query->clear() | ||||
|             ->select('t.*, count(c.id) AS children') | ||||
|             ->from($db->quoteName('#__finder_taxonomy') . ' AS t') | ||||
|             ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS c ON c.parent_id = t.id') | ||||
|             ->where('t.parent_id = 1') | ||||
|             ->where('t.state = 1') | ||||
|             ->where('t.access IN (' . $groups . ')') | ||||
|             ->group('t.id, t.parent_id, t.state, t.access, t.title, c.parent_id') | ||||
|             ->order('t.lft, t.title'); | ||||
|  | ||||
|         // Limit the branch children to a predefined filter. | ||||
|         if ($filter) { | ||||
|             $query->where('c.id IN(' . $filter->data . ')'); | ||||
|         } | ||||
|  | ||||
|         // Load the branches. | ||||
|         $db->setQuery($query); | ||||
|  | ||||
|         try { | ||||
|             $branches = $db->loadObjectList('id'); | ||||
|         } catch (\RuntimeException $e) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         // Check that we have at least one branch. | ||||
|         if (\count($branches) === 0) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         $branch_keys = array_keys($branches); | ||||
|         $html .= HTMLHelper::_('bootstrap.startAccordion', 'accordion', ['active' => 'accordion-' . $branch_keys[0]]); | ||||
|  | ||||
|         // Load plugin language files. | ||||
|         LanguageHelper::loadPluginLanguage(); | ||||
|  | ||||
|         // Iterate through the branches and build the branch groups. | ||||
|         foreach ($branches as $bk => $bv) { | ||||
|             // If the multi-lang plugin is enabled then drop the language branch. | ||||
|             if ($bv->title === 'Language' && Multilanguage::isEnabled()) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // Build the query to get the child nodes for this branch. | ||||
|             $query->clear() | ||||
|                 ->select('t.*') | ||||
|                 ->from($db->quoteName('#__finder_taxonomy') . ' AS t') | ||||
|                 ->where('t.lft > ' . (int) $bv->lft) | ||||
|                 ->where('t.rgt < ' . (int) $bv->rgt) | ||||
|                 ->where('t.state = 1') | ||||
|                 ->where('t.access IN (' . $groups . ')') | ||||
|                 ->order('t.lft, t.title'); | ||||
|  | ||||
|             // Self-join to get the parent title. | ||||
|             $query->select('e.title AS parent_title') | ||||
|                 ->join('LEFT', $db->quoteName('#__finder_taxonomy', 'e') . ' ON ' . $db->quoteName('e.id') . ' = ' . $db->quoteName('t.parent_id')); | ||||
|  | ||||
|             // Load the branches. | ||||
|             $db->setQuery($query); | ||||
|  | ||||
|             try { | ||||
|                 $nodes = $db->loadObjectList('id'); | ||||
|             } catch (\RuntimeException $e) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             // Translate node titles if possible. | ||||
|             $lang = Factory::getLanguage(); | ||||
|  | ||||
|             foreach ($nodes as $nv) { | ||||
|                 if (trim($nv->parent_title, '*') === 'Language') { | ||||
|                     $title = LanguageHelper::branchLanguageTitle($nv->title); | ||||
|                 } else { | ||||
|                     $key   = LanguageHelper::branchPlural($nv->title); | ||||
|                     $title = $lang->hasKey($key) ? Text::_($key) : $nv->title; | ||||
|                 } | ||||
|  | ||||
|                 $nv->title = $title; | ||||
|             } | ||||
|  | ||||
|             // Adding slides | ||||
|             $html .= HTMLHelper::_( | ||||
|                 'bootstrap.addSlide', | ||||
|                 'accordion', | ||||
|                 Text::sprintf( | ||||
|                     'COM_FINDER_FILTER_BRANCH_LABEL', | ||||
|                     Text::_(LanguageHelper::branchSingular($bv->title)) . ' - ' . \count($nodes) | ||||
|                 ), | ||||
|                 'accordion-' . $bk | ||||
|             ); | ||||
|  | ||||
|             // Populate the toggle button. | ||||
|             $html .= '<button class="btn btn-secondary js-filter" type="button" data-id="tax-' . $bk . '"><span class="icon-square" aria-hidden="true"></span> ' | ||||
|                 . Text::_('JGLOBAL_SELECTION_INVERT') . '</button><hr>'; | ||||
|  | ||||
|             // Populate the group with nodes. | ||||
|             foreach ($nodes as $nk => $nv) { | ||||
|                 // Determine if the node should be checked. | ||||
|                 $checked = \in_array($nk, $activeNodes) ? ' checked="checked"' : ''; | ||||
|  | ||||
|                 // Build a node. | ||||
|                 $html .= '<div class="form-check">'; | ||||
|                 $html .= '<label class="form-check-label">'; | ||||
|                 $html .= '<input type="checkbox" class="form-check-input selector filter-node' . $classSuffix | ||||
|                     . ' tax-' . $bk . '" value="' . $nk . '" name="t[]"' . $checked . '> ' . str_repeat('—', $nv->level - 2) . $nv->title; | ||||
|                 $html .= '</label>'; | ||||
|                 $html .= '</div>'; | ||||
|             } | ||||
|  | ||||
|             $html .= HTMLHelper::_('bootstrap.endSlide'); | ||||
|         } | ||||
|  | ||||
|         $html .= HTMLHelper::_('bootstrap.endAccordion'); | ||||
|  | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to generate filters using select box dropdown controls. | ||||
|      * | ||||
|      * @param   Query     $idxQuery  A Query object. | ||||
|      * @param   Registry  $options   An array of options. | ||||
|      * | ||||
|      * @return  string|null  A rendered HTML widget on success, null otherwise. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function select($idxQuery, $options) | ||||
|     { | ||||
|         $user   = Factory::getUser(); | ||||
|         $groups = implode(',', $user->getAuthorisedViewLevels()); | ||||
|         $filter = null; | ||||
|  | ||||
|         // Get the configuration options. | ||||
|         $classSuffix = $options->get('class_suffix', null); | ||||
|         $showDates   = $options->get('show_date_filters', false); | ||||
|  | ||||
|         // Try to load the results from cache. | ||||
|         $cache   = Factory::getCache('com_finder', ''); | ||||
|         $cacheId = 'filter_select_' . serialize([$idxQuery->filter, $options, $groups, Factory::getLanguage()->getTag()]); | ||||
|  | ||||
|         // Check the cached results. | ||||
|         if ($cache->contains($cacheId)) { | ||||
|             $branches = $cache->get($cacheId); | ||||
|         } else { | ||||
|             $db    = $this->getDatabase(); | ||||
|             $query = $db->getQuery(true); | ||||
|  | ||||
|             // Load the predefined filter if specified. | ||||
|             if (!empty($idxQuery->filter)) { | ||||
|                 $query->select('f.data, ' . $db->quoteName('f.params')) | ||||
|                     ->from($db->quoteName('#__finder_filters') . ' AS f') | ||||
|                     ->where('f.filter_id = ' . (int) $idxQuery->filter); | ||||
|  | ||||
|                 // Load the filter data. | ||||
|                 $db->setQuery($query); | ||||
|  | ||||
|                 try { | ||||
|                     $filter = $db->loadObject(); | ||||
|                 } catch (\RuntimeException $e) { | ||||
|                     return null; | ||||
|                 } | ||||
|  | ||||
|                 // Initialize the filter parameters. | ||||
|                 if ($filter) { | ||||
|                     $filter->params = new Registry($filter->params); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Build the query to get the branch data and the number of child nodes. | ||||
|             $query->clear() | ||||
|                 ->select('t.*, count(c.id) AS children') | ||||
|                 ->from($db->quoteName('#__finder_taxonomy') . ' AS t') | ||||
|                 ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS c ON c.parent_id = t.id') | ||||
|                 ->where('t.parent_id = 1') | ||||
|                 ->where('t.state = 1') | ||||
|                 ->where('t.access IN (' . $groups . ')') | ||||
|                 ->where('c.state = 1') | ||||
|                 ->where('c.access IN (' . $groups . ')') | ||||
|                 ->group($db->quoteName('t.id')) | ||||
|                 ->group($db->quoteName('t.parent_id')) | ||||
|                 ->group('t.title, t.state, t.access, t.lft') | ||||
|                 ->order('t.lft, t.title'); | ||||
|  | ||||
|             // Limit the branch children to a predefined filter. | ||||
|             if (!empty($filter->data)) { | ||||
|                 $query->where('c.id IN(' . $filter->data . ')'); | ||||
|             } | ||||
|  | ||||
|             // Load the branches. | ||||
|             $db->setQuery($query); | ||||
|  | ||||
|             try { | ||||
|                 $branches = $db->loadObjectList('id'); | ||||
|             } catch (\RuntimeException $e) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             // Check that we have at least one branch. | ||||
|             if (\count($branches) === 0) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             // Iterate through the branches and build the branch groups. | ||||
|             foreach ($branches as $bk => $bv) { | ||||
|                 // If the multi-lang plugin is enabled then drop the language branch. | ||||
|                 if ($bv->title === 'Language' && Multilanguage::isEnabled()) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 // Build the query to get the child nodes for this branch. | ||||
|                 $query->clear() | ||||
|                     ->select('t.*') | ||||
|                     ->from($db->quoteName('#__finder_taxonomy') . ' AS t') | ||||
|                     ->where('t.lft > :lft') | ||||
|                     ->where('t.rgt < :rgt') | ||||
|                     ->where('t.state = 1') | ||||
|                     ->whereIn('t.access', $user->getAuthorisedViewLevels()) | ||||
|                     ->order('t.level, t.parent_id, t.title') | ||||
|                     ->bind(':lft', $bv->lft, ParameterType::INTEGER) | ||||
|                     ->bind(':rgt', $bv->rgt, ParameterType::INTEGER); | ||||
|  | ||||
|                 // Apply multilanguage filter | ||||
|                 if (Multilanguage::isEnabled()) { | ||||
|                     $language = [Factory::getLanguage()->getTag(), '*']; | ||||
|                     $query->whereIn($db->quoteName('t.language'), $language, ParameterType::STRING); | ||||
|                 } | ||||
|  | ||||
|                 // Self-join to get the parent title. | ||||
|                 $query->select('e.title AS parent_title') | ||||
|                     ->join('LEFT', $db->quoteName('#__finder_taxonomy', 'e') . ' ON ' . $db->quoteName('e.id') . ' = ' . $db->quoteName('t.parent_id')); | ||||
|  | ||||
|                 // Limit the nodes to a predefined filter. | ||||
|                 if (!empty($filter->data)) { | ||||
|                     $query->whereIn('t.id', explode(",", $filter->data)); | ||||
|                 } | ||||
|  | ||||
|                 // Load the branches. | ||||
|                 $db->setQuery($query); | ||||
|  | ||||
|                 try { | ||||
|                     $bv->nodes = $db->loadObjectList('id'); | ||||
|                 } catch (\RuntimeException $e) { | ||||
|                     return null; | ||||
|                 } | ||||
|  | ||||
|                 // Translate branch nodes if possible. | ||||
|                 $language = Factory::getLanguage(); | ||||
|                 $root     = []; | ||||
|  | ||||
|                 foreach ($bv->nodes as $node_id => $node) { | ||||
|                     if (trim($node->parent_title, '*') === 'Language') { | ||||
|                         $title = LanguageHelper::branchLanguageTitle($node->title); | ||||
|                     } else { | ||||
|                         $key   = LanguageHelper::branchPlural($node->title); | ||||
|                         $title = $language->hasKey($key) ? Text::_($key) : $node->title; | ||||
|                     } | ||||
|  | ||||
|                     if ($node->level > 2) { | ||||
|                         $node->title = str_repeat('-', $node->level - 2) . $title; | ||||
|                     } else { | ||||
|                         $node->title = $title; | ||||
|                         $root[]      = $branches[$bk]->nodes[$node_id]; | ||||
|                     } | ||||
|  | ||||
|                     if ($node->parent_id && isset($branches[$bk]->nodes[$node->parent_id])) { | ||||
|                         if (!isset($branches[$bk]->nodes[$node->parent_id]->children)) { | ||||
|                             $branches[$bk]->nodes[$node->parent_id]->children = []; | ||||
|                         } | ||||
|                         $branches[$bk]->nodes[$node->parent_id]->children[] = $node; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 $branches[$bk]->nodes = $this->reduce($root); | ||||
|  | ||||
|                 // Add the Search All option to the branch. | ||||
|                 array_unshift($bv->nodes, ['id' => null, 'title' => Text::_('COM_FINDER_FILTER_SELECT_ALL_LABEL')]); | ||||
|             } | ||||
|  | ||||
|             // Store the data in cache. | ||||
|             $cache->store($branches, $cacheId); | ||||
|         } | ||||
|  | ||||
|         $html = ''; | ||||
|  | ||||
|         // Add the dates if enabled. | ||||
|         if ($showDates) { | ||||
|             $html .= HTMLHelper::_('filter.dates', $idxQuery, $options); | ||||
|         } | ||||
|  | ||||
|         $html .= '<div class="filter-branch' . $classSuffix . '">'; | ||||
|  | ||||
|         // Iterate through all branches and build code. | ||||
|         foreach ($branches as $bv) { | ||||
|             // If the multi-lang plugin is enabled then drop the language branch. | ||||
|             if ($bv->title === 'Language' && Multilanguage::isEnabled()) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             $active = null; | ||||
|  | ||||
|             // Check if the branch is in the filter. | ||||
|             if (\array_key_exists($bv->title, $idxQuery->filters)) { | ||||
|                 // Get the request filters. | ||||
|                 $temp   = Factory::getApplication()->getInput()->request->get('t', [], 'array'); | ||||
|  | ||||
|                 // Search for active nodes in the branch and get the active node. | ||||
|                 $active = array_intersect($temp, $idxQuery->filters[$bv->title]); | ||||
|                 $active = \count($active) === 1 ? array_shift($active) : null; | ||||
|             } | ||||
|  | ||||
|             // Build a node. | ||||
|             $html .= '<div class="control-group">'; | ||||
|             $html .= '<div class="control-label">'; | ||||
|             $html .= '<label for="tax-' . OutputFilter::stringURLSafe($bv->title) . '">'; | ||||
|             $html .= Text::sprintf('COM_FINDER_FILTER_BRANCH_LABEL', Text::_(LanguageHelper::branchSingular($bv->title))); | ||||
|             $html .= '</label>'; | ||||
|             $html .= '</div>'; | ||||
|             $html .= '<div class="controls">'; | ||||
|             $html .= HTMLHelper::_( | ||||
|                 'select.genericlist', | ||||
|                 $bv->nodes, | ||||
|                 't[]', | ||||
|                 'class="form-select advancedSelect"', | ||||
|                 'id', | ||||
|                 'title', | ||||
|                 $active, | ||||
|                 'tax-' . OutputFilter::stringURLSafe($bv->title) | ||||
|             ); | ||||
|             $html .= '</div>'; | ||||
|             $html .= '</div>'; | ||||
|         } | ||||
|  | ||||
|         $html .= '</div>'; | ||||
|  | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to generate fields for filtering dates | ||||
|      * | ||||
|      * @param   Query     $idxQuery  A Query object. | ||||
|      * @param   Registry  $options   An array of options. | ||||
|      * | ||||
|      * @return  string  A rendered HTML widget. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function dates($idxQuery, $options) | ||||
|     { | ||||
|         $html = ''; | ||||
|  | ||||
|         // Get the configuration options. | ||||
|         $classSuffix = $options->get('class_suffix', null); | ||||
|         $loadMedia   = $options->get('load_media', true); | ||||
|         $showDates   = $options->get('show_date_filters', false); | ||||
|  | ||||
|         if (!empty($showDates)) { | ||||
|             // Build the date operators options. | ||||
|             $operators   = []; | ||||
|             $operators[] = HTMLHelper::_('select.option', 'before', Text::_('COM_FINDER_FILTER_DATE_BEFORE')); | ||||
|             $operators[] = HTMLHelper::_('select.option', 'exact', Text::_('COM_FINDER_FILTER_DATE_EXACTLY')); | ||||
|             $operators[] = HTMLHelper::_('select.option', 'after', Text::_('COM_FINDER_FILTER_DATE_AFTER')); | ||||
|  | ||||
|             // Load the CSS/JS resources. | ||||
|             if ($loadMedia) { | ||||
|                 /** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */ | ||||
|                 $wa = Factory::getApplication()->getDocument()->getWebAssetManager(); | ||||
|                 $wa->useStyle('com_finder.dates'); | ||||
|             } | ||||
|  | ||||
|             // Open the widget. | ||||
|             $html .= '<ul id="finder-filter-select-dates">'; | ||||
|  | ||||
|             // Start date filter. | ||||
|             $attribs['class'] = 'input-medium'; | ||||
|             $html .= '<li class="filter-date float-start' . $classSuffix . '">'; | ||||
|             $html .= '<label for="filter_date1" class="hasTooltip" title ="' . Text::_('COM_FINDER_FILTER_DATE1_DESC') . '">'; | ||||
|             $html .= Text::_('COM_FINDER_FILTER_DATE1'); | ||||
|             $html .= '</label>'; | ||||
|             $html .= '<br>'; | ||||
|             $html .= '<label for="finder-filter-w1" class="visually-hidden">'; | ||||
|             $html .= Text::_('COM_FINDER_FILTER_DATE1_OPERATOR'); | ||||
|             $html .= '</label>'; | ||||
|             $html .= HTMLHelper::_( | ||||
|                 'select.genericlist', | ||||
|                 $operators, | ||||
|                 'w1', | ||||
|                 'class="inputbox filter-date-operator advancedSelect form-select w-auto mb-2"', | ||||
|                 'value', | ||||
|                 'text', | ||||
|                 $idxQuery->when1, | ||||
|                 'finder-filter-w1' | ||||
|             ); | ||||
|             $html .= HTMLHelper::_('calendar', $idxQuery->date1, 'd1', 'filter_date1', '%Y-%m-%d', $attribs); | ||||
|             $html .= '</li>'; | ||||
|  | ||||
|             // End date filter. | ||||
|             $html .= '<li class="filter-date float-end' . $classSuffix . '">'; | ||||
|             $html .= '<label for="filter_date2" class="hasTooltip" title ="' . Text::_('COM_FINDER_FILTER_DATE2_DESC') . '">'; | ||||
|             $html .= Text::_('COM_FINDER_FILTER_DATE2'); | ||||
|             $html .= '</label>'; | ||||
|             $html .= '<br>'; | ||||
|             $html .= '<label for="finder-filter-w2" class="visually-hidden">'; | ||||
|             $html .= Text::_('COM_FINDER_FILTER_DATE2_OPERATOR'); | ||||
|             $html .= '</label>'; | ||||
|             $html .= HTMLHelper::_( | ||||
|                 'select.genericlist', | ||||
|                 $operators, | ||||
|                 'w2', | ||||
|                 'class="inputbox filter-date-operator advancedSelect form-select w-auto mb-2"', | ||||
|                 'value', | ||||
|                 'text', | ||||
|                 $idxQuery->when2, | ||||
|                 'finder-filter-w2' | ||||
|             ); | ||||
|             $html .= HTMLHelper::_('calendar', $idxQuery->date2, 'd2', 'filter_date2', '%Y-%m-%d', $attribs); | ||||
|             $html .= '</li>'; | ||||
|  | ||||
|             // Close the widget. | ||||
|             $html .= '</ul>'; | ||||
|         } | ||||
|  | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to flatten a tree to a sorted array | ||||
|      * | ||||
|      * @param   \stdClass[]  $array | ||||
|      * | ||||
|      * @return  \stdClass[]  Flat array of all nodes of a tree with the children after each parent | ||||
|      * | ||||
|      * @since   5.1.0 | ||||
|      */ | ||||
|     private function reduce(array $array) | ||||
|     { | ||||
|         $return = []; | ||||
|  | ||||
|         foreach ($array as $item) { | ||||
|             $return[] = $item; | ||||
|             if (isset($item->children)) { | ||||
|                 $return = array_merge($return, $this->reduce($item->children)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $return; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										131
									
								
								administrator/components/com_finder/src/Service/HTML/Finder.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								administrator/components/com_finder/src/Service/HTML/Finder.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_finder | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Finder\Administrator\Service\HTML; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\HTML\HTMLHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\Component\Finder\Administrator\Helper\LanguageHelper; | ||||
| use Joomla\Database\DatabaseAwareTrait; | ||||
| use Joomla\Utilities\ArrayHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * HTML behavior class for Finder. | ||||
|  * | ||||
|  * @since  2.5 | ||||
|  */ | ||||
| class Finder | ||||
| { | ||||
|     use DatabaseAwareTrait; | ||||
|  | ||||
|     /** | ||||
|      * Creates a list of types to filter on. | ||||
|      * | ||||
|      * @return  array  An array containing the types that can be selected. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function typeslist() | ||||
|     { | ||||
|         // Load the finder types. | ||||
|         $db    = $this->getDatabase(); | ||||
|         $query = $db->getQuery(true) | ||||
|             ->select('DISTINCT t.title AS text, t.id AS value') | ||||
|             ->from($db->quoteName('#__finder_types') . ' AS t') | ||||
|             ->join('LEFT', $db->quoteName('#__finder_links') . ' AS l ON l.type_id = t.id') | ||||
|             ->order('t.title ASC'); | ||||
|         $db->setQuery($query); | ||||
|  | ||||
|         try { | ||||
|             $rows = $db->loadObjectList(); | ||||
|         } catch (\RuntimeException $e) { | ||||
|             return []; | ||||
|         } | ||||
|  | ||||
|         // Compile the options. | ||||
|         $options = []; | ||||
|  | ||||
|         $lang = Factory::getLanguage(); | ||||
|  | ||||
|         foreach ($rows as $row) { | ||||
|             $key       = $lang->hasKey(LanguageHelper::branchPlural($row->text)) ? LanguageHelper::branchPlural($row->text) : $row->text; | ||||
|             $options[] = HTMLHelper::_('select.option', $row->value, Text::sprintf('COM_FINDER_ITEM_X_ONLY', Text::_($key))); | ||||
|         } | ||||
|  | ||||
|         return $options; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Creates a list of maps. | ||||
|      * | ||||
|      * @return  array  An array containing the maps that can be selected. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function mapslist() | ||||
|     { | ||||
|         // Load the finder types. | ||||
|         $db    = $this->getDatabase(); | ||||
|         $query = $db->getQuery(true) | ||||
|             ->select($db->quoteName('title', 'text')) | ||||
|             ->select($db->quoteName('id', 'value')) | ||||
|             ->from($db->quoteName('#__finder_taxonomy')) | ||||
|             ->where($db->quoteName('parent_id') . ' = 1'); | ||||
|         $db->setQuery($query); | ||||
|  | ||||
|         try { | ||||
|             $branches = $db->loadObjectList(); | ||||
|         } catch (\RuntimeException $e) { | ||||
|             Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); | ||||
|         } | ||||
|  | ||||
|         // Translate. | ||||
|         $lang = Factory::getLanguage(); | ||||
|  | ||||
|         foreach ($branches as $branch) { | ||||
|             $key                    = LanguageHelper::branchPlural($branch->text); | ||||
|             $branch->translatedText = $lang->hasKey($key) ? Text::_($key) : $branch->text; | ||||
|         } | ||||
|  | ||||
|         // Order by title. | ||||
|         $branches = ArrayHelper::sortObjects($branches, 'translatedText', 1, true, true); | ||||
|  | ||||
|         // Compile the options. | ||||
|         $options   = []; | ||||
|         $options[] = HTMLHelper::_('select.option', '', Text::_('COM_FINDER_MAPS_SELECT_BRANCH')); | ||||
|  | ||||
|         // Convert the values to options. | ||||
|         foreach ($branches as $branch) { | ||||
|             $options[] = HTMLHelper::_('select.option', $branch->value, $branch->translatedText); | ||||
|         } | ||||
|  | ||||
|         return $options; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Creates a list of published states. | ||||
|      * | ||||
|      * @return  array  An array containing the states that can be selected. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public static function statelist() | ||||
|     { | ||||
|         return [ | ||||
|             HTMLHelper::_('select.option', '1', Text::sprintf('COM_FINDER_ITEM_X_ONLY', Text::_('JPUBLISHED'))), | ||||
|             HTMLHelper::_('select.option', '0', Text::sprintf('COM_FINDER_ITEM_X_ONLY', Text::_('JUNPUBLISHED'))), | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										156
									
								
								administrator/components/com_finder/src/Service/HTML/Query.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								administrator/components/com_finder/src/Service/HTML/Query.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_finder | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Finder\Administrator\Service\HTML; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\Component\Finder\Administrator\Helper\LanguageHelper; | ||||
| use Joomla\Component\Finder\Administrator\Indexer\Query as IndexerQuery; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Query HTML behavior class for Finder. | ||||
|  * | ||||
|  * @since  2.5 | ||||
|  */ | ||||
| class Query | ||||
| { | ||||
|     /** | ||||
|      * Method to get the explained (human-readable) search query. | ||||
|      * | ||||
|      * @param   IndexerQuery  $query  A IndexerQuery object to explain. | ||||
|      * | ||||
|      * @return  mixed  String if there is data to explain, null otherwise. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public static function explained(IndexerQuery $query) | ||||
|     { | ||||
|         $parts = []; | ||||
|  | ||||
|         // Process the required tokens. | ||||
|         foreach ($query->included as $token) { | ||||
|             if ($token->required && (!isset($token->derived) || $token->derived == false)) { | ||||
|                 $parts[] = '<span class="query-required">' . Text::sprintf('COM_FINDER_QUERY_TOKEN_REQUIRED', $token->term) . '</span>'; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Process the optional tokens. | ||||
|         foreach ($query->included as $token) { | ||||
|             if (!$token->required && (!isset($token->derived) || $token->derived == false)) { | ||||
|                 $parts[] = '<span class="query-optional">' . Text::sprintf('COM_FINDER_QUERY_TOKEN_OPTIONAL', $token->term) . '</span>'; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Process the excluded tokens. | ||||
|         foreach ($query->excluded as $token) { | ||||
|             if (!isset($token->derived) || $token->derived === false) { | ||||
|                 $parts[] = '<span class="query-excluded">' . Text::sprintf('COM_FINDER_QUERY_TOKEN_EXCLUDED', $token->term) . '</span>'; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Process the start date. | ||||
|         if ($query->date1) { | ||||
|             $date          = Factory::getDate($query->date1)->format(Text::_('DATE_FORMAT_LC')); | ||||
|             $datecondition = Text::_('COM_FINDER_QUERY_DATE_CONDITION_' . strtoupper($query->when1)); | ||||
|             $parts[]       = '<span class="query-start-date">' . Text::sprintf('COM_FINDER_QUERY_START_DATE', $datecondition, $date) . '</span>'; | ||||
|         } | ||||
|  | ||||
|         // Process the end date. | ||||
|         if ($query->date2) { | ||||
|             $date          = Factory::getDate($query->date2)->format(Text::_('DATE_FORMAT_LC')); | ||||
|             $datecondition = Text::_('COM_FINDER_QUERY_DATE_CONDITION_' . strtoupper($query->when2)); | ||||
|             $parts[]       = '<span class="query-end-date">' . Text::sprintf('COM_FINDER_QUERY_END_DATE', $datecondition, $date) . '</span>'; | ||||
|         } | ||||
|  | ||||
|         // Process the taxonomy filters. | ||||
|         if (!empty($query->filters)) { | ||||
|             // Get the filters in the request. | ||||
|             $t = Factory::getApplication()->getInput()->request->get('t', [], 'array'); | ||||
|  | ||||
|             // Process the taxonomy branches. | ||||
|             foreach ($query->filters as $branch => $nodes) { | ||||
|                 // Process the taxonomy nodes. | ||||
|                 $lang = Factory::getLanguage(); | ||||
|  | ||||
|                 foreach ($nodes as $title => $id) { | ||||
|                     // Translate the title for Types | ||||
|                     $key = LanguageHelper::branchPlural($title); | ||||
|  | ||||
|                     if ($lang->hasKey($key)) { | ||||
|                         $title = Text::_($key); | ||||
|                     } | ||||
|  | ||||
|                     // Don't include the node if it is not in the request. | ||||
|                     if (!\in_array($id, $t)) { | ||||
|                         continue; | ||||
|                     } | ||||
|  | ||||
|                     // Add the node to the explanation. | ||||
|                     $parts[] = '<span class="query-taxonomy">' | ||||
|                         . Text::sprintf('COM_FINDER_QUERY_TAXONOMY_NODE', $title, Text::_(LanguageHelper::branchSingular($branch))) | ||||
|                         . '</span>'; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Build the interpreted query. | ||||
|         return \count($parts) ? implode(Text::_('COM_FINDER_QUERY_TOKEN_GLUE'), $parts) : null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the suggested search query. | ||||
|      * | ||||
|      * @param   IndexerQuery  $query  A IndexerQuery object. | ||||
|      * | ||||
|      * @return  mixed  String if there is a suggestion, false otherwise. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public static function suggested(IndexerQuery $query) | ||||
|     { | ||||
|         $suggested = false; | ||||
|  | ||||
|         // Check if the query input is empty. | ||||
|         if (empty($query->input)) { | ||||
|             return $suggested; | ||||
|         } | ||||
|  | ||||
|         // Check if there were any ignored or included keywords. | ||||
|         if (\count($query->ignored) || \count($query->included)) { | ||||
|             $suggested = $query->input; | ||||
|  | ||||
|             // Replace the ignored keyword suggestions. | ||||
|             foreach (array_reverse($query->ignored) as $token) { | ||||
|                 if (isset($token->suggestion)) { | ||||
|                     $suggested = str_ireplace($token->term, $token->suggestion, $suggested); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Replace the included keyword suggestions. | ||||
|             foreach (array_reverse($query->included) as $token) { | ||||
|                 if (isset($token->suggestion)) { | ||||
|                     $suggested = str_ireplace($token->term, $token->suggestion, $suggested); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Check if we made any changes. | ||||
|             if ($suggested == $query->input) { | ||||
|                 $suggested = false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $suggested; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user