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 .= '
'; } @@ -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); ?> @@ -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);