Silverstripe-fulltextsearch - Adds external full text search engine support to SilverStripe

Overview

FullTextSearch module

Build Status Scrutinizer Code Quality codecov SilverStripe supported module

Adds support for fulltext search engines like Sphinx and Solr to SilverStripe CMS. Compatible with PHP 7.2

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:

$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:

SilverStripe\FullTextSearch\Search\Services\SearchableService:
  variant_state_draft_excluded: false

However, when set to false, it will still only index draft content when a DataObject is in a published state, not a draft-only or modified state. This is because it will still fail the new anonymous user canView() check in SearchableService::isSearchable() and be automatically deleted from the index.

If you wish to also index draft content when a DataObject is in a draft-only or a modified state, then you'll need to also configure SearchableService::indexing_canview_exclude_classes. See below for instructions on how to do this.

Disabling the anonymous user canView() pre-index check

You can apply configuration to remove the new pre-index canView() check from your DataObjects if it is not necessary, or if it impedes expected functionality (e.g. for sites where users must authenticate to view any content). This will also disable the check for descendants of the specified DataObjects. Ensure that your implementation of fulltextsearch is correctly performing a canView() check at query time before disabling the pre-index check, as this may result in leakage of private data.

SilverStripe\FullTextSearch\Search\Services\SearchableService:
  indexing_canview_exclude_classes:
    - Some\Org\MyDataObject
    # This will disable the check for all pagetypes:
    - SilverStripe\CMS\Model\SiteTree

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.

It is highly recommend you run a 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.

These additional check can have an impact on the reindex performance due to additional queries for permission checks. If your site also indexes content in files, such as pdf's or docx's, using the text-extraction module which is fairly time-intensive, then the relative performance impact of the canView() checks won't be as noticeable.

Details on filtering before adding content to the solr index

  • SearchableService::isIndexable() check in SolrReindexBase. Used when indexing all records during Solr reindex.
  • SearchableService::isIndexable() check in SearchUpdateProcessor. Used when indexing single records during DataObject->write().

Details on filtering when extracting results from the solr index

  • SearchableService::isViewable() check in SolrIndex. This will often be used in CWP implementations that use the CwpSearchEngine class, as well as most custom implementations that call MySearchIndex->search()
  • SearchableService::isViewable() check in SearchForm. This will be used in solr implementations where a /SearchForm url is used to display search results.
  • Some implementations will call SearchableService::isViewable() twice. If this happens then the first call will be cached in memory so there is virtually no performance penalty calling it a second time.
  • 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.

Documentation

For pure Solr docs, check out the Solr 4.10.4 guide.

See the docs for configuration and setup, or for the quick version see the quick start guide.

For details of updates, bugfixes, and features, please see the changelog.

TODO

  • Get rid of includeSubclasses - isn't actually used in practice, makes the codebase uglier, and ClassHierarchy can be used at query time for most of the same use cases

  • Fix field referencing in queries. Should be able to do $query->search('Text', 'Content'), not $query->search('Text', SiteTree::class . '_Content') like you have to do now

    • Make sure that when field exists in multiple classes, searching against bare fields searches all of them

    • Allow searching against specific instances too

  • Make fields restrictable by class in an index - 'SiteTree#Content' to limit fields to a particular class, maybe 'Content->Summary' to allow calling a specific method on the field object to get the text

  • Allow following user relationships (Children.Foo for example)

  • Be clearer about what happens with relationships to stateful objects (e.g. Parent.Foo where Parent is versioned)

  • Improvements to SearchUpdater

    • Make it work properly when in-between objects (the A in A.B.Foo) update

    • Allow user logic to cause triggering reindex of documents when field is user generated

  • Add generic APIs for spell correction, file text extraction and snippet generation

