Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show in search check for files #92

Merged
merged 13 commits into from
May 2, 2024
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') ?? [];
blueo marked this conversation as resolved.
Show resolved Hide resolved
$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)
);
}

}
15 changes: 12 additions & 3 deletions src/Extensions/SearchServiceExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Exception;
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 +37,14 @@ class SearchServiceExtension extends DataExtension
use BatchProcessorAware;

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

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

private bool $hasConfigured = false;

public function __construct(
Expand All @@ -59,12 +65,15 @@ public function updateCMSFields(FieldList $fields): void
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'));

if ($fields->hasTabSet()) {
$fields->addFieldToTab('Root.Main', $field);
$fields->addFieldToTab('Root.Main', $showInSearchField);
$fields->addFieldToTab('Root.Main', $searchIndexedField);
} else {
$fields->push($field);
$fields->push($showInSearchField);
$fields->push($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();
blueo marked this conversation as resolved.
Show resolved Hide resolved

$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\Forms\Form;
use SilverStripe\Assets\File;
use SilverStripe\Assets\Image;
use SilverStripe\Forms\TabSet;
use SilverStripe\Forms\FieldList;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Core\Config\Config;
use SilverStripe\SearchService\Extensions\SearchFormFactoryExtension;

class SearchFormFactoryExtensionTest extends SapphireTest
{

protected static $fixture_file = [
'../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.
Loading