You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
New language relevant PR in upstream repo: joomla/joomla-cms#36753 Here are the upstream changes:
Click to expand the diff!
diff --git a/administrator/components/com_finder/forms/indexer.xml b/administrator/components/com_finder/forms/indexer.xml
new file mode 100644
index 000000000000..a9559102a0c4
--- /dev/null+++ b/administrator/components/com_finder/forms/indexer.xml@@ -0,0 +1,19 @@+<?xml version="1.0" encoding="utf-8"?>+<form>+ <fieldset name="form">+ <field+ name="plugin"+ type="plugins"+ label="COM_FINDER_FIELD_FINDER_PLUGIN_LABEL"+ folder="finder"+ required="true"+ />++ <field+ name="id"+ type="text"+ label="JGLOBAL_FIELD_ID_LABEL"+ required="true"+ />+ </fieldset>+</form>diff --git a/administrator/components/com_finder/src/Controller/IndexerController.php b/administrator/components/com_finder/src/Controller/IndexerController.php
index 509750020562..51a398129a6f 100644
--- a/administrator/components/com_finder/src/Controller/IndexerController.php+++ b/administrator/components/com_finder/src/Controller/IndexerController.php@@ -17,6 +17,9 @@
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Session\Session;
+use Joomla\Component\Finder\Administrator\Indexer\Adapter;+use Joomla\Component\Finder\Administrator\Indexer\DebugAdapter;+use Joomla\Component\Finder\Administrator\Indexer\DebugIndexer;
use Joomla\Component\Finder\Administrator\Indexer\Indexer;
use Joomla\Component\Finder\Administrator\Response\Response;
@@ -147,22 +150,6 @@ public function batch()
// Import the finder plugins.
PluginHelper::importPlugin('finder');
- /*- * We are going to swap out the raw document object with an HTML document- * in order to work around some plugins that don't do proper environment- * checks before trying to use HTML document functions.- */- $lang = Factory::getLanguage();-- // Get the document properties.- $attributes = [- 'charset' => 'utf-8',- 'lineend' => 'unix',- 'tab' => ' ',- 'language' => $lang->getTag(),- 'direction' => $lang->isRtl() ? 'rtl' : 'ltr',- ];-
// Start the indexer.
try {
// Trigger the onBeforeIndex event.
@@ -281,4 +268,112 @@ public static function sendResponse($data = null)
// Send the JSON response.
echo json_encode($response);
}
++ /**+ * Method to call a specific indexing plugin and return debug info+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ * @internal+ */+ public function debug()+ {+ // Check for a valid token. If invalid, send a 403 with the error message.+ if (!Session::checkToken('request')) {+ static::sendResponse(new \Exception(Text::_('JINVALID_TOKEN_NOTICE'), 403));++ return;+ }++ // We don't want this form to be cached.+ $this->app->allowCache(false);++ // Put in a buffer to silence noise.+ ob_start();++ // Remove the script time limit.+ @set_time_limit(0);++ // Get the indexer state.+ Indexer::resetState();+ $state = Indexer::getState();++ // Reset the batch offset.+ $state->batchOffset = 0;++ // Update the indexer state.+ Indexer::setState($state);++ // Start the indexer.+ try {+ // Import the finder plugins.+ class_alias(DebugAdapter::class, Adapter::class);+ $plugin = Factory::getApplication()->bootPlugin($this->app->input->get('plugin'), 'finder');+ $plugin->setIndexer(new DebugIndexer());+ $plugin->debug($this->app->input->get('id'));++ $output = '';++ // Create list of attributes+ $output .= '<fieldset><legend>' . Text::_('COM_FINDER_INDEXER_FIELDSET_ATTRIBUTES') . '</legend>';+ $output .= '<dl class="row">';++ foreach (DebugIndexer::$item as $key => $value) {+ $output .= '<dt class="col-sm-2">' . $key . '</dt><dd class="col-sm-10">' . $value . '</dd>';+ }++ $output .= '</dl>';+ $output .= '</fieldset>';++ $output .= '<fieldset><legend>' . Text::_('COM_FINDER_INDEXER_FIELDSET_ELEMENTS') . '</legend>';+ $output .= '<dl class="row">';++ foreach (DebugIndexer::$item->getElements() as $key => $element) {+ $output .= '<dt class="col-sm-2">' . $key . '</dt><dd class="col-sm-10">' . $element . '</dd>';+ }++ $output .= '</dl>';+ $output .= '</fieldset>';++ $output .= '<fieldset><legend>' . Text::_('COM_FINDER_INDEXER_FIELDSET_INSTRUCTIONS') . '</legend>';+ $output .= '<dl class="row">';+ $contexts = [+ 1 => 'Title context',+ 2 => 'Text context',+ 3 => 'Meta context',+ 4 => 'Path context',+ 5 => 'Misc context',+ ];++ foreach (DebugIndexer::$item->getInstructions() as $key => $element) {+ $output .= '<dt class="col-sm-2">' . $contexts[$key] . '</dt><dd class="col-sm-10">' . json_encode($element) . '</dd>';+ }++ $output .= '</dl>';+ $output .= '</fieldset>';++ $output .= '<fieldset><legend>' . Text::_('COM_FINDER_INDEXER_FIELDSET_TAXONOMIES') . '</legend>';+ $output .= '<dl class="row">';++ foreach (DebugIndexer::$item->getTaxonomy() as $key => $element) {+ $output .= '<dt class="col-sm-2">' . $key . '</dt><dd class="col-sm-10">' . json_encode($element) . '</dd>';+ }++ $output .= '</dl>';+ $output .= '</fieldset>';++ // Get the indexer state.+ $state = Indexer::getState();+ $state->start = 0;+ $state->complete = 0;+ $state->rendered = $output;++ echo json_encode($state);+ } catch (\Exception $e) {+ // Catch an exception and return the response.+ // Send the response.+ static::sendResponse($e);+ }+ }
}
diff --git a/administrator/components/com_finder/src/Indexer/DebugAdapter.php b/administrator/components/com_finder/src/Indexer/DebugAdapter.php
new file mode 100644
index 000000000000..3e0ffa74b5e3
--- /dev/null+++ b/administrator/components/com_finder/src/Indexer/DebugAdapter.php@@ -0,0 +1,952 @@+<?php++/**+ * @package Joomla.Administrator+ * @subpackage com_finder+ *+ * @copyright (C) 2022 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\Indexer;++use Exception;+use Joomla\CMS\Plugin\CMSPlugin;+use Joomla\CMS\Table\Table;+use Joomla\Database\DatabaseInterface;+use Joomla\Database\QueryInterface;+use Joomla\Utilities\ArrayHelper;++/**+ * Prototype debug adapter class for the Finder indexer package.+ * THIS CLASS IS ONLY TO BE USED FOR DEBUGGING PURPOSES! DON'T+ * USE IT FOR PRODUCTIVE USE!+ *+ * @since __DEPLOY_VERSION__+ * @internal+ */+abstract class DebugAdapter extends CMSPlugin+{+ /**+ * The context is somewhat arbitrary but it must be unique or there will be+ * conflicts when managing plugin/indexer state. A good best practice is to+ * use the plugin name suffix as the context. For example, if the plugin is+ * named 'plgFinderContent', the context could be 'Content'.+ *+ * @var string+ * @since __DEPLOY_VERSION__+ */+ protected $context;++ /**+ * The extension name.+ *+ * @var string+ * @since __DEPLOY_VERSION__+ */+ protected $extension;++ /**+ * The sublayout to use when rendering the results.+ *+ * @var string+ * @since __DEPLOY_VERSION__+ */+ protected $layout;++ /**+ * The mime type of the content the adapter indexes.+ *+ * @var string+ * @since __DEPLOY_VERSION__+ */+ protected $mime;++ /**+ * The access level of an item before save.+ *+ * @var integer+ * @since __DEPLOY_VERSION__+ */+ protected $old_access;++ /**+ * The access level of a category before save.+ *+ * @var integer+ * @since __DEPLOY_VERSION__+ */+ protected $old_cataccess;++ /**+ * The type of content the adapter indexes.+ *+ * @var string+ * @since __DEPLOY_VERSION__+ */+ protected $type_title;++ /**+ * The type id of the content.+ *+ * @var integer+ * @since __DEPLOY_VERSION__+ */+ protected $type_id;++ /**+ * The database object.+ *+ * @var DatabaseInterface+ * @since __DEPLOY_VERSION__+ */+ protected $db;++ /**+ * The table name.+ *+ * @var string+ * @since __DEPLOY_VERSION__+ */+ protected $table;++ /**+ * The indexer object.+ *+ * @var Indexer+ * @since __DEPLOY_VERSION__+ */+ protected $indexer;++ /**+ * The field the published state is stored in.+ *+ * @var string+ * @since __DEPLOY_VERSION__+ */+ protected $state_field = 'state';++ /**+ * Method to instantiate the indexer adapter.+ *+ * @param object $subject The object to observe.+ * @param array $config An array that holds the plugin configuration.+ *+ * @since __DEPLOY_VERSION__+ */+ public function __construct(&$subject, $config)+ {+ // Call the parent constructor.+ parent::__construct($subject, $config);++ // Get the type id.+ $this->type_id = $this->getTypeId();++ // Add the content type if it doesn't exist and is set.+ if (empty($this->type_id) && !empty($this->type_title)) {+ $this->type_id = Helper::addContentType($this->type_title, $this->mime);+ }++ // Check for a layout override.+ if ($this->params->get('layout')) {+ $this->layout = $this->params->get('layout');+ }++ // Get the indexer object+ $this->indexer = new Indexer($this->db);+ }++ /**+ * Method to get the adapter state and push it into the indexer.+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on error.+ */+ public function onStartIndex()+ {+ // Get the indexer state.+ $iState = Indexer::getState();++ // Get the number of content items.+ $total = (int) $this->getContentCount();++ // Add the content count to the total number of items.+ $iState->totalItems += $total;++ // Populate the indexer state information for the adapter.+ $iState->pluginState[$this->context]['total'] = $total;+ $iState->pluginState[$this->context]['offset'] = 0;++ // Set the indexer state.+ Indexer::setState($iState);+ }++ /**+ * Method to prepare for the indexer to be run. This method will often+ * be used to include dependencies and things of that nature.+ *+ * @return boolean True on success.+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on error.+ */+ public function onBeforeIndex()+ {+ // Get the indexer and adapter state.+ $iState = Indexer::getState();+ $aState = $iState->pluginState[$this->context];++ // Check the progress of the indexer and the adapter.+ if ($iState->batchOffset == $iState->batchSize || $aState['offset'] == $aState['total']) {+ return true;+ }++ // Run the setup method.+ return $this->setup();+ }++ /**+ * Method to index a batch of content items. This method can be called by+ * the indexer many times throughout the indexing process depending on how+ * much content is available for indexing. It is important to track the+ * progress correctly so we can display it to the user.+ *+ * @return boolean True on success.+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on error.+ */+ public function onBuildIndex()+ {+ // Get the indexer and adapter state.+ $iState = Indexer::getState();+ $aState = $iState->pluginState[$this->context];++ // Check the progress of the indexer and the adapter.+ if ($iState->batchOffset == $iState->batchSize || $aState['offset'] == $aState['total']) {+ return true;+ }++ // Get the batch offset and size.+ $offset = (int) $aState['offset'];+ $limit = (int) ($iState->batchSize - $iState->batchOffset);++ // Get the content items to index.+ $items = $this->getItems($offset, $limit);++ // Iterate through the items and index them.+ for ($i = 0, $n = count($items); $i < $n; $i++) {+ // Index the item.+ $this->index($items[$i]);++ // Adjust the offsets.+ $offset++;+ $iState->batchOffset++;+ $iState->totalItems--;+ }++ // Update the indexer state.+ $aState['offset'] = $offset;+ $iState->pluginState[$this->context] = $aState;+ Indexer::setState($iState);++ return true;+ }++ /**+ * Method to remove outdated index entries+ *+ * @return integer+ *+ * @since ___DEPLOY_VERSION__+ */+ public function onFinderGarbageCollection()+ {+ $db = $this->db;+ $type_id = $this->getTypeId();++ $query = $db->getQuery(true);+ $subquery = $db->getQuery(true);+ $subquery->select('CONCAT(' . $db->quote($this->getUrl('', $this->extension, $this->layout)) . ', id)')+ ->from($db->quoteName($this->table));+ $query->select($db->quoteName('l.link_id'))+ ->from($db->quoteName('#__finder_links', 'l'))+ ->where($db->quoteName('l.type_id') . ' = ' . $type_id)+ ->where($db->quoteName('l.url') . ' LIKE ' . $db->quote($this->getUrl('%', $this->extension, $this->layout)))+ ->where($db->quoteName('l.url') . ' NOT IN (' . $subquery . ')');+ $db->setQuery($query);+ $items = $db->loadColumn();++ foreach ($items as $item) {+ $this->indexer->remove($item);+ }++ return count($items);+ }++ /**+ * Method to change the value of a content item's property in the links+ * table. This is used to synchronize published and access states that+ * are changed when not editing an item directly.+ *+ * @param string $id The ID of the item to change.+ * @param string $property The property that is being changed.+ * @param integer $value The new value of that property.+ *+ * @return boolean True on success.+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on database error.+ */+ protected function change($id, $property, $value)+ {+ // Check for a property we know how to handle.+ if ($property !== 'state' && $property !== 'access') {+ return true;+ }++ // Get the URL for the content id.+ $item = $this->db->quote($this->getUrl($id, $this->extension, $this->layout));++ // Update the content items.+ $query = $this->db->getQuery(true)+ ->update($this->db->quoteName('#__finder_links'))+ ->set($this->db->quoteName($property) . ' = ' . (int) $value)+ ->where($this->db->quoteName('url') . ' = ' . $item);+ $this->db->setQuery($query);+ $this->db->execute();++ return true;+ }++ /**+ * Method to index an item.+ *+ * @param Result $item The item to index as a Result object.+ *+ * @return boolean True on success.+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on database error.+ */+ abstract protected function index(Result $item);++ /**+ * Method to reindex an item.+ *+ * @param integer $id The ID of the item to reindex.+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on database error.+ */+ protected function reindex($id)+ {+ // Run the setup method.+ $this->setup();++ // Remove the old item.+ $this->remove($id, false);++ // Get the item.+ $item = $this->getItem($id);++ // Index the item.+ $this->index($item);++ Taxonomy::removeOrphanNodes();+ }++ /**+ * Method to remove an item from the index.+ *+ * @param string $id The ID of the item to remove.+ * @param bool $removeTaxonomies Remove empty taxonomies+ *+ * @return boolean True on success.+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on database error.+ */+ protected function remove($id, $removeTaxonomies = true)+ {+ // Get the item's URL+ $url = $this->db->quote($this->getUrl($id, $this->extension, $this->layout));++ // Get the link ids for the content items.+ $query = $this->db->getQuery(true)+ ->select($this->db->quoteName('link_id'))+ ->from($this->db->quoteName('#__finder_links'))+ ->where($this->db->quoteName('url') . ' = ' . $url);+ $this->db->setQuery($query);+ $items = $this->db->loadColumn();++ // Check the items.+ if (empty($items)) {+ $this->getApplication()->triggerEvent('onFinderIndexAfterDelete', [$id]);++ return true;+ }++ // Remove the items.+ foreach ($items as $item) {+ $this->indexer->remove($item, $removeTaxonomies);+ }++ return true;+ }++ /**+ * Method to setup the adapter before indexing.+ *+ * @return boolean True on success, false on failure.+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on database error.+ */+ abstract protected function setup();++ /**+ * Method to update index data on category access level changes+ *+ * @param Table $row A Table object+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ protected function categoryAccessChange($row)+ {+ $query = clone $this->getStateQuery();+ $query->where('c.id = ' . (int) $row->id);++ // Get the access level.+ $this->db->setQuery($query);+ $items = $this->db->loadObjectList();++ // Adjust the access level for each item within the category.+ foreach ($items as $item) {+ // Set the access level.+ $temp = max($item->access, $row->access);++ // Update the item.+ $this->change((int) $item->id, 'access', $temp);+ }+ }++ /**+ * Method to update index data on category access level changes+ *+ * @param array $pks A list of primary key ids of the content that has changed state.+ * @param integer $value The value of the state that the content has been changed to.+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ protected function categoryStateChange($pks, $value)+ {+ /*+ * The item's published state is tied to the category+ * published state so we need to look up all published states+ * before we change anything.+ */+ foreach ($pks as $pk) {+ $query = clone $this->getStateQuery();+ $query->where('c.id = ' . (int) $pk);++ // Get the published states.+ $this->db->setQuery($query);+ $items = $this->db->loadObjectList();++ // Adjust the state for each item within the category.+ foreach ($items as $item) {+ // Translate the state.+ $temp = $this->translateState($item->state, $value);++ // Update the item.+ $this->change($item->id, 'state', $temp);+ }+ }+ }++ /**+ * Method to check the existing access level for categories+ *+ * @param Table $row A Table object+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ protected function checkCategoryAccess($row)+ {+ $query = $this->db->getQuery(true)+ ->select($this->db->quoteName('access'))+ ->from($this->db->quoteName('#__categories'))+ ->where($this->db->quoteName('id') . ' = ' . (int) $row->id);+ $this->db->setQuery($query);++ // Store the access level to determine if it changes+ $this->old_cataccess = $this->db->loadResult();+ }++ /**+ * Method to check the existing access level for items+ *+ * @param Table $row A Table object+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ protected function checkItemAccess($row)+ {+ $query = $this->db->getQuery(true)+ ->select($this->db->quoteName('access'))+ ->from($this->db->quoteName($this->table))+ ->where($this->db->quoteName('id') . ' = ' . (int) $row->id);+ $this->db->setQuery($query);++ // Store the access level to determine if it changes+ $this->old_access = $this->db->loadResult();+ }++ /**+ * Method to get the number of content items available to index.+ *+ * @return integer The number of content items available to index.+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on database error.+ */+ protected function getContentCount()+ {+ $return = 0;++ // Get the list query.+ $query = $this->getListQuery();++ // Check if the query is valid.+ if (empty($query)) {+ return $return;+ }++ // Tweak the SQL query to make the total lookup faster.+ if ($query instanceof QueryInterface) {+ $query = clone $query;+ $query->clear('select')+ ->select('COUNT(*)')+ ->clear('order');+ }++ // Get the total number of content items to index.+ $this->db->setQuery($query);++ return (int) $this->db->loadResult();+ }++ /**+ * Method to get a content item to index.+ *+ * @param integer $id The id of the content item.+ *+ * @return Result A Result object.+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on database error.+ */+ protected function getItem($id)+ {+ // Get the list query and add the extra WHERE clause.+ $query = $this->getListQuery();+ $query->where('a.id = ' . (int) $id);++ // Get the item to index.+ $this->db->setQuery($query);+ $item = $this->db->loadAssoc();++ // Convert the item to a result object.+ $item = ArrayHelper::toObject((array) $item, Result::class);++ // Set the item type.+ $item->type_id = $this->type_id;++ // Set the item layout.+ $item->layout = $this->layout;++ return $item;+ }++ /**+ * Method to get a list of content items to index.+ *+ * @param integer $offset The list offset.+ * @param integer $limit The list limit.+ * @param QueryInterface $query A QueryInterface object. [optional]+ *+ * @return Result[] An array of Result objects.+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on database error.+ */+ protected function getItems($offset, $limit, $query = null)+ {+ // Get the content items to index.+ $this->db->setQuery($this->getListQuery($query)->setLimit($limit, $offset));+ $items = $this->db->loadAssocList();++ foreach ($items as &$item) {+ $item = ArrayHelper::toObject($item, Result::class);++ // Set the item type.+ $item->type_id = $this->type_id;++ // Set the mime type.+ $item->mime = $this->mime;++ // Set the item layout.+ $item->layout = $this->layout;+ }++ return $items;+ }++ /**+ * Method to get the SQL query used to retrieve the list of content items.+ *+ * @param mixed $query A QueryInterface object. [optional]+ *+ * @return QueryInterface A database object.+ *+ * @since __DEPLOY_VERSION__+ */+ protected function getListQuery($query = null)+ {+ // Check if we can use the supplied SQL query.+ return $query instanceof QueryInterface ? $query : $this->db->getQuery(true);+ }++ /**+ * Method to get the plugin type+ *+ * @param integer $id The plugin ID+ *+ * @return string The plugin type+ *+ * @since __DEPLOY_VERSION__+ */+ protected function getPluginType($id)+ {+ // Prepare the query+ $query = $this->db->getQuery(true)+ ->select($this->db->quoteName('element'))+ ->from($this->db->quoteName('#__extensions'))+ ->where($this->db->quoteName('extension_id') . ' = ' . (int) $id);+ $this->db->setQuery($query);++ return $this->db->loadResult();+ }++ /**+ * Method to get a SQL query to load the published and access states for+ * an article and category.+ *+ * @return QueryInterface A database object.+ *+ * @since __DEPLOY_VERSION__+ */+ protected function getStateQuery()+ {+ $query = $this->db->getQuery(true);++ // Item ID+ $query->select('a.id');++ // Item and category published state+ $query->select('a.' . $this->state_field . ' AS state, c.published AS cat_state');++ // Item and category access levels+ $query->select('a.access, c.access AS cat_access')+ ->from($this->table . ' AS a')+ ->join('LEFT', '#__categories AS c ON c.id = a.catid');++ return $query;+ }++ /**+ * Method to get the query clause for getting items to update by time.+ *+ * @param string $time The modified timestamp.+ *+ * @return QueryInterface A database object.+ *+ * @since __DEPLOY_VERSION__+ */+ protected function getUpdateQueryByTime($time)+ {+ // Build an SQL query based on the modified time.+ $query = $this->db->getQuery(true)+ ->where('a.modified >= ' . $this->db->quote($time));++ return $query;+ }++ /**+ * Method to get the query clause for getting items to update by id.+ *+ * @param array $ids The ids to load.+ *+ * @return QueryInterface A database object.+ *+ * @since __DEPLOY_VERSION__+ */+ protected function getUpdateQueryByIds($ids)+ {+ // Build an SQL query based on the item ids.+ $query = $this->db->getQuery(true)+ ->where('a.id IN(' . implode(',', $ids) . ')');++ return $query;+ }++ /**+ * Method to get the type id for the adapter content.+ *+ * @return integer The numeric type id for the content.+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on database error.+ */+ protected function getTypeId()+ {+ // Get the type id from the database.+ $query = $this->db->getQuery(true)+ ->select($this->db->quoteName('id'))+ ->from($this->db->quoteName('#__finder_types'))+ ->where($this->db->quoteName('title') . ' = ' . $this->db->quote($this->type_title));+ $this->db->setQuery($query);++ return (int) $this->db->loadResult();+ }++ /**+ * Method to get the URL for the item. The URL is how we look up the link+ * in the Finder index.+ *+ * @param integer $id The id of the item.+ * @param string $extension The extension the category is in.+ * @param string $view The view for the URL.+ *+ * @return string The URL of the item.+ *+ * @since __DEPLOY_VERSION__+ */+ protected function getUrl($id, $extension, $view)+ {+ return 'index.php?option=' . $extension . '&view=' . $view . '&id=' . $id;+ }++ /**+ * Method to get the page title of any menu item that is linked to the+ * content item, if it exists and is set.+ *+ * @param string $url The URL of the item.+ *+ * @return mixed The title on success, null if not found.+ *+ * @since __DEPLOY_VERSION__+ * @throws Exception on database error.+ */+ protected function getItemMenuTitle($url)+ {+ $return = null;++ // Set variables+ $user = $this->getApplication()->getIdentity();+ $groups = implode(',', $user->getAuthorisedViewLevels());++ // Build a query to get the menu params.+ $query = $this->db->getQuery(true)+ ->select($this->db->quoteName('params'))+ ->from($this->db->quoteName('#__menu'))+ ->where($this->db->quoteName('link') . ' = ' . $this->db->quote($url))+ ->where($this->db->quoteName('published') . ' = 1')+ ->where($this->db->quoteName('access') . ' IN (' . $groups . ')');++ // Get the menu params from the database.+ $this->db->setQuery($query);+ $params = $this->db->loadResult();++ // Check the results.+ if (empty($params)) {+ return $return;+ }++ // Instantiate the params.+ $params = json_decode($params);++ // Get the page title if it is set.+ if (isset($params->page_title) && $params->page_title) {+ $return = $params->page_title;+ }++ return $return;+ }++ /**+ * Method to update index data on access level changes+ *+ * @param Table $row A Table object+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ protected function itemAccessChange($row)+ {+ $query = clone $this->getStateQuery();+ $query->where('a.id = ' . (int) $row->id);++ // Get the access level.+ $this->db->setQuery($query);+ $item = $this->db->loadObject();++ // Set the access level.+ $temp = max($row->access, $item->cat_access);++ // Update the item.+ $this->change((int) $row->id, 'access', $temp);+ }++ /**+ * Method to update index data on published state changes+ *+ * @param array $pks A list of primary key ids of the content that has changed state.+ * @param integer $value The value of the state that the content has been changed to.+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ protected function itemStateChange($pks, $value)+ {+ /*+ * The item's published state is tied to the category+ * published state so we need to look up all published states+ * before we change anything.+ */+ foreach ($pks as $pk) {+ $query = clone $this->getStateQuery();+ $query->where('a.id = ' . (int) $pk);++ // Get the published states.+ $this->db->setQuery($query);+ $item = $this->db->loadObject();++ // Translate the state.+ $temp = $this->translateState($value, $item->cat_state);++ // Update the item.+ $this->change($pk, 'state', $temp);+ }+ }++ /**+ * Method to update index data when a plugin is disabled+ *+ * @param array $pks A list of primary key ids of the content that has changed state.+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ protected function pluginDisable($pks)+ {+ // Since multiple plugins may be disabled at a time, we need to check first+ // that we're handling the appropriate one for the context+ foreach ($pks as $pk) {+ if ($this->getPluginType($pk) == strtolower($this->context)) {+ // Get all of the items to unindex them+ $query = clone $this->getStateQuery();+ $this->db->setQuery($query);+ $items = $this->db->loadColumn();++ // Remove each item+ foreach ($items as $item) {+ $this->remove($item);+ }+ }+ }+ }++ /**+ * Method to translate the native content states into states that the+ * indexer can use.+ *+ * @param integer $item The item state.+ * @param integer $category The category state. [optional]+ *+ * @return integer The translated indexer state.+ *+ * @since __DEPLOY_VERSION__+ */+ protected function translateState($item, $category = null)+ {+ // If category is present, factor in its states as well+ if ($category !== null && $category == 0) {+ $item = 0;+ }++ // Translate the state+ switch ($item) {+ // Published and archived items only should return a published state+ case 1:+ case 2:+ return 1;++ // All other states should return an unpublished state+ default:+ return 0;+ }+ }++ /**+ * Debug method to set the used indexer+ *+ * @param Indexer $indexer Indexer object+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ public function setIndexer(Indexer $indexer)+ {+ $this->indexer = $indexer;+ }++ /**+ * Debug method to run a specific plugin to prepare a result object.+ * The object is then stored in the indexer object to debug further.+ *+ * @param mixed $id ID to index+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ public function debug($id)+ {+ // Run the setup method.+ $this->setup();++ // Get the item.+ $item = $this->getItem($id);++ // Index the item.+ $this->index($item);+ }+}diff --git a/administrator/components/com_finder/src/Indexer/DebugIndexer.php b/administrator/components/com_finder/src/Indexer/DebugIndexer.php
new file mode 100644
index 000000000000..03f5743bf00d
--- /dev/null+++ b/administrator/components/com_finder/src/Indexer/DebugIndexer.php@@ -0,0 +1,44 @@+<?php++/**+ * @package Joomla.Administrator+ * @subpackage com_finder+ *+ * @copyright (C) 2022 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\Indexer;++/**+ * Debugging indexer class for the Finder indexer package.+ *+ * @since __DEPLOY_VERSION__+ * @internal+ */+class DebugIndexer extends Indexer+{+ /**+ * The result object from the last call to self::index()+ *+ * @var Result+ *+ * @since __DEPLOY_VERSION__+ */+ public static $item;++ /**+ * Stub for index() in indexer class+ *+ * @param Result $item Result object to index+ * @param string $format Format to index+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ public function index($item, $format = 'html')+ {+ self::$item = $item;+ }+}diff --git a/administrator/components/com_finder/src/Model/IndexerModel.php b/administrator/components/com_finder/src/Model/IndexerModel.php
index 46e8b6cd0d99..3328ce94788e 100644
--- a/administrator/components/com_finder/src/Model/IndexerModel.php+++ b/administrator/components/com_finder/src/Model/IndexerModel.php@@ -10,7 +10,8 @@
namespace Joomla\Component\Finder\Administrator\Model;
-use Joomla\CMS\MVC\Model\BaseDatabaseModel;+use Joomla\CMS\Form\Form;+use Joomla\CMS\MVC\Model\FormModel;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
@@ -21,6 +22,29 @@
*
* @since 2.5
*/
-class IndexerModel extends BaseDatabaseModel+class IndexerModel extends FormModel
{
+ /**+ * Method for getting a form.+ *+ * @param array $data Data for the form.+ * @param boolean $loadData True if the form is to load its own data (default case), false if not.+ *+ * @return Form+ *+ * @since __DEPLOY_VERSION__+ *+ * @throws \Exception+ */+ public function getForm($data = [], $loadData = true)+ {+ // Get the form.+ $form = $this->loadForm('com_finder.indexer', 'indexer', ['control' => '', 'load_data' => $loadData]);++ if (empty($form)) {+ return false;+ }++ return $form;+ }
}
diff --git a/administrator/components/com_finder/src/Model/ItemModel.php b/administrator/components/com_finder/src/Model/ItemModel.php
new file mode 100644
index 000000000000..66360f75f61b
--- /dev/null+++ b/administrator/components/com_finder/src/Model/ItemModel.php@@ -0,0 +1,107 @@+<?php++/**+ * @package Joomla.Administrator+ * @subpackage com_finder+ *+ * @copyright (C) 2022 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\Model;++use Joomla\CMS\Factory;+use Joomla\CMS\MVC\Model\BaseDatabaseModel;+use Joomla\Database\ParameterType;++/**+ * Index Item model class for Finder.+ *+ * @since __DEPLOY_VERSION__+ */+class ItemModel extends BaseDatabaseModel+{+ /**+ * Stock method to auto-populate the model state.+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ protected function populateState()+ {+ // Get the pk of the record from the request.+ $pk = Factory::getApplication()->input->getInt('id');+ $this->setState('item.link_id', $pk);+ }++ /**+ * Get a finder link object+ *+ * @return object+ *+ * @since __DEPLOY_VERSION__+ */+ public function getItem()+ {+ $link_id = (int) $this->getState('item.link_id');+ $db = $this->getDatabase();+ $query = $db->getQuery(true)+ ->select('*')+ ->from($db->quoteName('#__finder_links', 'l'))+ ->where($db->quoteName('l.link_id') . ' = :link_id')+ ->bind(':link_id', $link_id, ParameterType::INTEGER);++ $db->setQuery($query);++ return $db->loadObject();+ }++ /**+ * Get terms associated with a finder link+ *+ * @return object[]+ *+ * @since __DEPLOY_VERSION__+ */+ public function getTerms()+ {+ $link_id = (int) $this->getState('item.link_id');+ $db = $this->getDatabase();+ $query = $db->getQuery(true)+ ->select('t.*, l.*')+ ->from($db->quoteName('#__finder_links_terms', 'l'))+ ->leftJoin($db->quoteName('#__finder_terms', 't') . ' ON ' . $db->quoteName('t.term_id') . ' = ' . $db->quoteName('l.term_id'))+ ->where($db->quoteName('l.link_id') . ' = :link_id')+ ->order('l.weight')+ ->bind(':link_id', $link_id, ParameterType::INTEGER);++ $db->setQuery($query);++ return $db->loadObjectList();+ }++ /**+ * Get taxonomies associated with a finder link+ *+ * @return \stdClass[]+ *+ * @since __DEPLOY_VERSION__+ */+ public function getTaxonomies()+ {+ $link_id = (int) $this->getState('item.link_id');+ $db = $this->getDatabase();+ $query = $db->getQuery(true)+ ->select('t.*, m.*')+ ->from($db->quoteName('#__finder_taxonomy_map', 'm'))+ ->leftJoin($db->quoteName('#__finder_taxonomy', 't') . ' ON ' . $db->quoteName('t.id') . ' = ' . $db->quoteName('m.node_id'))+ ->where($db->quoteName('m.link_id') . ' = :link_id')+ ->order('t.title')+ ->bind(':link_id', $link_id, ParameterType::INTEGER);++ $db->setQuery($query);++ return $db->loadObjectList();+ }+}diff --git a/administrator/components/com_finder/src/View/Index/HtmlView.php b/administrator/components/com_finder/src/View/Index/HtmlView.php
index 5cd83861e7bf..5c611a8607ee 100644
--- a/administrator/components/com_finder/src/View/Index/HtmlView.php+++ b/administrator/components/com_finder/src/View/Index/HtmlView.php@@ -174,13 +174,35 @@ protected function addToolbar()
ToolbarHelper::title(Text::_('COM_FINDER_INDEX_TOOLBAR_TITLE'), 'search-plus finder');
- $toolbar->popupButton('archive', 'COM_FINDER_INDEX')- ->url('index.php?option=com_finder&view=indexer&tmpl=component')- ->iframeWidth(550)- ->iframeHeight(210)- ->onclose('window.parent.location.reload()')- ->icon('icon-archive')- ->title(Text::_('COM_FINDER_HEADING_INDEXER'));+ if (JDEBUG) {+ $dropdown = $toolbar->dropdownButton('indexing-group');+ $dropdown->text('COM_FINDER_INDEX')+ ->toggleSplit(false)+ ->icon('icon-archive')+ ->buttonClass('btn btn-action');++ $childBar = $dropdown->getChildToolbar();++ $childBar->popupButton('index', 'COM_FINDER_INDEX')+ ->url('index.php?option=com_finder&view=indexer&tmpl=component')+ ->icon('icon-archive')+ ->iframeWidth(500)+ ->iframeHeight(210)+ ->onclose('window.parent.location.reload()')+ ->title(Text::_('COM_FINDER_HEADING_INDEXER'));++ $childBar->linkButton('indexdebug', 'COM_FINDER_INDEX_TOOLBAR_INDEX_DEBUGGING')+ ->url('index.php?option=com_finder&view=indexer&layout=debug')+ ->icon('icon-tools');+ } else {+ $toolbar->popupButton('index', 'COM_FINDER_INDEX')+ ->url('index.php?option=com_finder&view=indexer&tmpl=component')+ ->icon('icon-archive')+ ->iframeWidth(500)+ ->iframeHeight(210)+ ->onclose('window.parent.location.reload()')+ ->title(Text::_('COM_FINDER_HEADING_INDEXER'));+ }
if (!$this->isEmptyState) {
if ($canDo->get('core.edit.state')) {
diff --git a/administrator/components/com_finder/src/View/Indexer/HtmlView.php b/administrator/components/com_finder/src/View/Indexer/HtmlView.php
index e13214d3d24c..a65d408621be 100644
--- a/administrator/components/com_finder/src/View/Indexer/HtmlView.php+++ b/administrator/components/com_finder/src/View/Indexer/HtmlView.php@@ -10,7 +10,14 @@
namespace Joomla\Component\Finder\Administrator\View\Indexer;
+use Joomla\CMS\Factory;+use Joomla\CMS\Form\Form;+use Joomla\CMS\Helper\ContentHelper;+use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
+use Joomla\CMS\Router\Route;+use Joomla\CMS\Toolbar\Toolbar;+use Joomla\CMS\Toolbar\ToolbarHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
@@ -23,4 +30,55 @@
*/
class HtmlView extends BaseHtmlView
{
+ /**+ * @var Form $form+ *+ * @since __DEPLOY_VERSION__+ */+ public $form;++ /**+ * Method to display the view.+ *+ * @param string $tpl A template file to load. [optional]+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ public function display($tpl = null)+ {+ if ($this->getLayout() == 'debug') {+ $this->form = $this->get('Form');+ $this->addToolbar();+ }++ parent::display($tpl);+ }++ /**+ * Method to configure the toolbar for this view.+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ protected function addToolbar()+ {+ $toolbar = Toolbar::getInstance('toolbar');++ ToolbarHelper::title(Text::_('COM_FINDER_INDEXER_TOOLBAR_TITLE'), 'search-plus finder');++ $arrow = Factory::getLanguage()->isRtl() ? 'arrow-right' : 'arrow-left';++ ToolbarHelper::link(+ Route::_('index.php?option=com_finder&view=index'),+ 'JTOOLBAR_BACK',+ $arrow+ );++ $toolbar->standardButton('index', 'COM_FINDER_INDEX')+ ->icon('icon-play')+ ->onclick('Joomla.debugIndexing();');+ }
}
diff --git a/administrator/components/com_finder/src/View/Item/HtmlView.php b/administrator/components/com_finder/src/View/Item/HtmlView.php
new file mode 100644
index 000000000000..b3c8624b400f
--- /dev/null+++ b/administrator/components/com_finder/src/View/Item/HtmlView.php@@ -0,0 +1,84 @@+<?php++/**+ * @package Joomla.Administrator+ * @subpackage com_finder+ *+ * @copyright (C) 2022 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\View\Item;++use Joomla\CMS\Language\Text;+use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;+use Joomla\CMS\Toolbar\ToolbarHelper;++/**+ * Index view class for Finder.+ *+ * @since __DEPLOY_VERSION__+ */+class HtmlView extends BaseHtmlView+{+ /**+ * The indexed item+ *+ * @var object+ *+ * @since __DEPLOY_VERSION__+ */+ protected $item;++ /**+ * The associated terms+ *+ * @var object[]+ *+ * @since __DEPLOY_VERSION__+ */+ protected $terms;++ /**+ * The associated taxonomies+ *+ * @var object[]+ *+ * @since __DEPLOY_VERSION__+ */+ protected $taxonomies;++ /**+ * Method to display the view.+ *+ * @param string $tpl A template file to load. [optional]+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ public function display($tpl = null)+ {+ $this->item = $this->get('Item');+ $this->terms = $this->get('Terms');+ $this->taxonomies = $this->get('Taxonomies');++ // Configure the toolbar.+ $this->addToolbar();++ parent::display($tpl);+ }++ /**+ * Method to configure the toolbar for this view.+ *+ * @return void+ *+ * @since __DEPLOY_VERSION__+ */+ protected function addToolbar()+ {+ ToolbarHelper::title(Text::_('COM_FINDER_INDEX_TOOLBAR_TITLE'), 'search-plus finder');+ ToolbarHelper::back('JTOOLBAR_BACK', 'index.php?option=com_finder&view=index');+ }+}diff --git a/administrator/components/com_finder/tmpl/index/default.php b/administrator/components/com_finder/tmpl/index/default.php
index c51294871e46..b30d081cf782 100644
--- a/administrator/components/com_finder/tmpl/index/default.php+++ b/administrator/components/com_finder/tmpl/index/default.php@@ -26,7 +26,6 @@
$wa = $this->document->getWebAssetManager();
$wa->useScript('multiselect')
->useScript('table.columns');
-
?>
<form action="<?php echo Route::_('index.php?option=com_finder&view=index'); ?>" method="post" name="adminForm" id="adminForm">
<div class="row">
@@ -111,7 +110,13 @@
<?php echo HTMLHelper::_('jgrid.published', $item->published, $i, 'index.', $canChange, 'cb'); ?>
</td>
<th scope="row">
- <?php echo $this->escape($item->title); ?>+ <?php if (JDEBUG) : ?>+ <a href="index.php?option=com_finder&view=item&id=<?php echo $item->link_id; ?>">+ <?php echo $this->escape($item->title); ?>+ </a>+ <?php else : ?>+ <?php echo $this->escape($item->title); ?>+ <?php endif; ?>
</th>
<td class="small d-none d-md-table-cell">
<?php
diff --git a/administrator/components/com_finder/tmpl/indexer/debug.php b/administrator/components/com_finder/tmpl/indexer/debug.php
new file mode 100644
index 000000000000..b4247b72025e
--- /dev/null+++ b/administrator/components/com_finder/tmpl/indexer/debug.php@@ -0,0 +1,61 @@+<?php++/**+ * @package Joomla.Administrator+ * @subpackage com_finder+ *+ * @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>+ * @license GNU General Public License version 2 or later; see LICENSE.txt+ */++defined('_JEXEC') or die;++use Joomla\CMS\Factory;+use Joomla\CMS\Language\Text;+use Joomla\CMS\Router\Route;++/** @var Joomla\Component\Finder\Administrator\View\Indexer\HtmlView $this */++Text::script('COM_FINDER_INDEXER_MESSAGE_COMPLETE', true);++/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */+$wa = $this->document->getWebAssetManager();+$wa->useScript('keepalive')+ ->useScript('com_finder.debug');++?>++<form action="<?php echo Route::_('index.php?option=com_finder&layout=debug'); ?>" method="post" name="adminForm" id="debug-form">+ <div class="form-horizontal">+ <div class="card mt-3">+ <div class="card-body">+ <fieldset class="adminform p-4">+ <div class="alert alert-info">+ <h2 class="alert-heading"><?php echo Text::_('COM_FINDER_INDEXER_MSG_DEBUGGING_INDEXING'); ?></h2>+ <?php echo Text::_('COM_FINDER_INDEXER_MSG_DEBUGGING_INDEXING_TEXT'); ?>+ </div>+ <?php echo $this->form->renderField('plugin'); ?>+ <?php echo $this->form->renderField('id'); ?>++ <input id="finder-indexer-token" type="hidden" name="<?php echo Factory::getSession()->getFormToken(); ?>" value="1">+ </fieldset>+ </div>+ </div>+ </div>+</form>++<div class="form-horizontal">+ <div class="card mt-3">+ <div class="card-body">+ <fieldset class="adminform">+ <legend><?php echo Text::_('COM_FINDER_INDEXER_OUTPUT_AREA_TITLE'); ?></legend>+ <div id="indexer-output" class="border p-3" style="min-height:200px;">++ </div>+ </fieldset>+ </div>+ </div>+</div>+++diff --git a/administrator/components/com_finder/tmpl/item/default.php b/administrator/components/com_finder/tmpl/item/default.php
new file mode 100644
index 000000000000..c76160c693c0
--- /dev/null+++ b/administrator/components/com_finder/tmpl/item/default.php@@ -0,0 +1,100 @@+<?php++/**+ * @package Joomla.Administrator+ * @subpackage com_finder+ *+ * @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>+ * @license GNU General Public License version 2 or later; see LICENSE.txt+ */++defined('_JEXEC') or die;++use Joomla\CMS\Language\Text;+?>+<div role="main">+ <h1 class="mb-3"><?php echo $this->item->title; ?></h1>+ <div class="card mb-3">+ <div class="card-header"><h2><?php echo Text::_('COM_FINDER_ITEM_FIELDSET_ITEM_TITLE'); ?></h2></div>+ <div class="card-body">+ <dl class="row">+ <?php foreach ($this->item as $key => $value) : ?>+ <dt class="col-sm-3"><?php echo $key; ?></dt>+ <dd class="col-sm-9<?php echo $key == 'object' ? ' text-break' : '';?>"><?php echo $value; ?></dd>+ <?php endforeach; ?>+ </dl>+ </div>+ </div>+ <div class="card mb-3">+ <div class="card-header"><h2><?php echo Text::_('COM_FINDER_ITEM_FIELDSET_TERMS_TITLE'); ?></h2></div>+ <div class="card-body">+ <table class="table">+ <caption class="visually-hidden">+ <?php echo Text::_('COM_FINDER_ITEM_TERMS_TABLE_CAPTION'); ?>,+ </caption>+ <thead>+ <tr>+ <th scope="col">id</th>+ <th scope="col">term</th>+ <th scope="col">stem</th>+ <th scope="col">common</th>+ <th scope="col">phrase</th>+ <th scope="col">weight</th>+ <th scope="col">links</th>+ <th scope="col">language</th>+ </tr>+ </thead>+ <tbody>+ <?php foreach ($this->terms as $term) : ?>+ <tr>+ <th scope="row"><?php echo $term->term_id; ?></th>+ <td><?php echo $term->term; ?></td>+ <td><?php echo $term->stem; ?></td>+ <td><?php echo $term->common; ?></td>+ <td><?php echo $term->phrase; ?></td>+ <td><?php echo $term->weight; ?></td>+ <td><?php echo $term->links; ?></td>+ <td><?php echo $term->language; ?></td>+ </tr>+ <?php endforeach; ?>+ </tbody>+ </table>+ </div>+ </div>+ <div class="card mb-3">+ <div class="card-header"><h2><?php echo Text::_('COM_FINDER_ITEM_FIELDSET_TAXONOMIES_TITLE'); ?></h2></div>+ <div class="card-body">+ <table class="table">+ <caption class="visually-hidden">+ <?php echo Text::_('COM_FINDER_ITEM_TAXONOMIES_TABLE_CAPTION'); ?>,+ </caption>+ <thead>+ <tr>+ <th scope="col">id</th>+ <th scope="col">title</th>+ <th scope="col">alias</th>+ <th scope="col">lft</th>+ <th scope="col">path</th>+ <th scope="col">state</th>+ <th scope="col">access</th>+ <th scope="col">language</th>+ </tr>+ </thead>+ <tbody>+ <?php foreach ($this->taxonomies as $taxonomy) : ?>+ <tr>+ <th scope="row"><?php echo $taxonomy->id; ?></th>+ <td><?php echo $taxonomy->title; ?></td>+ <td><?php echo $taxonomy->alias; ?></td>+ <td><?php echo $taxonomy->lft; ?></td>+ <td><?php echo $taxonomy->path; ?></td>+ <td><?php echo $taxonomy->state; ?></td>+ <td><?php echo $taxonomy->access; ?></td>+ <td><?php echo $taxonomy->language; ?></td>+ </tr>+ <?php endforeach; ?>+ </tbody>+ </table>+ </div>+ </div>+</div>diff --git a/administrator/language/en-GB/com_finder.ini b/administrator/language/en-GB/com_finder.ini
index 5630de653ae4..1bf0cf4df979 100644
--- a/administrator/language/en-GB/com_finder.ini+++ b/administrator/language/en-GB/com_finder.ini@@ -72,6 +72,7 @@ COM_FINDER_EMPTYSTATE_CONTENT="No content has been indexed or you have deleted a
COM_FINDER_EMPTYSTATE_SEARCHES_CONTENT="There are no phrases used for site searching to view yet."
COM_FINDER_FIELD_CREATED_BY_ALIAS_LABEL="Alias"
COM_FINDER_FIELD_CREATED_BY_LABEL="Created By"
+COM_FINDER_FIELD_FINDER_PLUGIN_LABEL="Finder Plugin"
COM_FINDER_FIELDSET_INDEX_OPTIONS_DESCRIPTION="These options influence how the content is indexed. After changing settings here, the index needs to be rebuilt."
COM_FINDER_FIELDSET_INDEX_OPTIONS_LABEL="Index"
COM_FINDER_FIELDSET_SEARCH_OPTIONS_LABEL="Smart Search"
@@ -152,11 +153,16 @@ COM_FINDER_INDEX_SEARCH_DESC="Search in title, URL and last updated date."
COM_FINDER_INDEX_SEARCH_LABEL="Search Indexed Content"
COM_FINDER_INDEX_TABLE_CAPTION="Indexed Content"
COM_FINDER_INDEX_TIP="Start the indexer by pressing the button below, or in the toolbar."
+COM_FINDER_INDEX_TOOLBAR_INDEX_DEBUGGING="Index Debugging"
COM_FINDER_INDEX_TOOLBAR_MAINTENANCE="Maintenance"
COM_FINDER_INDEX_TOOLBAR_OPTIMISE="Optimise"
COM_FINDER_INDEX_TOOLBAR_PURGE="Clear Index"
COM_FINDER_INDEX_TOOLBAR_TITLE="Smart Search: Indexed Content"
COM_FINDER_INDEX_TYPE_FILTER="Any Type of Content"
+COM_FINDER_INDEXER_FIELDSET_ATTRIBUTES="Result Object"+COM_FINDER_INDEXER_FIELDSET_ELEMENTS="Additional Elements"+COM_FINDER_INDEXER_FIELDSET_INSTRUCTIONS="Instructions"+COM_FINDER_INDEXER_FIELDSET_TAXONOMIES="Taxonomies"
COM_FINDER_INDEXER_HEADER_COMPLETE="Indexing Complete"
COM_FINDER_INDEXER_HEADER_ERROR="An Error Has Occurred"
COM_FINDER_INDEXER_HEADER_INIT="Starting Indexer"
@@ -169,6 +175,15 @@ COM_FINDER_INDEXER_MESSAGE_COMPLETE="The indexing process is complete. It is now
COM_FINDER_INDEXER_MESSAGE_INIT="The indexer is starting. Do not close this window."
COM_FINDER_INDEXER_MESSAGE_OPTIMIZE="The index tables are being optimised for the best possible performance. Do not close this window."
COM_FINDER_INDEXER_MESSAGE_RUNNING="Your content is being indexed. Do not close this window."
+COM_FINDER_INDEXER_MSG_DEBUGGING_INDEXING="Debugging Smart Search indexing plugins"+COM_FINDER_INDEXER_MSG_DEBUGGING_INDEXING_TEXT="Select a Smart Search plugin and provide an ID to index. The result of that plugin for that ID will then be displayed in the below area."+COM_FINDER_INDEXER_OUTPUT_AREA_TITLE="Output"+COM_FINDER_INDEXER_TOOLBAR_TITLE="Indexer: Debug Mode"+COM_FINDER_ITEM_FIELDSET_ITEM_TITLE="Item attributes"+COM_FINDER_ITEM_FIELDSET_TAXONOMIES_TITLE="Taxonomies"+COM_FINDER_ITEM_FIELDSET_TERMS_TITLE="Terms"+COM_FINDER_ITEM_TAXONOMIES_TABLE_CAPTION="Table of taxonomies"+COM_FINDER_ITEM_TERMS_TABLE_CAPTION="Table of terms"
COM_FINDER_ITEM_X_ONLY="%s Only"
COM_FINDER_ITEMS="Content"
COM_FINDER_LOGGING_DISABLED="Gathering of statistics is disabled. Enable it in the %s."
diff --git a/build/media_source/com_finder/joomla.asset.json b/build/media_source/com_finder/joomla.asset.json
index 8d562f35ec7d..6f964164c45d 100644
--- a/build/media_source/com_finder/joomla.asset.json+++ b/build/media_source/com_finder/joomla.asset.json@@ -10,6 +10,29 @@
"type": "style",
"uri": "com_finder/dates.min.css"
},
+ {+ "name": "com_finder.debug.es5",+ "type": "script",+ "uri": "com_finder/debug-es5.min.js",+ "dependencies": [+ "core"+ ],+ "attributes": {+ "nomodule": true,+ "defer": true+ }+ },+ {+ "name": "com_finder.debug",+ "type": "script",+ "uri": "com_finder/debug.min.js",+ "dependencies": [+ "com_finder.debug.es5"+ ],+ "attributes": {+ "type": "module"+ }+ },
{
"name": "com_finder.filters.es5",
"type": "script",
diff --git a/build/media_source/com_finder/js/debug.es6.js b/build/media_source/com_finder/js/debug.es6.js
new file mode 100644
index 000000000000..274ba59c49d3
--- /dev/null+++ b/build/media_source/com_finder/js/debug.es6.js@@ -0,0 +1,46 @@+/**+ * @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>+ * @license GNU General Public License version 2 or later; see LICENSE.txt+ */+// eslint-disable no-alert+((Joomla, document) => {+ 'use strict';++ if (!Joomla) {+ throw new Error('core.js was not properly initialised');+ }++ Joomla.finderIndexer = () => {+ const path = 'index.php?option=com_finder&task=indexer.debug&tmpl=component&format=json';+ const token = `&${document.getElementById('finder-indexer-token').getAttribute('name')}=1`;++ Joomla.debugIndexing = () => {+ const formEls = new URLSearchParams(Array.from(new FormData(document.getElementById('debug-form')))).toString();+ Joomla.request({+ url: `${path}${token}&${formEls}`,+ method: 'GET',+ data: '',+ perform: true,+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },+ onSuccess: (response) => {+ const output = document.getElementById('indexer-output');+ try {+ const parsed = JSON.parse(response);+ output.innerHTML = parsed.rendered;+ } catch (e) {+ output.innerHTML = response;+ }+ },+ onError: (xhr) => {+ const output = document.getElementById('indexer-output');+ output.innerHTML = xhr.response;+ },+ });+ };+ };+})(Joomla, document);++// @todo use directly the Joomla.finderIndexer() instead of the Indexer()!!!+document.addEventListener('DOMContentLoaded', () => {+ window.Indexer = Joomla.finderIndexer();+});
The text was updated successfully, but these errors were encountered:
New language relevant PR in upstream repo: joomla/joomla-cms#36753 Here are the upstream changes:
Click to expand the diff!
The text was updated successfully, but these errors were encountered: