diff --git a/CHANGELOG.md b/CHANGELOG.md index d5c5ee6..5e88786 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# v3.3.0 +## 12/02/2020 + +1. [](#new) + * Upgraded to TNTSearch version 2.5 + * Pass phpstan level 7 tests +1. [](#bugfix) + * Fixed FlexPages events for add+delete + * Fixed running scheduled index job [#104](https://github.com/trilbymedia/grav-plugin-tntsearch/pull/104) + # v3.2.1 ## 09/04/2020 diff --git a/blueprints.yaml b/blueprints.yaml index e8c4cd9..9afcb16 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,7 +1,7 @@ name: TNT Search -slug: tntsearch type: plugin -version: 3.2.1 +slug: tntsearch +version: 3.3.0 testing: false description: Powerful indexed-based full text search engine powered by TNTSearch icon: binoculars diff --git a/classes/GravConnector.php b/classes/GravConnector.php index 9ab2b23..4223af2 100644 --- a/classes/GravConnector.php +++ b/classes/GravConnector.php @@ -14,11 +14,19 @@ public function __construct() } + /** + * @param int $attribute + * @return bool + */ public function getAttribute($attribute): bool { return false; } + /** + * @param string $query + * @return GravResultObject + */ public function query($query) { $counter = 0; diff --git a/classes/GravResultObject.php b/classes/GravResultObject.php index c3660d5..898f815 100644 --- a/classes/GravResultObject.php +++ b/classes/GravResultObject.php @@ -3,14 +3,25 @@ class GravResultObject { + /** @var array */ protected $items; + /** @var int */ protected $counter; + /** + * GravResultObject constructor. + * @param array $items + */ public function __construct($items) { $this->counter = 0; $this->items = $items; } + + /** + * @param array $options + * @return array + */ public function fetch($options) { return $this->items[$this->counter++]; diff --git a/classes/GravTNTSearch.php b/classes/GravTNTSearch.php index 1af79b4..3d1396a 100644 --- a/classes/GravTNTSearch.php +++ b/classes/GravTNTSearch.php @@ -18,10 +18,15 @@ class GravTNTSearch { + /** @var TNTSearch */ public $tnt; + /** @var array */ protected $options; + /** @var string[] */ protected $bool_characters = ['-', '(', ')', 'or']; + /** @var string */ protected $index = 'grav.index'; + /** @var false|string */ protected $language; /** @@ -78,7 +83,7 @@ public function __construct($options = []) } /** - * @param $query + * @param string $query * @return object|string * @throws IndexNotFoundException */ @@ -97,6 +102,7 @@ public function search($query) $limit = (int)$this->options['limit']; $type = $type ?? $this->options['search_type']; + // TODO: Multiword parameter has been removed from $tnt->search(), please check if this works $multiword = null; if (isset($this->options['phrases']) && $this->options['phrases']) { if (strlen($query) > 2) { @@ -111,7 +117,7 @@ public function search($query) switch ($type) { case 'basic': - $results = $this->tnt->search($query, $limit, $multiword); + $results = $this->tnt->search($query, $limit); break; case 'boolean': $results = $this->tnt->searchBoolean($query, $limit); @@ -170,7 +176,7 @@ protected function processResults($res, $query) } if ($this->options['json']) { - return json_encode($data, JSON_PRETTY_PRINT); + return json_encode($data, JSON_PRETTY_PRINT) ?: ''; } return $data; @@ -193,6 +199,7 @@ public static function getCleanContent($page) $twig = $grav['twig']; $header = $page->header(); + // @phpstan-ignore-next-line if (isset($header->tntsearch['template'])) { $processed_page = $twig->processTemplate($header->tntsearch['template'] . '.html.twig', ['page' => $page]); $content = $processed_page; @@ -200,7 +207,8 @@ public static function getCleanContent($page) $content = $page->content(); } - $content = preg_replace('/[ \t]+/', ' ', preg_replace('/\s*$^\s*/m', "\n", strip_tags($content))); + $content = strip_tags($content); + $content = preg_replace('/[ \t]+/', ' ', preg_replace('/\s*$^\s*/m', "\n", $content)); // Restore active page in Grav. unset($grav['page']); @@ -209,6 +217,9 @@ public static function getCleanContent($page) return $content; } + /** + * @return void + */ public function createIndex() { $this->tnt->setDatabaseHandle(new GravConnector); @@ -222,6 +233,10 @@ public function createIndex() $indexer->run(); } + /** + * @return void + * @throws IndexNotFoundException + */ public function selectIndex() { $this->tnt->selectIndex($this->index); @@ -229,6 +244,7 @@ public function selectIndex() /** * @param object $object + * @return void */ public function deleteIndex($object) { @@ -251,6 +267,7 @@ public function deleteIndex($object) /** * @param object $object + * @return void */ public function updateIndex($object) { @@ -282,7 +299,8 @@ public function updateIndex($object) /** @var Collection $collection */ $collection = $apage->collection($filter, false); - if (array_key_exists($object->path(), $collection->toArray())) { + $path = $object->path(); + if ($path && array_key_exists($path, $collection->toArray())) { $fields = $this->indexPageData($object); $document = (array) $fields; diff --git a/cli/TNTSearchIndexerCommand.php b/cli/TNTSearchIndexerCommand.php index 2ede722..5dfd775 100644 --- a/cli/TNTSearchIndexerCommand.php +++ b/cli/TNTSearchIndexerCommand.php @@ -31,7 +31,7 @@ class TNTSearchIndexerCommand extends ConsoleCommand ]; /** - * + * @return void */ protected function configure() { @@ -54,7 +54,7 @@ protected function configure() } /** - * @return int|null|void + * @return void */ protected function serve() { diff --git a/cli/TNTSearchQueryCommand.php b/cli/TNTSearchQueryCommand.php index 7e775aa..11c46a9 100644 --- a/cli/TNTSearchQueryCommand.php +++ b/cli/TNTSearchQueryCommand.php @@ -32,10 +32,8 @@ class TNTSearchQueryCommand extends ConsoleCommand 'EMERGENCY' => 'magenta' ]; - protected $tnt; - /** - * + * @return void */ protected function configure() { @@ -58,7 +56,7 @@ protected function configure() } /** - * @return int|null|void + * @return void */ protected function serve() { @@ -69,6 +67,9 @@ protected function serve() $this->output->writeln(''); } + /** + * @return void + */ private function doQuery() { $gtnt = TNTSearchPlugin::getSearchObjectType(['json' => true]); diff --git a/composer.json b/composer.json index c446bbe..a3dd8e9 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "grav-plugin-tntsearch", + "name": "trilbymedia/grav-plugin-tntsearch", "type": "grav-plugin", "description": "TNTSearch plugin for Grav CMS", "keywords": ["tntsearch","search"], diff --git a/composer.lock b/composer.lock index 946e6bf..b8c7d11 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c82d44d0c8d193d3b4aeeaceaf771019", + "content-hash": "775528937eccd0ee40e69297d965d06c", "packages": [ { "name": "teamtnt/tntsearch", - "version": "v2.2.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/teamtnt/tntsearch.git", - "reference": "a24399e04b6d7f152d3b31ea4a59efc6385cfd06" + "reference": "60ac210e46ded12182316e789519b32617829e01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/teamtnt/tntsearch/zipball/a24399e04b6d7f152d3b31ea4a59efc6385cfd06", - "reference": "a24399e04b6d7f152d3b31ea4a59efc6385cfd06", + "url": "https://api.github.com/repos/teamtnt/tntsearch/zipball/60ac210e46ded12182316e789519b32617829e01", + "reference": "60ac210e46ded12182316e789519b32617829e01", "shasum": "" }, "require": { @@ -54,13 +54,34 @@ "homepage": "https://github.com/teamtnt/tntsearch", "keywords": [ "Fuzzy search", + "bm25", "fulltext", "geosearch", "search", + "stemming", "teamtnt", + "text classification", "tntsearch" ], - "time": "2019-10-07T10:02:35+00:00" + "support": { + "issues": "https://github.com/teamtnt/tntsearch/issues", + "source": "https://github.com/teamtnt/tntsearch/tree/v2.5.0" + }, + "funding": [ + { + "url": "https://ko-fi.com/nticaric", + "type": "ko_fi" + }, + { + "url": "https://opencollective.com/tntsearch", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/nticaric", + "type": "patreon" + } + ], + "time": "2020-11-23T13:54:31+00:00" } ], "packages-dev": [], @@ -69,6 +90,13 @@ "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [] + "platform": { + "php": ">=7.1.3", + "ext-json": "*" + }, + "platform-dev": [], + "platform-overrides": { + "php": "7.1.3" + }, + "plugin-api-version": "2.0.0" } diff --git a/tntsearch.php b/tntsearch.php index 252a98a..b04a378 100644 --- a/tntsearch.php +++ b/tntsearch.php @@ -19,13 +19,19 @@ */ class TNTSearchPlugin extends Plugin { + /** @var array|object|string */ protected $results = []; + /** @var string */ protected $query; - + /** @var bool */ protected $built_in_search_page; + /** @var string */ protected $query_route; + /** @var string */ protected $search_route; + /** @var string */ protected $current_route; + /** @var string */ protected $admin_route; /** @@ -50,8 +56,6 @@ public static function getSubscribedEvents(): array 'onTNTSearchReIndex' => ['onTNTSearchReIndex', 0], 'onTNTSearchIndex' => ['onTNTSearchIndex', 0], 'onTNTSearchQuery' => ['onTNTSearchQuery', 0], - 'onFlexObjectSave' => ['onObjectSave', 0], - 'onFlexObjectDelete' => ['onObjectDelete', 0], ]; } @@ -85,8 +89,10 @@ public function onPluginsInitialized(): void if ($this->config->get('plugins.tntsearch.enable_admin_page_events', true)) { $this->enable([ - 'onAdminAfterSave' => ['onObjectSave', 0], - 'onAdminAfterDelete' => ['onObjectDelete', 0], + 'onAdminAfterSave' => ['onObjectSave', 0], + 'onAdminAfterDelete' => ['onObjectDelete', 0], + 'onFlexObjectSave' => ['onObjectSave', 0], + 'onFlexObjectDelete' => ['onObjectDelete', 0], ]); } @@ -110,7 +116,7 @@ public function onSchedulerInitialized(Event $e): void $scheduler = $e['scheduler']; $at = $this->config->get('plugins.tntsearch.scheduled_index.at'); $logs = $this->config->get('plugins.tntsearch.scheduled_index.logs'); - $job = $scheduler->addCommand('bin/plugin tntsearch index', [], 'tntsearch-index'); + $job = $scheduler->addCommand('bin/plugin', ['tntsearch', 'index'], 'tntsearch-index'); $job->at($at); $job->output($logs); $job->backlink('/plugins/tntsearch'); @@ -203,7 +209,7 @@ public function onPagesInitialized(): void } } - $this->query = $uri->param('q') ?: $uri->query('q'); + $this->query = (string)($uri->param('q', null) ?? $uri->query('q') ?: ''); if ($this->query) { $snippet = $this->getFormValue('sl'); @@ -387,7 +393,7 @@ public function onAdminMenu(): void /** * Wrapper to get the number of documents currently indexed * - * @param $gtnt GravTNTSearch + * @param GravTNTSearch $gtnt * @return array */ protected static function getIndexCount($gtnt): array @@ -414,7 +420,7 @@ protected static function getIndexCount($gtnt): array /** * Helper function to read form/url values * - * @param $val + * @param string $val * @return mixed */ protected function getFormValue($val) @@ -424,6 +430,10 @@ protected function getFormValue($val) return $uri->param($val) ?: $uri->query($val) ?: filter_input(INPUT_POST, $val, FILTER_SANITIZE_ENCODED); } + /** + * @param array $options + * @return GravTNTSearch + */ public static function getSearchObjectType($options = []) { $type = 'Grav\\Plugin\\TNTSearch\\' . Grav::instance()['config']->get('plugins.tntsearch.search_object_type', 'Grav') . 'TNTSearch'; @@ -500,7 +510,7 @@ public static function indexJob(string $langCode = null) /** * Helper to initialize TNTSearch if required * - * @return TNTSearch\GravTNTSearch + * @return GravTNTSearch */ protected function GravTNTSearch() { diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index dc02dfb..1a58957 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -37,8 +37,8 @@ * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { @@ -60,7 +60,7 @@ class ClassLoader public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); } return array(); @@ -279,7 +279,7 @@ public function isClassMapAuthoritative() */ public function setApcuPrefix($apcuPrefix) { - $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; } /** @@ -377,7 +377,7 @@ private function findFileWithExtension($class, $ext) $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); - $search = $subPath.'\\'; + $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000..094af82 --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,218 @@ + + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => 'd202e52e50d96d2ff15be1826fa2e9561efe63bd', + 'name' => 'trilbymedia/grav-plugin-tntsearch', + ), + 'versions' => + array ( + 'teamtnt/tntsearch' => + array ( + 'pretty_version' => 'v2.5.0', + 'version' => '2.5.0.0', + 'aliases' => + array ( + ), + 'reference' => '60ac210e46ded12182316e789519b32617829e01', + ), + 'trilbymedia/grav-plugin-tntsearch' => + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => 'd202e52e50d96d2ff15be1826fa2e9561efe63bd', + ), + ), +); + + + + + + + +public static function getInstalledPackages() +{ +return array_keys(self::$installed['versions']); +} + + + + + + + + + +public static function isInstalled($packageName) +{ +return isset(self::$installed['versions'][$packageName]); +} + + + + + + + + + + + + + + +public static function satisfies(VersionParser $parser, $packageName, $constraint) +{ +$constraint = $parser->parseConstraints($constraint); +$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + +return $provided->matches($constraint); +} + + + + + + + + + + +public static function getVersionRanges($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +$ranges = array(); +if (isset(self::$installed['versions'][$packageName]['pretty_version'])) { +$ranges[] = self::$installed['versions'][$packageName]['pretty_version']; +} +if (array_key_exists('aliases', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']); +} +if (array_key_exists('replaced', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']); +} +if (array_key_exists('provided', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']); +} + +return implode(' || ', $ranges); +} + + + + + +public static function getVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['version']; +} + + + + + +public static function getPrettyVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['pretty_version']; +} + + + + + +public static function getReference($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['reference'])) { +return null; +} + +return self::$installed['versions'][$packageName]['reference']; +} + + + + + +public static function getRootPackage() +{ +return self::$installed['root']; +} + + + + + + + +public static function getRawData() +{ +return self::$installed; +} + + + + + + + + + + + + + + + + + + + +public static function reload($data) +{ +self::$installed = $data; +} +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index faf96ff..042e42d 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -6,5 +6,6 @@ $baseDir = dirname($vendorDir); return array( + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'Grav\\Plugin\\TNTSearchPlugin' => $baseDir . '/tntsearch.php', ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 4275b84..43b2d5c 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -13,19 +13,24 @@ public static function loadClassLoader($class) } } + /** + * @return \Composer\Autoload\ClassLoader + */ public static function getLoader() { if (null !== self::$loader) { return self::$loader; } + require __DIR__ . '/platform_check.php'; + spl_autoload_register(array('ComposerAutoloaderInit6693564509f9a3fa6ed2c7bf76fdb017', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit6693564509f9a3fa6ed2c7bf76fdb017', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; + require __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInit6693564509f9a3fa6ed2c7bf76fdb017::getInitializer($loader)); } else { diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index b01a290..ac0125d 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -38,6 +38,7 @@ class ComposerStaticInit6693564509f9a3fa6ed2c7bf76fdb017 ); public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'Grav\\Plugin\\TNTSearchPlugin' => __DIR__ . '/../..' . '/tntsearch.php', ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 12734ab..c92b1ab 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,60 +1,68 @@ -[ - { - "name": "teamtnt/tntsearch", - "version": "v2.2.0", - "version_normalized": "2.2.0.0", - "source": { - "type": "git", - "url": "https://github.com/teamtnt/tntsearch.git", - "reference": "a24399e04b6d7f152d3b31ea4a59efc6385cfd06" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/teamtnt/tntsearch/zipball/a24399e04b6d7f152d3b31ea4a59efc6385cfd06", - "reference": "a24399e04b6d7f152d3b31ea4a59efc6385cfd06", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "ext-pdo_sqlite": "*", - "ext-sqlite3": "*", - "php": "~7.1" - }, - "require-dev": { - "phpunit/phpunit": "7.*" - }, - "time": "2019-10-07T10:02:35+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "TeamTNT\\TNTSearch\\": "src" +{ + "packages": [ + { + "name": "teamtnt/tntsearch", + "version": "v2.5.0", + "version_normalized": "2.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/teamtnt/tntsearch.git", + "reference": "60ac210e46ded12182316e789519b32617829e01" }, - "files": [ - "helper/helpers.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nenad Tičarić", - "email": "nticaric@gmail.com", - "homepage": "http://www.tntstudio.us", - "role": "Developer" - } - ], - "description": "A fully featured full text search engine written in PHP", - "homepage": "https://github.com/teamtnt/tntsearch", - "keywords": [ - "Fuzzy search", - "fulltext", - "geosearch", - "search", - "teamtnt", - "tntsearch" - ] - } -] + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/teamtnt/tntsearch/zipball/60ac210e46ded12182316e789519b32617829e01", + "reference": "60ac210e46ded12182316e789519b32617829e01", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-pdo_sqlite": "*", + "ext-sqlite3": "*", + "php": "~7.1" + }, + "require-dev": { + "phpunit/phpunit": "7.*" + }, + "time": "2020-11-23T13:54:31+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "TeamTNT\\TNTSearch\\": "src" + }, + "files": [ + "helper/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nenad Tičarić", + "email": "nticaric@gmail.com", + "homepage": "http://www.tntstudio.us", + "role": "Developer" + } + ], + "description": "A fully featured full text search engine written in PHP", + "homepage": "https://github.com/teamtnt/tntsearch", + "keywords": [ + "Fuzzy search", + "bm25", + "fulltext", + "geosearch", + "search", + "stemming", + "teamtnt", + "text classification", + "tntsearch" + ], + "install-path": "../teamtnt/tntsearch" + } + ], + "dev": true, + "dev-package-names": [] +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 0000000..27b33f2 --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,33 @@ + + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => 'd202e52e50d96d2ff15be1826fa2e9561efe63bd', + 'name' => 'trilbymedia/grav-plugin-tntsearch', + ), + 'versions' => + array ( + 'teamtnt/tntsearch' => + array ( + 'pretty_version' => 'v2.5.0', + 'version' => '2.5.0.0', + 'aliases' => + array ( + ), + 'reference' => '60ac210e46ded12182316e789519b32617829e01', + ), + 'trilbymedia/grav-plugin-tntsearch' => + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => 'd202e52e50d96d2ff15be1826fa2e9561efe63bd', + ), + ), +); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php new file mode 100644 index 0000000..cd1bd2c --- /dev/null +++ b/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70103)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.3". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/vendor/teamtnt/tntsearch/README.md b/vendor/teamtnt/tntsearch/README.md index 4ae8ead..63d6d93 100644 --- a/vendor/teamtnt/tntsearch/README.md +++ b/vendor/teamtnt/tntsearch/README.md @@ -4,25 +4,26 @@ [![Build Status](https://img.shields.io/travis/teamtnt/tntsearch/master.svg?style=flat-square)](https://travis-ci.org/teamtnt/tntsearch) [![Slack Status](https://img.shields.io/badge/slack-chat-E01563.svg?style=flat-square)](https://tntsearch.slack.com) -![TNTSearch Banner](https://cloud.githubusercontent.com/assets/824840/17067635/edf2ae50-504c-11e6-9c63-a73955f55c29.jpg) +![TNTSearch](https://i.imgur.com/aYKsNYv.png) # TNTSearch -TNTSearch is a fully featured full text search engine written entirely in PHP. It's simple configuration allows you to add an amazing search experience to your site in just minutes. -It has also a build in geo-search and a text classifier. Other features are - -* fuzzy search -* as you type functionality -* geo-search -* text-classification -* stemming -* custom tokenizers -* bm25 ranking algorithm -* boolean search -* result highlighting - -We created also some demo pages that show tolerant retrieval with n-grams in action. -The package has bunch of helper functions like jaro-winkler and cosine similarity for distance calculations. It supports stemming for English, Croatian, Arabic, Italian, Russian, Portuguese and Ukrainian. If the built in stemmers aren't enough, the engine lets you easily plugin any compatible snowball stemmer. Some forks of the package even support Chinese. +TNTSearch is a full-featured full text search (FTS) engine written entirely in PHP. A simple configuration allows you to add an amazing search experience in just minutes. Features include: + +* Fuzzy search +* Search as you type +* Geo-search +* Text classification +* Stemming +* Custom tokenizers +* Bm25 ranking algorithm +* Boolean search +* Result highlighting +* Dynamic index updates (no need to reindex each time) +* Easily deployable via Packagist.org + +We also created some demo pages that show tolerant retrieval with n-grams in action. +The package has a bunch of helper functions like Jaro-Winkler and Cosine similarity for distance calculations. It supports stemming for English, Croatian, Arabic, Italian, Russian, Portuguese and Ukrainian. If the built-in stemmers aren't enough, the engine lets you easily plugin any compatible snowball stemmer. Some forks of the package even support Chinese. And please contribute other languages! Unlike many other engines, the index can be easily updated without doing a reindex or using deltas. @@ -33,7 +34,7 @@ or [Facebook](https://www.facebook.com/tntstudiohr)  | 

