diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-16.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-16.sql
new file mode 100644
index 0000000000000..fbb857cdf4df5
--- /dev/null
+++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-16.sql
@@ -0,0 +1,185 @@
+INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES (493, 0, 'plg_extension_finder', 'plugin', 'finder', 'extension', 0, 1, 1, 0, '', '', 0, '0000-00-00 00:00:00', 0, 0);
+DROP TABLE IF EXISTS `#__finder_terms_common`;
+CREATE TABLE `#__finder_terms_common` (
+ `term` varchar(75) NOT NULL DEFAULT '',
+ `language` char(7) NOT NULL DEFAULT '',
+ `custom` int(11) NOT NULL DEFAULT '0',
+ UNIQUE KEY `idx_word_lang` (`term`,`language`),
+ KEY `idx_lang` (`language`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_bin;
+
+INSERT INTO `#__finder_terms_common` (`term`, `language`, `custom`) VALUES
+ ('i', 'en', 0),
+ ('me', 'en', 0),
+ ('my', 'en', 0),
+ ('myself', 'en', 0),
+ ('we', 'en', 0),
+ ('our', 'en', 0),
+ ('ours', 'en', 0),
+ ('ourselves', 'en', 0),
+ ('you', 'en', 0),
+ ('your', 'en', 0),
+ ('yours', 'en', 0),
+ ('yourself', 'en', 0),
+ ('yourselves', 'en', 0),
+ ('he', 'en', 0),
+ ('him', 'en', 0),
+ ('his', 'en', 0),
+ ('himself', 'en', 0),
+ ('she', 'en', 0),
+ ('her', 'en', 0),
+ ('hers', 'en', 0),
+ ('herself', 'en', 0),
+ ('it', 'en', 0),
+ ('its', 'en', 0),
+ ('itself', 'en', 0),
+ ('they', 'en', 0),
+ ('them', 'en', 0),
+ ('their', 'en', 0),
+ ('theirs', 'en', 0),
+ ('themselves', 'en', 0),
+ ('what', 'en', 0),
+ ('which', 'en', 0),
+ ('who', 'en', 0),
+ ('whom', 'en', 0),
+ ('this', 'en', 0),
+ ('that', 'en', 0),
+ ('these', 'en', 0),
+ ('those', 'en', 0),
+ ('am', 'en', 0),
+ ('is', 'en', 0),
+ ('are', 'en', 0),
+ ('was', 'en', 0),
+ ('were', 'en', 0),
+ ('be', 'en', 0),
+ ('been', 'en', 0),
+ ('being', 'en', 0),
+ ('have', 'en', 0),
+ ('has', 'en', 0),
+ ('had', 'en', 0),
+ ('having', 'en', 0),
+ ('do', 'en', 0),
+ ('does', 'en', 0),
+ ('did', 'en', 0),
+ ('doing', 'en', 0),
+ ('would', 'en', 0),
+ ('should', 'en', 0),
+ ('could', 'en', 0),
+ ('ought', 'en', 0),
+ ('i\'m', 'en', 0),
+ ('you\'re', 'en', 0),
+ ('he\'s', 'en', 0),
+ ('she\'s', 'en', 0),
+ ('it\'s', 'en', 0),
+ ('we\'re', 'en', 0),
+ ('they\'re', 'en', 0),
+ ('i\'ve', 'en', 0),
+ ('you\'ve', 'en', 0),
+ ('we\'ve', 'en', 0),
+ ('they\'ve', 'en', 0),
+ ('i\'d', 'en', 0),
+ ('you\'d', 'en', 0),
+ ('he\'d', 'en', 0),
+ ('she\'d', 'en', 0),
+ ('we\'d', 'en', 0),
+ ('they\'d', 'en', 0),
+ ('i\'ll', 'en', 0),
+ ('you\'ll', 'en', 0),
+ ('he\'ll', 'en', 0),
+ ('she\'ll', 'en', 0),
+ ('we\'ll', 'en', 0),
+ ('they\'ll', 'en', 0),
+ ('isn\'t', 'en', 0),
+ ('aren\'t', 'en', 0),
+ ('wasn\'t', 'en', 0),
+ ('weren\'t', 'en', 0),
+ ('hasn\'t', 'en', 0),
+ ('haven\'t', 'en', 0),
+ ('hadn\'t', 'en', 0),
+ ('doesn\'t', 'en', 0),
+ ('don\'t', 'en', 0),
+ ('didn\'t', 'en', 0),
+ ('won\'t', 'en', 0),
+ ('wouldn\'t', 'en', 0),
+ ('shan\'t', 'en', 0),
+ ('shouldn\'t', 'en', 0),
+ ('can\'t', 'en', 0),
+ ('cannot', 'en', 0),
+ ('couldn\'t', 'en', 0),
+ ('mustn\'t', 'en', 0),
+ ('let\'s', 'en', 0),
+ ('that\'s', 'en', 0),
+ ('who\'s', 'en', 0),
+ ('what\'s', 'en', 0),
+ ('here\'s', 'en', 0),
+ ('there\'s', 'en', 0),
+ ('when\'s', 'en', 0),
+ ('where\'s', 'en', 0),
+ ('why\'s', 'en', 0),
+ ('how\'s', 'en', 0),
+ ('a', 'en', 0),
+ ('an', 'en', 0),
+ ('the', 'en', 0),
+ ('and', 'en', 0),
+ ('but', 'en', 0),
+ ('if', 'en', 0),
+ ('or', 'en', 0),
+ ('because', 'en', 0),
+ ('as', 'en', 0),
+ ('until', 'en', 0),
+ ('while', 'en', 0),
+ ('of', 'en', 0),
+ ('at', 'en', 0),
+ ('by', 'en', 0),
+ ('for', 'en', 0),
+ ('with', 'en', 0),
+ ('about', 'en', 0),
+ ('against', 'en', 0),
+ ('between', 'en', 0),
+ ('into', 'en', 0),
+ ('through', 'en', 0),
+ ('during', 'en', 0),
+ ('before', 'en', 0),
+ ('after', 'en', 0),
+ ('above', 'en', 0),
+ ('below', 'en', 0),
+ ('to', 'en', 0),
+ ('from', 'en', 0),
+ ('up', 'en', 0),
+ ('down', 'en', 0),
+ ('in', 'en', 0),
+ ('out', 'en', 0),
+ ('on', 'en', 0),
+ ('off', 'en', 0),
+ ('over', 'en', 0),
+ ('under', 'en', 0),
+ ('again', 'en', 0),
+ ('further', 'en', 0),
+ ('then', 'en', 0),
+ ('once', 'en', 0),
+ ('here', 'en', 0),
+ ('there', 'en', 0),
+ ('when', 'en', 0),
+ ('where', 'en', 0),
+ ('why', 'en', 0),
+ ('how', 'en', 0),
+ ('all', 'en', 0),
+ ('any', 'en', 0),
+ ('both', 'en', 0),
+ ('each', 'en', 0),
+ ('few', 'en', 0),
+ ('more', 'en', 0),
+ ('most', 'en', 0),
+ ('other', 'en', 0),
+ ('some', 'en', 0),
+ ('such', 'en', 0),
+ ('no', 'en', 0),
+ ('nor', 'en', 0),
+ ('not', 'en', 0),
+ ('only', 'en', 0),
+ ('own', 'en', 0),
+ ('same', 'en', 0),
+ ('so', 'en', 0),
+ ('than', 'en', 0),
+ ('too', 'en', 0),
+ ('very', 'en', 0);
diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-07-29.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-07-29.sql
new file mode 100644
index 0000000000000..9437f4bf5e014
--- /dev/null
+++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-07-29.sql
@@ -0,0 +1,26 @@
+DROP TABLE #__finder_taxonomy;
+
+CREATE TABLE IF NOT EXISTS `#__finder_taxonomy` (
+ `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `parent_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `lft` INT(11) NOT NULL DEFAULT '0',
+ `rgt` INT(11) NOT NULL DEFAULT '0',
+ `level` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `path` VARCHAR(400) NOT NULL DEFAULT '',
+ `title` VARCHAR(255) NOT NULL DEFAULT '',
+ `alias` VARCHAR(400) NOT NULL DEFAULT '',
+ `state` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
+ `access` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
+ `language` CHAR(7) NOT NULL DEFAULT '',
+ PRIMARY KEY (`id`),
+ INDEX `idx_state` (`state`),
+ INDEX `idx_access` (`access`),
+ INDEX `idx_path` (`path`(100)),
+ INDEX `idx_left_right` (`lft`, `rgt`),
+ INDEX `idx_alias` (`alias`(100)),
+ INDEX `idx_language` (`language`),
+ INDEX `idx_parent_published` (`parent_id`, `state`, `access`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci;
+
+INSERT INTO `#__finder_taxonomy` (`id`, `parent_id`, `lft`, `rgt`, `level`, `path`, `title`, `alias`, `state`, `access`, `language`) VALUES
+(1, 0, 0, 1, 0, '', 'ROOT', 'root', 1, 1, '*');
diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-16.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-16.sql
new file mode 100644
index 0000000000000..6ae5c4c13d39a
--- /dev/null
+++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-16.sql
@@ -0,0 +1,186 @@
+INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "checked_out", "checked_out_time", "ordering", "state") VALUES (493, 0, 'plg_extension_finder', 'plugin', 'finder', 'extension', 0, 1, 1, 0, '', '', 0, '0000-00-00 00:00:00', 0, 0);
+DROP TABLE IF EXISTS "#__finder_terms_common";
+CREATE TABLE "#__finder_terms_common" (
+ "term" varchar(75) NOT NULL,
+ "language" varchar(7) DEFAULT '' NOT NULL,
+ "custom" integer DEFAULT 0 NOT NULL,
+ CONSTRAINT "#__finder_terms_idx_term" UNIQUE ("term", "language")
+);
+CREATE INDEX "#__finder_terms_common_idx_word_lang" on "#__finder_terms_common" ("term", "language");
+CREATE INDEX "#__finder_terms_common_idx_lang" on "#__finder_terms_common" ("language");
+
+INSERT INTO "#__finder_terms_common" ("term", "language", "custom") VALUES
+ ('i', 'en', 0),
+ ('me', 'en', 0),
+ ('my', 'en', 0),
+ ('myself', 'en', 0),
+ ('we', 'en', 0),
+ ('our', 'en', 0),
+ ('ours', 'en', 0),
+ ('ourselves', 'en', 0),
+ ('you', 'en', 0),
+ ('your', 'en', 0),
+ ('yours', 'en', 0),
+ ('yourself', 'en', 0),
+ ('yourselves', 'en', 0),
+ ('he', 'en', 0),
+ ('him', 'en', 0),
+ ('his', 'en', 0),
+ ('himself', 'en', 0),
+ ('she', 'en', 0),
+ ('her', 'en', 0),
+ ('hers', 'en', 0),
+ ('herself', 'en', 0),
+ ('it', 'en', 0),
+ ('its', 'en', 0),
+ ('itself', 'en', 0),
+ ('they', 'en', 0),
+ ('them', 'en', 0),
+ ('their', 'en', 0),
+ ('theirs', 'en', 0),
+ ('themselves', 'en', 0),
+ ('what', 'en', 0),
+ ('which', 'en', 0),
+ ('who', 'en', 0),
+ ('whom', 'en', 0),
+ ('this', 'en', 0),
+ ('that', 'en', 0),
+ ('these', 'en', 0),
+ ('those', 'en', 0),
+ ('am', 'en', 0),
+ ('is', 'en', 0),
+ ('are', 'en', 0),
+ ('was', 'en', 0),
+ ('were', 'en', 0),
+ ('be', 'en', 0),
+ ('been', 'en', 0),
+ ('being', 'en', 0),
+ ('have', 'en', 0),
+ ('has', 'en', 0),
+ ('had', 'en', 0),
+ ('having', 'en', 0),
+ ('do', 'en', 0),
+ ('does', 'en', 0),
+ ('did', 'en', 0),
+ ('doing', 'en', 0),
+ ('would', 'en', 0),
+ ('should', 'en', 0),
+ ('could', 'en', 0),
+ ('ought', 'en', 0),
+ ('i\'m', 'en', 0),
+ ('you\'re', 'en', 0),
+ ('he\'s', 'en', 0),
+ ('she\'s', 'en', 0),
+ ('it\'s', 'en', 0),
+ ('we\'re', 'en', 0),
+ ('they\'re', 'en', 0),
+ ('i\'ve', 'en', 0),
+ ('you\'ve', 'en', 0),
+ ('we\'ve', 'en', 0),
+ ('they\'ve', 'en', 0),
+ ('i\'d', 'en', 0),
+ ('you\'d', 'en', 0),
+ ('he\'d', 'en', 0),
+ ('she\'d', 'en', 0),
+ ('we\'d', 'en', 0),
+ ('they\'d', 'en', 0),
+ ('i\'ll', 'en', 0),
+ ('you\'ll', 'en', 0),
+ ('he\'ll', 'en', 0),
+ ('she\'ll', 'en', 0),
+ ('we\'ll', 'en', 0),
+ ('they\'ll', 'en', 0),
+ ('isn\'t', 'en', 0),
+ ('aren\'t', 'en', 0),
+ ('wasn\'t', 'en', 0),
+ ('weren\'t', 'en', 0),
+ ('hasn\'t', 'en', 0),
+ ('haven\'t', 'en', 0),
+ ('hadn\'t', 'en', 0),
+ ('doesn\'t', 'en', 0),
+ ('don\'t', 'en', 0),
+ ('didn\'t', 'en', 0),
+ ('won\'t', 'en', 0),
+ ('wouldn\'t', 'en', 0),
+ ('shan\'t', 'en', 0),
+ ('shouldn\'t', 'en', 0),
+ ('can\'t', 'en', 0),
+ ('cannot', 'en', 0),
+ ('couldn\'t', 'en', 0),
+ ('mustn\'t', 'en', 0),
+ ('let\'s', 'en', 0),
+ ('that\'s', 'en', 0),
+ ('who\'s', 'en', 0),
+ ('what\'s', 'en', 0),
+ ('here\'s', 'en', 0),
+ ('there\'s', 'en', 0),
+ ('when\'s', 'en', 0),
+ ('where\'s', 'en', 0),
+ ('why\'s', 'en', 0),
+ ('how\'s', 'en', 0),
+ ('a', 'en', 0),
+ ('an', 'en', 0),
+ ('the', 'en', 0),
+ ('and', 'en', 0),
+ ('but', 'en', 0),
+ ('if', 'en', 0),
+ ('or', 'en', 0),
+ ('because', 'en', 0),
+ ('as', 'en', 0),
+ ('until', 'en', 0),
+ ('while', 'en', 0),
+ ('of', 'en', 0),
+ ('at', 'en', 0),
+ ('by', 'en', 0),
+ ('for', 'en', 0),
+ ('with', 'en', 0),
+ ('about', 'en', 0),
+ ('against', 'en', 0),
+ ('between', 'en', 0),
+ ('into', 'en', 0),
+ ('through', 'en', 0),
+ ('during', 'en', 0),
+ ('before', 'en', 0),
+ ('after', 'en', 0),
+ ('above', 'en', 0),
+ ('below', 'en', 0),
+ ('to', 'en', 0),
+ ('from', 'en', 0),
+ ('up', 'en', 0),
+ ('down', 'en', 0),
+ ('in', 'en', 0),
+ ('out', 'en', 0),
+ ('on', 'en', 0),
+ ('off', 'en', 0),
+ ('over', 'en', 0),
+ ('under', 'en', 0),
+ ('again', 'en', 0),
+ ('further', 'en', 0),
+ ('then', 'en', 0),
+ ('once', 'en', 0),
+ ('here', 'en', 0),
+ ('there', 'en', 0),
+ ('when', 'en', 0),
+ ('where', 'en', 0),
+ ('why', 'en', 0),
+ ('how', 'en', 0),
+ ('all', 'en', 0),
+ ('any', 'en', 0),
+ ('both', 'en', 0),
+ ('each', 'en', 0),
+ ('few', 'en', 0),
+ ('more', 'en', 0),
+ ('most', 'en', 0),
+ ('other', 'en', 0),
+ ('some', 'en', 0),
+ ('such', 'en', 0),
+ ('no', 'en', 0),
+ ('nor', 'en', 0),
+ ('not', 'en', 0),
+ ('only', 'en', 0),
+ ('own', 'en', 0),
+ ('same', 'en', 0),
+ ('so', 'en', 0),
+ ('than', 'en', 0),
+ ('too', 'en', 0),
+ ('very', 'en', 0);
diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-07-29.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-07-29.sql
new file mode 100644
index 0000000000000..ea1b4ae743d71
--- /dev/null
+++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-07-29.sql
@@ -0,0 +1,28 @@
+DROP TABLE "#__finder_taxonomy";
+
+CREATE TABLE IF NOT EXISTS "#__finder_taxonomy" (
+ "id" serial NOT NULL,
+ "parent_id" integer DEFAULT 0 NOT NULL,
+ "lft" integer DEFAULT 0 NOT NULL,
+ "rgt" integer DEFAULT 0 NOT NULL,
+ "level" integer DEFAULT 0 NOT NULL,
+ "path" VARCHAR(400) NOT NULL DEFAULT '',
+ "title" VARCHAR(255) NOT NULL DEFAULT '',
+ "alias" VARCHAR(400) NOT NULL DEFAULT '',
+ "state" smallint DEFAULT 1 NOT NULL,
+ "access" smallint DEFAULT 1 NOT NULL,
+ "language" varchar(7) DEFAULT '' NOT NULL,
+ PRIMARY KEY ("id")
+);
+CREATE INDEX "#__finder_taxonomy_state" on "#__finder_taxonomy" ("state");
+CREATE INDEX "#__finder_taxonomy_access" on "#__finder_taxonomy" ("access");
+CREATE INDEX "#__finder_taxonomy_path" on "#__finder_taxonomy" ("path");
+CREATE INDEX "#__finder_taxonomy_lft_rgt" on "#__finder_taxonomy" ("lft", "rgt");
+CREATE INDEX "#__finder_taxonomy_alias" on "#__finder_taxonomy" ("alias");
+CREATE INDEX "#__finder_taxonomy_language" on "#__finder_taxonomy" ("language");
+CREATE INDEX "#__finder_taxonomy_idx_parent_published" on "#__finder_taxonomy" ("parent_id", "state", "access");
+
+INSERT INTO "#__finder_taxonomy" ("id", "parent_id", "lft", "rgt", "level", "path", "title", "alias", "state", "access", "language") VALUES
+(1, 0, 0, 1, 0, '', 'ROOT', 'root', 1, 1, '*');
+
+SELECT setval('#__finder_taxonomy_id_seq', 2, false);
\ No newline at end of file
diff --git a/administrator/components/com_finder/Model/IndexModel.php b/administrator/components/com_finder/Model/IndexModel.php
index 3ccecff74f508..c5ed63efa2688 100644
--- a/administrator/components/com_finder/Model/IndexModel.php
+++ b/administrator/components/com_finder/Model/IndexModel.php
@@ -353,7 +353,19 @@ public function purge()
// Truncate the taxonomy table and insert the root node.
$db->truncateTable('#__finder_taxonomy');
- $root = (object) array('id' => 1, 'parent_id' => 0, 'title' => 'ROOT', 'state' => 0, 'access' => 0, 'ordering' => 0);
+ $root = (object) array(
+ 'id' => 1,
+ 'parent_id' => 0,
+ 'lft' => 0,
+ 'rgt' => 1,
+ 'level' => 0,
+ 'path' => '',
+ 'title' => 'ROOT',
+ 'alias' => 'root',
+ 'state' => 1,
+ 'access' => 1,
+ 'language' => '*'
+ );
$db->insertObject('#__finder_taxonomy', $root);
// Truncate the tokens tables.
diff --git a/administrator/components/com_finder/Model/MapsModel.php b/administrator/components/com_finder/Model/MapsModel.php
index 3fb39b5487023..fe5f3307ee59c 100644
--- a/administrator/components/com_finder/Model/MapsModel.php
+++ b/administrator/components/com_finder/Model/MapsModel.php
@@ -165,24 +165,13 @@ protected function getListQuery()
// Select all fields from the table.
$query = $db->getQuery(true)
- ->select('a.id, a.parent_id, a.title, a.state, a.access, a.ordering')
- ->select('CASE WHEN a.parent_id = 1 THEN 1 ELSE 2 END AS level')
- ->select('p.title AS parent_title')
+ ->select('a.id, a.parent_id, a.lft, a.rgt, a.level, a.path, a.title, a.alias, a.state, a.access, a.language')
->from($db->quoteName('#__finder_taxonomy', 'a'))
- ->leftJoin($db->quoteName('#__finder_taxonomy', 'p') . ' ON p.id = a.parent_id')
->where('a.parent_id != 0');
- $childQuery = $db->getQuery(true)
- ->select('parent_id')
- ->select('COUNT(*) AS num_children')
- ->from($db->quoteName('#__finder_taxonomy'))
- ->where('parent_id != 0')
- ->group('parent_id');
-
- // Join to get children.
- $query->select('b.num_children');
- $query->select('CASE WHEN a.parent_id = 1 THEN a.title ELSE p.title END AS branch_title');
- $query->leftJoin('(' . $childQuery . ') AS b ON b.parent_id = a.id');
+ // Join to get the branch title
+ $query->select([$query->qn('b.id', 'branch_id'), $query->qn('b.title', 'branch_title')])
+ ->leftJoin($query->qn('#__finder_taxonomy', 'b') . ' ON b.level = 1 AND b.lft <= a.lft AND a.rgt <= b.rgt');
// Join to get the map links.
$stateQuery = $db->getQuery(true)
@@ -229,16 +218,16 @@ protected function getListQuery()
}
// Handle the list ordering.
- $listOrdering = $this->getState('list.ordering', 'd.branch_title');
+ $listOrdering = $this->getState('list.ordering', 'a.lft');
$listDirn = $this->getState('list.direction', 'ASC');
- if ($listOrdering === 'd.branch_title')
+ if ($listOrdering === 'a.state')
{
- $query->order("branch_title $listDirn, level ASC, a.title $listDirn");
+ $query->order("a.state $listDirn, a.lft $listDirn, level ASC");
}
- elseif ($listOrdering === 'a.state')
+ else
{
- $query->order("a.state $listDirn, branch_title $listDirn, level ASC");
+ $query->order($listOrdering . ' ' . $listDirn);
}
return $query;
@@ -311,7 +300,7 @@ public function getTable($type = 'Map', $prefix = 'Administrator', $config = arr
*
* @since 2.5
*/
- protected function populateState($ordering = 'd.branch_title', $direction = 'ASC')
+ protected function populateState($ordering = 'a.lft', $direction = 'ASC')
{
// Load the filter state.
$this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string'));
diff --git a/administrator/components/com_finder/Service/HTML/Filter.php b/administrator/components/com_finder/Service/HTML/Filter.php
index c2a02abe8818e..02d5185a1aa38 100644
--- a/administrator/components/com_finder/Service/HTML/Filter.php
+++ b/administrator/components/com_finder/Service/HTML/Filter.php
@@ -84,8 +84,8 @@ public function slider($options = array())
->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.ordering, t.title, c.parent_id')
- ->order('t.ordering, t.title');
+ ->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)
@@ -131,10 +131,11 @@ public function slider($options = array())
$query->clear()
->select('t.*')
->from($db->quoteName('#__finder_taxonomy') . ' AS t')
- ->where('t.parent_id = ' . (int) $bk)
+ ->where('t.lft > ' . (int) $bv->lft)
+ ->where('t.rgt < ' . (int) $bv->rgt)
->where('t.state = 1')
->where('t.access IN (' . $groups . ')')
- ->order('t.ordering, t.title');
+ ->order('t.lft, t.title');
// Self-join to get the parent title.
$query->select('e.title AS parent_title')
@@ -195,7 +196,7 @@ public function slider($options = array())
$html .= '
';
$html .= '';
$html .= ' ' . $nv->title;
+ . $bk . '"' . $checked . '> ' . str_repeat('—', $nv->level - 2) . $nv->title;
$html .= ' ';
$html .= '
';
}
@@ -280,8 +281,8 @@ public function select($idxQuery, $options)
->where('c.access IN (' . $groups . ')')
->group($db->quoteName('t.id'))
->group($db->quoteName('t.parent_id'))
- ->group('t.title, t.state, t.access, t.ordering')
- ->order('t.ordering, t.title');
+ ->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))
@@ -320,10 +321,11 @@ public function select($idxQuery, $options)
$query->clear()
->select('t.*')
->from($db->quoteName('#__finder_taxonomy') . ' AS t')
- ->where('t.parent_id = ' . (int) $bk)
+ ->where('t.lft >= ' . (int) $bv->lft)
+ ->where('t.rgt <= ' . (int) $bv->rgt)
->where('t.state = 1')
->where('t.access IN (' . $groups . ')')
- ->order('t.ordering, t.title');
+ ->order('t.lft, t.title');
// Self-join to get the parent title.
$query->select('e.title AS parent_title')
@@ -362,7 +364,14 @@ public function select($idxQuery, $options)
$title = $language->hasKey($key) ? Text::_($key) : $node->title;
}
- $branches[$bk]->nodes[$node_id]->title = $title;
+ if ($node->level > 2)
+ {
+ $branches[$bk]->nodes[$node_id]->title = str_repeat('-', $node->level - 2) . $title;
+ }
+ else
+ {
+ $branches[$bk]->nodes[$node_id]->title = $title;
+ }
}
// Add the Search All option to the branch.
diff --git a/administrator/components/com_finder/Table/MapTable.php b/administrator/components/com_finder/Table/MapTable.php
index 2715cce6d9f9f..f1e9de3339373 100644
--- a/administrator/components/com_finder/Table/MapTable.php
+++ b/administrator/components/com_finder/Table/MapTable.php
@@ -11,7 +11,9 @@
defined('_JEXEC') or die;
-use Joomla\CMS\Table\Table;
+use Joomla\CMS\Application\ApplicationHelper;
+use Joomla\CMS\Factory;
+use Joomla\CMS\Table\Nested;
use Joomla\Database\DatabaseDriver;
use Joomla\Utilities\ArrayHelper;
@@ -20,7 +22,7 @@
*
* @since 2.5
*/
-class MapTable extends Table
+class MapTable extends Nested
{
/**
* Constructor
@@ -32,6 +34,46 @@ class MapTable extends Table
public function __construct(DatabaseDriver $db)
{
parent::__construct('#__finder_taxonomy', 'id', $db);
+ $this->access = (int) Factory::getConfig()->get('access');
+ }
+
+ /**
+ * Override check function
+ *
+ * @return boolean
+ *
+ * @see Table::check()
+ * @since __DEPLOY_VERSION__
+ */
+ public function check()
+ {
+ try
+ {
+ parent::check();
+ }
+ catch (\Exception $e)
+ {
+ $this->setError($e->getMessage());
+
+ return false;
+ }
+
+ // Check for a title.
+ if (trim($this->title) == '')
+ {
+ $this->setError(Text::_('JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_CATEGORY'));
+
+ return false;
+ }
+
+ $this->alias = ApplicationHelper::stringURLSafe($this->title, $this->language);
+
+ if (trim($this->alias) == '')
+ {
+ $this->alias = md5(serialize($this->getProperties()));
+ }
+
+ return true;
}
/**
diff --git a/administrator/components/com_finder/helpers/indexer/driver/mysql.php b/administrator/components/com_finder/helpers/indexer/driver/mysql.php
index 124a390f4704d..5b47bf840c771 100644
--- a/administrator/components/com_finder/helpers/indexer/driver/mysql.php
+++ b/administrator/components/com_finder/helpers/indexer/driver/mysql.php
@@ -57,7 +57,7 @@ public function index($item, $format = 'html')
// Get the signatures of the item.
$curSig = static::getSignature($item);
- $oldSig = isset($link->md5sum) ? $link->md5sum : null;
+ $oldSig = $link->md5sum ?? null;
// Get the other item information.
$linkId = empty($link->link_id) ? null : $link->link_id;
@@ -104,69 +104,35 @@ public function index($item, $format = 'html')
* already exists in the database, we need to use an UPDATE query.
* Otherwise, we need to use an INSERT to get the link id back.
*/
+ $entry = new stdClass;
+ $entry->url = $item->url;
+ $entry->route = $item->route;
+ $entry->title = $item->title;
+ $entry->description = $item->description;
+ $entry->indexdate = JFactory::getDate()->toSql();
+ $entry->state = (int) $item->state;
+ $entry->access = (int) $item->access;
+ $entry->language = $item->language;
+ $entry->type_id = (int) $item->type_id;
+ $entry->object = '';
+ $entry->publish_start_date = $item->publish_start_date;
+ $entry->publish_end_date = $item->publish_end_date;
+ $entry->start_date = $item->start_date;
+ $entry->end_date = $item->end_date;
+ $entry->list_price = (double) ($item->list_price ?: 0);
+ $entry->sale_price = (double) ($item->sale_price ?: 0);
if ($isNew)
{
- $columnsArray = array(
- $db->quoteName('url'), $db->quoteName('route'), $db->quoteName('title'), $db->quoteName('description'),
- $db->quoteName('indexdate'), $db->quoteName('published'), $db->quoteName('state'), $db->quoteName('access'),
- $db->quoteName('language'), $db->quoteName('type_id'), $db->quoteName('object'), $db->quoteName('publish_start_date'),
- $db->quoteName('publish_end_date'), $db->quoteName('start_date'), $db->quoteName('end_date'), $db->quoteName('list_price'),
- $db->quoteName('sale_price')
- );
-
- // Insert the link.
- $query->clear()
- ->insert($db->quoteName('#__finder_links'))
- ->columns($columnsArray)
- ->values(
- $db->quote($item->url) . ', '
- . $db->quote($item->route) . ', '
- . $db->quote($item->title) . ', '
- . $db->quote($item->description) . ', '
- . $query->currentTimestamp() . ', '
- . '1, '
- . (int) $item->state . ', '
- . (int) $item->access . ', '
- . $db->quote($item->language) . ', '
- . (int) $item->type_id . ', '
- . $db->quote(serialize($item)) . ', '
- . $db->quote($item->publish_start_date) . ', '
- . $db->quote($item->publish_end_date) . ', '
- . $db->quote($item->start_date) . ', '
- . $db->quote($item->end_date) . ', '
- . (double) ($item->list_price ?: 0) . ', '
- . (double) ($item->sale_price ?: 0)
- );
- $db->setQuery($query);
- $db->execute();
-
- // Get the link id.
+ // Insert the link and get its id.
+ $db->insertObject('#__finder_links', $entry);
$linkId = (int) $db->insertid();
}
else
{
// Update the link.
- $query->clear()
- ->update($db->quoteName('#__finder_links'))
- ->set($db->quoteName('route') . ' = ' . $db->quote($item->route))
- ->set($db->quoteName('title') . ' = ' . $db->quote($item->title))
- ->set($db->quoteName('description') . ' = ' . $db->quote($item->description))
- ->set($db->quoteName('indexdate') . ' = ' . $query->currentTimestamp())
- ->set($db->quoteName('state') . ' = ' . (int) $item->state)
- ->set($db->quoteName('access') . ' = ' . (int) $item->access)
- ->set($db->quoteName('language') . ' = ' . $db->quote($item->language))
- ->set($db->quoteName('type_id') . ' = ' . (int) $item->type_id)
- ->set($db->quoteName('object') . ' = ' . $db->quote(serialize($item)))
- ->set($db->quoteName('publish_start_date') . ' = ' . $db->quote($item->publish_start_date))
- ->set($db->quoteName('publish_end_date') . ' = ' . $db->quote($item->publish_end_date))
- ->set($db->quoteName('start_date') . ' = ' . $db->quote($item->start_date))
- ->set($db->quoteName('end_date') . ' = ' . $db->quote($item->end_date))
- ->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ?: 0))
- ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ?: 0))
- ->where('link_id = ' . (int) $linkId);
- $db->setQuery($query);
- $db->execute();
+ $entry->link_id = $linkId;
+ $db->updateObject('#__finder_links', $entry, 'link_id');
}
// Set up the variables we will need during processing.
@@ -261,10 +227,18 @@ public function index($item, $format = 'html')
foreach ($nodes as $node)
{
// Add the node to the tree.
- $nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access);
+ if ($node->nested)
+ {
+ $nodeId = FinderIndexerTaxonomy::addNestedNode($branch, $node->node, $node->state, $node->access, $node->language);
+ }
+ else
+ {
+ $nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access, $node->language);
+ }
// Add the link => node map.
FinderIndexerTaxonomy::addMap($linkId, $nodeId);
+ $node->id = $nodeId;
// Tokenize the node title and add them to the database.
$count += $this->tokenizeToDb($node->title, static::META_CONTEXT, $item->language, $format);
@@ -398,6 +372,7 @@ public function index($item, $format = 'html')
$query->clear()
->update($db->quoteName('#__finder_links'))
->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig))
+ ->set($db->quoteName('object') . ' = ' . $db->quote(serialize($item)))
->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId));
$db->setQuery($query);
$db->execute();
@@ -508,15 +483,15 @@ protected function toggleTables($memory)
// Set the internal state.
$state = $memory;
}
- // We must be setting the tables to the MyISAM engine.
+ // We must be setting the tables to the InnoDB engine.
elseif ($memory === false && $state !== false)
{
- // Set the tokens table to MyISAM.
- $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens') . ' ENGINE = MYISAM');
+ // Set the tokens table to InnoDB.
+ $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens') . ' ENGINE = INNODB');
$db->execute();
- // Set the tokens aggregate table to MyISAM.
- $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens_aggregate') . ' ENGINE = MYISAM');
+ // Set the tokens aggregate table to InnoDB.
+ $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens_aggregate') . ' ENGINE = INNODB');
$db->execute();
// Set the internal state.
diff --git a/administrator/components/com_finder/helpers/indexer/driver/postgresql.php b/administrator/components/com_finder/helpers/indexer/driver/postgresql.php
index adcbe727c6daa..8c6f8b73f46a8 100644
--- a/administrator/components/com_finder/helpers/indexer/driver/postgresql.php
+++ b/administrator/components/com_finder/helpers/indexer/driver/postgresql.php
@@ -96,69 +96,35 @@ public function index($item, $format = 'html')
* already exists in the database, we need to use an UPDATE query.
* Otherwise, we need to use an INSERT to get the link id back.
*/
+ $entry = new stdClass;
+ $entry->url = $item->url;
+ $entry->route = $item->route;
+ $entry->title = $item->title;
+ $entry->description = $item->description;
+ $entry->indexdate = JFactory::getDate()->toSql();
+ $entry->state = (int) $item->state;
+ $entry->access = (int) $item->access;
+ $entry->language = $item->language;
+ $entry->type_id = (int) $item->type_id;
+ $entry->object = '';
+ $entry->publish_start_date = $item->publish_start_date;
+ $entry->publish_end_date = $item->publish_end_date;
+ $entry->start_date = $item->start_date;
+ $entry->end_date = $item->end_date;
+ $entry->list_price = (double) ($item->list_price ?: 0);
+ $entry->sale_price = (double) ($item->sale_price ?: 0);
if ($isNew)
{
- $columnsArray = array(
- $db->quoteName('url'), $db->quoteName('route'), $db->quoteName('title'), $db->quoteName('description'),
- $db->quoteName('indexdate'), $db->quoteName('published'), $db->quoteName('state'), $db->quoteName('access'),
- $db->quoteName('language'), $db->quoteName('type_id'), $db->quoteName('object'), $db->quoteName('publish_start_date'),
- $db->quoteName('publish_end_date'), $db->quoteName('start_date'), $db->quoteName('end_date'), $db->quoteName('list_price'),
- $db->quoteName('sale_price')
- );
-
- // Insert the link.
- $query->clear()
- ->insert($db->quoteName('#__finder_links'))
- ->columns($columnsArray)
- ->values(
- $db->quote($item->url) . ', '
- . $db->quote($item->route) . ', '
- . $db->quote($item->title) . ', '
- . $db->quote($item->description) . ', '
- . $query->currentTimestamp() . ', '
- . '1, '
- . (int) $item->state . ', '
- . (int) $item->access . ', '
- . $db->quote($item->language) . ', '
- . (int) $item->type_id . ', '
- . $db->quote(serialize($item)) . ', '
- . $db->quote($item->publish_start_date) . ', '
- . $db->quote($item->publish_end_date) . ', '
- . $db->quote($item->start_date) . ', '
- . $db->quote($item->end_date) . ', '
- . (double) ($item->list_price ?: 0) . ', '
- . (double) ($item->sale_price ?: 0)
- );
- $db->setQuery($query);
- $db->execute();
-
- // Get the link id.
+ // Insert the link and get its id.
+ $db->insertObject('#__finder_links', $entry);
$linkId = (int) $db->insertid();
}
else
{
// Update the link.
- $query->clear()
- ->update($db->quoteName('#__finder_links'))
- ->set($db->quoteName('route') . ' = ' . $db->quote($item->route))
- ->set($db->quoteName('title') . ' = ' . $db->quote($item->title))
- ->set($db->quoteName('description') . ' = ' . $db->quote($item->description))
- ->set($db->quoteName('indexdate') . ' = ' . $query->currentTimestamp())
- ->set($db->quoteName('state') . ' = ' . (int) $item->state)
- ->set($db->quoteName('access') . ' = ' . (int) $item->access)
- ->set($db->quoteName('language') . ' = ' . $db->quote($item->language))
- ->set($db->quoteName('type_id') . ' = ' . (int) $item->type_id)
- ->set($db->quoteName('object') . ' = ' . $db->quote(serialize($item)))
- ->set($db->quoteName('publish_start_date') . ' = ' . $db->quote($item->publish_start_date))
- ->set($db->quoteName('publish_end_date') . ' = ' . $db->quote($item->publish_end_date))
- ->set($db->quoteName('start_date') . ' = ' . $db->quote($item->start_date))
- ->set($db->quoteName('end_date') . ' = ' . $db->quote($item->end_date))
- ->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ?: 0))
- ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ?: 0))
- ->where('link_id = ' . (int) $linkId);
- $db->setQuery($query);
- $db->execute();
+ $entry->link_id = $linkId;
+ $db->updateObject('#__finder_links', $entry, 'link_id');
}
// Set up the variables we will need during processing.
@@ -253,10 +219,18 @@ public function index($item, $format = 'html')
foreach ($nodes as $node)
{
// Add the node to the tree.
- $nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access);
+ if ($node->nested)
+ {
+ $nodeId = FinderIndexerTaxonomy::addNestedNode($branch, $node->node, $node->state, $node->access, $node->language);
+ }
+ else
+ {
+ $nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access, $node->language);
+ }
// Add the link => node map.
FinderIndexerTaxonomy::addMap($linkId, $nodeId);
+ $node->id = $nodeId;
// Tokenize the node title and add them to the database.
$count += $this->tokenizeToDb($node->title, static::META_CONTEXT, $item->language, $format);
@@ -274,28 +248,28 @@ public function index($item, $format = 'html')
* table.
*/
$query = 'INSERT INTO ' . $db->quoteName('#__finder_tokens_aggregate') .
- ' (' . $db->quoteName('term_id') .
- ', ' . $db->quoteName('term') .
- ', ' . $db->quoteName('stem') .
- ', ' . $db->quoteName('common') .
- ', ' . $db->quoteName('phrase') .
- ', ' . $db->quoteName('term_weight') .
- ', ' . $db->quoteName('context') .
- ', ' . $db->quoteName('context_weight') .
- ', ' . $db->quoteName('language') . ')' .
- ' SELECT' .
- ' t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' .
- ' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, t1.language' .
- ' FROM (' .
- ' SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
- ' FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' .
- ' WHERE t1.context = %d' .
- ' ) AS t1' .
- ' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term' .
- ' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term' .
- ' WHERE t2.context = %d AND t.term_id IS NOT NULL' .
- ' GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
- ' ORDER BY t1.term DESC';
+ ' (' . $db->quoteName('term_id') .
+ ', ' . $db->quoteName('term') .
+ ', ' . $db->quoteName('stem') .
+ ', ' . $db->quoteName('common') .
+ ', ' . $db->quoteName('phrase') .
+ ', ' . $db->quoteName('term_weight') .
+ ', ' . $db->quoteName('context') .
+ ', ' . $db->quoteName('context_weight') .
+ ', ' . $db->quoteName('language') . ')' .
+ ' SELECT' .
+ ' t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' .
+ ' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, t1.language' .
+ ' FROM (' .
+ ' SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
+ ' FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' .
+ ' WHERE t1.context = %d' .
+ ' ) AS t1' .
+ ' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term' .
+ ' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term' .
+ ' WHERE t2.context = %d AND t.term_id IS NOT NULL' .
+ ' GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
+ ' ORDER BY t1.term DESC';
// Iterate through the contexts and aggregate the tokens per context.
foreach ($state->weights as $context => $multiplier)
@@ -401,6 +375,7 @@ public function index($item, $format = 'html')
$query->clear()
->update($db->quoteName('#__finder_links'))
->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig))
+ ->set($db->quoteName('object') . ' = ' . $db->quote(serialize($item)))
->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId));
$db->setQuery($query);
$db->execute();
diff --git a/administrator/components/com_finder/helpers/indexer/indexer.php b/administrator/components/com_finder/helpers/indexer/indexer.php
index c2c3b3aaf01d7..b6c60b9fdbc95 100644
--- a/administrator/components/com_finder/helpers/indexer/indexer.php
+++ b/administrator/components/com_finder/helpers/indexer/indexer.php
@@ -100,7 +100,7 @@ abstract class FinderIndexer
/**
* Reusable Query Template. To be used with clone.
*
- * @var JDatabaseQuery
+ * @var Joomla\Database\QueryInterface
* @since 3.8.0
*/
protected $addTokensToDbQueryTemplate;
diff --git a/administrator/components/com_finder/helpers/indexer/result.php b/administrator/components/com_finder/helpers/indexer/result.php
index 58629d069bf27..8c31b066aa95e 100644
--- a/administrator/components/com_finder/helpers/indexer/result.php
+++ b/administrator/components/com_finder/helpers/indexer/result.php
@@ -9,6 +9,7 @@
defined('_JEXEC') or die;
+use Joomla\CMS\Tree\ImmutableNodeInterface;
JLoader::register('FinderIndexer', __DIR__ . '/indexer.php');
/**
@@ -21,7 +22,7 @@
*
* @since 2.5
*/
-class FinderIndexerResult
+class FinderIndexerResult implements Serializable
{
/**
* An array of extra result properties.
@@ -375,9 +376,6 @@ public function getTaxonomy($branch = null)
// Get the taxonomy branch if available.
if ($branch !== null && isset($this->taxonomy[$branch]))
{
- // Filter the input.
- $branch = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,_]+#mui', ' ', $branch);
-
return $this->taxonomy[$branch];
}
@@ -387,28 +385,62 @@ public function getTaxonomy($branch = null)
/**
* Method to add a taxonomy map for an item.
*
- * @param string $branch The title of the taxonomy branch to add the node to.
- * @param string $title The title of the taxonomy node.
- * @param integer $state The published state of the taxonomy node. [optional]
- * @param integer $access The access level of the taxonomy node. [optional]
+ * @param string $branch The title of the taxonomy branch to add the node to.
+ * @param string $title The title of the taxonomy node.
+ * @param integer $state The published state of the taxonomy node. [optional]
+ * @param integer $access The access level of the taxonomy node. [optional]
+ * @param string $language The language of the taxonomy. [optional]
*
* @return void
*
* @since 2.5
*/
- public function addTaxonomy($branch, $title, $state = 1, $access = 1)
+ public function addTaxonomy($branch, $title, $state = 1, $access = 1, $language = '')
{
// Filter the input.
$branch = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,_]+#mui', ' ', $branch);
// Create the taxonomy node.
- $node = new JObject;
+ $node = new stdClass;
$node->title = $title;
$node->state = (int) $state;
$node->access = (int) $access;
+ $node->language = $language;
+ $node->nested = false;
+
+ // Add the node to the taxonomy branch.
+ $this->taxonomy[$branch][] = $node;
+ }
+
+ /**
+ * Method to add a nested taxonomy map for an item.
+ *
+ * @param string $branch The title of the taxonomy branch to add the node to.
+ * @param ImmutableNodeInterface $contentNode The node object.
+ * @param integer $state The published state of the taxonomy node. [optional]
+ * @param integer $access The access level of the taxonomy node. [optional]
+ * @param string $language The language of the taxonomy. [optional]
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function addNestedTaxonomy($branch, ImmutableNodeInterface $contentNode, $state = 1, $access = 1, $language = '')
+ {
+ // Filter the input.
+ $branch = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,_]+#mui', ' ', $branch);
+
+ // Create the taxonomy node.
+ $node = new stdClass;
+ $node->title = $contentNode->title;
+ $node->state = (int) $state;
+ $node->access = (int) $access;
+ $node->language = $language;
+ $node->nested = true;
+ $node->node = $contentNode;
// Add the node to the taxonomy branch.
- $this->taxonomy[$branch][$node->title] = $node;
+ $this->taxonomy[$branch][] = $node;
}
/**
@@ -425,4 +457,103 @@ public function setLanguage()
$this->language = $this->defaultLanguage;
}
}
+
+ /**
+ * Helper function to serialise the data of a FinderIndexerResult object
+ *
+ * @return string The serialised data
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function serialize()
+ {
+ $taxonomy = array();
+
+ foreach ($this->taxonomy as $branch => $nodes)
+ {
+ $taxonomy[$branch] = array();
+
+ foreach ($nodes as $node)
+ {
+ if ($node->nested)
+ {
+ $n = clone $node;
+ unset($n->node);
+ $taxonomy[$branch][] = $n;
+ }
+ else
+ {
+ $taxonomy[$branch][] = $node;
+ }
+ }
+ }
+
+ return serialize(
+ [
+ $this->access,
+ $this->defaultLanguage,
+ $this->description,
+ $this->elements,
+ $this->end_date,
+ $this->instructions,
+ $this->language,
+ $this->list_price,
+ $this->publish_end_date,
+ $this->publish_start_date,
+ $this->published,
+ $this->route,
+ $this->sale_price,
+ $this->start_date,
+ $this->state,
+ $taxonomy,
+ $this->title,
+ $this->type_id,
+ $this->url
+ ]
+ );
+ }
+
+ /**
+ * Helper function to unserialise the data for this object
+ *
+ * @param string $serialized Serialised data to unserialise
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function unserialize($serialized)
+ {
+ list(
+ $this->access,
+ $this->defaultLanguage,
+ $this->description,
+ $this->elements,
+ $this->end_date,
+ $this->instructions,
+ $this->language,
+ $this->list_price,
+ $this->publish_end_date,
+ $this->publish_start_date,
+ $this->published,
+ $this->route,
+ $this->sale_price,
+ $this->start_date,
+ $this->state,
+ $this->taxonomy,
+ $this->title,
+ $this->type_id,
+ $this->url
+ ) = unserialize($serialized);
+
+ foreach ($this->taxonomy as $nodes)
+ {
+ foreach ($nodes as $node)
+ {
+ $curTaxonomy = FinderIndexerTaxonomy::getTaxonomy($node->id);
+ $node->state = $curTaxonomy->state;
+ $node->access = $curTaxonomy->access;
+ }
+ }
+ }
}
diff --git a/administrator/components/com_finder/helpers/indexer/taxonomy.php b/administrator/components/com_finder/helpers/indexer/taxonomy.php
index 0b90dde30d38f..23d2d296cdf0b 100644
--- a/administrator/components/com_finder/helpers/indexer/taxonomy.php
+++ b/administrator/components/com_finder/helpers/indexer/taxonomy.php
@@ -9,6 +9,9 @@
defined('_JEXEC') or die;
+use Joomla\CMS\Tree\NodeInterface;
+use Joomla\Component\Finder\Administrator\Table\MapTable;
+
/**
* Taxonomy base class for the Finder indexer package.
*
@@ -17,15 +20,23 @@
class FinderIndexerTaxonomy
{
/**
- * An internal cache of taxonomy branch data.
+ * An internal cache of taxonomy data.
*
* @var array
- * @since 2.5
+ * @since __DEPLOY_VERSION__
+ */
+ public static $taxonomies = array();
+
+ /**
+ * An internal cache of branch data.
+ *
+ * @var array
+ * @since __DEPLOY_VERSION__
*/
public static $branches = array();
/**
- * An internal cache of taxonomy node data.
+ * An internal cache of taxonomy node data for inserting it.
*
* @var array
* @since 2.5
@@ -46,111 +57,127 @@ class FinderIndexerTaxonomy
*/
public static function addBranch($title, $state = 1, $access = 1)
{
- // Check to see if the branch is in the cache.
- if (isset(static::$branches[$title]))
- {
- return static::$branches[$title]->id;
- }
+ $node = new stdClass;
+ $node->title = $title;
+ $node->state = $state;
+ $node->access = $access;
+ $node->parent_id = 1;
+ $node->language = '';
+
+ return self::storeNode($node, 1);
+ }
- // Check to see if the branch is in the table.
- $db = JFactory::getDbo();
- $query = $db->getQuery(true)
- ->select('*')
- ->from($db->quoteName('#__finder_taxonomy'))
- ->where($db->quoteName('parent_id') . ' = 1')
- ->where($db->quoteName('title') . ' = ' . $db->quote($title));
- $db->setQuery($query);
+ /**
+ * Method to add a node to the taxonomy tree.
+ *
+ * @param string $branch The title of the branch to store the node in.
+ * @param string $title The title of the node.
+ * @param integer $state The published state of the node. [optional]
+ * @param integer $access The access state of the node. [optional]
+ * @param string $language The language of the node. [optional]
+ *
+ * @return integer The id of the node.
+ *
+ * @since 2.5
+ * @throws Exception on database error.
+ */
+ public static function addNode($branch, $title, $state = 1, $access = 1, $language = '')
+ {
+ // Get the branch id, insert it if it does not exist.
+ $branchId = static::addBranch($branch);
- // Get the result.
- $result = $db->loadObject();
+ $node = new stdClass;
+ $node->title = $title;
+ $node->state = $state;
+ $node->access = $access;
+ $node->parent_id = $branchId;
+ $node->language = $language;
- // Check if the database matches the input data.
- if (!empty($result) && $result->state == $state && $result->access == $access)
- {
- // The data matches, add the item to the cache.
- static::$branches[$title] = $result;
+ return self::storeNode($node, $branchId);
+ }
- return static::$branches[$title]->id;
+ /**
+ * Method to add a nested node to the taxonomy tree.
+ *
+ * @param string $branch The title of the branch to store the node in.
+ * @param NodeInterface $node The source-node of the taxonomy node.
+ * @param integer $state The published state of the node. [optional]
+ * @param integer $access The access state of the node. [optional]
+ * @param string $language The language of the node. [optional]
+ * @param integer $branchId ID of a branch if known. [optional]
+ *
+ * @return integer The id of the node.
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public static function addNestedNode($branch, NodeInterface $node, $state = 1, $access = 1, $language = '', $branchId = null)
+ {
+ if (!$branchId)
+ {
+ // Get the branch id, insert it if it does not exist.
+ $branchId = static::addBranch($branch);
}
- /*
- * The database did not match the input. This could be because the
- * state has changed or because the branch does not exist. Let's figure
- * out which case is true and deal with it.
- */
- $branch = new JObject;
+ $parent = $node->getParent();
- if (empty($result))
+ if ($parent && $parent->title !='ROOT')
{
- // Prepare the branch object.
- $branch->parent_id = 1;
- $branch->title = $title;
- $branch->state = (int) $state;
- $branch->access = (int) $access;
+ $parentId = self::addNestedNode($branch, $parent, $state, $access, $language = '', $branchId);
}
else
{
- // Prepare the branch object.
- $branch->id = (int) $result->id;
- $branch->parent_id = (int) $result->parent_id;
- $branch->title = $result->title;
- $branch->state = (int) $result->title;
- $branch->access = (int) $result->access;
- $branch->ordering = (int) $result->ordering;
+ $parentId = $branchId;
}
- // Store the branch.
- static::storeNode($branch);
-
- // Add the branch to the cache.
- static::$branches[$title] = $branch;
+ $temp = new stdClass;
+ $temp->title = $node->title;
+ $temp->state = $state;
+ $temp->access = $access;
+ $temp->parent_id = $parentId;
+ $temp->language = $language;
- return static::$branches[$title]->id;
+ return self::storeNode($temp, $parentId);
}
/**
- * Method to add a node to the taxonomy tree.
- *
- * @param string $branch The title of the branch to store the node in.
- * @param string $title The title of the node.
- * @param integer $state The published state of the node. [optional]
- * @param integer $access The access state of the node. [optional]
- *
- * @return integer The id of the node.
- *
- * @since 2.5
- * @throws Exception on database error.
+ * A helper method to store a node in the taxonomy
+ *
+ * @param object $node The node data to include
+ * @param integer $parent_id The parent id of the node to add.
+ *
+ * @return integer The id of the inserted node.
+ *
+ * @since __DEPLOY_VERSION__
*/
- public static function addNode($branch, $title, $state = 1, $access = 1)
+ protected static function storeNode($node, $parent_id)
{
// Check to see if the node is in the cache.
- if (isset(static::$nodes[$branch][$title]))
+ if (isset(static::$nodes[$parent_id . ':' . $node->title]))
{
- return static::$nodes[$branch][$title]->id;
+ return static::$nodes[$parent_id . ':' . $node->title]->id;
}
- // Get the branch id, insert it if it does not exist.
- $branchId = static::addBranch($branch);
-
// Check to see if the node is in the table.
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__finder_taxonomy'))
- ->where($db->quoteName('parent_id') . ' = ' . $db->quote($branchId))
- ->where($db->quoteName('title') . ' = ' . $db->quote($title));
+ ->where($db->quoteName('parent_id') . ' = ' . $db->quote($parent_id))
+ ->where($db->quoteName('title') . ' = ' . $db->quote($node->title))
+ ->where($db->quoteName('language') . ' = ' . $db->quote($node->language));
+
$db->setQuery($query);
// Get the result.
$result = $db->loadObject();
// Check if the database matches the input data.
- if (!empty($result) && $result->state == $state && $result->access == $access)
+ if (!empty($result) && $result->state == $node->state && $result->access == $node->access)
{
// The data matches, add the item to the cache.
- static::$nodes[$branch][$title] = $result;
+ static::$nodes[$parent_id . ':' . $node->title] = $result;
- return static::$nodes[$branch][$title]->id;
+ return static::$nodes[$parent_id . ':' . $node->title]->id;
}
/*
@@ -158,34 +185,38 @@ public static function addNode($branch, $title, $state = 1, $access = 1)
* state has changed or because the node does not exist. Let's figure
* out which case is true and deal with it.
*/
- $node = new JObject;
+ /** TODO: use factory? **/
+ $nodeTable = new MapTable($db);
if (empty($result))
{
// Prepare the node object.
- $node->parent_id = (int) $branchId;
- $node->title = $title;
- $node->state = (int) $state;
- $node->access = (int) $access;
+ $nodeTable->title = $node->title;
+ $nodeTable->state = (int) $node->state;
+ $nodeTable->access = (int) $node->access;
+ $nodeTable->language = $node->language;
+ $nodeTable->setLocation((int) $parent_id, 'last-child');
}
else
{
// Prepare the node object.
- $node->id = (int) $result->id;
- $node->parent_id = (int) $result->parent_id;
- $node->title = $result->title;
- $node->state = (int) $result->title;
- $node->access = (int) $result->access;
- $node->ordering = (int) $result->ordering;
+ $nodeTable->id = (int) $result->id;
+ $nodeTable->title = $result->title;
+ $nodeTable->state = (int) $result->title;
+ $nodeTable->access = (int) $result->access;
+ $nodeTable->language = $node->language;
+ $nodeTable->setLocation($result->parent_id, 'last-child');
}
- // Store the node.
- static::storeNode($node);
+ // Store the branch.
+ $nodeTable->check();
+ $nodeTable->store();
+ $nodeTable->rebuildPath($nodeTable->id);
// Add the node to the cache.
- static::$nodes[$branch][$title] = $node;
+ static::$nodes[$parent_id . ':' . $nodeTable->title] = (object) $nodeTable->getProperties();
- return static::$nodes[$branch][$title]->id;
+ return static::$nodes[$parent_id . ':' . $nodeTable->title]->id;
}
/**
@@ -213,16 +244,11 @@ public static function addMap($linkId, $nodeId)
$db->execute();
$id = (int) $db->loadResult();
- $map = new JObject;
- $map->link_id = (int) $linkId;
- $map->node_id = (int) $nodeId;
-
- if ($id)
- {
- $db->updateObject('#__finder_taxonomy_map', $map, array('link_id', 'node_id'));
- }
- else
+ if (!$id)
{
+ $map = new stdClass;
+ $map->link_id = (int) $linkId;
+ $map->node_id = (int) $nodeId;
$db->insertObject('#__finder_taxonomy_map', $map);
}
@@ -352,31 +378,76 @@ public static function removeOrphanNodes()
}
/**
- * Method to store a node to the database. This method will accept either a branch or a node.
- *
- * @param object $item The item to store.
- *
- * @return boolean True on success.
- *
- * @since 2.5
- * @throws Exception on database error.
+ * Get a taxonomy based on its id or all taxonomies
+ *
+ * @param integer $id Id of the taxonomy
+ *
+ * @return object|array A taxonomy object or an array of all taxonomies
+ *
+ * @since __DEPLOY_VERSION__
*/
- protected static function storeNode($item)
+ public static function getTaxonomy($id = 0)
{
- $db = JFactory::getDbo();
+ if (!count(self::$taxonomies))
+ {
+ $db = JFactory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query->select(array('id','parent_id','lft','rgt','level','path','title','alias','state','access','language'))
+ ->from($db->quoteName('#__finder_taxonomy'))
+ ->order($db->quoteName('lft'));
- // Check if we are updating or inserting the item.
- if (empty($item->id))
+ $db->setQuery($query);
+ self::$taxonomies = $db->loadObjectList('id');
+ }
+
+ if ($id == 0)
{
- // Insert the item.
- $db->insertObject('#__finder_taxonomy', $item, 'id');
+ return self::$taxonomies;
}
- else
+
+ if (isset(self::$taxonomies[$id]))
{
- // Update the item.
- $db->updateObject('#__finder_taxonomy', $item, 'id');
+ return self::$taxonomies[$id];
}
- return true;
+ return false;
+ }
+
+ /**
+ * Get a taxonomy branch object based on its title or all branches
+ *
+ * @param string $title Title of the branch
+ *
+ * @return object|array The object with the branch data or an array of all branches
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public static function getBranch($title = '')
+ {
+ if (!count(self::$branches))
+ {
+ $taxonomies = self::getTaxonomy();
+
+ foreach ($taxonomies as $t)
+ {
+ if ($t->level == 1)
+ {
+ self::$branches[$t->title] = $t;
+ }
+ }
+ }
+
+ if ($title == '')
+ {
+ return self::$branches;
+ }
+
+ if (isset(self::$branches[$title]))
+ {
+ return self::$branches[$title];
+ }
+
+ return false;
}
}
diff --git a/administrator/components/com_finder/sql/install.mysql.sql b/administrator/components/com_finder/sql/install.mysql.sql
index 71e4f42ea8235..5c744d2e071bd 100644
--- a/administrator/components/com_finder/sql/install.mysql.sql
+++ b/administrator/components/com_finder/sql/install.mysql.sql
@@ -85,26 +85,33 @@ CREATE TABLE IF NOT EXISTS `#__finder_logging` (
--
CREATE TABLE IF NOT EXISTS `#__finder_taxonomy` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `parent_id` int(10) unsigned NOT NULL DEFAULT 0,
- `title` varchar(255) NOT NULL,
- `state` tinyint(1) unsigned NOT NULL DEFAULT 1,
- `access` tinyint(1) unsigned NOT NULL DEFAULT 0,
- `ordering` tinyint(1) unsigned NOT NULL DEFAULT 0,
+ `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `parent_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `lft` INT(11) NOT NULL DEFAULT '0',
+ `rgt` INT(11) NOT NULL DEFAULT '0',
+ `level` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `path` VARCHAR(400) NOT NULL DEFAULT '',
+ `title` VARCHAR(255) NOT NULL DEFAULT '',
+ `alias` VARCHAR(400) NOT NULL DEFAULT '',
+ `state` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
+ `access` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
+ `language` CHAR(7) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
- KEY `parent_id` (`parent_id`),
- KEY `state` (`state`),
- KEY `ordering` (`ordering`),
- KEY `access` (`access`),
- KEY `idx_parent_published` (`parent_id`,`state`,`access`)
+ INDEX `idx_state` (`state`),
+ INDEX `idx_access` (`access`),
+ INDEX `idx_path` (`path`(100)),
+ INDEX `idx_left_right` (`lft`, `rgt`),
+ INDEX `idx_alias` (`alias`(100)),
+ INDEX `idx_language` (`language`),
+ INDEX `idx_parent_published` (`parent_id`, `state`, `access`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci;
--
-- Dumping data for table `#__finder_taxonomy`
--
-REPLACE INTO `#__finder_taxonomy` (`id`, `parent_id`, `title`, `state`, `access`, `ordering`) VALUES
-(1, 0, 'ROOT', 0, 0, 0);
+INSERT INTO `#__finder_taxonomy` (`id`, `parent_id`, `lft`, `rgt`, `level`, `path`, `title`, `alias`, `state`, `access`, `language`) VALUES
+(1, 0, 0, 1, 0, '', 'ROOT', 'root', 1, 1, '*');
--
-- Table structure for table `#__finder_taxonomy_map`
diff --git a/administrator/components/com_finder/sql/install.postgresql.sql b/administrator/components/com_finder/sql/install.postgresql.sql
index 086964f903f0f..95d1abbd9afd7 100644
--- a/administrator/components/com_finder/sql/install.postgresql.sql
+++ b/administrator/components/com_finder/sql/install.postgresql.sql
@@ -84,29 +84,32 @@ CREATE INDEX "#__finder_logging_idx_searchterm" on "#__finder_logging" ("searcht
CREATE TABLE IF NOT EXISTS "#__finder_taxonomy" (
"id" serial NOT NULL,
"parent_id" integer DEFAULT 0 NOT NULL,
- "title" character varying(255) NOT NULL,
+ "lft" integer DEFAULT 0 NOT NULL,
+ "rgt" integer DEFAULT 0 NOT NULL,
+ "level" integer DEFAULT 0 NOT NULL,
+ "path" VARCHAR(400) NOT NULL DEFAULT '',
+ "title" VARCHAR(255) NOT NULL DEFAULT '',
+ "alias" VARCHAR(400) NOT NULL DEFAULT '',
"state" smallint DEFAULT 1 NOT NULL,
- "access" smallint DEFAULT 0 NOT NULL,
- "ordering" smallint DEFAULT 0 NOT NULL,
+ "access" smallint DEFAULT 1 NOT NULL,
+ "language" varchar(7) DEFAULT '' NOT NULL,
PRIMARY KEY ("id")
);
-CREATE INDEX "#__finder_taxonomy_parent_id" on "#__finder_taxonomy" ("parent_id");
CREATE INDEX "#__finder_taxonomy_state" on "#__finder_taxonomy" ("state");
-CREATE INDEX "#__finder_taxonomy_ordering" on "#__finder_taxonomy" ("ordering");
CREATE INDEX "#__finder_taxonomy_access" on "#__finder_taxonomy" ("access");
+CREATE INDEX "#__finder_taxonomy_path" on "#__finder_taxonomy" ("path");
+CREATE INDEX "#__finder_taxonomy_lft_rgt" on "#__finder_taxonomy" ("lft", "rgt");
+CREATE INDEX "#__finder_taxonomy_alias" on "#__finder_taxonomy" ("alias");
+CREATE INDEX "#__finder_taxonomy_language" on "#__finder_taxonomy" ("language");
CREATE INDEX "#__finder_taxonomy_idx_parent_published" on "#__finder_taxonomy" ("parent_id", "state", "access");
--
-- Dumping data for table #__finder_taxonomy
--
-UPDATE "#__finder_taxonomy" SET ("id", "parent_id", "title", "state", "access", "ordering") = (1, 0, 'ROOT', 0, 0, 0)
-WHERE "id"=1;
-
-INSERT INTO "#__finder_taxonomy" ("id", "parent_id", "title", "state", "access", "ordering")
-SELECT 1, 0, 'ROOT', 0, 0, 0 WHERE 1 NOT IN
-(SELECT 1 FROM "#__finder_taxonomy" WHERE "id"=1);
-
+INSERT INTO "#__finder_taxonomy" ("id", "parent_id", "lft", "rgt", "level", "path", "title", "alias", "state", "access", "language") VALUES
+(1, 0, 0, 1, 0, '', 'ROOT', 'root', 1, 1, '*');
+SELECT setval('#__finder_taxonomy_id_seq', 2, false);
--
-- Table: #__finder_taxonomy_map
diff --git a/administrator/components/com_finder/tmpl/maps/default.php b/administrator/components/com_finder/tmpl/maps/default.php
index 2f17fac643bb0..3f76ee04089f0 100644
--- a/administrator/components/com_finder/tmpl/maps/default.php
+++ b/administrator/components/com_finder/tmpl/maps/default.php
@@ -65,6 +65,11 @@
+
+
+
+
+
@@ -79,7 +84,7 @@
parent_title, '**') === 'Language')
+ if (trim($item->branch_title, '**') === 'Language')
{
$title = FinderHelperLanguage::branchLanguageTitle($item->title);
}
@@ -89,9 +94,7 @@
$title = $lang->hasKey($key) ? Text::_($key) : $item->title;
}
?>
- num_children === 0) : ?>
- —
-
+ —', $item->level - 1); ?>
escape($title); ?>
@@ -101,16 +104,16 @@
- num_children !== 0) : ?>
+ rgt - $item->lft > 1) : ?>
- num_children; ?>
+ rgt - $item->lft) / 2); ?>
-
- num_children === 0) : ?>
+ level > 1) : ?>
count_published; ?>
@@ -118,13 +121,18 @@
- num_children === 0) : ?>
+ level > 1) : ?>
count_unpublished; ?>
-
+
+
+ language; ?>
+
+
diff --git a/administrator/language/en-GB/en-GB.plg_extension_finder.ini b/administrator/language/en-GB/en-GB.plg_extension_finder.ini
new file mode 100644
index 0000000000000..434240a12b994
--- /dev/null
+++ b/administrator/language/en-GB/en-GB.plg_extension_finder.ini
@@ -0,0 +1,7 @@
+; Joomla! Project
+; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved.
+; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
+; Note : All ini files need to be saved as UTF-8
+
+PLG_EXTENSION_FINDER="Extension - Finder"
+PLG_EXTENSION_FINDER_XML_DESCRIPTION="Manage the common words in Smart Search."
diff --git a/administrator/language/en-GB/en-GB.plg_extension_finder.sys.ini b/administrator/language/en-GB/en-GB.plg_extension_finder.sys.ini
new file mode 100644
index 0000000000000..4a44f0949badb
--- /dev/null
+++ b/administrator/language/en-GB/en-GB.plg_extension_finder.sys.ini
@@ -0,0 +1,7 @@
+; Joomla! Project
+; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved.
+; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
+; Note : All ini files need to be saved as UTF-8
+
+PLG_EXTENSION_FINDER="Extension - Finder"
+PLG_EXTENSION_FINDER_XML_DESCRIPTION="Manage the common words in Smart Search."
\ No newline at end of file
diff --git a/components/com_finder/tmpl/search/default_result.php b/components/com_finder/tmpl/search/default_result.php
index 55e409110d1ff..dc89c91bcbc31 100644
--- a/components/com_finder/tmpl/search/default_result.php
+++ b/components/com_finder/tmpl/search/default_result.php
@@ -11,6 +11,8 @@
use Joomla\String\StringHelper;
+$user = JFactory::getUser();
+
// Get the mime type class.
$mime = !empty($this->result->mime) ? 'mime-' . $this->result->mime : null;
@@ -62,7 +64,21 @@
params->get('show_taxonomy', 1)) : ?>
$taxonomy) : ?>
-
+
+ state == 1 && in_array($branch->access, $user->getAuthorisedViewLevels())) : ?>
+ state == 1 && in_array($node->access, $user->getAuthorisedViewLevels())) :
+ $taxonomy_text[] = $node->title;
+ endif;
+ endforeach;
+
+ if (count($taxonomy_text)) : ?>
+
+
+
diff --git a/installation/sql/mysql/joomla.sql b/installation/sql/mysql/joomla.sql
index 5e6157ecab299..da9ef43370168 100644
--- a/installation/sql/mysql/joomla.sql
+++ b/installation/sql/mysql/joomla.sql
@@ -675,12 +675,14 @@ INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `elem
(490, 0, 'plg_extension_namespacemap', 'plugin', 'namespacemap', 'extension', 0, 1, 1, 1, '', '{}', 0, '0000-00-00 00:00:00', 0, 0),
(491, 0, 'plg_installer_override', 'plugin', 'override', 'installer', 0, 1, 1, 1, '', '', 0, '0000-00-00 00:00:00', 4, 0),
(492, 0, 'plg_quickicon_overridecheck', 'plugin', 'overridecheck', 'quickicon', 0, 1, 1, 1, '', '', 0, '0000-00-00 00:00:00', 0, 0),
+(493, 0, 'plg_extension_finder', 'plugin', 'finder', 'extension', 0, 1, 1, 0, '', '', 0, '0000-00-00 00:00:00', 0, 0),
(509, 0, 'atum', 'template', 'atum', '', 1, 1, 1, 0, '', '', 0, '0000-00-00 00:00:00', 0, 0),
(510, 0, 'cassiopeia', 'template', 'cassiopeia', '', 0, 1, 1, 0, '', '{"logoFile":"","fluidContainer":"0","sidebarLeftWidth":"3","sidebarRightWidth":"3"}', 0, '0000-00-00 00:00:00', 0, 0),
(600, 802, 'English (en-GB)', 'language', 'en-GB', '', 0, 1, 1, 1, '', '', 0, '0000-00-00 00:00:00', 0, 0),
(601, 802, 'English (en-GB)', 'language', 'en-GB', '', 1, 1, 1, 1, '', '', 0, '0000-00-00 00:00:00', 0, 0),
(700, 0, 'files_joomla', 'file', 'joomla', '', 0, 1, 1, 1, '', '', 0, '0000-00-00 00:00:00', 0, 0),
(802, 0, 'English (en-GB) Language Pack', 'package', 'pkg_en-GB', '', 0, 1, 1, 1, '', '', 0, '0000-00-00 00:00:00', 0, 0);
+
-- --------------------------------------------------------
--
@@ -877,26 +879,33 @@ CREATE TABLE IF NOT EXISTS `#__finder_logging` (
--
CREATE TABLE IF NOT EXISTS `#__finder_taxonomy` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `parent_id` int(10) unsigned NOT NULL DEFAULT 0,
- `title` varchar(255) NOT NULL,
- `state` tinyint(1) unsigned NOT NULL DEFAULT 1,
- `access` tinyint(1) unsigned NOT NULL DEFAULT 0,
- `ordering` tinyint(1) unsigned NOT NULL DEFAULT 0,
+ `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `parent_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `lft` INT(11) NOT NULL DEFAULT '0',
+ `rgt` INT(11) NOT NULL DEFAULT '0',
+ `level` INT(10) UNSIGNED NOT NULL DEFAULT '0',
+ `path` VARCHAR(400) NOT NULL DEFAULT '',
+ `title` VARCHAR(255) NOT NULL DEFAULT '',
+ `alias` VARCHAR(400) NOT NULL DEFAULT '',
+ `state` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
+ `access` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
+ `language` CHAR(7) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
- KEY `parent_id` (`parent_id`),
- KEY `state` (`state`),
- KEY `ordering` (`ordering`),
- KEY `access` (`access`),
- KEY `idx_parent_published` (`parent_id`,`state`,`access`)
+ INDEX `idx_state` (`state`),
+ INDEX `idx_access` (`access`),
+ INDEX `idx_path` (`path`(100)),
+ INDEX `idx_left_right` (`lft`, `rgt`),
+ INDEX `idx_alias` (`alias`(100)),
+ INDEX `idx_language` (`language`),
+ INDEX `idx_parent_published` (`parent_id`, `state`, `access`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci;
--
-- Dumping data for table `#__finder_taxonomy`
--
-INSERT INTO `#__finder_taxonomy` (`id`, `parent_id`, `title`, `state`, `access`, `ordering`) VALUES
-(1, 0, 'ROOT', 0, 0, 0);
+INSERT INTO `#__finder_taxonomy` (`id`, `parent_id`, `lft`, `rgt`, `level`, `path`, `title`, `alias`, `state`, `access`, `language`) VALUES
+(1, 0, 0, 1, 0, '', 'ROOT', 'root', 1, 1, '*');
-- --------------------------------------------------------
@@ -942,127 +951,192 @@ CREATE TABLE IF NOT EXISTS `#__finder_terms` (
--
CREATE TABLE IF NOT EXISTS `#__finder_terms_common` (
- `term` varchar(75) NOT NULL,
+ `term` varchar(75) NOT NULL DEFAULT '',
`language` char(7) NOT NULL DEFAULT '',
- KEY `idx_word_lang` (`term`,`language`),
+ `custom` int(11) NOT NULL DEFAULT '0',
+ UNIQUE KEY `idx_word_lang` (`term`,`language`),
KEY `idx_lang` (`language`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_bin;
--
-- Dumping data for table `#__finder_terms_common`
--
-INSERT INTO `#__finder_terms_common` (`term`, `language`) VALUES
-('a', 'en-GB'),
-('about', 'en-GB'),
-('after', 'en-GB'),
-('ago', 'en-GB'),
-('all', 'en-GB'),
-('am', 'en-GB'),
-('an', 'en-GB'),
-('and', 'en-GB'),
-('any', 'en-GB'),
-('are', 'en-GB'),
-('aren''t', 'en-GB'),
-('as', 'en-GB'),
-('at', 'en-GB'),
-('be', 'en-GB'),
-('but', 'en-GB'),
-('by', 'en-GB'),
-('for', 'en-GB'),
-('from', 'en-GB'),
-('get', 'en-GB'),
-('go', 'en-GB'),
-('how', 'en-GB'),
-('if', 'en-GB'),
-('in', 'en-GB'),
-('into', 'en-GB'),
-('is', 'en-GB'),
-('isn''t', 'en-GB'),
-('it', 'en-GB'),
-('its', 'en-GB'),
-('me', 'en-GB'),
-('more', 'en-GB'),
-('most', 'en-GB'),
-('must', 'en-GB'),
-('my', 'en-GB'),
-('new', 'en-GB'),
-('no', 'en-GB'),
-('none', 'en-GB'),
-('not', 'en-GB'),
-('nothing', 'en-GB'),
-('of', 'en-GB'),
-('off', 'en-GB'),
-('often', 'en-GB'),
-('old', 'en-GB'),
-('on', 'en-GB'),
-('onc', 'en-GB'),
-('once', 'en-GB'),
-('only', 'en-GB'),
-('or', 'en-GB'),
-('other', 'en-GB'),
-('our', 'en-GB'),
-('ours', 'en-GB'),
-('out', 'en-GB'),
-('over', 'en-GB'),
-('page', 'en-GB'),
-('she', 'en-GB'),
-('should', 'en-GB'),
-('small', 'en-GB'),
-('so', 'en-GB'),
-('some', 'en-GB'),
-('than', 'en-GB'),
-('thank', 'en-GB'),
-('that', 'en-GB'),
-('the', 'en-GB'),
-('their', 'en-GB'),
-('theirs', 'en-GB'),
-('them', 'en-GB'),
-('then', 'en-GB'),
-('there', 'en-GB'),
-('these', 'en-GB'),
-('they', 'en-GB'),
-('this', 'en-GB'),
-('those', 'en-GB'),
-('thus', 'en-GB'),
-('time', 'en-GB'),
-('times', 'en-GB'),
-('to', 'en-GB'),
-('too', 'en-GB'),
-('true', 'en-GB'),
-('under', 'en-GB'),
-('until', 'en-GB'),
-('up', 'en-GB'),
-('upon', 'en-GB'),
-('use', 'en-GB'),
-('user', 'en-GB'),
-('users', 'en-GB'),
-('version', 'en-GB'),
-('very', 'en-GB'),
-('via', 'en-GB'),
-('want', 'en-GB'),
-('was', 'en-GB'),
-('way', 'en-GB'),
-('were', 'en-GB'),
-('what', 'en-GB'),
-('when', 'en-GB'),
-('where', 'en-GB'),
-('which', 'en-GB'),
-('who', 'en-GB'),
-('whom', 'en-GB'),
-('whose', 'en-GB'),
-('why', 'en-GB'),
-('wide', 'en-GB'),
-('will', 'en-GB'),
-('with', 'en-GB'),
-('within', 'en-GB'),
-('without', 'en-GB'),
-('would', 'en-GB'),
-('yes', 'en-GB'),
-('yet', 'en-GB'),
-('you', 'en-GB'),
-('your', 'en-GB'),
-('yours', 'en-GB');
+INSERT INTO `#__finder_terms_common` (`term`, `language`, `custom`) VALUES
+('i', 'en', 0),
+('me', 'en', 0),
+('my', 'en', 0),
+('myself', 'en', 0),
+('we', 'en', 0),
+('our', 'en', 0),
+('ours', 'en', 0),
+('ourselves', 'en', 0),
+('you', 'en', 0),
+('your', 'en', 0),
+('yours', 'en', 0),
+('yourself', 'en', 0),
+('yourselves', 'en', 0),
+('he', 'en', 0),
+('him', 'en', 0),
+('his', 'en', 0),
+('himself', 'en', 0),
+('she', 'en', 0),
+('her', 'en', 0),
+('hers', 'en', 0),
+('herself', 'en', 0),
+('it', 'en', 0),
+('its', 'en', 0),
+('itself', 'en', 0),
+('they', 'en', 0),
+('them', 'en', 0),
+('their', 'en', 0),
+('theirs', 'en', 0),
+('themselves', 'en', 0),
+('what', 'en', 0),
+('which', 'en', 0),
+('who', 'en', 0),
+('whom', 'en', 0),
+('this', 'en', 0),
+('that', 'en', 0),
+('these', 'en', 0),
+('those', 'en', 0),
+('am', 'en', 0),
+('is', 'en', 0),
+('are', 'en', 0),
+('was', 'en', 0),
+('were', 'en', 0),
+('be', 'en', 0),
+('been', 'en', 0),
+('being', 'en', 0),
+('have', 'en', 0),
+('has', 'en', 0),
+('had', 'en', 0),
+('having', 'en', 0),
+('do', 'en', 0),
+('does', 'en', 0),
+('did', 'en', 0),
+('doing', 'en', 0),
+('would', 'en', 0),
+('should', 'en', 0),
+('could', 'en', 0),
+('ought', 'en', 0),
+('i\'m', 'en', 0),
+('you\'re', 'en', 0),
+('he\'s', 'en', 0),
+('she\'s', 'en', 0),
+('it\'s', 'en', 0),
+('we\'re', 'en', 0),
+('they\'re', 'en', 0),
+('i\'ve', 'en', 0),
+('you\'ve', 'en', 0),
+('we\'ve', 'en', 0),
+('they\'ve', 'en', 0),
+('i\'d', 'en', 0),
+('you\'d', 'en', 0),
+('he\'d', 'en', 0),
+('she\'d', 'en', 0),
+('we\'d', 'en', 0),
+('they\'d', 'en', 0),
+('i\'ll', 'en', 0),
+('you\'ll', 'en', 0),
+('he\'ll', 'en', 0),
+('she\'ll', 'en', 0),
+('we\'ll', 'en', 0),
+('they\'ll', 'en', 0),
+('isn\'t', 'en', 0),
+('aren\'t', 'en', 0),
+('wasn\'t', 'en', 0),
+('weren\'t', 'en', 0),
+('hasn\'t', 'en', 0),
+('haven\'t', 'en', 0),
+('hadn\'t', 'en', 0),
+('doesn\'t', 'en', 0),
+('don\'t', 'en', 0),
+('didn\'t', 'en', 0),
+('won\'t', 'en', 0),
+('wouldn\'t', 'en', 0),
+('shan\'t', 'en', 0),
+('shouldn\'t', 'en', 0),
+('can\'t', 'en', 0),
+('cannot', 'en', 0),
+('couldn\'t', 'en', 0),
+('mustn\'t', 'en', 0),
+('let\'s', 'en', 0),
+('that\'s', 'en', 0),
+('who\'s', 'en', 0),
+('what\'s', 'en', 0),
+('here\'s', 'en', 0),
+('there\'s', 'en', 0),
+('when\'s', 'en', 0),
+('where\'s', 'en', 0),
+('why\'s', 'en', 0),
+('how\'s', 'en', 0),
+('a', 'en', 0),
+('an', 'en', 0),
+('the', 'en', 0),
+('and', 'en', 0),
+('but', 'en', 0),
+('if', 'en', 0),
+('or', 'en', 0),
+('because', 'en', 0),
+('as', 'en', 0),
+('until', 'en', 0),
+('while', 'en', 0),
+('of', 'en', 0),
+('at', 'en', 0),
+('by', 'en', 0),
+('for', 'en', 0),
+('with', 'en', 0),
+('about', 'en', 0),
+('against', 'en', 0),
+('between', 'en', 0),
+('into', 'en', 0),
+('through', 'en', 0),
+('during', 'en', 0),
+('before', 'en', 0),
+('after', 'en', 0),
+('above', 'en', 0),
+('below', 'en', 0),
+('to', 'en', 0),
+('from', 'en', 0),
+('up', 'en', 0),
+('down', 'en', 0),
+('in', 'en', 0),
+('out', 'en', 0),
+('on', 'en', 0),
+('off', 'en', 0),
+('over', 'en', 0),
+('under', 'en', 0),
+('again', 'en', 0),
+('further', 'en', 0),
+('then', 'en', 0),
+('once', 'en', 0),
+('here', 'en', 0),
+('there', 'en', 0),
+('when', 'en', 0),
+('where', 'en', 0),
+('why', 'en', 0),
+('how', 'en', 0),
+('all', 'en', 0),
+('any', 'en', 0),
+('both', 'en', 0),
+('each', 'en', 0),
+('few', 'en', 0),
+('more', 'en', 0),
+('most', 'en', 0),
+('other', 'en', 0),
+('some', 'en', 0),
+('such', 'en', 0),
+('no', 'en', 0),
+('nor', 'en', 0),
+('not', 'en', 0),
+('only', 'en', 0),
+('own', 'en', 0),
+('same', 'en', 0),
+('so', 'en', 0),
+('than', 'en', 0),
+('too', 'en', 0),
+('very', 'en', 0);
-- --------------------------------------------------------
diff --git a/installation/sql/postgresql/joomla.sql b/installation/sql/postgresql/joomla.sql
index c4650862766b8..eefffd61493c8 100644
--- a/installation/sql/postgresql/joomla.sql
+++ b/installation/sql/postgresql/joomla.sql
@@ -684,6 +684,7 @@ INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "elem
(490, 0, 'plg_extension_namespacemap', 'plugin', 'namespacemap', 'extension', 0, 1, 1, 1, '', '{}', 0, '1970-01-01 00:00:00', 0, 0),
(491, 0, 'plg_installer_override', 'plugin', 'override', 'installer', 0, 1, 1, 1, '', '', 0, '1970-01-01 00:00:00', 4, 0),
(492, 0, 'plg_quickicon_overridecheck', 'plugin', 'overridecheck', 'quickicon', 0, 1, 1, 1, '', '', 0, '1970-01-01 00:00:00', 0, 0),
+(493, 0, 'plg_extension_finder', 'plugin', 'finder', 'extension', 0, 1, 1, 0, '', '', 0, '0000-00-00 00:00:00', 0, 0),
(600, 802, 'English (en-GB)', 'language', 'en-GB', '', 0, 1, 1, 1, '', '', 0, '1970-01-01 00:00:00', 0, 0),
(601, 802, 'English (en-GB)', 'language', 'en-GB', '', 1, 1, 1, 1, '', '', 0, '1970-01-01 00:00:00', 0, 0),
(700, 0, 'files_joomla', 'file', 'joomla', '', 0, 1, 1, 1, '', '', 0, '1970-01-01 00:00:00', 0, 0),
@@ -876,24 +877,31 @@ CREATE INDEX "#__finder_logging_idx_searchterm" on "#__finder_logging" ("searcht
CREATE TABLE IF NOT EXISTS "#__finder_taxonomy" (
"id" serial NOT NULL,
"parent_id" integer DEFAULT 0 NOT NULL,
- "title" varchar(255) NOT NULL,
+ "lft" integer DEFAULT 0 NOT NULL,
+ "rgt" integer DEFAULT 0 NOT NULL,
+ "level" integer DEFAULT 0 NOT NULL,
+ "path" VARCHAR(400) NOT NULL DEFAULT '',
+ "title" VARCHAR(255) NOT NULL DEFAULT '',
+ "alias" VARCHAR(400) NOT NULL DEFAULT '',
"state" smallint DEFAULT 1 NOT NULL,
- "access" smallint DEFAULT 0 NOT NULL,
- "ordering" smallint DEFAULT 0 NOT NULL,
+ "access" smallint DEFAULT 1 NOT NULL,
+ "language" varchar(7) DEFAULT '' NOT NULL,
PRIMARY KEY ("id")
);
-CREATE INDEX "#__finder_taxonomy_parent_id" on "#__finder_taxonomy" ("parent_id");
CREATE INDEX "#__finder_taxonomy_state" on "#__finder_taxonomy" ("state");
-CREATE INDEX "#__finder_taxonomy_ordering" on "#__finder_taxonomy" ("ordering");
CREATE INDEX "#__finder_taxonomy_access" on "#__finder_taxonomy" ("access");
+CREATE INDEX "#__finder_taxonomy_path" on "#__finder_taxonomy" ("path");
+CREATE INDEX "#__finder_taxonomy_lft_rgt" on "#__finder_taxonomy" ("lft", "rgt");
+CREATE INDEX "#__finder_taxonomy_alias" on "#__finder_taxonomy" ("alias");
+CREATE INDEX "#__finder_taxonomy_language" on "#__finder_taxonomy" ("language");
CREATE INDEX "#__finder_taxonomy_idx_parent_published" on "#__finder_taxonomy" ("parent_id", "state", "access");
--
-- Dumping data for table `#__finder_taxonomy`
--
-INSERT INTO "#__finder_taxonomy" ("id", "parent_id", "title", "state", "access", "ordering") VALUES
-(1, 0, 'ROOT', 0, 0, 0);
+INSERT INTO "#__finder_taxonomy" ("id", "parent_id", "lft", "rgt", "level", "path", "title", "alias", "state", "access", "language") VALUES
+(1, 0, 0, 1, 0, '', 'ROOT', 'root', 1, 1, '*');
SELECT setval('#__finder_taxonomy_id_seq', 2, false);
@@ -936,7 +944,9 @@ CREATE INDEX "#__finder_terms_idx_soundex_phrase" on "#__finder_terms" ("soundex
CREATE TABLE IF NOT EXISTS "#__finder_terms_common" (
"term" varchar(75) NOT NULL,
- "language" varchar(7) DEFAULT '' NOT NULL
+ "language" varchar(7) DEFAULT '' NOT NULL,
+ "custom" integer DEFAULT 0 NOT NULL,
+ CONSTRAINT "#__finder_terms_idx_term" UNIQUE ("term", "language")
);
CREATE INDEX "#__finder_terms_common_idx_word_lang" on "#__finder_terms_common" ("term", "language");
CREATE INDEX "#__finder_terms_common_idx_lang" on "#__finder_terms_common" ("language");
@@ -945,117 +955,181 @@ CREATE INDEX "#__finder_terms_common_idx_lang" on "#__finder_terms_common" ("lan
-- Dumping data for table `#__finder_terms_common`
--
-INSERT INTO "#__finder_terms_common" ("term", "language") VALUES
-('a', 'en-GB'),
-('about', 'en-GB'),
-('after', 'en-GB'),
-('ago', 'en-GB'),
-('all', 'en-GB'),
-('am', 'en-GB'),
-('an', 'en-GB'),
-('and', 'en-GB'),
-('any', 'en-GB'),
-('are', 'en-GB'),
-('aren''t', 'en-GB'),
-('as', 'en-GB'),
-('at', 'en-GB'),
-('be', 'en-GB'),
-('but', 'en-GB'),
-('by', 'en-GB'),
-('for', 'en-GB'),
-('from', 'en-GB'),
-('get', 'en-GB'),
-('go', 'en-GB'),
-('how', 'en-GB'),
-('if', 'en-GB'),
-('in', 'en-GB'),
-('into', 'en-GB'),
-('is', 'en-GB'),
-('isn''t', 'en-GB'),
-('it', 'en-GB'),
-('its', 'en-GB'),
-('me', 'en-GB'),
-('more', 'en-GB'),
-('most', 'en-GB'),
-('must', 'en-GB'),
-('my', 'en-GB'),
-('new', 'en-GB'),
-('no', 'en-GB'),
-('none', 'en-GB'),
-('not', 'en-GB'),
-('nothing', 'en-GB'),
-('of', 'en-GB'),
-('off', 'en-GB'),
-('often', 'en-GB'),
-('old', 'en-GB'),
-('on', 'en-GB'),
-('onc', 'en-GB'),
-('once', 'en-GB'),
-('only', 'en-GB'),
-('or', 'en-GB'),
-('other', 'en-GB'),
-('our', 'en-GB'),
-('ours', 'en-GB'),
-('out', 'en-GB'),
-('over', 'en-GB'),
-('page', 'en-GB'),
-('she', 'en-GB'),
-('should', 'en-GB'),
-('small', 'en-GB'),
-('so', 'en-GB'),
-('some', 'en-GB'),
-('than', 'en-GB'),
-('thank', 'en-GB'),
-('that', 'en-GB'),
-('the', 'en-GB'),
-('their', 'en-GB'),
-('theirs', 'en-GB'),
-('them', 'en-GB'),
-('then', 'en-GB'),
-('there', 'en-GB'),
-('these', 'en-GB'),
-('they', 'en-GB'),
-('this', 'en-GB'),
-('those', 'en-GB'),
-('thus', 'en-GB'),
-('time', 'en-GB'),
-('times', 'en-GB'),
-('to', 'en-GB'),
-('too', 'en-GB'),
-('true', 'en-GB'),
-('under', 'en-GB'),
-('until', 'en-GB'),
-('up', 'en-GB'),
-('upon', 'en-GB'),
-('use', 'en-GB'),
-('user', 'en-GB'),
-('users', 'en-GB'),
-('version', 'en-GB'),
-('very', 'en-GB'),
-('via', 'en-GB'),
-('want', 'en-GB'),
-('was', 'en-GB'),
-('way', 'en-GB'),
-('were', 'en-GB'),
-('what', 'en-GB'),
-('when', 'en-GB'),
-('where', 'en-GB'),
-('which', 'en-GB'),
-('who', 'en-GB'),
-('whom', 'en-GB'),
-('whose', 'en-GB'),
-('why', 'en-GB'),
-('wide', 'en-GB'),
-('will', 'en-GB'),
-('with', 'en-GB'),
-('within', 'en-GB'),
-('without', 'en-GB'),
-('would', 'en-GB'),
-('yes', 'en-GB'),
-('yet', 'en-GB'),
-('you', 'en-GB'),
-('your', 'en-GB'),
-('yours', 'en-GB');
+INSERT INTO "#__finder_terms_common" ("term", "language", "custom") VALUES
+('i', 'en', 0),
+('me', 'en', 0),
+('my', 'en', 0),
+('myself', 'en', 0),
+('we', 'en', 0),
+('our', 'en', 0),
+('ours', 'en', 0),
+('ourselves', 'en', 0),
+('you', 'en', 0),
+('your', 'en', 0),
+('yours', 'en', 0),
+('yourself', 'en', 0),
+('yourselves', 'en', 0),
+('he', 'en', 0),
+('him', 'en', 0),
+('his', 'en', 0),
+('himself', 'en', 0),
+('she', 'en', 0),
+('her', 'en', 0),
+('hers', 'en', 0),
+('herself', 'en', 0),
+('it', 'en', 0),
+('its', 'en', 0),
+('itself', 'en', 0),
+('they', 'en', 0),
+('them', 'en', 0),
+('their', 'en', 0),
+('theirs', 'en', 0),
+('themselves', 'en', 0),
+('what', 'en', 0),
+('which', 'en', 0),
+('who', 'en', 0),
+('whom', 'en', 0),
+('this', 'en', 0),
+('that', 'en', 0),
+('these', 'en', 0),
+('those', 'en', 0),
+('am', 'en', 0),
+('is', 'en', 0),
+('are', 'en', 0),
+('was', 'en', 0),
+('were', 'en', 0),
+('be', 'en', 0),
+('been', 'en', 0),
+('being', 'en', 0),
+('have', 'en', 0),
+('has', 'en', 0),
+('had', 'en', 0),
+('having', 'en', 0),
+('do', 'en', 0),
+('does', 'en', 0),
+('did', 'en', 0),
+('doing', 'en', 0),
+('would', 'en', 0),
+('should', 'en', 0),
+('could', 'en', 0),
+('ought', 'en', 0),
+('i\'m', 'en', 0),
+('you\'re', 'en', 0),
+('he\'s', 'en', 0),
+('she\'s', 'en', 0),
+('it\'s', 'en', 0),
+('we\'re', 'en', 0),
+('they\'re', 'en', 0),
+('i\'ve', 'en', 0),
+('you\'ve', 'en', 0),
+('we\'ve', 'en', 0),
+('they\'ve', 'en', 0),
+('i\'d', 'en', 0),
+('you\'d', 'en', 0),
+('he\'d', 'en', 0),
+('she\'d', 'en', 0),
+('we\'d', 'en', 0),
+('they\'d', 'en', 0),
+('i\'ll', 'en', 0),
+('you\'ll', 'en', 0),
+('he\'ll', 'en', 0),
+('she\'ll', 'en', 0),
+('we\'ll', 'en', 0),
+('they\'ll', 'en', 0),
+('isn\'t', 'en', 0),
+('aren\'t', 'en', 0),
+('wasn\'t', 'en', 0),
+('weren\'t', 'en', 0),
+('hasn\'t', 'en', 0),
+('haven\'t', 'en', 0),
+('hadn\'t', 'en', 0),
+('doesn\'t', 'en', 0),
+('don\'t', 'en', 0),
+('didn\'t', 'en', 0),
+('won\'t', 'en', 0),
+('wouldn\'t', 'en', 0),
+('shan\'t', 'en', 0),
+('shouldn\'t', 'en', 0),
+('can\'t', 'en', 0),
+('cannot', 'en', 0),
+('couldn\'t', 'en', 0),
+('mustn\'t', 'en', 0),
+('let\'s', 'en', 0),
+('that\'s', 'en', 0),
+('who\'s', 'en', 0),
+('what\'s', 'en', 0),
+('here\'s', 'en', 0),
+('there\'s', 'en', 0),
+('when\'s', 'en', 0),
+('where\'s', 'en', 0),
+('why\'s', 'en', 0),
+('how\'s', 'en', 0),
+('a', 'en', 0),
+('an', 'en', 0),
+('the', 'en', 0),
+('and', 'en', 0),
+('but', 'en', 0),
+('if', 'en', 0),
+('or', 'en', 0),
+('because', 'en', 0),
+('as', 'en', 0),
+('until', 'en', 0),
+('while', 'en', 0),
+('of', 'en', 0),
+('at', 'en', 0),
+('by', 'en', 0),
+('for', 'en', 0),
+('with', 'en', 0),
+('about', 'en', 0),
+('against', 'en', 0),
+('between', 'en', 0),
+('into', 'en', 0),
+('through', 'en', 0),
+('during', 'en', 0),
+('before', 'en', 0),
+('after', 'en', 0),
+('above', 'en', 0),
+('below', 'en', 0),
+('to', 'en', 0),
+('from', 'en', 0),
+('up', 'en', 0),
+('down', 'en', 0),
+('in', 'en', 0),
+('out', 'en', 0),
+('on', 'en', 0),
+('off', 'en', 0),
+('over', 'en', 0),
+('under', 'en', 0),
+('again', 'en', 0),
+('further', 'en', 0),
+('then', 'en', 0),
+('once', 'en', 0),
+('here', 'en', 0),
+('there', 'en', 0),
+('when', 'en', 0),
+('where', 'en', 0),
+('why', 'en', 0),
+('how', 'en', 0),
+('all', 'en', 0),
+('any', 'en', 0),
+('both', 'en', 0),
+('each', 'en', 0),
+('few', 'en', 0),
+('more', 'en', 0),
+('most', 'en', 0),
+('other', 'en', 0),
+('some', 'en', 0),
+('such', 'en', 0),
+('no', 'en', 0),
+('nor', 'en', 0),
+('not', 'en', 0),
+('only', 'en', 0),
+('own', 'en', 0),
+('same', 'en', 0),
+('so', 'en', 0),
+('than', 'en', 0),
+('too', 'en', 0),
+('very', 'en', 0);
--
-- Table structure for table `#__finder_tokens`
diff --git a/language/en-GB/en-GB.com_finder.commonwords.txt b/language/en-GB/en-GB.com_finder.commonwords.txt
new file mode 100644
index 0000000000000..c41a615d99532
--- /dev/null
+++ b/language/en-GB/en-GB.com_finder.commonwords.txt
@@ -0,0 +1,179 @@
+; Joomla! Project
+; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved.
+; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
+; Note : This file needs to be saved as UTF-8
+
+i
+me
+my
+myself
+we
+our
+ours
+ourselves
+you
+your
+yours
+yourself
+yourselves
+he
+him
+his
+himself
+she
+her
+hers
+herself
+it
+its
+itself
+they
+them
+their
+theirs
+themselves
+what
+which
+who
+whom
+this
+that
+these
+those
+am
+is
+are
+was
+were
+be
+been
+being
+have
+has
+had
+having
+do
+does
+did
+doing
+would
+should
+could
+ought
+i'm
+you're
+he's
+she's
+it's
+we're
+they're
+i've
+you've
+we've
+they've
+i'd
+you'd
+he'd
+she'd
+we'd
+they'd
+i'll
+you'll
+he'll
+she'll
+we'll
+they'll
+isn't
+aren't
+wasn't
+weren't
+hasn't
+haven't
+hadn't
+doesn't
+don't
+didn't
+won't
+wouldn't
+shan't
+shouldn't
+can't
+cannot
+couldn't
+mustn't
+let's
+that's
+who's
+what's
+here's
+there's
+when's
+where's
+why's
+how's
+a
+an
+the
+and
+but
+if
+or
+because
+as
+until
+while
+of
+at
+by
+for
+with
+about
+against
+between
+into
+through
+during
+before
+after
+above
+below
+to
+from
+up
+down
+in
+out
+on
+off
+over
+under
+again
+further
+then
+once
+here
+there
+when
+where
+why
+how
+all
+any
+both
+each
+few
+more
+most
+other
+some
+such
+no
+nor
+not
+only
+own
+same
+so
+than
+too
+very
diff --git a/plugins/extension/finder/finder.php b/plugins/extension/finder/finder.php
new file mode 100644
index 0000000000000..2bdb9fd333901
--- /dev/null
+++ b/plugins/extension/finder/finder.php
@@ -0,0 +1,194 @@
+getLanguage($eid);
+
+ if ($extension)
+ {
+ $this->removeCommonWords($extension);
+ $this->addCommonWords($extension);
+ }
+ }
+
+ /**
+ * Add common words to finder after language got updated
+ *
+ * @param JInstaller $installer Installer object
+ * @param integer $eid Extension identifier
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function onExtensionAfterUpdate($installer, $eid)
+ {
+ $this->onExtensionAfterInstall($installer, $eid);
+ }
+
+ /**
+ * Remove common words to finder after language got uninstalled
+ *
+ * @param JInstaller $installer Installer instance
+ * @param integer $eid Extension id
+ * @param boolean $removed Installation result
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function onExtensionBeforeUninstall($installer, $eid, $removed)
+ {
+ $extension = $this->getLanguage($eid);
+
+ if ($extension)
+ {
+ $this->removeCommonWords($extension);
+ }
+ }
+
+ /**
+ * Get an object of information if the handled extension is a language
+ *
+ * @param integer $eid Extensuon id
+ *
+ * @return object
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function getLanguage($eid)
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true)
+ ->select('element, client_id')
+ ->from('#__extensions')
+ ->where('extension_id = ' . (int) $eid)
+ ->where('type = ' . $db->quote('language'));
+ $db->setQuery($query);
+ $extension = $db->loadObject();
+
+ return $extension;
+ }
+
+ /**
+ * Add common words from a txt file to com_finder
+ *
+ * @param object $extension Extension object
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function addCommonWords($extension)
+ {
+ if ($extension->client_id == 0)
+ {
+ $path = JPATH_SITE . '/language/' . $extension->element . '/' . $extension->element . '.com_finder.commonwords.txt';
+ }
+ else
+ {
+ $path = JPATH_ADMINISTRATOR . '/language/' . $extension->element . '/' . $extension->element . '.com_finder.commonwords.txt';
+ }
+
+ if (!file_exists($path))
+ {
+ return;
+ }
+
+ $file_content = file_get_contents($path);
+ $words = explode("\n", $file_content);
+ $words = array_map(
+ function ($word)
+ {
+ // Remove comments
+ if (StringHelper::strpos($word, ';') !== false)
+ {
+ $word = StringHelper::substr($word, 0, StringHelper::strpos($word, ';'));
+ }
+
+ return $word;
+ }, $words
+ );
+
+ $words = array_filter(array_map('trim', $words));
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+ require_once JPATH_ADMINISTRATOR . '/components/com_finder/helpers/indexer/helper.php';
+ $lang = \FinderIndexerHelper::getPrimaryLanguage($extension->element);
+ $query->insert('#__finder_terms_common')
+ ->columns(array($db->qn('term'), $db->qn('language'), $db->qn('custom')));
+ $template = ',' . $db->q($lang) . ',0';
+
+ foreach ($words as $word)
+ {
+ $query->values($db->q($word) . $template);
+ }
+
+ try
+ {
+ $db->setQuery($query);
+ $db->execute();
+ }
+ catch (Exception $ex)
+ {
+ // It would be nice if the common word is stored to the DB, but it isn't super important
+ }
+ }
+
+ /**
+ * Remove common words of a language from com_finder
+ *
+ * @param object $extension Extension object
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function removeCommonWords($extension)
+ {
+ $db = Factory::getDbo();
+ require_once JPATH_ADMINISTRATOR . '/components/com_finder/helpers/indexer/helper.php';
+ $lang = \FinderIndexerHelper::getPrimaryLanguage($extension->element);
+ $query = $db->getQuery(true)
+ ->delete('#__finder_terms_common')
+ ->where('language = ' . $db->quote($lang))
+ ->where('custom = 0');
+ $db->setQuery($query);
+ $db->execute();
+ }
+}
diff --git a/plugins/extension/finder/finder.xml b/plugins/extension/finder/finder.xml
new file mode 100644
index 0000000000000..9387df4f45d51
--- /dev/null
+++ b/plugins/extension/finder/finder.xml
@@ -0,0 +1,19 @@
+
+
+ plg_extension_finder
+ Joomla! Project
+ June 2018
+ Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved.
+ GNU General Public License version 2 or later; see LICENSE.txt
+ admin@joomla.org
+ www.joomla.org
+ 4.0.0
+ PLG_EXTENSION_FINDER_XML_DESCRIPTION
+
+ finder.php
+
+
+ en-GB.plg_extension_finder.ini
+ en-GB.plg_extension_finder.sys.ini
+
+
diff --git a/plugins/finder/contacts/contacts.php b/plugins/finder/contacts/contacts.php
index 7f3c1daabcfa4..a70b1f4c5bd34 100644
--- a/plugins/finder/contacts/contacts.php
+++ b/plugins/finder/contacts/contacts.php
@@ -357,7 +357,9 @@ protected function index(FinderIndexerResult $item, $format = 'html')
$item->addTaxonomy('Type', 'Contact');
// Add the category taxonomy data.
- $item->addTaxonomy('Category', $item->category, $item->cat_state, $item->cat_access);
+ $categories = JCategories::getInstance('com_contact');
+ $category = $categories->get($item->catid);
+ $item->addNestedTaxonomy('Category', $category, $category->published, $category->access, $category->language);
// Add the language taxonomy data.
$item->addTaxonomy('Language', $item->language);
diff --git a/plugins/finder/content/content.php b/plugins/finder/content/content.php
index e926e44ba42a7..86635f7027652 100644
--- a/plugins/finder/content/content.php
+++ b/plugins/finder/content/content.php
@@ -305,7 +305,9 @@ protected function index(FinderIndexerResult $item, $format = 'html')
}
// Add the category taxonomy data.
- $item->addTaxonomy('Category', $item->category, $item->cat_state, $item->cat_access);
+ $categories = JCategories::getInstance('com_content');
+ $category = $categories->get($item->catid);
+ $item->addNestedTaxonomy('Category', $category, $category->published, $category->access, $category->language);
// Add the language taxonomy data.
$item->addTaxonomy('Language', $item->language);
diff --git a/plugins/finder/newsfeeds/newsfeeds.php b/plugins/finder/newsfeeds/newsfeeds.php
index 38ba280d75e51..1f92c3b04ef7f 100644
--- a/plugins/finder/newsfeeds/newsfeeds.php
+++ b/plugins/finder/newsfeeds/newsfeeds.php
@@ -293,7 +293,9 @@ protected function index(FinderIndexerResult $item, $format = 'html')
$item->addTaxonomy('Type', 'News Feed');
// Add the category taxonomy data.
- $item->addTaxonomy('Category', $item->category, $item->cat_state, $item->cat_access);
+ $categories = JCategories::getInstance('com_newsfeeds');
+ $category = $categories->get($item->catid);
+ $item->addNestedTaxonomy('Category', $category, $category->published, $category->access, $category->language);
// Add the language taxonomy data.
$item->addTaxonomy('Language', $item->language);