Comments
  • Enable support for Solr5

    Enable support for Solr5

    I've been working on a 3.6 site that needs support for Solr 5. Therefore, I've branched off the 2.4.0 tag and added support for it. The changes are almost entirely in the solrconfig.xml and types.ss file and were created from a copy of the templates/4 folder. This work carried on from some work undertaken by @zarocknz and @firesphere helped with some implementation details.

    List of changes:

    • solrconfig.xml: luceneMatchVersion 6.0
    • solrconfig.xml: JsonUpdateRequestHandler -> UpdateRequestHandler
    • solrconfig.xml: CsvUpdateRequestHandler -> UpdateRequestHandler
    • solrconfig.xml: remove node containing requestHandler name="/admin"
    • types.ss: remove all instances of enablePositionIncrements="true"
    • Solr.php: enable checks for version 5
    • Solr5Service: extended classes from Solr4Service

    I've kept the "default" version of the module at 4 to avoid making this a breaking change, but if a user wants to use 5, they'll need to specify that in their config (example provided in docs)

    I'll raise a separate pull request to enable SS4 support when I get the time to do so.

    opened by elliot-sawyer 22
  • Don't index records with ShowInSearch=false

    Don't index records with ShowInSearch=false

    The module makes no assumption about what criteria might be applied for records to be added to the index. I'm proposing elsewhere that we filter out records with anonymous canView=false.

    In addition, I think we should add behavior to prevent indexing of a record based on custom, model specific flags like ShowInSearch. Currently, the docs mention this usage pattern (e.g. https://www.cwp.govt.nz/developer-docs/en/2/features/solr_search/default_search_index/), and recommend adding this as a filter field. You're still in charge of filtering on that field by default. The CWPSearchEngine performs this filter out of the box, but only on SiteTree and File (see pull request). If you're defining your own index on other objects, or include other objects in that index, you need to create your own search engine - the filter field is indexed, but it's ignored during searches. The docs for searching dataobjects fail to mention that as well. This illustrates why we shouldn't have those records in the index in the first place.

    This has some of the same rollout issues as filter out records with anonymous canView=false, we'd need to advise devs on how to get those existing index entries with ShowInSearch=false out of their index.

    When releasing this, we should strongly recommend to search users that they run a reindex to prune any records with ShowInSearch=0 in their current search state.

    Another thing to check: when we change ShowInSearch from 1 to 0 and click save/publish, does it get removed from the index straight away?

    ACs

    • [x] Records which have a ShowInSearch method or database property returning false are not indexed
    • [x] This applies to built-in records (Page, File) as well as custom record definitions
    • [x] This behaviour applies to both CWP and core module search
    • [x] The ShowInSearch value is inspected every time a record is saved (non-versioned) or published (versioned), and the index entry is updated accordingly
    • [x] Existing index entries with ShowInSearch=0 can be pruned through a reindex
    • [x] There is documentation both for CWP and generic module upgrade paths
    • [x] Documentation is adjusted to state that you MUST filter out ShowInSearch during search request for safety (rather than reindexing) Steve: users don't need to filter out during search, happens automatically
    • [x] Funtionality for filtering ShowInSearch during search requests is retained in order to minimise risk, but marked as deprecated and non-functional - Steve: have instead deleted functionality from cwp-search module

    Note:

    We still have to index the ShowInSearch property, otherwise search request filtering on existing implementations will fail

    PRs:

    https://github.com/silverstripe/silverstripe-fulltextsearch/pull/275 https://github.com/silverstripe/cwp/pull/260 https://github.com/silverstripe/cwp-search/pull/31

    Subtasks

    • [x] Work out central place to add $this->addFilterField('ShowInSearch') so that it's available in core
    • [x] Investigate where solr index is being updated so that we can also delete from there
    • [x] Test also works for getShowInSearch() (it does, comments below)
    • [x] Investigate filtering solr outlet on DataObject.ShowInSearch (for sites that have not reindexed)
    • [x] Determine if $obj->getShowInSearch() is relevant for outlet filtering (it is)
    • [x] (Ingo) Investigate what it would take to index a field across models with the same name, so ShowInSearch rather than MyModel_ShowInSearch - Steve: there's no need for this as we'll be filtering all these results out before they get in the index anyway
    • [x] (Ingo) add a warning label about creating non-deterministic getShowInSearch() implementations
    • [x] Ensure inlet filtering applied to both cms save (dirty items) as well as solr_reindex
    • [x] Ensure variantStateExcluded (draft?) functionality still works for all cases above
    • [x] Get agreement with Cheddam about a combined approach with the canView() checks
    • [x] Test with frameworktest records to ensure that reindex still functions OK
    • [x] Update documentation
    • [x] Write unit tests for 2x inlet filtering, determined to be not feasible for outlet filtering
    • [x] Write release comms saying run solr_reindex, possibly commit straight to changelog
    • [x] Investigate deleting $this->addFilterField('ShowInSearch') and related code used in outlet filtering - possibly a separate optional PR

    Links

    https://silverstripeltd.slack.com/archives/CLXKD9X51/p1584670614347800

    affects/v4 complexity/medium impact/high type/bug 
    opened by chillu 17
  • Solr searching fails when not searching Versioned content

    Solr searching fails when not searching Versioned content

    If you create a sub-class of SolrIndex to define indexes on DataObjects that don't use the Versioned extension, the index will be built and loaded into Solr, but no searches performed against that index will work.

    For example:

    // Story.php
    class Story extends DataObject {
        private static $db = array(
            'Title' => 'Varchar(255)'
        );
    }
    
    // StorySolrIndex.php
    class StorySolrIndex extends SolrIndex {
        public function init() {
            $this->addClass('Story');
            $this->addFulltextField('Title');
        }
    }
    

    Running Solr_Configure and Solr_Reindex will work fine (Solr_Reindex will say class Story, total: 5 in state [])

    However, creating an instance of that SolrIndex and running a query against it will fail:

    $index = new StorySolrIndex();
    $query = new SearchQuery();
    $query->search('Test', null, array(
        'Story_Title' => 2
    ));
    
    $results = $index->search($query);
    

    Nothing will be returned, but Solr will log an Exception with the message: SEVERE: org.apache.solr.common.SolrException: undefined field _versionedstage

    If you add something to the StorySolrIndex that is versioned (e.g. SiteTree), then the search will work as usual, but with extra stuff in the index.

    // StorySolrIndex.php
    class StorySolrIndex extends SolrIndex {
        public function init() {
            $this->addClass('Story');
            $this->addClass('SiteTree'); // This works around the bug
            $this->addFulltextField('Title');
        }
    }
    
    affects/v4 complexity/high impact/high type/bug 
    opened by madmatt 16
  • Don't index records where canView=false for anonymous users

    Don't index records where canView=false for anonymous users

    The module denies access to a search result if you can’t view the underlying record: https://github.com/silverstripe/silverstripe-fulltextsearch/blob/f89818909a0d0c08f7d8f05217eb62e32988aa20/src/Solr/Forms/SearchForm.php#L89. It does however index all records, incl. ones with canView=false. The canView check is implemented in SearchForm->getResults(), which is a commonly subclassed method - so still a residual risk that devs will skip that check.

    I think we should default to not indexing records where canView() returns false for anonymous users. You could overwrite this behaviour, e.g. to include silverstripe/secureassets in 3.x, or protected/private files in 4.x. But that would be a conscious decision, with the module staying secure by default.

    We'd need to do this in a backwards compatible way (not breaking existing searches which rely on the absence of these checks). Although you could argue that those implementations rely on a bug?

    When releasing this, we should strongly recommend to search users that they run a reindex to prune any records with canView=false in their current search state.

    ACs

    • [x] Records returning canView() as false for anonymous users are not indexed by default
    • [x] This behaviour applies to draft pages and other versioned records in draft stage
    • [x] This behaviour applies to draft files, as well as protected files
    • [x] A reindex prunes out any records where canView() returns false that would've been previously indexed
    • [x] When a new record is saved (unversioned) or published (versioned) in a way that changes anonymous canView() permissions, that's reflected by adding to or removing from the index
      • [x] This does not cover traversing child objects and reindexing them
    • [x] The "exclude variant" functionality is retained, but is a no-op for versioned draft stages now due to the existing canView checks
    • [x] This functionality works consistently between the core module and any CWP customisations
    • [x] Developers can opt in to their own canView handling on a per-classtree basis, with a big warning label about implications and clear documentation that minimises room for error
    • [x] There is documentation both for CWP and generic module upgrade paths
      • [x] These docs note that this implementation has edgecases and cannot be relied upon solely
    • [ ] Performance is measured against a large dataset on real-world environments (10,000 records, CWP + SC) - Steve: do we still want this? Based on https://github.com/silverstripe/silverstripe-fulltextsearch/pull/276 we can roughly expect solr_reindex to double on basic pages, though basic pages index very fast. What really messes up reindex times is tika text-extraction on pdf's/docx's which will barely be impacted by an extra canView() check.

    Removed ACs

    • [x] InheritedPermissions is leveraged to reduce performance impact - Steve: found that this would have lead to potential security issues
    • [x] Any documentation advising to exclude draft variants is removed - Steve: retaining this, as you may still wish to exclude draft variant if you skip the canView() check

    Subtasks

    • [x] Introduce canView condition in appropriate places
    • [x] Add configuration to allow disabling condition
    • [x] Test create, edit, protect, delete operations to ensure the correct behaviour is observed
    • [x] Document the change in behaviour, and how to disable it

    PRs

    • [ ] #281
    • [ ] https://github.com/silverstripe/cwp/pull/266
    affects/v4 complexity/low impact/high type/bug 
    opened by chillu 15
  • API QueuedJob support for Solr_Reindex

    API QueuedJob support for Solr_Reindex

    This also has incremental deletion of records; Rather than deleting all records in solr up front, it'll simply delete all records that it KNOWS won't exist up front, and then deletes all other records incrementally in batches.

    Each batch is derived using the formula ID % total_groups = this_group. This means that batches don't need to store a list of IDs for each record, and copes with cases where ids may not be contiguous, as well as deleted IDs that may not have a local record anymore.

    Re-index is broken into a base implementation, with separate subclasses for each implementation (including immediate reindex for local, message queue and queuedjobs).

    Solr_Reindex, two queued jobs, a new logging API, and several tests have been added.

    Part of the logic for generating SOLR query syntax has been moved out of SolrIndex and into SearchQuery. This is so that SearchQuery may be used to generate syntax for deletion of records, which is necessary for the incremental deletion feature.

    opened by tractorcow 14
  • SearchableService canView()

    SearchableService canView()

    Issue: https://github.com/silverstripe/silverstripe-fulltextsearch/issues/252

    Adds a canView() check on everything going in to a solr index and on most implementations will also check it on the way out too

    This is PR no.2 for this issue, PR no.1 (merged) added a ShowInSearch check https://github.com/silverstripe/silverstripe-fulltextsearch/pull/275

    This PR in a continuation of the work previously done in this PR https://github.com/silverstripe/silverstripe-fulltextsearch/pull/276

    opened by emteknetnz 13
  • singleton($step['class'])->extend('augmentSQL', $sql); in SearchIndex::getDirtyIDs() causes throwing Fatal Errors

    singleton($step['class'])->extend('augmentSQL', $sql); in SearchIndex::getDirtyIDs() causes throwing Fatal Errors

    singleton($step['class'])->extend('augmentSQL', $sql); in SearchIndex::getDirtyIDs() function breaks some DataExtension objects when calling to their function augmentSQL(), eg. Translatable, or SiteTreeSubsites, since Translatable::augumentSQL(SQLQuery &$query, DataQuery &$dataQuery = null) is expecting the second parameter is a DataQuery object and directly uses it to call its function getQueryParam() in its implementation without checking if $dataQuery is a non-object or not

    So this issue could be either fixed in Translatable class or SearchIndex class. Giving that if we fix here in SearchIndex, non of those DataExtension classes need to do anything, I hope it could fixed here.

    affects/v4 impact/high type/bug 
    opened by normann 13
  • Solr Synonyms Don't Work

    Solr Synonyms Don't Work

    Scenario I create three different pages. On each of them I have put one of: gdp, jel, knp (unique words so I know these aren't anywhere else on the site) I run a Solr_Reindex I search for "gdp" and just that one page is returned in the results. Searching any of the unique words returns the correct result.

    Now, I'd like to make these words synonyms. I go into the Fulltext Search tab in Settings of the CMS (which uses CWP's SynonymsSiteConfig) This config modifies the synonyms.txt file. I enter gdp, jel, knpas my Solr Synonyms. I run a Solr_Configure.

    Result Now when I search any of the unique words, I get no results. I do a Reindex just to see if that has an effect. Still no results.

    Expected Result What I would expect, is that if I searched for any of those words that all 3 pages would be returned.

    Am I misunderstanding the concept of Solr Synonyms? Or do they not function correctly in the module? An issue with version of Solr used in fulltextsearch-local? Or something else?

    Just thought I would get the convo started and see if anyone else is having this issue. 😄

    type/bug 
    opened by PsukheDelos 12
  • Add nested filtering via Criteria and Criterion objects.

    Add nested filtering via Criteria and Criterion objects.

    Purpose

    Currently in fulltextsearch we can filter and we can exclude, but both of these are "single level", in that you cannot group filters with combinations of AND and OR statements.

    In order to allow for more complex filtering, I have implemented criterion objects. These objects can be joined and grouped in any number of ways - allowing you to achieve any kind of nested filter that you might want.

    New objects

    • SearchCriteriaInterface: Interface for SearchCriterion and SearchCriteria classes.
    • SearchCriterion: An object containing a single field filter (target field, comparison value, comparison type).
    • SearchCriteria: An object containing a collection of SearchCriterion and/or SearchCriteria with conjunctions (IE: AND, OR) between each.
    • SearchQueryWriter: A class used to generate a query string based on a SearchCriterion.
    • SearchAdapterInterface: An Interface for our Search. This adapter will control what SearchQueryWriter is used for each SearchCriteria.

    General usage

    We need 3 things to create a SearchCriterion:

    • Target: EG the field in our Search Index that we want to filter against.
    • Value: The value we want to use for comparison.
    • Comparison: The type of comparison (EG: EQUAL, IN, etc).

    All currently supported comparisons can be found as constants in SearchCriterion.

    Creating a new SearchCriterion

    Method 1a and 1b

    // `EQUAL` is the default comparison for `SearchCriterion`, so no third param is required.
    $criterion = new SearchCriterion('Product_Title', 'My Product');
    
    // Or use the `create` static method.
    $criterion = SearchCriterion::create('Product_Title', 'My Product');
    

    Creating a new SearchCriteria

    SearchCriteria has a property called $clauses which is a collection of SearchCriterion (above) and/or SearchCriteria (allowing for infinite nesting of clauses), along with the conjunction used between each clause (IE: AND, OR). We want to build up our SearchCriteria by adding to it's $clauses collection.

    SearchCriteria can either be passed an object that implements SearchCriteriaInterface, or it can be passed the Target, Value, and Comparison (like above).

    Method 1

    Instantiate a new SearchCriteria by providing an already instantiated SearchCriterion object. This $criterion will be added as the first item in the $clauses collection.

    $criteria = SearchCriteria::create($criterion);
    

    Method 2

    Instantiate a new SearchCriteria objects and define the Target, Value, and Comparison. SearchCriteria will create a new SearchCriterion object based on the values, and add it to the $clauses collection.

    $criteria = SearchCriteria::create('Product_CatID', array(21, 24, 25), SearchCriterion::IN);
    

    Adding additional SearchCriterion to our SearchCriteria

    When you want to add more complexity to your SearchCriteria, there are two methods available:

    • addAnd: Add a new SearchCriterion or SearchCriteria with an AND conjunction.
    • addOr: Add a new SearchCriterion or SearchCriteria with an OR conjunction.

    Method 1

    Use method chaining to create a SearchCriterion with two clauses.

    // Filter by products with stock that are in either of these 3 categories.
    $criteria = SearchCriteria::create('Product_CatID', array(21, 24, 25), SearchCriterion::IN)
        ->addAnd('Product_Stock', 0, SearchCriterion::GREATER_THAN);
    

    Method 2

    Systematically add clauses to your already instantiated SearchCriteria.

    // Filter by products in either of these 3 categories.
    $criteria = SearchCriteria::create('Product_CatID', array(21, 24, 25), SearchCriterion::IN);
    
    ... other stuff
    
    // Filter by products with stock.
    $criteria->addAnd('Product_StockLevel', 0, SearchCriterion::GREATER_THAN);
    

    Adding multiple levels of filtering to our SearchCriteria

    SearchCriteria also allows you to pass in other SearchCriteria objects as you instantiate it and as you use the addAnd and addOr methods.

    // Filter by products that are in either of these 3 categories with stock.
    $stockCategoryCriteria = SearchCriteria::create('Product_CatID', array(21, 24, 25), SearchCriterion::IN)
        ->addAnd('Product_Stock', 0, SearchCriterion::GREATER_THAN);
    
    // Filter by products in Category ID  1 with stock over 5.
    $legoCriteria = SearchCriteria::create('Product_CatID', 1, SearchCriterion::EQUAL)
        ->addAnd('Product_Stock', 5, SearchCriterion::GREATER_THAN);
    
    // Combine the two criteria with an `OR` conjunction
    $criteria = SearchCriteria::create($stockCategoryCriteria)
        ->addOr($legoCriteria);
    

    The end result is that you get any products that are in categories 21, 24, 25 that have stock, and any products in category 1 with more than 5 in stock.

    Adding SearchCriteria to our SearchQuery

    Our SearchQuery class now has a property called $criteria which holds all of our SearchCriteria. You can add new SearchCriteria by using SearchQuery::filterBy().

    Method 1

    Pass in an already instantiated SearchCriteria object. If you implemented complex filtering (above), you will probably need to follow this method - fully creating your SearchCriteria first, and then passing it to the SearchQuery.

    $query->filterBy($criteria);
    

    Method 2a

    Where basic (single level) filtering is ok, the SearchQuery::filterBy() method can be used to create your SearchCriterion and SearchCriteria object.

    $query->filterBy('Product_CatID', array(21, 24, 25), SearchCriterion::IN);
    

    Method 2b

    The filterBy() method will return the current SearchCriteria, this allows you to method chain the addAnd and addOr methods.

    // Filter by products with stock that are in either of these 3 categories.
    $searchQuery->filterBy('Product_CategoryID', array(21, 24, 25), SearchCriterion::IN)
                ->addAnd('Product_StockLevel', 0, SearchCriterion::GREATER_THAN);
    

    Each item in the $criteria collection are treated with an AND conjunction (matching current filter/exclude functionality).

    Search Query Writers

    Provided are 3 different SearchQueryWriters for Solr:

    • SolrSearchQueryWriter_Basic
    • SolrSearchQueryWriter_In
    • SolrSearchQueryWriter_Range

    When these Writers are provided a SearchCriterion, they will generate the desired query string.

    Search Adapters

    Search Adapters need to provide the following information:

    • What is the search engine's conjunction strings? (EG: are they "AND" and "OR", or are they "&&" and "||", etc).
    • What is the desired comparison container string? (EG: "+( query here )") for Solr).
    • Most importantly - how to generate the query string from a SearchCriterion.

    The SolrSearchAdapter uses SearchQueryWriters (above) to generate query strings from a SearchCriterion.

    I realise that having SearchQueryWriters is an additional step, and that usually the Adapter would do the generating (all by itself), but I really wanted to give devs a way to bypass the default "writing" behaviour if they needed to.

    Customising your SearchCriterion/SearchQueryWriter

    If you find that you do not want your SearchCriterion being parsed by one of the default SearchQueryWriters (for whatever reason), you can optionally pass your own SearchQueryWriter to your SearchCriterion either as the fourth parameter when instantiating it, or by calling setSearchQueryWriter().

    If this value is set, then the (default Solr) Adapter will always use the provided SearchQueryWriter, rather than deciding for itself.

    This should allow you to have full control over how your query strings are being generated if the default SearchQueryWriters are not cutting it for you.

    affects/v4 
    opened by chrispenny 12
  • many_many filters no longer work on 3.0

    many_many filters no longer work on 3.0

    I'm trying to index a many_many field so that I can filter on it. This used to work in 2.3.5 (or thereabouts) but no longer works in 3.0

    public function init() {
       $this->addClass(MyPage::class);
    ...
       $this->addFilterField('Categories.ID', 'Int');
    ...
    }
    
    ...
        private static $many_many = [
          'Categories' => TaxonomyTerm::class,
       ]
    ...
    

    The schema gets generated correctly: <field name='MyPage_Categories_ID' type='tint' indexed='true' stored='true' multiValued='true'/> but the data never appears on the record in Solr. This means it's impossible to filter on it at query time.

    One of my colleagues has experienced a similar problem, and found that one resolution is to rollback to 2.3.5. Unfortunately, my project is on SS4 and I don't have this option.

    affects/v4 complexity/medium impact/high type/bug 
    opened by silverstripe-elliot 11
  • Allowing Symfony 3.2 or 4 can break reindexing

    Allowing Symfony 3.2 or 4 can break reindexing

    In the following commit https://github.com/silverstripe/silverstripe-fulltextsearch/commit/34e0594e48f8f5c140e3b41544d39c8f88184114 we allow Symfony 3.2 or 4 however the Process class constructor in these 2 versions works differently.

    In Symfony Process 3.2 the constructor accepts a string for the commandline parameter, in Symfony Process 4 the constructor requries an array for the commandline parameter.

    SolrReindexImmediateHandler.php sends the command line as a array (previous versions sent it as a string)

    affects/v4 impact/critical type/bug 
    opened by textagroup 10
  • RFC: Search index update/new searcher on auto commit

    RFC: Search index update/new searcher on auto commit

    Following on from/coming back to https://github.com/silverstripe/silverstripe-fulltextsearch/pull/278 and https://github.com/silverstripe/silverstripe-fulltextsearch/issues/274, it seems either something changed in Silverstripe Cloud Platform or the change in the merged PR worked intermittently/by accident, but there were several sites with issues relating to being able to find newly published content changes through the search on sites on SCP. Full reindex works, but publishing a page doesn't cause the content change to become visible in search.

    The latest advice from SCP support is to enable the openSearcher option within the autoCommit config, causing the searchers to reload after each auto commit. The setting can be enabled by copying the solrconfig.xml into the project code, adjusting the config there to override the default, and pointing Solr to it to use when configuring the core as a workaround.

    <autoCommit>
        <maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
        <openSearcher>true</openSearcher>
    </autoCommit>
    

    Should this become the default? Would it have any unwanted implications for systems/platforms, possibly loading up new searchers too many times?

    affects/v4 complexity/medium impact/critical type/bug 
    opened by michalkleiner 7
  • SearchIndex::fieldData is inefficient

    SearchIndex::fieldData is inefficient

    On a large site it is reasonable it will also have a large index (or many small indices) amounting to a large and varied number of fields being indexed on a document.

    SearchIndex::__construct calls init which in turn is intended to complete a full build of the index structure. The important components of this are addClass and addFulltextField, the latter of which relies upon fieldData which uses a complex series of introspection calls in nested foreach loops.

    The consequence of this is that adding a single field of a not very complicated page type to a search index can take an extreme amount of execution time, e.g. nearly 4 seconds and over 350000 function calls to do it.

    The consequence of this can be e.g. HTTP 500.

    This is of particular bother as every index is built on every write procedure. E.g. browsing the CMS triggers a write operation for SilverStripe\Security\RememberLoginHash, which in turn is scanned by FulltextSearch to see if it needs to update an index (also in complete pointlessness, I should hope this is never indexed data for the purpose of site search).

    Weirdly this seems to affect POST submissions much more than GET, and for some particular pages not others (e.g. UserDefinedForm page). But is a performance issue 100% of the time regardless of the end result in the specific use case.

    affects/v4 impact/medium type/enhancement 
    opened by NightJar 0
  • Module shouldn't use file_get_contents to access external URLs

    Module shouldn't use file_get_contents to access external URLs

    See cross-post issue on silverstripe/cwp-search: https://github.com/silverstripe/cwp-search/issues/25

    This module uses file_get_contents() to post/retrieve data from Solr in some instances. It shouldn't do so, as some servers may have allow_url_fopen disabled in php.ini.

    Instead, use of Guzzle (or raw curl) is encouraged for security reasons, mainly to prevent accidental remote code execution/remote file inclusion bugs.

    Note that this module explicitly isn't susceptible to RFI vulnerabilities as far as I can tell, but if you're trying to use the module on a hardened server this config value is likely disabled.

    edit: Also, renaming the variable from $targetDir would help avoid doubt about whether or not it's a URL. Suggested name: $targetUrl

    affects/v4 complexity/low impact/low type/bug 
    opened by madmatt 3
  • "2.0" is expanded to "2. 0" in search results, and doesn't match `.` or `-`

    CWP 2.3.x-dev with demo site sample data

    If you search for "CWP" it returns a list of results containing CWP 2.0 info. One example shows that 2.0 is always expanded to 2. 0 in context summaries:

    image


    Not matching some characters:

    affects/v4 complexity/medium impact/medium type/bug 
    opened by robbieaverill 3
  • SolrIndex->getRequireFiltersComponent does not sanitise class names

    SolrIndex->getRequireFiltersComponent does not sanitise class names

    I am receiving an error from Solr when trying to filter results on the Content field of SiteTree. Specifically:

    org.apache.solr.common.SolrException: undefined field SilverStripeCMSModelSiteTree_Content
    

    I am adding the filter by using the SearchQuery class, like so: (simplified example)

    $query = new SearchQuery();
    $query->addFilter(SiteTree::class . '_Content', 'filter text');
    
    $index->search($query);
    

    It looks like this issue is caused due to a missing call to SolrIndex->sanitiseClassName in SolrIndex->getRequireFiltersComponent.

    You can see an example of where the field name is being sanitised correctly in SolrIndex->getExcludeFiltersComponent here: https://github.com/silverstripe/silverstripe-fulltextsearch/blob/master/src/Solr/SolrIndex.php#L965-L970 which is what lead me to believe it was missing in getRequireFiltersComponent

    Edit: I am using silverstripe/fulltextsearch version 3.4.1 but this issue appears to affect newer versions too

    affects/v4 complexity/low impact/medium type/bug 
    opened by guttmann 2