- +

@@ -41,7 +42,7 @@ or [Facebook](https://www.facebook.com/tntstudiohr)  |  ## Demo * [TV Shows Search](http://tntsearch.tntstudio.us/) -* [PHPUnit Documentatin Search](http://phpunit.tntstudio.us) +* [PHPUnit Documentation Search](http://phpunit.tntstudio.us) * [City Search with n-grams](http://cities.tnt.studio/) ## Tutorials @@ -64,7 +65,7 @@ composer require teamtnt/tntsearch ## Requirements -Before you proceed make sure your server meets the following requirements: +Before you proceed, make sure your server meets the following requirements: * PHP >= 7.1 * PDO PHP Extension @@ -75,7 +76,7 @@ Before you proceed make sure your server meets the following requirements: ### Creating an index -In order to be able to make full text search queries you have to create an index. +In order to be able to make full text search queries, you have to create an index. Usage: ```php @@ -114,7 +115,7 @@ $indexer->setPrimaryKey('article_id'); ### Making the primary key searchable -By default the primary key is not searchable, if you wanna make it searchable simply run: +By default the primary key is not searchable. If you wanna make it searchable, simply run: ```php $indexer->includePrimaryKey(); @@ -141,8 +142,8 @@ print_r($res); //returns an array of 12 document ids that best match your query // SELECT * FROM articles WHERE id IN $res ORDER BY FIELD(id, $res); ``` -The ORDER BY FIELD clause is important otherwise the database engine will not return -the results in required order +The ORDER BY FIELD clause is important, otherwise the database engine will not return +the results in the required order. ### Boolean Search @@ -172,7 +173,7 @@ The fuzziness can be tweaked by setting the following member variables: ```php public $fuzzy_prefix_length = 2; public $fuzzy_max_expansions = 50; -public $fuzzy_distance = 2 //represents the levenshtein distance; +public $fuzzy_distance = 2; //represents the Levenshtein distance; ``` ```php @@ -184,14 +185,14 @@ $tnt->loadConfig($config); $tnt->selectIndex("name.index"); $tnt->fuzziness = true; -//when the fuzziness flag is set to true the keyword juleit will return -//documents that match the word juliet, the default levenshtein distance is 2 +//when the fuzziness flag is set to true, the keyword juleit will return +//documents that match the word juliet, the default Levenshtein distance is 2 $res = $tnt->search("juleit"); ``` ## Updating the index -Once you created an index you don't need to reindex it each time you make some changes +Once you created an index, you don't need to reindex it each time you make some changes to your document collection. TNTSearch supports dynamic index updates. ```php @@ -215,23 +216,27 @@ $index->delete(12); ``` ## Custom Tokenizer -First, create your own Tokenizer class that implements TokenizerInterface: +First, create your own Tokenizer class. It should extend AbstractTokenizer class, define +word split $pattern value and must implement TokenizerInterface: ``` php +use TeamTNT\TNTSearch\Support\AbstractTokenizer; use TeamTNT\TNTSearch\Support\TokenizerInterface; -class SomeTokenizer implements TokenizerInterface { +class SomeTokenizer extends AbstractTokenizer implements TokenizerInterface +{ + static protected $pattern = '/[\s,\.]+/'; public function tokenize($text) { - return preg_split("/[^\p{L}\p{N}-]+/u", strtolower($text), -1, PREG_SPLIT_NO_EMPTY); + return preg_split($this->getPattern(), strtolower($text), -1, PREG_SPLIT_NO_EMPTY); } } ``` -The only difference here from the original is that the regex contains a dash `[^\p{L}\p{N}-]` +This tokenizer will split words using spaces, commas and periods. -After you have the tokenizer ready, your `TNTIndexer` and `TNTSearch` class should consume it. +After you have the tokenizer ready, you should pass it to `TNTIndexer` via `setTokenizer` method. ``` php $someTokenizer = new SomeTokenizer; @@ -240,13 +245,28 @@ $indexer = new TNTIndexer; $indexer->setTokenizer($someTokenizer); ``` -And in the `TNTSearch` class you do the same +Another way would be to pass the tokenizer via config: -``` php -$someTokenizer = new SomeTokenizer; +```php +use TeamTNT\TNTSearch\TNTSearch; $tnt = new TNTSearch; -$tnt->setTokenizer($someTokenizer); + +$tnt->loadConfig([ + 'driver' => 'mysql', + 'host' => 'localhost', + 'database' => 'dbname', + 'username' => 'user', + 'password' => 'pass', + 'storage' => '/var/www/tntsearch/examples/', + 'stemmer' => \TeamTNT\TNTSearch\Stemmer\PorterStemmer::class//optional, + 'tokenizer' => \TeamTNT\TNTSearch\Support\SomeTokenizer::class +]); + +$indexer = $tnt->createIndex('name.index'); +$indexer->query('SELECT id, article FROM articles;'); +$indexer->run(); + ``` ## Geo Search @@ -312,7 +332,7 @@ $classifier->load('sports.cls'); ## PS4Ware -You're free to use this package, but if it makes it to your production environment we would highly appreciate you sending us a PS4 game of your choise. This way you support us to further develop and add new features to this package. +You're free to use this package, but if it makes it to your production environment, we would highly appreciate you sending us a PS4 game of your choice. This way you support us to further develop and add new features. Our address is: TNT Studio, Sv. Mateja 19, 10010 Zagreb, Croatia. diff --git a/vendor/teamtnt/tntsearch/composer.json b/vendor/teamtnt/tntsearch/composer.json index d16b65a..3fb7d29 100644 --- a/vendor/teamtnt/tntsearch/composer.json +++ b/vendor/teamtnt/tntsearch/composer.json @@ -3,7 +3,15 @@ "type": "library", "description": "A fully featured full text search engine written in PHP", "keywords": [ - "teamtnt", "tntsearch", "search", "fulltext", "geosearch", "fuzzy search" + "teamtnt", + "tntsearch", + "search", + "fulltext", + "geosearch", + "text classification", + "bm25", + "stemming", + "fuzzy search" ], "homepage": "https://github.com/teamtnt/tntsearch", "license": "MIT", @@ -30,4 +38,4 @@ "helper/helpers.php" ] } -} \ No newline at end of file +} diff --git a/vendor/teamtnt/tntsearch/src/Connectors/Connector.php b/vendor/teamtnt/tntsearch/src/Connectors/Connector.php index 18f7dab..7f573b2 100644 --- a/vendor/teamtnt/tntsearch/src/Connectors/Connector.php +++ b/vendor/teamtnt/tntsearch/src/Connectors/Connector.php @@ -15,7 +15,6 @@ class Connector PDO::ATTR_CASE => PDO::CASE_NATURAL, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, - PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false, PDO::ATTR_STRINGIFY_FETCHES => false, PDO::ATTR_EMULATE_PREPARES => false, ]; diff --git a/vendor/teamtnt/tntsearch/src/Connectors/MySqlConnector.php b/vendor/teamtnt/tntsearch/src/Connectors/MySqlConnector.php index 4778da6..f8dbb05 100644 --- a/vendor/teamtnt/tntsearch/src/Connectors/MySqlConnector.php +++ b/vendor/teamtnt/tntsearch/src/Connectors/MySqlConnector.php @@ -58,6 +58,13 @@ public function connect(array $config) return $connection; } + public function getOptions(array $config) + { + return array_merge(parent::getOptions($config), [ + PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false, + ]); + } + /** * Create a DSN string from a configuration. * @@ -129,4 +136,4 @@ protected function setModes(PDO $connection, array $config) } } } -} \ No newline at end of file +} diff --git a/vendor/teamtnt/tntsearch/src/Indexer/TNTIndexer.php b/vendor/teamtnt/tntsearch/src/Indexer/TNTIndexer.php index 74b7fa3..1742d3a 100644 --- a/vendor/teamtnt/tntsearch/src/Indexer/TNTIndexer.php +++ b/vendor/teamtnt/tntsearch/src/Indexer/TNTIndexer.php @@ -52,8 +52,7 @@ public function __construct() public function setTokenizer(TokenizerInterface $tokenizer) { $this->tokenizer = $tokenizer; - $class = get_class($tokenizer); - $this->index->exec("INSERT INTO info ( 'key', 'value') values ( 'tokenizer', '$class')"); + $this->updateInfoTable('tokenizer', get_class($tokenizer)); } public function setStopWords(array $stopWords) @@ -72,11 +71,10 @@ public function loadConfig(array $config) if (!isset($this->config['driver'])) { $this->config['driver'] = ""; } - - if (isset($this->config['tokenizer'])) { - $this->tokenizer = new $this->config['tokenizer']; + + if (!isset($this->config['wal'])) { + $this->config['wal'] = true; } - } /** @@ -124,8 +122,7 @@ public function includePrimaryKey() public function setStemmer($stemmer) { $this->stemmer = $stemmer; - $class = get_class($stemmer); - $this->index->exec("INSERT INTO info ( 'key', 'value') values ( 'stemmer', '$class')"); + $this->updateInfoTable('stemmer', get_class($stemmer)); } public function setCroatianStemmer() @@ -181,6 +178,10 @@ public function createIndex($indexName) $this->index = new PDO('sqlite:'.$this->config['storage'].$indexName); $this->index->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + if($this->config['wal']) { + $this->index->exec("PRAGMA journal_mode=wal;"); + } + $this->index->exec("CREATE TABLE IF NOT EXISTS wordlist ( id INTEGER PRIMARY KEY, term TEXT UNIQUE COLLATE nocase, @@ -210,8 +211,19 @@ public function createIndex($indexName) value INTEGER)"); $this->index->exec("INSERT INTO info ( 'key', 'value') values ( 'total_documents', 0)"); + $this->index->exec("INSERT INTO info ( 'key', 'value') values ( 'stemmer', 'TeamTNT\TNTSearch\Stemmer\NoStemmer')"); + $this->index->exec("INSERT INTO info ( 'key', 'value') values ( 'tokenizer', 'TeamTNT\TNTSearch\Support\Tokenizer')"); $this->index->exec("CREATE INDEX IF NOT EXISTS 'main'.'term_id_index' ON doclist ('term_id' COLLATE BINARY);"); + $this->index->exec("CREATE INDEX IF NOT EXISTS 'main'.'doc_id_index' ON doclist ('doc_id');"); + + if (isset($this->config['stemmer'])) { + $this->setStemmer(new $this->config['stemmer']); + } + + if (isset($this->config['tokenizer'])) { + $this->setTokenizer(new $this->config['tokenizer']); + } if (!$this->dbh) { $connector = $this->createConnector($this->config); @@ -340,10 +352,12 @@ public function readDocumentsFromFileSystem() ]; $fileCollection = new Collection($file); - if (is_callable($this->filereader->fileFilterCallback)) { + if (property_exists($this->filereader, 'fileFilterCallback') + && is_callable($this->filereader->fileFilterCallback)) { $fileCollection = $fileCollection->filter($this->filereader->fileFilterCallback); } - if (is_callable($this->filereader->fileMapCallback)) { + if (property_exists($this->filereader, 'fileMapCallback') + && is_callable($this->filereader->fileMapCallback)) { $fileCollection = $fileCollection->map($this->filereader->fileMapCallback); } @@ -422,7 +436,10 @@ public function delete($documentId) public function updateInfoTable($key, $value) { - $this->index->exec("UPDATE info SET value = $value WHERE key = '$key'"); + $this->updateInfoTableStmt = $this->index->prepare("UPDATE info SET value = :value WHERE key = :key"); + $this->updateInfoTableStmt->bindValue(':key', $key); + $this->updateInfoTableStmt->bindValue(':value', $value); + $this->updateInfoTableStmt->execute(); } public function stemText($text) diff --git a/vendor/teamtnt/tntsearch/src/Stemmer/ItalianStemmer.php b/vendor/teamtnt/tntsearch/src/Stemmer/ItalianStemmer.php index 0c78ad3..764a5a5 100644 --- a/vendor/teamtnt/tntsearch/src/Stemmer/ItalianStemmer.php +++ b/vendor/teamtnt/tntsearch/src/Stemmer/ItalianStemmer.php @@ -74,9 +74,9 @@ class ItalianStemmer implements Stemmer public function __construct() { - usort(self::$suffissi_step0, create_function('$a,$b', 'return mb_strlen($a)>mb_strlen($b) ? -1 : 1;')); - usort(self::$suffissi_step1_a, create_function('$a,$b', 'return mb_strlen($a)>mb_strlen($b) ? -1 : 1;')); - usort(self::$suffissi_step2, create_function('$a,$b', 'return mb_strlen($a)>mb_strlen($b) ? -1 : 1;')); + usort(self::$suffissi_step0, function($a,$b) { return mb_strlen($a)>mb_strlen($b) ? -1 : 1; }); + usort(self::$suffissi_step1_a, function($a,$b) { return mb_strlen($a)>mb_strlen($b) ? -1 : 1;}); + usort(self::$suffissi_step2, function($a,$b) { return mb_strlen($a)>mb_strlen($b) ? -1 : 1;}); } /** @@ -326,13 +326,13 @@ private static function step1($str) } // Delete if in R2 - if (count($ret_str = self::deleteStuff(self::$suffissi_step1_a, $str, $str_len, 'r2', true))) { + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_a, $str, $str_len, 'r2', true))) { return $ret_str; } // Delete if in R2, if preceded by 'ic', delete if in R2 - if (count($ret_str = self::deleteStuff(self::$suffissi_step1_b, $str, $str_len, 'r2'))) { - if (count($ret_str1 = self::deleteStuff(['ic'], $ret_str, mb_strlen($ret_str), 'r2'))) { + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_b, $str, $str_len, 'r2'))) { + if (!empty($ret_str1 = self::deleteStuff(['ic'], $ret_str, mb_strlen($ret_str), 'r2'))) { return $ret_str1; } else { return $ret_str; @@ -340,28 +340,28 @@ private static function step1($str) } // Replace with 'log' if in R2 - if (count($ret_str = self::deleteStuff(self::$suffissi_step1_c, $str, $str_len, 'r2'))) { + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_c, $str, $str_len, 'r2'))) { return $ret_str.'log'; } // Replace with 'u' if in R2 - if (count($ret_str = self::deleteStuff(self::$suffissi_step1_d, $str, $str_len, 'r2'))) { + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_d, $str, $str_len, 'r2'))) { return $ret_str.'u'; } // Replace with 'ente' if in R2 - if (count($ret_str = self::deleteStuff(self::$suffissi_step1_e, $str, $str_len, 'r2'))) { + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_e, $str, $str_len, 'r2'))) { return $ret_str.'ente'; } // Delete if in RV - if (count($ret_str = self::deleteStuff(self::$suffissi_step1_f, $str, $str_len, 'rv'))) { + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_f, $str, $str_len, 'rv'))) { return $ret_str; } // Delete if in R2, if preceded by 'abil', 'ic' or 'iv', delete if in R2 - if (count($ret_str = self::deleteStuff(self::$suffissi_step1_h, $str, $str_len, 'r2'))) { - if (count($ret_str1 = self::deleteStuff(['abil', 'ic', 'iv'], $ret_str, mb_strlen($ret_str), 'r2'))) { + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_h, $str, $str_len, 'r2'))) { + if (!empty($ret_str1 = self::deleteStuff(['abil', 'ic', 'iv'], $ret_str, mb_strlen($ret_str), 'r2'))) { return $ret_str1; } else { return $ret_str; @@ -369,9 +369,9 @@ private static function step1($str) } // Delete if in R2, if preceded by 'at', delete if in R2 (and if further preceded by 'ic', delete if in R2) - if (count($ret_str = self::deleteStuff(self::$suffissi_step1_i, $str, $str_len, 'r2'))) { - if (count($ret_str1 = self::deleteStuff(['at'], $ret_str, mb_strlen($ret_str), 'r2'))) { - if (count($ret_str2 = self::deleteStuff(['ic'], $ret_str1, mb_strlen($ret_str1), 'r2'))) { + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step1_i, $str, $str_len, 'r2'))) { + if (!empty($ret_str1 = self::deleteStuff(['at'], $ret_str, mb_strlen($ret_str), 'r2'))) { + if (!empty($ret_str2 = self::deleteStuff(['ic'], $ret_str1, mb_strlen($ret_str1), 'r2'))) { return $ret_str2; } else { return $ret_str1; @@ -395,7 +395,7 @@ private static function step2($str, $str_step1) $str_len = mb_strlen($str); - if (count($ret_str = self::deleteStuff(self::$suffissi_step2, $str, $str_len, 'rv'))) { + if (!empty($ret_str = self::deleteStuff(self::$suffissi_step2, $str, $str_len, 'rv'))) { return $ret_str; } @@ -412,8 +412,8 @@ private static function step3a($str) $str_len = mb_strlen($str); - if (count($ret_str = self::deleteStuff($vocale_finale, $str, $str_len, 'rv'))) { - if (count($ret_str1 = self::deleteStuff(['i'], $ret_str, mb_strlen($ret_str), 'rv'))) { + if (!empty($ret_str = self::deleteStuff($vocale_finale, $str, $str_len, 'rv'))) { + if (!empty($ret_str1 = self::deleteStuff(['i'], $ret_str, mb_strlen($ret_str), 'rv'))) { return $ret_str1; } else { return $ret_str; diff --git a/vendor/teamtnt/tntsearch/src/Stopwords/russian.json b/vendor/teamtnt/tntsearch/src/Stopwords/russian.json index 15c3077..54bb5a1 100644 --- a/vendor/teamtnt/tntsearch/src/Stopwords/russian.json +++ b/vendor/teamtnt/tntsearch/src/Stopwords/russian.json @@ -1 +1 @@ -["\u0431\u043e\u043b\u044c\u0448\u0435", "\u043c\u043e\u0436\u0435\u0442", "\u043c\u043d\u043e\u0433\u043e", "\u0431\u043e\u043b\u0435\u0435", "\u0435\u0435", "\u0441\u043e", "\u043e\u043d\u0430", "\u043a", "\u043f\u043e\u0442\u043e\u043c\u0443", "\u0438", "\u0445\u043e\u0440\u043e\u0448\u043e", "\u043d\u0430\u0434\u043e", "\u043d\u0435", "\u0436\u0435", "\u043f\u043e", "\u0435\u0441\u0442\u044c", "\u0440\u0430\u0437", "\u043a\u043e\u043d\u0435\u0447\u043d\u043e", "\u0443", "\u043d\u0435\u043b\u044c\u0437\u044f", "\u0431\u044b\u0442\u044c", "\u043a\u0442\u043e", "\u043f\u043e\u0434", "\u0432", "\u0432\u043e", "\u043e\u0431", "\u043b\u0443\u0447\u0448\u0435", "\u043a\u0430\u043a\u043e\u0439", "\u0434\u0430\u0436\u0435", "\u0435\u043c\u0443", "\u0434\u043e", "\u044f", "\u043f\u043e\u0447\u0442\u0438", "\u0442\u0435\u043c", "\u0432\u0434\u0440\u0443\u0433", "\u043a\u0430\u043a", "\u0432\u044b", "\u043d\u0438\u0445", "\u0434\u0430", "\u043d\u043e", "\u0432\u0430\u0441", "\u0432\u0430\u043c", "\u0441\u0430\u043c", "\u0441\u0432\u043e\u044e", "\u0442\u0430\u043c", "\u043d\u0435\u0435", "\u043e\u0434\u0438\u043d", "\u0442\u043e", "\u0431\u044b\u043b\u043e", "\u043d\u0443", "\u044d\u0442\u0443", "\u0434\u0432\u0430", "\u0442\u043e\u0433\u043e", "\u043d\u0438\u043a\u043e\u0433\u0434\u0430", "\u044d\u0442\u043e\u0442", "\u0447\u0442\u043e\u0431\u044b", "\u0447\u0435\u0433\u043e", "\u043d\u0435\u0442", "\u0432\u0441\u0435\u0433\u043e", "\u043c\u0435\u043d\u044f", "\u043f\u0440\u0438", "\u0432\u043f\u0440\u043e\u0447\u0435\u043c", "\u044d\u0442\u043e\u0433\u043e", "\u0442\u0430\u043a\u043e\u0439", "\u043f\u043e\u0441\u043b\u0435", "\u043d\u0430\u0441", "\u0447\u0442\u043e", "\u043f\u0435\u0440\u0435\u0434", "\u043d\u0438", "\u0432\u0435\u0434\u044c", "\u043a\u043e\u0433\u0434\u0430", "\u0438\u043c", "\u043d\u0438\u043c", "\u043c\u0435\u0436\u0434\u0443", "\u0436", "\u0430", "\u0438\u0437", "\u043d\u0430\u043a\u043e\u043d\u0435\u0446", "\u0432\u043e\u0442", "\u043d\u0438\u0431\u0443\u0434\u044c", "\u043a\u0443\u0434\u0430", "\u0447\u0443\u0442\u044c", "\u0438\u043d\u043e\u0433\u0434\u0430", "\u0432\u0441\u0435", "\u0441", "\u0442\u043e\u0433\u0434\u0430", "\u0442\u044b", "\u0442\u043e\u0436\u0435", "\u043d\u0438\u0447\u0435\u0433\u043e", "\u0441\u0435\u0431\u0435", "\u0442\u0430\u043a", "\u0443\u0436\u0435", "\u043e\u043d\u0438", "\u0442\u0443\u0442", "\u0431\u044b\u043b", "\u043d\u0430\u0434", "\u044d\u0442\u0438", "\u043a\u0430\u043a\u0430\u044f", "\u043e\u043f\u044f\u0442\u044c", "\u044d\u0442\u043e\u0439", "\u043c\u043e\u0436\u043d\u043e", "\u0441\u043e\u0432\u0441\u0435\u043c", "\u043d\u0435\u0433\u043e", "\u043d\u0435\u0439", "\u0431\u044b\u043b\u0430", "\u043d\u0430", "\u0447\u0435\u043c", "\u0434\u043b\u044f", "\u0435\u0449\u0435", "\u0431\u0435\u0437", "\u043e\u0442", "\u043c\u043e\u044f", "\u043f\u043e\u0442\u043e\u043c", "\u0438\u0445", "\u0441\u0435\u0439\u0447\u0430\u0441", "\u044d\u0442\u043e\u043c", "\u043e\u043d", "\u0434\u0440\u0443\u0433\u043e\u0439", "\u043f\u0440\u043e", "\u0437\u0434\u0435\u0441\u044c", "\u0442\u0440\u0438", "\u0431\u044b\u043b\u0438", "\u0431\u0443\u0434\u0442\u043e", "\u0440\u0430\u0437\u0432\u0435", "\u0442\u043e\u043b\u044c\u043a\u043e", "\u0432\u0441\u0435\u0433\u0434\u0430", "\u0443\u0436", "\u0438\u043b\u0438", "\u0432\u0441\u0435\u0445", "\u043c\u044b", "\u0442\u043e\u043c", "\u0447\u0442\u043e\u0431", "\u0435\u0441\u043b\u0438", "\u0433\u0434\u0435", "\u0437\u0430", "\u0442\u043e\u0442", "\u0445\u043e\u0442\u044c", "\u0435\u0439", "\u0437\u0430\u0447\u0435\u043c", "\u0447\u0435\u0440\u0435\u0437", "\u043e", "\u0441\u0435\u0431\u044f", "\u0431\u044b", "\u043c\u043d\u0435", "\u043b\u0438", "\u0432\u0441\u044e", "\u0431\u0443\u0434\u0435\u0442", "\u043c\u043e\u0439", "\u0442\u0435\u043f\u0435\u0440\u044c", "\u0442\u0435\u0431\u044f", "\u0435\u0433\u043e"] \ No newline at end of file +["больше","может","много","более","ее","со","она","к","потому","и","хорошо","надо","не","же","по","есть","раз","конечно","у","нельзя","быть","кто","под","в","во","об","лучше","какой","даже","ему","до","я","почти","тем","вдруг","как","вы","них","да","но","вас","вам","сам","свою","там","нее","один","то","было","ну","эту","два","того","никогда","этот","чтобы","чего","нет","всего","меня","при","впрочем","этого","такой","после","нас","что","перед","ни","ведь","когда","им","ним","между","ж","а","из","наконец","вот","нибудь","куда","чуть","иногда","все","с","тогда","ты","тоже","ничего","себе","так","уже","они","тут","был","над","эти","какая","опять","этой","можно","совсем","него","ней","была","на","чем","для","еще","без","от","моя","потом","их","сейчас","этом","он","другой","про","здесь","три","были","будто","разве","только","всегда","уж","или","всех","мы","том","чтоб","если","где","за","тот","хоть","ей","зачем","через","о","себя","бы","мне","ли","всю","будет","мой","теперь","тебя","его"] \ No newline at end of file diff --git a/vendor/teamtnt/tntsearch/src/Stopwords/ukrainian.json b/vendor/teamtnt/tntsearch/src/Stopwords/ukrainian.json new file mode 100644 index 0000000..37a40b4 --- /dev/null +++ b/vendor/teamtnt/tntsearch/src/Stopwords/ukrainian.json @@ -0,0 +1 @@ +["а","аби","абиде","абиким","абикого","абиколи","абикому","абикуди","абихто","абичий","абичийого","абичийому","абичим","абичию","абичия","абичиє","абичиєму","абичиєю","абичиєї","абичиї","абичиїй","абичиїм","абичиїми","абичиїх","абичого","абичому","абищо","абияка","абияке","абиякий","абияким","абиякими","абияких","абиякого","абиякому","абиякою","абиякої","абияку","абиякі","абиякій","абиякім","або","абощо","авжеж","авось","ага","адже","аж","ажень","але","амінь","ану","ані","аніде","аніж","анізащо","аніким","анікого","анікогісінько","аніколи","анікому","аніскільки","аніхто","анічим","анічого","анічогісінько","анічому","аніщо","аніяка","аніяке","аніякий","аніяким","аніякими","аніяких","аніякого","аніякому","аніякою","аніякої","аніяку","аніякі","аніякій","аніякім","аніякісенька","аніякісеньке","аніякісенький","аніякісеньким","аніякісенькими","аніякісеньких","аніякісенького","аніякісенькому","аніякісенькою","аніякісенької","аніякісеньку","аніякісенькі","аніякісенькій","аніякісенькім","аніякісінька","аніякісіньке","аніякісінький","аніякісіньким","аніякісінькими","аніякісіньких","аніякісінького","аніякісінькому","аніякісінькою","аніякісінької","аніякісіньку","аніякісінькі","аніякісінькій","аніякісінькім","ато","атож","ач","ачей","аякже","б","ба","багато","багатьма","багатьом","багатьох","без","би","бо","бодай","був","буде","будем","будемо","будете","будеш","буду","будуть","будь","будьмо","будьте","була","були","було","бути","буцім","буцімто","більш","біля","в","вам","вами","вас","ваш","ваша","ваше","вашим","вашими","ваших","вашого","вашому","вашою","вашої","вашу","ваші","вашій","вашім","ввесь","вві","весь","вздовж","ви","власне","властиво","внаслідок","вниз","внизу","вона","вони","воно","вподовж","впоперек","впродовж","все","всередині","вслід","всупереч","всього","всьому","всю","всюди","вся","всяк","всяка","всяке","всякий","всяким","всякими","всяких","всякого","всякому","всякою","всякої","всяку","всякі","всякій","всякім","всі","всій","всіляка","всіляке","всілякий","всіляким","всілякими","всіляких","всілякого","всілякому","всілякою","всілякої","всіляку","всілякі","всілякій","всілякім","всім","всіма","всіх","всією","всієї","втім","ві","від","відколи","відповідно","відтепер","відтоді","він","віщо","віщось","гаразд","ге","геть","да","давай","давати","де","дедалі","деким","декого","деколи","декому","декотра","декотре","декотрий","декотрим","декотрими","декотрих","декотрого","декотрому","декотрою","декотрої","декотру","декотрі","декотрій","декотрім","декілька","декільком","декількома","декількох","декім","десь","дехто","дечий","дечийого","дечийому","дечим","дечию","дечия","дечиє","дечиєму","дечиєю","дечиєї","дечиї","дечиїй","дечиїм","дечиїми","дечиїх","дечого","дечому","дечім","дещо","деяка","деяке","деякий","деяким","деякими","деяких","деякого","деякому","деякою","деякої","деяку","деякі","деякій","деякім","деінде","для","до","довкола","доки","допоки","допіру","досі","дотепер","доти","еге","ж","же","жоден","жодна","жодне","жодний","жодним","жодними","жодних","жодного","жодному","жодною","жодної","жодну","жодні","жодній","жоднім","жоднісінька","жоднісіньке","жоднісінький","жоднісіньким","жоднісінькими","жоднісіньких","жоднісінького","жоднісінькому","жоднісінькою","жоднісінької","жоднісіньку","жоднісінькі","жоднісінькій","жоднісінькім","з","за","завгодно","завдяки","завжди","завше","задля","залежно","замість","заради","зараз","зате","зверху","звідки","звідкилясь","звідкись","звідкіль","звідкіля","звідкілясь","звідси","звідсіль","звідсіля","звідти","звідтіль","звідтіля","звідусюди","звідусіль","звідціля","здовж","ззаду","зо","зсередини","зі","ич","й","його","йому","ким","кимось","кимсь","кого","когось","кожен","кожна","кожне","кожний","кожним","кожними","кожних","кожного","кожному","кожною","кожної","кожну","кожні","кожній","кожнім","кожнісінька","кожнісіньке","кожнісінький","кожнісіньким","кожнісінькими","кожнісіньких","кожнісінького","кожнісінькому","кожнісінькою","кожнісінької","кожнісіньку","кожнісінькі","кожнісінькій","кожнісінькім","коли","колись","коло","кому","комусь","котра","котрась","котре","котресь","котрий","котрийсь","котрим","котрими","котримись","котримось","котримсь","котрих","котрихось","котрихсь","котрого","котрогось","котрому","котромусь","котрою","котроюсь","котрої","котроїсь","котру","котрусь","котрі","котрій","котрійсь","котрім","котрімсь","котрісь","край","круг","кругом","крізь","крім","куди","кудись","кудою","кілька","кільком","кількома","кількох","кім","кімось","кімсь","кінець","ледве","ледь","лиш","лише","лишень","майже","мене","мені","мерсі","ми","мною","мов","мовби","мовбито","могла","могли","могло","мого","могти","може","можем","можемо","можете","можеш","можна","можу","можуть","можіть","мою","моя","моє","моєму","моєю","моєї","мої","моїй","моїм","моїми","моїх","міг","між","мій","на","навколо","навкруг","навпаки","навперейми","навпроти","навіть","навіщо","навіщось","над","надо","наді","нам","нами","наперед","напередодні","наперекір","напереріз","наприкінці","напроти","нас","насеред","насупроти","нате","наче","начеб","начебто","наш","наша","наше","нашим","нашими","наших","нашого","нашому","нашою","нашої","нашу","наші","нашій","нашім","не","неабичим","неабичого","неабичому","неабищо","небагато","небагатьма","небагатьом","небагатьох","невважаючи","невже","незважаючи","немов","немовби","немовбито","неначе","неначебто","нехай","нею","неї","нижче","ним","ними","них","но","ну","нумо","нумте","нього","ньому","ні","ніби","нібито","ніде","ніж","нізащо","нізвідки","нізвідкіля","ній","ніким","нікого","нікогісінько","ніколи","нікому","нікотра","нікотре","нікотрий","нікотрим","нікотрими","нікотрих","нікотрого","нікотрому","нікотрою","нікотрої","нікотру","нікотрі","нікотрій","нікотрім","нікуди","нім","нінащо","ніскільки","ніхто","нічий","нічийна","нічийне","нічийний","нічийним","нічийними","нічийних","нічийного","нічийному","нічийною","нічийної","нічийну","нічийні","нічийній","нічийнім","нічийого","нічийому","нічим","нічию","нічия","нічиє","нічиєму","нічиєю","нічиєї","нічиї","нічиїй","нічиїм","нічиїми","нічиїх","нічого","нічому","ніщо","ніяк","ніяка","ніяке","ніякий","ніяким","ніякими","ніяких","ніякого","ніякому","ніякою","ніякої","ніяку","ніякі","ніякій","ніякім","ніякісінька","ніякісіньке","ніякісінький","ніякісіньким","ніякісінькими","ніякісіньких","ніякісінького","ніякісінькому","ніякісінькою","ніякісінької","ніякісіньку","ніякісінькі","ніякісінькій","ніякісінькім","о","об","обабіч","обік","обіч","од","один","одна","однак","одначе","одне","одним","одними","одних","одно","одного","одному","одною","одної","одну","одні","одній","однім","однією","однієї","окрай","округ","округи","окрім","он","онде","онно","оно","опріч","опісля","осе","оскільки","ось","осісьо","от","ота","отак","отака","отаке","отакий","отаким","отакими","отаких","отакого","отакому","отакою","отакої","отаку","отакі","отакій","отакім","отакісінька","отакісіньке","отакісінький","отакісіньким","отакісінькими","отакісіньких","отакісінького","отакісінькому","отакісінькою","отакісінької","отакісіньку","отакісінькі","отакісінькій","отакісінькім","отам","оте","отже","отим","отими","отих","ото","отого","отож","отой","отому","отою","отої","отсе","оттак","отто","оту","отут","оті","отій","отім","отією","отієї","оце","оцей","оцим","оцими","оцих","оцього","оцьому","оцю","оця","оці","оцій","оцім","оцією","оцієї","пак","перед","перетака","перетаке","перетакий","перетаким","перетакими","перетаких","перетакого","перетакому","перетакою","перетакої","перетаку","перетакі","перетакій","перетакім","по","поблизу","побік","побіч","поверх","повз","повздовж","повсюди","повсюдно","подекуди","подеяка","подеяке","подеякий","подеяким","подеякими","подеяких","подеякого","подеякому","подеякою","подеякої","подеяку","подеякі","подеякій","подеякім","подовж","поза","позад","позаду","позата","позате","позатим","позатими","позатих","позатого","позатой","позатому","позатою","позатої","позату","позаті","позатій","позатім","позатією","позатієї","позаяк","поздовж","поки","покрай","покіль","поміж","понад","понадо","понижче","поперед","попереду","поперек","попліч","попри","попросту","попід","поруч","поряд","посеред","посередині","потім","поуз","прецінь","при","притому","причому","причім","про","проміж","просто","проте","проти","протягом","під","підо","після","раз","раніше","сам","сама","саме","сами","самий","самим","самими","самих","само","самого","самому","самою","самої","саму","самі","самій","самім","свого","свою","своя","своє","своєму","своєю","своєї","свої","своїй","своїм","своїми","своїх","свій","се","себе","себто","серед","сиріч","скрізь","скільки","скількись","скільком","скількома","скількомась","скількомось","скількомсь","скількох","скількохось","скількохсь","собою","собі","спереду","справді","стільки","стільком","стількома","стількох","супроти","супротив","суть","сюди","сяка","сяке","сякий","сяким","сякими","сяких","сякого","сякому","сякою","сякої","сяку","сякі","сякій","сякім","та","так","така","таке","такенна","такенне","такенний","такенним","такенними","такенних","такенного","такенному","такенною","такенної","такенну","такенні","такенній","такеннім","таки","такий","таким","такими","таких","такого","також","такому","такою","такої","таку","такі","такій","такім","такісінька","такісіньке","такісінький","такісіньким","такісінькими","такісіньких","такісінького","такісінькому","такісінькою","такісінької","такісіньку","такісінькі","такісінькій","такісінькім","там","тамки","тамта","тамте","тамтим","тамтими","тамтих","тамтого","тамтой","тамтому","тамтою","тамтої","тамту","тамті","тамтій","тамтім","тамтією","тамтієї","твого","твою","твоя","твоє","твоєму","твоєю","твоєї","твої","твоїй","твоїм","твоїми","твоїх","твій","те","тебе","теж","тепер","теперечки","теє","ти","тим","тими","тих","то","тобою","тобто","тобі","того","тоді","тож","той","тому","тощо","тою","тої","ту","туди","тудою","тут","тутеньки","тутечки","тутки","ті","тій","тільки","тім","тією","тієї","у","ув","увесь","уві","угу","уздовж","унаслідок","уподовж","упоперек","упродовж","усе","услід","усупереч","усього","усьому","усю","усюди","уся","усяк","усяка","усяке","усякий","усяким","усякими","усяких","усякого","усякому","усякою","усякої","усяку","усякі","усякій","усякім","усі","усій","усіляка","усіляке","усілякий","усіляким","усілякими","усіляких","усілякого","усілякому","усілякою","усілякої","усіляку","усілякі","усілякій","усілякім","усім","усіма","усіх","усією","усієї","утім","хай","хоч","хоча","хто","хтось","хіба","це","цебто","цей","цим","цими","цих","цього","цьому","цю","ця","ці","цій","цім","цією","цієї","чень","через","чи","чий","чийого","чийогось","чийому","чийомусь","чийсь","чим","чимось","чимсь","чию","чиюсь","чия","чиясь","чиє","чиєму","чиємусь","чиєсь","чиєю","чиєюсь","чиєї","чиєїсь","чиї","чиїй","чиїйсь","чиїм","чиїми","чиїмись","чиїмось","чиїмсь","чиїсь","чиїх","чиїхось","чиїхсь","чого","чогось","чому","чомусь","чортзна","чім","чімось","чімсь","шляхом","ще","що","щоб","щоби","щодо","щойно","щоправда","щось","я","як","яка","якась","якби","яке","якесь","який","якийсь","яким","якими","якимись","якимось","якимсь","яких","якихось","якихсь","якого","якогось","якому","якомусь","якось","якою","якоюсь","якої","якоїсь","якраз","яку","якусь","якщо","які","якій","якійсь","якім","якімсь","якісь","є","єси","і","ібн","із","ізсередини","інакша","інакше","інакший","інакшим","інакшими","інакших","інакшого","інакшому","інакшою","інакшої","інакшу","інакші","інакшій","інакшім","інколи","іноді","інша","інше","інший","іншим","іншими","інших","іншого","іншому","іншою","іншої","іншу","інші","іншій","іншім","іще","їй","їм","їх","їхнього","їхньому","їхньою","їхньої","їхню","їхня","їхнє","їхні","їхній","їхнім","їхніми","їхніх","її"] \ No newline at end of file diff --git a/vendor/teamtnt/tntsearch/src/Support/AbstractTokenizer.php b/vendor/teamtnt/tntsearch/src/Support/AbstractTokenizer.php new file mode 100644 index 0000000..fcafbff --- /dev/null +++ b/vendor/teamtnt/tntsearch/src/Support/AbstractTokenizer.php @@ -0,0 +1,16 @@ +tokenizer = $tokenizer; + } else { + $this->tokenizer = new Tokenizer; + } + } + /** * @param $text * @param $needle @@ -37,7 +48,7 @@ public function highlight($text, $needle, $tag = 'em', $options = []) } $highlight = '<' . $tag . $tagAttributes .'>\1'; - $needle = preg_split('/\PL+/u', $needle, -1, PREG_SPLIT_NO_EMPTY); + $needle = preg_split($this->tokenizer->getPattern(), $needle, -1, PREG_SPLIT_NO_EMPTY); // Select pattern to use if ($this->options['simple']) { @@ -165,7 +176,7 @@ public function _determineSnipLocation($locations, $prevcount) */ public function extractRelevant($words, $fulltext, $rellength = 300, $prevcount = 50, $indicator = '...') { - $words = preg_split('/\PL+/u', $words, -1, PREG_SPLIT_NO_EMPTY); + $words = preg_split($this->tokenizer->getPattern(), $words, -1, PREG_SPLIT_NO_EMPTY); $textlength = strlen($fulltext); if ($textlength <= $rellength) { return $fulltext; diff --git a/vendor/teamtnt/tntsearch/src/Support/ProductTokenizer.php b/vendor/teamtnt/tntsearch/src/Support/ProductTokenizer.php index 930f7d2..1053230 100644 --- a/vendor/teamtnt/tntsearch/src/Support/ProductTokenizer.php +++ b/vendor/teamtnt/tntsearch/src/Support/ProductTokenizer.php @@ -1,12 +1,14 @@ getPattern(), $text, -1, PREG_SPLIT_NO_EMPTY); return array_diff($split, $stopwords); } } diff --git a/vendor/teamtnt/tntsearch/src/Support/Tokenizer.php b/vendor/teamtnt/tntsearch/src/Support/Tokenizer.php index d8a65b7..8166e27 100644 --- a/vendor/teamtnt/tntsearch/src/Support/Tokenizer.php +++ b/vendor/teamtnt/tntsearch/src/Support/Tokenizer.php @@ -1,12 +1,14 @@ getPattern(), $text, -1, PREG_SPLIT_NO_EMPTY); return array_diff($split, $stopwords); } } diff --git a/vendor/teamtnt/tntsearch/src/Support/TokenizerInterface.php b/vendor/teamtnt/tntsearch/src/Support/TokenizerInterface.php index b0458f1..56d4e2f 100644 --- a/vendor/teamtnt/tntsearch/src/Support/TokenizerInterface.php +++ b/vendor/teamtnt/tntsearch/src/Support/TokenizerInterface.php @@ -4,4 +4,6 @@ interface TokenizerInterface { public function tokenize($text, $stopwords); + + public function getPattern(); } diff --git a/vendor/teamtnt/tntsearch/src/TNTSearch.php b/vendor/teamtnt/tntsearch/src/TNTSearch.php index b6b3edd..d370f39 100644 --- a/vendor/teamtnt/tntsearch/src/TNTSearch.php +++ b/vendor/teamtnt/tntsearch/src/TNTSearch.php @@ -436,13 +436,13 @@ public function breakIntoTokens($text) */ public function highlight($text, $needle, $tag = 'em', $options = []) { - $hl = new Highlighter; + $hl = new Highlighter($this->tokenizer); return $hl->highlight($text, $needle, $tag, $options); } public function snippet($words, $fulltext, $rellength = 300, $prevcount = 50, $indicator = '...') { - $hl = new Highlighter; + $hl = new Highlighter($this->tokenizer); return $hl->extractRelevant($words, $fulltext, $rellength, $prevcount, $indicator); } diff --git a/vendor/teamtnt/tntsearch/tests/TNTSearchTest.php b/vendor/teamtnt/tntsearch/tests/TNTSearchTest.php index 54b1c9c..dfa4e02 100644 --- a/vendor/teamtnt/tntsearch/tests/TNTSearchTest.php +++ b/vendor/teamtnt/tntsearch/tests/TNTSearchTest.php @@ -329,7 +329,7 @@ public function testDefaultStemmerIsSetOnNewIndexesIfNoneConfigured() $tnt->createIndex($this->indexName); $tnt->selectIndex($this->indexName); - $this->assertInstanceOf(\TeamTNT\TNTSearch\Stemmer\PorterStemmer::class, $tnt->getStemmer()); + $this->assertInstanceOf(\TeamTNT\TNTSearch\Stemmer\NoStemmer::class, $tnt->getStemmer()); } public function tearDown(): void diff --git a/vendor/teamtnt/tntsearch/tests/indexer/TNTIndexerTest.php b/vendor/teamtnt/tntsearch/tests/indexer/TNTIndexerTest.php index 71902c3..cbb8552 100644 --- a/vendor/teamtnt/tntsearch/tests/indexer/TNTIndexerTest.php +++ b/vendor/teamtnt/tntsearch/tests/indexer/TNTIndexerTest.php @@ -1,6 +1,7 @@ countWordInWordList('document'); $this->assertTrue($count == 3, 'Word document should be 3'); - $this->assertEquals('TeamTNT\TNTSearch\Stemmer\PorterStemmer', get_class($tnt->getStemmer())); + $this->assertEquals('TeamTNT\TNTSearch\Stemmer\NoStemmer', get_class($tnt->getStemmer())); } public function testIfCroatianStemmerIsSet() @@ -178,11 +179,12 @@ public function testCustomPrimaryKey() } } -class SomeTokenizer implements TokenizerInterface +class SomeTokenizer extends AbstractTokenizer implements TokenizerInterface { + static protected $pattern = '/[\s,\.]+/'; public function tokenize($text, $stopwords = []) { - return preg_split("/[^\p{L}\p{N}-]+/u", mb_strtolower($text), -1, PREG_SPLIT_NO_EMPTY); + return preg_split($this->getPattern(), mb_strtolower($text), -1, PREG_SPLIT_NO_EMPTY); } } diff --git a/vendor/teamtnt/tntsearch/tests/support/ExpressionTest.php b/vendor/teamtnt/tntsearch/tests/support/ExpressionTest.php index a42c804..dddccd3 100644 --- a/vendor/teamtnt/tntsearch/tests/support/ExpressionTest.php +++ b/vendor/teamtnt/tntsearch/tests/support/ExpressionTest.php @@ -15,7 +15,6 @@ public function testToPostfix() $this->assertEquals(['great', 'awsome', '|'], $exp->toPostfix("great or awsome")); $this->assertEquals(['great', 'awsome', '&'], $exp->toPostfix("great awsome")); $this->assertEquals(['email', 'test', '&', 'com', '&'], $exp->toPostfix("email test com")); - $this->assertEquals(['email', 'test', '&', 'com', '&'], $exp->toPostfix("email@test.com")); $this->assertEquals(['first', 'last', '&', 'something', 'else', '&', '|'], $exp->toPostfix("(first last) or (something else)")); } } diff --git a/vendor/teamtnt/tntsearch/tests/support/TokenizerTest.php b/vendor/teamtnt/tntsearch/tests/support/TokenizerTest.php index cce8800..5fbcc5b 100644 --- a/vendor/teamtnt/tntsearch/tests/support/TokenizerTest.php +++ b/vendor/teamtnt/tntsearch/tests/support/TokenizerTest.php @@ -22,6 +22,7 @@ public function testTokenize() $res = $tokenizer->tokenize($text); $this->assertContains("test", $res); $this->assertContains("email", $res); + $this->assertContains("test@email", $res); $this->assertContains("contains", $res); $this->assertContains("123", $res);