Skip to content

Commit

Permalink
Show in search check for files (silverstripe#92)
Browse files Browse the repository at this point in the history
* Index or remove from index based on ShowInSearch value

* Add Show in search and last indexed field to file details tab

* Add tests and revert onAfterPublish code

* Add DataObject search content controls

* Generic SearchFormFactoryExtension and fixing tests

* Add config and update tests

* Default config and update doc

* Update ShowInSearch if files is not set to index

* Add tests for SearchFormFactoryExtension

* Fix broken tests

* Linting fixes

* Show in search remove duplicated field for SiteTree main tab

* Update settings for SiteTree objects
  • Loading branch information
amolswnz authored May 2, 2024
1 parent 4509830 commit afbe384
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 7 deletions.
9 changes: 9 additions & 0 deletions _config/extensions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,12 @@ SilverStripe\CMS\Model\SiteTree:
extensions:
SearchServiceExtension: SilverStripe\SearchService\Extensions\SearchServiceExtension
SiteTreeHierarchyExtension: SilverStripe\SearchService\Extensions\SiteTreeHierarchyExtension
---
Name: search-service-form-extension
---
SilverStripe\AssetAdmin\Forms\FileFormFactory:
extensions:
- SilverStripe\SearchService\Extensions\SearchFormFactoryExtension
SilverStripe\SearchService\Extensions\SearchFormFactoryExtension:
exclude_classes:
- SilverStripe\Assets\Image
23 changes: 23 additions & 0 deletions docs/en/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,29 @@ __Additional note__:
This is handled via `SubsiteIndexConfigurationExtension` - this logic could be
replicated for other scenarios like languages if required.

## Configuring search exclusion for files

By default, `SilverStripe\Assets\Image` is excluded from the search. To change this default
setting, use the code snippet below.

```yaml
---
After: search-service-form-extension
---
SilverStripe\SearchService\Extensions\SearchFormFactoryExtension:
exclude_classes: null
```
If you want to exclude certain file extensions from being added to the search index, add
the following configuration to your code base:
```yaml
SilverStripe\SearchService\Extensions\SearchFormFactoryExtension:
exclude_file_extensions:
- svg
- mp4
```
## More information
* [Usage](usage.md)
Expand Down
63 changes: 63 additions & 0 deletions src/Extensions/SearchFormFactoryExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace SilverStripe\SearchService\Extensions;

use SilverStripe\Control\RequestHandler;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Extension;
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\DatetimeField;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FormFactory;

class SearchFormFactoryExtension extends Extension
{

public function updateForm(
Form $form,
?RequestHandler $controller = null,
string $name = FormFactory::DEFAULT_NAME,
array $context = []
): void {
$fields = $form->Fields()->findOrMakeTab('Editor.Details');
$file = $context['Record'] ?? null;

$excludedClasses = Config::inst()->get(self::class, 'exclude_classes') ?? [];
$excludeFileTypes = Config::inst()->get(self::class, 'exclude_file_extensions') ?? [];

if (!$fields || !$file) {
return;
}

if (in_array($file->ClassName, $excludedClasses) || in_array($file->getExtension(), $excludeFileTypes)) {
if ($file->ShowInSearch) {
$file->ShowInSearch = false;
$file->write();
}

return;
}

$fields->push(
CheckboxField::create(
'ShowInSearch',
_t(
'SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.SHOWINSEARRCH',
'Show in search?'
)
)
);

$fields->push(
DatetimeField::create(
'SearchIndexed',
_t(
'SilverStripe\\SearchService\\Extensions\\SearchServiceExtension.LastIndexed',
'Last indexed in search'
)
)
->setReadonly(true)
);
}

}
49 changes: 43 additions & 6 deletions src/Extensions/SearchServiceExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
namespace SilverStripe\SearchService\Extensions;

use Exception;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Core\Config\Configurable;
use SilverStripe\Core\Injector\Injectable;
use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\ReadonlyField;
use SilverStripe\ORM\DataExtension;
Expand Down Expand Up @@ -36,9 +38,14 @@ class SearchServiceExtension extends DataExtension
use BatchProcessorAware;

private static array $db = [
'ShowInSearch' => 'Boolean',
'SearchIndexed' => 'Datetime',
];

private static array $defaults = [
'ShowInSearch' => true,
];

private bool $hasConfigured = false;

public function __construct(
Expand All @@ -53,19 +60,49 @@ public function __construct(
$this->setBatchProcessor($batchProcessor);
}

/**
* General DataObject Search settings
*
* @param FieldList $fields
* @return void
*/
public function updateCMSFields(FieldList $fields): void
{
if (!$this->getConfiguration()->isEnabled()) {
if ($this->owner instanceof SiteTree || !$this->getConfiguration()->isEnabled()) {
return;
}

$field = ReadonlyField::create('SearchIndexed', _t(self::class.'.LastIndexed', 'Last indexed in search'));
$showInSearchField = CheckboxField::create(
'ShowInSearch',
_t(self::class . '.ShowInSearch', 'Show in search?')
);
$searchIndexedField = ReadonlyField::create(
'SearchIndexed',
_t(self::class . '.LastIndexed', 'Last indexed in search')
);

$fields->push($showInSearchField);
$fields->push($searchIndexedField);
}

if ($fields->hasTabSet()) {
$fields->addFieldToTab('Root.Main', $field);
} else {
$fields->push($field);
/**
* Specific settings for SiteTree
*
* @param FieldList $fields
* @return void
*/
public function updateSettingsFields(FieldList $fields): void
{
if (!$this->owner instanceof SiteTree || !$this->getConfiguration()->isEnabled()) {
return;
}

$searchIndexedField = ReadonlyField::create(
'SearchIndexed',
_t(self::class . '.LastIndexed', 'Last indexed in search')
);

$fields->insertAfter('ShowInSearch', $searchIndexedField);
}

/**
Expand Down
28 changes: 28 additions & 0 deletions tests/DataObject/DataObjectDocumentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -758,4 +758,32 @@ public function testIndexDataObjectDocument(): void
});
}

public function testIndexDataObjectDocumentShowInSearch(): void
{
$dataObject = $this->objFromFixture(DataObjectFakeVersioned::class, 'two');
$doc = DataObjectDocument::create($dataObject);

$config = $this->mockConfig();
$config->set(
'getIndexesForDocument',
[
$doc->getIdentifier() => [
'index' => 'data',
],
]
);

// Should not index as ShowInSearch is false for this DataObject
$dataObject->publishRecursive();
$this->assertFalse($doc->shouldIndex());

// Should index as ShowInSearch is now set to true
$dataObject->ShowInSearch = true;
$dataObject->publishRecursive();

$doc = DataObjectDocument::create($dataObject);

$this->assertTrue($doc->shouldIndex());
}

}
68 changes: 68 additions & 0 deletions tests/Extensions/SearchFormFactoryExtensionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace SilverStripe\SearchService\Tests\Extensions;

use SilverStripe\Assets\File;
use SilverStripe\Assets\Image;
use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\TabSet;
use SilverStripe\SearchService\Extensions\SearchFormFactoryExtension;

class SearchFormFactoryExtensionTest extends SapphireTest
{

protected static $fixture_file = [ // phpcs:ignore
'../fixtures.yml',
'../pages.yml',
];

public function testDefaultConfigValues(): void
{
$expected = ['SilverStripe\Assets\Image'];
$actual = Config::inst()->get(SearchFormFactoryExtension::class, 'exclude_classes');
$this->assertEquals($expected, $actual);
}

public function testImageAndFileInclusionInShowInSearch(): void
{
$form = Form::create();
$fields = new FieldList(new TabSet('Editor'));
$form->setFields($fields);

$image = $this->objFromFixture(Image::class, 'image');
// Every file has default ShowInSearch value of 1
// (https://github.com/silverstripe/silverstripe-assets/blob/2/src/File.php#L163)
$this->assertEquals(1, $image->ShowInSearch);

$searchFormFactoryExtension = new SearchFormFactoryExtension();
$searchFormFactoryExtension->updateForm($form, null, 'Form', ['Record' => $image]);
// By default, `SilverStripe\Assets\Image` is excluded from the search - see `_config/extensions.yml`
$this->assertEquals(0, $image->ShowInSearch);

$file = $this->objFromFixture(File::class, 'pdf-file');
$searchFormFactoryExtension->updateForm($form, null, 'Form', ['Record' => $file]);
$this->assertEquals(1, $file->ShowInSearch);
}

public function testExcludedFileExtensionShowInSearch(): void
{
// Modify config to exclude pdf files from search
Config::modify()->set(SearchFormFactoryExtension::class, 'exclude_file_extensions', ['pdf']);

$file = $this->objFromFixture(File::class, 'pdf-file');
// Default ShowInSearch value of 1
$this->assertEquals(1, $file->ShowInSearch);

$form = Form::create();
$fields = new FieldList(new TabSet('Editor'));
$form->setFields($fields);

$searchFormFactoryExtension = new SearchFormFactoryExtension();
$searchFormFactoryExtension->updateForm($form, null, 'Form', ['Record' => $file]);
$this->assertEquals(0, $file->ShowInSearch);
}

}
1 change: 0 additions & 1 deletion tests/Fake/DataObjectFake.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class DataObjectFake extends DataObject implements TestOnly

private static array $db = [
'Title' => 'Varchar',
'ShowInSearch' => 'Boolean',
'Sort' => 'Int',
];

Expand Down
13 changes: 13 additions & 0 deletions tests/fixtures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,16 @@ SilverStripe\Subsites\Model\Subsite:
Title: 'Subsite 1'
subsite2:
Title: 'Subsite 2'


SilverStripe\Assets\Image:
image:
Name: 'Image'
Filename: silverstripe-logo.png
PopulateFileFrom: tests/silverstripe-logo.png

SilverStripe\Assets\File:
pdf-file:
Title: Test File
Filename: test-file.pdf
PopulateFileFrom: tests/test-file.pdf
Binary file added tests/silverstripe-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/test-file.pdf
Binary file not shown.

0 comments on commit afbe384

Please sign in to comment.