Releases(3.11.1)
  • 3.11.1(May 30, 2022)

    What's Changed

    • DEP Require proxy-db ^1 by @emteknetnz in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/326

    Full Changelog: https://github.com/silverstripe/silverstripe-fulltextsearch/compare/3.11.0...3.11.1

    Source code(tar.gz)
    Source code(zip)
  • 3.11.0(May 16, 2022)

    What's Changed

    • NEW Ensure commits are visible to seachers (fixes #274) by @chillu in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/278

    Full Changelog: https://github.com/silverstripe/silverstripe-fulltextsearch/compare/3.10.1...3.11.0

    Source code(tar.gz)
    Source code(zip)
  • 3.10.1(May 2, 2022)

    What's Changed

    • DEP Require proxy-db ^1 by @emteknetnz in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/322

    Full Changelog: https://github.com/silverstripe/silverstripe-fulltextsearch/compare/3.10.0...3.10.1

    Source code(tar.gz)
    Source code(zip)
  • 3.10.0(May 2, 2022)

    What's Changed

    • FIX Separate out all command components so Solr_Reindex works in dev mode by @GuySartorelli in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/309
    • DOCS Change "SilverStripe" to "Silverstripe" in readme by @GuySartorelli in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/307
    • DEP Set PHP 7.4 as the minimum version by @emteknetnz in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/310
    • Symfony process constructor fix by @textagroup in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/312
    • DEP Use silverstripe fork by @emteknetnz in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/321
    • ENH PHP 8.1 compatibility by @emteknetnz in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/319

    New Contributors

    • @textagroup made their first contribution in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/312

    Full Changelog: https://github.com/silverstripe/silverstripe-fulltextsearch/compare/3.9.6...3.10.0

    Source code(tar.gz)
    Source code(zip)
  • 3.9.6(Mar 23, 2022)

    What's Changed

    • FIX Ensure DB is active before processing by @emteknetnz in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/318

    Full Changelog: https://github.com/silverstripe/silverstripe-fulltextsearch/compare/3.9.5...3.9.6

    Source code(tar.gz)
    Source code(zip)
  • 3.9.5(Mar 4, 2022)

    What's Changed

    • Don't double-escape state field by @tim-mediasuite in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/317

    New Contributors

    • @tim-mediasuite made their first contribution in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/317

    Full Changelog: https://github.com/silverstripe/silverstripe-fulltextsearch/compare/3.9.4...3.9.5

    Source code(tar.gz)
    Source code(zip)
  • 3.9.4(Mar 3, 2022)

    What's Changed

    • [Backport] Let symfony/process escape each command part separately by @michalkleiner in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/315

    Full Changelog: https://github.com/silverstripe/silverstripe-fulltextsearch/compare/3.9.3...3.9.4

    Source code(tar.gz)
    Source code(zip)
  • 3.9.3(Feb 18, 2022)

    What's Changed

    • [Backport] Symfony process constructor fix (#312) by @emteknetnz in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/313
    • MNT Use php 7.4 for job by @emteknetnz in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/314

    Full Changelog: https://github.com/silverstripe/silverstripe-fulltextsearch/compare/3.9.2...3.9.3

    Source code(tar.gz)
    Source code(zip)
  • 3.9.2(Feb 1, 2022)

    What's Changed

    • Close curl handles after use by @dhensby in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/305

    Full Changelog: https://github.com/silverstripe/silverstripe-fulltextsearch/compare/3.9.1...3.9.2

    Source code(tar.gz)
    Source code(zip)
  • 3.9.1(Jan 26, 2022)

    What's Changed

    • FIX Don't assume DataObject::canView always returns bool by @GuySartorelli in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/306

    Full Changelog: https://github.com/silverstripe/silverstripe-fulltextsearch/compare/3.9.0...3.9.1

    Source code(tar.gz)
    Source code(zip)
  • 3.8.2(Dec 15, 2021)

    What's Changed

    • ENH Show error message instead of error code on WebDAV check by @michalkleiner in https://github.com/silverstripe/silverstripe-fulltextsearch/pull/300

    Full Changelog: https://github.com/silverstripe/silverstripe-fulltextsearch/compare/3.8.1...3.8.2

    Source code(tar.gz)
    Source code(zip)
  • 3.8.1(Sep 13, 2021)

  • 3.7.1(Nov 5, 2020)

    Hotfix with a YAML config syntax patch - https://github.com/silverstripe/silverstripe-fulltextsearch/commit/de167beb34655b3f9ca7ac2d56e92dfcabaada9f

    Source code(tar.gz)
    Source code(zip)
  • 3.6.2(Nov 5, 2020)

  • 3.6.1(Feb 17, 2020)

  • 3.6.0(Nov 17, 2019)

  • 3.5.2(Jul 25, 2019)

    • Update core releases tested against in Travis config (Garion Herman) - 1fb7830
    • FIX Make remotepath optional to restore compatibility with CWP (Garion Herman) - c54f683
    • DOCS Fix doc block formatting in SolrService (Robbie Averill) - 14b35f1
    • Remove unused class imports, import docblock reference for Apache_Solr_Response, use strict comparison (Robbie Averill) - b1ec2ed
    • Update translations (Robbie Averill) - 565a9e1
    • DOCS Fix broken phpdoc types and tighten string comparison operators (Robbie Averill) - fece48c
    Source code(tar.gz)
    Source code(zip)
  • 2.4.1(Apr 14, 2019)

  • 3.1.0(Mar 14, 2018)

    • Update doc blocks at class level (Raissa North) - f47f433
    • Update scrutinizer config (Raissa North) - f416a64
    • DOCS Add doc blocks for ProxyDBExtension (Raissa North) - 0805243
    • NEW Update to use proxied DB instead of self-proxied (Raissa North) - e7420a5
    Source code(tar.gz)
    Source code(zip)
  • 3.0.0-rc2(Mar 13, 2018)

    • FIX Reenable indexing of relationship fields (Dylan Wagstaff) - 138fdad
    • Remove unneeded test as getClassNameFromIndex has been removed (jovenden) - c110eac
    • Remove all further references to getClassNameFromIndex() (jovenden) - 0fbff7c
    • Use full namespaced core for index and commit actions (jovenden) - 9153365
    • Ensure only Namespaced format is used for Configure (jovenden) - 0764c0e
    • Fix issue where schema.xml etc is put in a different dir than the core is instantiated in (jovenden) - b6e64a2
    • Update doc block for withCommon to indicate an array of strings, shorten serialized cache key (Robbie Averill) - c64c0c0
    • FIX Don't assume a DataObject's table. (Dylan Wagstaff) - 9e32f2a
    • FIX permit reindexing on a Windows machine (Dylan Wagstaff) - 367343c
    • FIX Update tests to reflect the fact that the versioned variant is not relevant for SearchUpdaterTest_Container (Robbie Averill) - 3199185
    • NEW Add SearchVariant::withCommon to run callbacks on relevant variants rather than all (Robbie Averill) - 6e5b37e
    Source code(tar.gz)
    Source code(zip)
  • 3.0.0-rc1(Mar 13, 2018)

  • 3.0.0-beta2(Jan 11, 2018)

    • MINOR Correct PHPDoc types and remove unused imports (Robbie Averill) - 345a45d
    • API More TestState into source folder from tests (Robbie Averill) - 7b933cb
    • Update branch alias for 2.5.x-dev (Robbie Averill) - 196fc38
    • Remove obsolete branch alias (Robbie Averill) - 0692e2a
    • Adding extension hooks before and after Solr_Configure and Solr_Reindex tasks to allow (e.g. Translatable) to modify filters consistently across multiple task iterations (BrewCurious) - 20e1b1c
    Source code(tar.gz)
    Source code(zip)
  • 3.0.0-beta1(Dec 13, 2017)

    SilverStripe 4 compatible

    • Switch testSoftCap from skipped to incomplete (Robbie Averill) - 2ac0178
    • Add Capture classes to upgrade.yml (Robbie Averill) - 59a1643
    • FIX Update setUpBeforeClass and illegal_extensions (Robbie Averill) - 6ecf843
    • FIX Use correct namespace for SQLite3 adapter, implement injector prioritisation for database (Robbie Averill) - a47d5e8
    • Skip testSoftCap for now, passes in isolation but not in the suite. Use constants for queue statics (Robbie Averill) - 21a0451
    • API Remove bind_manipulation_capture and RequestFilter, use Injector instead (Robbie Averill) - 45c402f
    • FIX Ensure queued job signature remains under 64 character limit (fixes Postgres error) (Robbie Averill) - fccac37
    • FIX Implement correct namespace for PostgreSQL and add to Travis matrix (Robbie Averill) - e47ab9c
    • NEW Replace backslashes in Solr index names with dashes (Robbie Averill) - 4d57f09
    • FIX Double escape namespace separators in class names when boosting fields (Robbie Averill) - b64f027
    • FIX Double escape namespace separators in class names when excluding fields (Robbie Averill) - 7ae7f70
    • API Update Subsite integration, remove Polyhome variant (Robbie Averill) - 861f875
    • FIX: coreIsActive() failed when using a namespaced core (Matt Peel) - 7bacda9
    • FIX Replace uppercase String occurences with lowercase version ones (Raissa North) - b066628
    • ENHANCEMENT Use namespace imports rather than fully qualified class names in strings (Raissa North) - 0c3b4ff
    • API Remove deprecated code (Raissa North) - bd405c6
    • Add .upgrade.yml for silverstripe-upgrader tool class mapping (Robbie Averill) - 2b55442
    • API Make SearchVariant::call(...) arguments variadic (Raissa North) - 193fe81
    • NEW Support environment variables for Solr index prefix and suffix (Robbie Averill) - 6811082
    • FIX Disable QueuedJobService shutdown function in fulltextsearch unit tests (Robbie Averill) - c7cbb01
    • FIX Disabled the shutdown handler in QueuedJobs (Raissa North) - 6f8ef48
    • API Remove Solr PHP client from thirdparty library and include with composer instead (Robbie Averill) - 9b26af1
    • FIX Update namespace references to Symbiote (Raissa North) - acd8b7b
    • FIX Update directory structure for PSR-4 compatibility and rename "code" to "src" (Robbie Averill) - 7b72774
    • FIX Replace use of SS_Log with Psr logger (Robbie Averill) - f1ab8c9
    • DOCS Update namespaces and code formatting in documentation (Robbie Averill) - 74db46f
    • FIX Escape backslashes in class namespaces when performing queries, tidy up SearchVariantVersioned a bit (Robbie Averill) - fbc4c0e
    • FIX Use instanceof check for $object against DBString (Robbie Averill) - a26f437
    • FIX Use ModuleLoader to resolve the path to cli-script.php in framework (Robbie Averill) - 992bb5a
    • FIX Replace Object reference with Injector and use ModuleLoader to resolve schema location (Robbie Averill) - 216613d
    • DOCS Add build badges to readme, update requirements for SS4 (Robbie Averill) - fc51d1a
    • FIX Replace deprecated create_function with closure (Robbie Averill) - 9106371
    • FIX Remove obsolete Object reference in Solr (Robbie Averill) - e001b68
    • FIX Run phpcbf automated linting to fix PSR-2 code styles, add PSR-4 autoloader (Robbie Averill) - e590132
    • FIX Update Travis configuration for SS4, add phpunit config and necessary composer updates (Robbie Averill) - 1080d64
    • NEW Add config for shutdown flush, remove references to Object and update tests (Robbie Averill) - b448bfc
    • API Remove Object inheritance and update method signatures in CaptureFilter request filter (Robbie Averill) - b996f68
    • Update branch alias for 3.x-dev (Robbie Averill) - d56da21
    • fixes to allow namespacing in index class (elliot sawyer) - d7805f4
    • SS 4.0 - Include PHPUnit in composer.json (Brett Tasker) - 4ff4404
    • FIX: Update travis to remove php 5.5 + Fix SearchVariantSubsiteTest reference to SapphireTest (Brett Tasker) - 8adb317
    • FIX: Broken merge as files have been moved + Fixed additional tests (Brett Tasker) - 4c44d1c
    • Use ->config()->segment instead. It's possible for somebody to change the value of using the Config API (Marco Hermo) - 6478a13
    • Use to make backwards compatible with existing code (Marco Hermo) - e6cd3f4
    • SS 4.0 - Strip namespaces from core name since backslashes are not acceptable Solr core names (elliot sawyer) - 815d619
    • Removed @todo as SearchLogFactory interface is injected via Yaml config (Marco Hermo) - 7c0ff89
    • Change segments for configure and reindex tasks (Marco Hermo) - 2932ae9
    • Add extra slashes to namespaced class passed as variable to shell commands (Marco Hermo) - b4d1e45
    • Replace deprecated code with DataObject::getSchema()->classHasTable() (Marco Hermo) - 8bc6f59
    • Add FieldDefinitions and CopyFieldDefinitions to casting property in order to render them as HTMLText (Marco Hermo) - 561550c
    • SS 4.0 - Upgrade Combinations array and Logging (Brett Tasker) - fa7a23a
    • SS 4.0 - Upgrade Solr services and stores (Brett Tasker) - 6fb5736
    • SS 4.0 - Upgrade Solr reindex components (Brett Tasker) - 5fae523
    • SS 4.0 - Remove MessageHandler Solr integration (Brett Tasker) - 4143850
    • Only commit non-null values to Solr (Brett Tasker) - ea94437
    • SS 4.0 - Upgrade Solr & Solr Index (Brett Tasker) - 4530fb2
    • Use actual classname in SearchVariantVersioned (Brett Tasker) - 7baf7d5
    • SS 4.0 - Upgrade search variants (Brett Tasker) - 59c3ad2
    • SS 4.0 - Upgrade FullTextSearch, queries and updaters (Brett Tasker) - 022575f
    • Update manyMany array index as SS4.0 as an additional class in history. (Brett Tasker) - 590ac4c
    • SS 4.0 - Upgrade search processors and remove MessageQueue as not maintained (Brett Tasker) - 8e07d4a
    • SS 4.0 - Upgrade search indexes (Brett Tasker) - 695b2d2
    • SS 4.0 - Disable SubSite installation as SubSite has yet to be upgraded (Brett Tasker) - 3c1ace8
    • SS 4.0 - Update config files to use full class names & update travis (Brett Tasker) - 57f6a55
    • SS 4.0 - Upgrade tests to SilverStripe 4.0 & Replace Phockito (Brett Tasker) - 73e4888
    • Use PHP5.5 class name resolution operator (Marco Hermo) - 3160c06
    • Use PHP5.5 class name resolution operator (Marco Hermo) - e422ad4
    • WIP: Silverstripe 4 compatibility (Elliot Sawyer) - 1728a62
    • Fix invalid namespace reference for SolrService_Core (Marco Hermo) - d13601f
    • Explicit namespace definition on YAML files (Marco Hermo) - 8228c76
    • SS 4.0 - Skip Subsite tests if module is not installed (Brett Tasker) - 168b674
    • SS 4.0 - Replace inst()->update with modify()->set and hasOne with hasOneComponent (Brett Tasker) - 43dd2ba
    • SS 4.0 - Fix SearchIntrospection and SearchIndex (Brett Tasker) - faacb6b
    • SS 4.0 - Update references to thirdparty Solr API as its not namespaced (Brett Tasker) - 0b7281b
    • SS 4.0 - Update Variants (Brett Tasker) - eac9485
    • SS 4.0 - Update Database Captures to support Postgres & SQLite (Brett Tasker) - fcf9a4f
    • Update Search Manipulater (Brett Tasker) - 6066af5
    • Use root namespace in referencing Apache_Solr_Document (Marco Hermo) - da0a217
    • Update _config.php to use namespace (Marco Hermo) - 62ba531
    • Batch fixes for tests #2 (Brett Tasker) - 9d5ea93
    • Update namespacing for Search indexes and variants in tests (Brett Tasker) - 6a2a4a8
    • break out search components with multiple classes into individual files and change namespaces (elliot sawyer) - 13bef6e
    • Fix PHP errors in test (Brett Tasker) - 0ee34e4
    • Second push of Test changes + namespacing (Brett Tasker) - 0ebf6e6
    • WIP split Solr files with multiple classes into single file / single class. Adjust namespaces (elliot sawyer) - 424107f
    • WIP add namespaces to all classes (elliot sawyer) - abdfe19
    • Namespacing for tests (Brett Tasker) - ddbab95
    • WIP respect current include path WIP Namespacing and use on SearchIndex class (elliot sawyer) - 9aac0ff
    • WIP fix solr path to use DIR, avoid hardcoded module name (elliot sawyer) - 26b629a
    • WIP more SS4 compatibility fixes (elliot sawyer) - 19b38e0
    • remove php <5.5 from travis.yml (elliot sawyer) - 45473db
    • Update composer.json (Elliot Sawyer) - b0436d7
    • more replacements and patches to migrate this module to 4.0 (elliot sawyer) - 7c27484
    • WIP Silverstripe 4 compatibility fixes (elliot sawyer) - bbdf79e
    • Bump framework/cms to ^4.0@dev (Elliot Sawyer) - 6fbb25a
    Source code(tar.gz)
    Source code(zip)
  • 2.4.0(Nov 20, 2017)

    • Remove obsolete branch alias (Robbie Averill) - 0692e2a
    • Adding extension hooks before and after Solr_Configure and Solr_Reindex tasks to allow (e.g. Translatable) to modify filters consistently across multiple task iterations (BrewCurious) - 20e1b1c
    • Remove PHP 5.3 from Travis build matrix and remove extra jobs to simplify (Robbie Averill) - 9760b72
    • Update branch alias for 2.4.x-dev (Robbie Averill) - 5a69377
    • Move SynonymFilterFactory to bottom of analyzer to include synonyms in search results (Glen Peek) - e5f0182
    • Remove PHP 5.3 tests as 5.3 is now unsupported. (cpenny) - 0fb7f01
    • Bugfix: Set SearchUpdateCommitJobProcessor::$dirty_indexes prop type to array, not bool (cpenny) - e196de2
    • Index now supports multiple relations with the same name. (Mojmir Fendek) - 16fc54e
    • Test for ambiguous relationships (Ingo Schommer) - b7f4c1e
    • Index now supports multiple relations with the same name. (Mojmir Fendek) - 2b33575
    • Add PHP7 + SS3.6 build to Travis configuration (Robbie Averill) - 558fa48
    • Obtain search results for a particular subsite when the request comes from a query (#136) (Elliot Sawyer) - 2246fa9
    • Update Solr.md (Elliot Sawyer) - f5392b6
    • Update Solr.md (Elliot Sawyer) - 5790802
    • Fixed Travis URL (Ingo Schommer) - 51749c6
    Source code(tar.gz)
    Source code(zip)
  • 2.3.5(Nov 10, 2017)

    • Move SynonymFilterFactory to bottom of analyzer to include synonyms in search results (Glen Peek) - e5f0182
    • Remove PHP 5.3 tests as 5.3 is now unsupported. (cpenny) - 0fb7f01
    • Bugfix: Set SearchUpdateCommitJobProcessor::$dirty_indexes prop type to array, not bool (cpenny) - e196de2
    Source code(tar.gz)
    Source code(zip)
  • 2.3.3(Nov 10, 2017)

  • 2.3.2(Nov 10, 2017)

Owner
Silverstripe CMS
Silverstripe CMS is the intuitive content management system and flexible framework loved by editors and developers alike.
Silverstripe CMS
Nova Search is an open source search engine developed by the Artado Project.

Loli Search Loli Search açık kaynak kodlu bir arama motorudur ve yalnızca kendi sonuçlarını değil, diğer arama motorlarının sonuçlarını da göstermekte

Artado Project 10 Jul 22, 2022
Doogle is a search engine and web crawler which can search indexed websites and images

Doogle Doogle is a search engine and web crawler which can search indexed websites and images, and then use keywords to be searched later. Written pri

Zepher Ashe 9 Jan 1, 2023
Silverstripe-masquerade - SilverStripe module to allow users to "masquerade" as other users

SilverStripe Masquerade Module About This module is designed to allow an Administrator to "login" as another "Member" without changing their password

Daniel Hensby 14 Apr 14, 2022
Silverstripe-debugbar/ - SilverStripe DebugBar module

SilverStripe DebugBar module Requirements SilverStripe ^4.0 maximebf/php-debugbar jdorn/sql-formatter Installation You can install the debug bar with

Thomas Portelange 52 Dec 21, 2022
A SilverStripe module for conveniently injecting JSON-LD metadata into the header of each rendered page in SilverStripe

A SilverStripe module for conveniently injecting JSON-LD metadata into the header of each rendered page in Silver

null 4 Apr 20, 2022
Adds a "spam protection" field to SilverStripe userforms using Cloudflare's Turnstile service.

Turnstile for Silverstripe Adds a "spam protection" field to SilverStripe userforms using Cloudflare's Turnstile service. Maintainer Contact Ed Chipma

Webbuilders Group 3 Dec 15, 2022
Adds my own text to WooCommerce add to cart button.

My Add to Cart Text Adds my own text to WooCommerce add to cart button. Installation Get the .zip package of this plugin. Install manually to your Wor

Kharis Sulistiyono 1 Jan 25, 2022
Laminas\Text is a component to work on text strings

laminas-text This package is considered feature-complete, and is now in security-only maintenance mode, following a decision by the Technical Steering

Laminas Project 38 Dec 31, 2022
Zend\Text is a component to work on text strings from Zend Framework

zend-text Repository abandoned 2019-12-31 This repository has moved to laminas/laminas-text. Zend\Text is a component to work on text strings. It cont

Zend Framework 31 Jan 24, 2021
html-sanitizer is a library aiming at handling, cleaning and sanitizing HTML sent by external users

html-sanitizer html-sanitizer is a library aiming at handling, cleaning and sanitizing HTML sent by external users (who you cannot trust), allowing yo

Titouan Galopin 381 Dec 12, 2022
Engine for performing and rendering text diffs

Text_Diff Engine for performing and rendering text diffs This package provides a text-based diff engine and renderers for multiple diff output formats

PEAR - PHP Extension and Application Repository 15 Jan 4, 2022
JSONFinder - a library that can find json values in a mixed text or html documents, can filter and search the json tree, and converts php objects to json without 'ext-json' extension.

JSONFinder - a library that can find json values in a mixed text or html documents, can filter and search the json tree, and converts php objects to json without 'ext-json' extension.

Eboubaker Eboubaker 2 Jul 31, 2022
search non profitable charity or organization through api search

Non Profile Charity Search Search non profitable organization or get the details of an organization Installation Require the package using composer: c

Touhidur Rahman 5 Jan 20, 2022
Smile ElasticSuite - Magento 2 merchandising and search engine built on ElasticSearch

News ⚠️ Magento versions compatibility : Due to several changes in Magento 2.4.0, we cannot ensure compatibility between ElasticSuite <2.10 and Magent

Smile - Open Source Solutions 724 Dec 30, 2022
Magento 2 Module for Search Engine Optimization

Magento 2 Search Engine Optimization Magento 2 Module to Improve Search Engine Optimization (SEO) on your Magento site. Installation Install the modul

Stämpfli AG 100 Oct 7, 2022
A privacy respecting free as in freedom meta search engine for Google and popular torrent sites

A privacy respecting free as in freedom meta search engine for Google and popular torrent sites

null 329 Dec 27, 2022
An Elasticsearch engine plugin for Moodle's Global Search

Moodle Global Search - Elasticsearch Backend This plugin allows Moodle to use Elasticsearch as the search engine for Moodle's Global Search. The follo

Catalyst IT 12 Nov 3, 2022
PHP Japanese string helper functions for converting Japanese strings from full-width to half-width and reverse. Laravel Rule for validation Japanese string only full-width or only half-width.

Japanese String Helpers PHP Japanese string helper functions for converting Japanese strings from full-width to half-width and reverse. Laravel Rule f

Deha 54 Mar 22, 2022
Task for GrumPHP that adds CSS linting support with stylelint. An easy way to enforce convention and avoid errors in your styles

grumphp-stylelint-task Installation Stylelint is a static analysis tool for styles. A mighty, modern linter that helps you avoid errors and enforce co

null 3 Apr 29, 2021