Compare commits

..

2 Commits
4.0.2 ... 3

Author SHA1 Message Date
Guy Sartorelli 23f9210918
Merge branch '3.12' into 3 2023-08-29 10:28:05 +12:00
Guy Sartorelli 47a2a1e1a8
ENH Update translations (#352) 2023-08-21 12:51:35 +12:00
16 changed files with 309 additions and 43 deletions

View File

@ -12,4 +12,4 @@ jobs:
with:
extra_jobs: |
- name_suffix: subsites
composer_require_extra: silverstripe/subsites:^3
composer_require_extra: silverstripe/subsites:^2

49
.upgrade.yml Normal file
View File

@ -0,0 +1,49 @@
mappings:
SearchUpdateBatchesProcessor: SilverStripe\FullTextSearch\Search\Processors\SearchUpdateBatchesProcessor
SearchUpdateCommitJobProcessor: SilverStripe\FullTextSearch\Search\Processors\SearchUpdateCommitJobProcessor
SearchUpdateImmediateProcessor: SilverStripe\FullTextSearch\Search\Processors\SearchUpdateImmediateProcessor
SearchUpdateProcessor: SilverStripe\FullTextSearch\Search\Processors\SearchUpdateProcessor
SearchUpdateQueuedJobProcessor: SilverStripe\FullTextSearch\Search\Processors\SearchUpdateQueuedJobProcessor
FullTextSearch: SilverStripe\FullTextSearch\Search\FullTextSearch
SearchManipulateCapture_MySQLDatabase: SilverStripe\FullTextSearch\Search\Captures\SearchManipulateCapture_MySQLDatabase
SearchManipulateCapture_PostgreSQLDatabase: SilverStripe\FullTextSearch\Search\Captures\SearchManipulateCapture_PostgreSQLDatabase
SearchManipulateCapture_SQLite3Database: SilverStripe\FullTextSearch\Search\Captures\SearchManipulateCapture_SQLite3Database
SearchIndex: SilverStripe\FullTextSearch\Search\Indexes\SearchIndex
SearchIndex_Null: SilverStripe\FullTextSearch\Search\Indexes\SearchIndex_Null
SearchIndex_Recording: SilverStripe\FullTextSearch\Search\Indexes\SearchIndex_Recording
SearchIntrospection: SilverStripe\FullTextSearch\Search\SearchIntrospection
SearchQuery: SilverStripe\FullTextSearch\Search\Queries\SearchQuery
SearchQuery_Range: SilverStripe\FullTextSearch\Search\Queries\SearchQuery_Range
SearchUpdater: SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater
SearchUpdater_ObjectHandler: SilverStripe\FullTextSearch\Search\Extensions\SearchUpdater_ObjectHandler
SearchVariant: SilverStripe\FullTextSearch\Search\Variants\SearchVariant
SearchVariant_Caller: SilverStripe\FullTextSearch\Search\Variants\SearchVariant_Caller
SearchVariantSubsites: SilverStripe\FullTextSearch\Search\Variants\SearchVariantSubsites
SearchVariantVersioned: SilverStripe\FullTextSearch\Search\Variants\SearchVariantVersioned
SolrReindexBase: SilverStripe\FullTextSearch\Solr\Reindex\Handlers\SolrReindexBase
SolrReindexHandler: SilverStripe\FullTextSearch\Solr\Reindex\Handlers\SolrReindexHandler
SolrReindexImmediateHandler: SilverStripe\FullTextSearch\Solr\Reindex\Handlers\SolrReindexImmediateHandler
SolrReindexQueuedHandler: SilverStripe\FullTextSearch\Solr\Reindex\Handlers\SolrReindexQueuedHandler
SolrReindexGroupQueuedJob: SilverStripe\FullTextSearch\Solr\Reindex\Jobs\SolrReindexGroupQueuedJob
SolrReindexQueuedJob: SilverStripe\FullTextSearch\Solr\Reindex\Jobs\SolrReindexQueuedJob
SolrReindexQueuedJobBase: SilverStripe\FullTextSearch\Solr\Reindex\Jobs\SolrReindexQueuedJobBase
Solr: SilverStripe\FullTextSearch\Solr\Solr
SolrIndex: SilverStripe\FullTextSearch\Solr\SolrIndex
Solr3Service: SilverStripe\FullTextSearch\Solr\Services\Solr3Service
Solr3Service_Core: SilverStripe\FullTextSearch\Solr\Services\Solr3Service_Core
Solr4Service: SilverStripe\FullTextSearch\Solr\Services\Solr4Service
Solr4Service_Core: SilverStripe\FullTextSearch\Solr\Services\Solr4Service_Core
SolrService: SilverStripe\FullTextSearch\Solr\Services\SolrService
SolrService_Core: SilverStripe\FullTextSearch\Solr\Services\SolrService_Core
SolrConfigStore: SilverStripe\FullTextSearch\Solr\Stores\SolrConfigStore
SolrConfigStore_File: SilverStripe\FullTextSearch\Solr\Stores\SolrConfigStore_File
SolrConfigStore_WebDAV: SilverStripe\FullTextSearch\Solr\Stores\SolrConfigStore_WebDAV
MonologFactory: SilverStripe\FullTextSearch\Utils\Logging\MonologFactory
QueuedJobLogHandler: SilverStripe\FullTextSearch\Utils\Logging\QueuedJobLogHandler
SearchLogFactory: SilverStripe\FullTextSearch\Utils\Logging\SearchLogFactory
CombinationsArrayIterator: SilverStripe\FullTextSearch\Utils\CombinationsArrayIterator
MultipleArrayIterator: SilverStripe\FullTextSearch\Utils\MultipleArrayIterator
WebDAV: SilverStripe\FullTextSearch\Utils\WebDAV
Solr_BuildTask: SilverStripe\FullTextSearch\Tasks\Solr_BuildTask
Solr_Configure: SilverStripe\FullTextSearch\Tasks\Solr_Configure
Solr_Reindex: SilverStripe\FullTextSearch\Tasks\Solr_Reindex

View File

@ -4,18 +4,32 @@
[![Silverstripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
Adds support for fulltext search engines like Sphinx and Solr to Silverstripe CMS.
Compatible with PHP 7.2
## Installation
## Important notes when upgrading to fulltextsearch 3.7.0+
There are some significant changes from previous versions:
Draft content will no longer be automatically added to the search index. This new behaviour was previously an
opt-in behaviour that was enabled by adding the following line to a search index:
```sh
composer require silverstripe/fulltextsearch
```
$this->excludeVariantState([SearchVariantVersioned::class => Versioned::DRAFT]);
```
A new `canView()` check against an anonymous user (i.e. someone not logged in) and a `ShowInSearch` check is now
performed by default against all records (DataObjects) before being added to the search index, and also before being
shown in search results. This may mean that some records that were previously being indexed and shown in search results
will no longer appear due to these additional checks.
These additional checks have been added with data security in mind, and it's assumed that records failing these
checks probably should not be indexed in the first place.
# Enable indexing of draft content:
You can index draft content with the following yml configuration:
```yaml
```
SilverStripe\FullTextSearch\Search\Services\SearchableService:
variant_state_draft_excluded: false
```
@ -35,7 +49,7 @@ also disable the check for descendants of the specified DataObjects. Ensure that
is correctly performing a `canView()` check at query time before disabling the pre-index check, as this may result in
leakage of private data.
```yaml
```
SilverStripe\FullTextSearch\Search\Services\SearchableService:
indexing_canview_exclude_classes:
- Some\Org\MyDataObject
@ -44,7 +58,7 @@ SilverStripe\FullTextSearch\Search\Services\SearchableService:
```
You can also use the `updateIsSearchable` extension point on `SearchableService` to modify the result of the method
after the `ShowInSearch` and `canView()` checks have run.
after the `ShowInSearch` and `canView()` checks have run.
It is highly recommend you run a [solr_reindex](https://github.com/silverstripe/silverstripe-fulltextsearch/blob/3/docs/en/03_configuration.md#solr-reindex)
on your production site after upgrading from 3.6 or earlier to purge any old data that should no longer be in the search index.
@ -68,6 +82,12 @@ cached in memory so there is virtually no performance penalty calling it a secon
- If your implementation is very custom and does not subclass nor make use of either `SolrIndex` or `SearchForm`, then
it's recommended you update your implementation to call `SearchableService::isViewable()`.
## Requirements
* Silverstripe 4.0+
**Note:** For Silverstripe 3.x, please use the [2.x release line](https://github.com/silverstripe/silverstripe-fulltextsearch/tree/2).
## Documentation
For pure Solr docs, check out [the Solr 4.10.4 guide](https://archive.apache.org/dist/lucene/solr/ref-guide/apache-solr-ref-guide-4.10.pdf).

View File

@ -21,19 +21,19 @@
}
],
"require": {
"php": "^8.1",
"silverstripe/framework": "^5",
"monolog/monolog": "^3.2",
"silverstripe/solr-php-client": "^1",
"symfony/process": "^6.2",
"silverstripe/silverstripe-proxy-db": "^2",
"php": "^7.4 || ^8.0",
"silverstripe/framework": "^4.10",
"monolog/monolog": "~1.15",
"silverstripe/solr-php-client": "^1.0",
"symfony/process": "^3.4 || ^4",
"tractorcow/silverstripe-proxy-db": "^1",
"ext-curl": "*"
},
"require-dev": {
"silverstripe/cms": "^5",
"silverstripe/cms": "^4.0",
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "^3",
"symbiote/silverstripe-queuedjobs": "^5"
"squizlabs/php_codesniffer": "^3.0",
"symbiote/silverstripe-queuedjobs": "^4.9"
},
"autoload": {
"psr-4": {

View File

@ -3,12 +3,12 @@ fi:
GO: Hae
SEARCH: Haku
SolrResultsPage:
SearchQuery: 'Hakusanasi oli'
DidYouMean: Tarkoititko
ReadMore: 'Lue lisää'
NoResults: 'Pahoittelut, mutta hakusi ei tuottanut yhtään osumaa.'
Page: Sivu
of: /
ViewPreviousPage: 'Katso edellinen sivu'
ReadMore: 'Lue lisää'
SearchQuery: 'Hakusanasi oli'
'View page number': 'Siirry sivulle'
ViewNextPage: 'Katso seuraava sivu'
ViewPreviousPage: 'Katso edellinen sivu'
of: /

View File

@ -0,0 +1,29 @@
<?php
namespace SilverStripe\FullTextSearch\Search\Captures;
use SilverStripe\Dev\Deprecation;
use SilverStripe\ORM\Connect\MySQLDatabase;
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
/**
* @deprecated 3.1.0 Use tractorcow/silverstripe-proxy-db to proxy the database connector instead
*/
class SearchManipulateCapture_MySQLDatabase extends MySQLDatabase
{
public $isManipulationCapture = true;
public function __construct()
{
Deprecation::notice('3.1.0', 'Use tractorcow/silverstripe-proxy-db to proxy the database connector instead', Deprecation::SCOPE_CLASS);
}
public function manipulate($manipulation)
{
$res = parent::manipulate($manipulation);
SearchUpdater::handle_manipulation($manipulation);
return $res;
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace SilverStripe\FullTextSearch\Search\Captures;
use SilverStripe\Dev\Deprecation;
use SilverStripe\PostgreSQL\PostgreSQLDatabase;
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
if (!class_exists(PostgreSQLDatabase::class)) {
return;
}
/**
* @deprecated 3.1.0 Use tractorcow/silverstripe-proxy-db to proxy the database connector instead
*/
class SearchManipulateCapture_PostgreSQLDatabase extends PostgreSQLDatabase
{
public $isManipulationCapture = true;
public function __construct()
{
Deprecation::notice('3.1.0', 'Use tractorcow/silverstripe-proxy-db to proxy the database connector instead', Deprecation::SCOPE_CLASS);
}
public function manipulate($manipulation)
{
$res = parent::manipulate($manipulation);
SearchUpdater::handle_manipulation($manipulation);
return $res;
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace SilverStripe\FullTextSearch\Search\Captures;
use SilverStripe\Dev\Deprecation;
use SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater;
use SilverStripe\SQLite\SQLite3Database;
if (!class_exists(SQLite3Database::class)) {
return;
}
/**
* @deprecated 3.1.0 Use tractorcow/silverstripe-proxy-db to proxy the database connector instead
*/
class SearchManipulateCapture_SQLite3Database extends SQLite3Database
{
public $isManipulationCapture = true;
public function __construct()
{
Deprecation::notice('3.1.0', 'Use tractorcow/silverstripe-proxy-db to proxy the database connector instead', Deprecation::SCOPE_CLASS);
}
public function manipulate($manipulation)
{
$res = parent::manipulate($manipulation);
SearchUpdater::handle_manipulation($manipulation);
return $res;
}
}

View File

@ -2,6 +2,7 @@
namespace SilverStripe\FullTextSearch\Search\Queries;
use SilverStripe\Dev\Deprecation;
use SilverStripe\FullTextSearch\Search\Adapters\SearchAdapterInterface;
use SilverStripe\FullTextSearch\Search\Criteria\SearchCriteria;
use SilverStripe\FullTextSearch\Search\Criteria\SearchCriteriaInterface;
@ -281,6 +282,86 @@ class SearchQuery extends ViewableData
return "Search Query\n";
}
/**
* @codeCoverageIgnore
* @deprecated 4.0.0 Use addSearchTerm() instead
*/
public function search($text, $fields = null, $boost = [])
{
Deprecation::notice('4.0.0', 'Use addSearchTerm() instead');
return $this->addSearchTerm($text, $fields, $boost);
}
/**
* @codeCoverageIgnore
* @deprecated 4.0.0 Use addFuzzySearchTerm() instead
*/
public function fuzzysearch($text, $fields = null, $boost = [])
{
Deprecation::notice('4.0.0', 'Use addFuzzySearchTerm() instead');
return $this->addFuzzySearchTerm($text, $fields, $boost);
}
/**
* @codeCoverageIgnore
* @deprecated 4.0.0 Use addClassFilter() instead
*/
public function inClass($class, $includeSubclasses = true)
{
Deprecation::notice('4.0.0', 'Use addClassFilter() instead');
return $this->addClassFilter($class, $includeSubclasses);
}
/**
* @codeCoverageIgnore
* @deprecated 4.0.0 Use addFilter() instead
*/
public function filter($field, $values)
{
Deprecation::notice('4.0.0', 'Use addFilter() instead');
return $this->addFilter($field, $values);
}
/**
* @codeCoverageIgnore
* @deprecated 4.0.0 Use addExclude() instead
*/
public function exclude($field, $values)
{
Deprecation::notice('4.0.0', 'Use addExclude() instead');
return $this->addExclude($field, $values);
}
/**
* @codeCoverageIgnore
* @deprecated 4.0.0 Use setStart() instead
*/
public function start($start)
{
Deprecation::notice('4.0.0', 'Use setStart() instead');
return $this->setStart($start);
}
/**
* @codeCoverageIgnore
* @deprecated 4.0.0 Use setLimit() instead
*/
public function limit($limit)
{
Deprecation::notice('4.0.0', 'Use setLimit() instead');
return $this->setLimit($limit);
}
/**
* @codeCoverageIgnore
* @deprecated 4.0.0 Use setPageSize() instead
*/
public function page($page)
{
Deprecation::notice('4.0.0', 'Use setPageSize() instead');
return $this->setPageSize($page);
}
/**
* @return SearchCriteriaInterface[]
*/

View File

@ -3,6 +3,7 @@
namespace SilverStripe\FullTextSearch\Search\Queries;
use SilverStripe\Core\Injector\Injectable;
use SilverStripe\Dev\Deprecation;
/**
* Create one of these and pass as one of the values in filter or exclude to filter or exclude by a (possibly
@ -37,4 +38,24 @@ class SearchQuery_Range
{
return $this->start !== null || $this->end !== null;
}
/**
* @deprecated 4.0.0 Use setStart() instead
* @codeCoverageIgnore
*/
public function start($start)
{
Deprecation::notice('4.0.0', 'Use setStart() instead');
return $this->setStart($start);
}
/**
* @deprecated 4.0.0 Use setEnd() instead
* @codeCoverageIgnore
*/
public function end($end)
{
Deprecation::notice('4.0.0', 'Use setEnd() instead');
return $this->setEnd($end);
}
}

View File

@ -2,7 +2,6 @@
namespace SilverStripe\FullTextSearch\Search\Variants;
use InvalidArgumentException;
use SilverStripe\Assets\File;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\FullTextSearch\Search\Indexes\SearchIndex;
@ -49,7 +48,7 @@ class SearchVariantSubsites extends SearchVariant
public function currentState()
{
return SubsiteState::singleton()->getSubsiteId();
return (string) SubsiteState::singleton()->getSubsiteId();
}
public function reindexStates()
@ -72,12 +71,6 @@ class SearchVariantSubsites extends SearchVariant
return;
}
if (is_numeric($state)) {
$state = (int) $state;
} elseif ($state !== null) {
throw new InvalidArgumentException("Invalid state ID. State ID should be number or null.");
}
// Note: Setting directly to the SubsiteState because we don't want the subsite ID to be persisted
// like Subsite::changeSubsite would do.
SubsiteState::singleton()->setSubsiteId($state);

View File

@ -104,6 +104,7 @@ class SolrReindexImmediateHandler extends SolrReindexBase
// Set timeout from config. Process default is 60 seconds
$process->setTimeout($this->config()->get('process_timeout'));
$process->inheritEnvironmentVariables();
$process->run();
$res = $process->getOutput();

View File

@ -32,26 +32,29 @@ class CombinationsArrayIterator implements Iterator
$this->rewind();
}
public function rewind(): void
#[\ReturnTypeWillChange]
public function rewind()
{
if (!$this->numArrays) {
$this->isValid = false;
} else {
$this->isValid = true;
$this->k = 0;
for ($i = 0; $i < $this->numArrays; $i++) {
reset($this->arrays[$i]);
}
}
}
public function valid(): bool
#[\ReturnTypeWillChange]
public function valid()
{
return $this->isValid;
}
public function next(): void
#[\ReturnTypeWillChange]
public function next()
{
$this->k++;
@ -68,7 +71,8 @@ class CombinationsArrayIterator implements Iterator
}
}
public function current(): mixed
#[\ReturnTypeWillChange]
public function current()
{
$res = array();
for ($i = 0; $i < $this->numArrays; $i++) {
@ -77,7 +81,8 @@ class CombinationsArrayIterator implements Iterator
return $res;
}
public function key(): mixed
#[\ReturnTypeWillChange]
public function key()
{
return $this->k;
}

View File

@ -3,7 +3,6 @@
namespace SilverStripe\FullTextSearch\Utils\Logging;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\LogRecord;
use Monolog\Logger;
use Symbiote\QueuedJobs\Services\QueuedJob;
@ -54,7 +53,7 @@ class QueuedJobLogHandler extends AbstractProcessingHandler
return $this->queuedJob;
}
protected function write(LogRecord $record): void
protected function write(array $record)
{
// Write formatted message
$this->getQueuedJob()->addMessage($record['formatted']);

View File

@ -22,7 +22,8 @@ class MultipleArrayIterator implements Iterator
$this->rewind();
}
public function rewind(): void
#[\ReturnTypeWillChange]
public function rewind()
{
$this->active = $this->arrays;
if ($this->active) {
@ -30,17 +31,20 @@ class MultipleArrayIterator implements Iterator
}
}
public function current(): mixed
#[\ReturnTypeWillChange]
public function current()
{
return $this->active ? current($this->active[0]) : false;
}
public function key(): mixed
#[\ReturnTypeWillChange]
public function key()
{
return $this->active ? key($this->active[0]) : false;
}
public function next(): void
#[\ReturnTypeWillChange]
public function next()
{
if (!$this->active) {
return;
@ -54,7 +58,8 @@ class MultipleArrayIterator implements Iterator
}
}
public function valid(): bool
#[\ReturnTypeWillChange]
public function valid()
{
return $this->active && (current($this->active[0] ?? []) !== false);
}

View File

@ -3,7 +3,6 @@
namespace SilverStripe\FullTextSearch\Tests\SolrReindexTest;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\LogRecord;
use SilverStripe\Dev\TestOnly;
/**
@ -33,7 +32,7 @@ class SolrReindexTest_Handler extends AbstractProcessingHandler implements TestO
$this->messages = array();
}
protected function write(LogRecord $record): void
protected function write(array $record)
{
$this->messages[] = $record['message'];
}