Loading src/Plugin/search_api/data_type/DateRangeDataType.php 0 → 100644 +20 −0 Original line number Diff line number Diff line <?php namespace Drupal\search_api_opensearch\Plugin\search_api\data_type; use Drupal\search_api\Plugin\search_api\data_type\DateDataType; /** * Provides a date range data type. * * @SearchApiDataType( * id = "search_api_opensearch_date_range", * label = @Translation("Date range"), * description = @Translation("Date field that contains date ranges."), * fallback = "date", * prefix = "dr" * ) */ class DateRangeDataType extends DateDataType { } src/Plugin/search_api/processor/DateRange.php 0 → 100644 +55 −0 Original line number Diff line number Diff line <?php namespace Drupal\search_api_opensearch\Plugin\search_api\processor; use Drupal\search_api\Processor\ProcessorPluginBase; /** * Add date ranges to the index. * * @SearchApiProcessor( * id = "search_api_opensearch_date_range", * label = @Translation("Date ranges"), * description = @Translation("Date ranges."), * stages = { * "preprocess_index" = 0, * }, * locked = true, * hidden = true, * ) */ class DateRange extends ProcessorPluginBase { /** * {@inheritdoc} */ public function preprocessIndexItems(array $items) { foreach ($items as $item) { foreach ($item->getFields() as $field) { if ('search_api_opensearch_date_range' == $field->getType()) { $required_properties = [ $item->getDatasourceId() => [ $field->getPropertyPath() . ':value' => 'start', $field->getPropertyPath() . ':end_value' => 'end', ], ]; $item_values = $this->getFieldsHelper()->extractItemValues([$item], $required_properties); foreach ($item_values as $dates) { $start_dates = $dates['start']; $end_dates = $dates['end']; for ($i = 0, $n = count($start_dates); $i < $n; $i++) { $values[$i] = [ 'gte' => $start_dates[$i], 'lte' => $end_dates[$i], ]; } } if (!empty($values)) { $field->setValues($values); } } } } } } src/SearchAPI/FieldMapper.php +4 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,10 @@ class FieldMapper { 'type' => 'date', 'format' => 'strict_date_optional_time||epoch_second', ], 'search_api_opensearch_date_range' => [ 'type' => 'date_range', 'format' => 'strict_date_optional_time||epoch_second', ], 'attachment' => ['type' => 'attachment'], 'object' => ['type' => 'nested'], 'location' => ['type' => 'geo_point'], Loading tests/src/Kernel/DataTypeTest.php +13 −0 Original line number Diff line number Diff line Loading @@ -29,4 +29,17 @@ class DataTypeTest extends KernelTestBase { $this->assertEquals('search_api_opensearch', $definition['provider']); } /** * Tests the date range type is found. */ public function testHasDateRangeDataType() { /** @var \Drupal\search_api\DataType\DataTypePluginManager $manager */ $manager = $this->container->get('plugin.manager.search_api.data_type'); $definitions = $manager->getDefinitions(); $this->assertArrayHasKey('search_api_opensearch_date_range', $definitions); $definition = $definitions['search_api_opensearch_date_range']; $this->assertEquals('search_api_opensearch_date_range', $definition['id']); $this->assertEquals('search_api_opensearch', $definition['provider']); } } tests/src/Unit/Plugin/processor/DateRangeTest.php 0 → 100644 +128 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\search_api_opensearch\Unit\Plugin\processor; use Drupal\search_api\Datasource\DatasourceInterface; use Drupal\search_api\IndexInterface; use Drupal\search_api\Item\Field; use Drupal\search_api\Item\Item; use Drupal\search_api\Utility\FieldsHelper; use Drupal\search_api_opensearch\Plugin\search_api\processor\DateRange; use Drupal\Tests\UnitTestCase; /** * Tests the date range processor. * * @coversDefaultClass \Drupal\search_api_opensearch\Plugin\search_api\processor\DateRange * @group search_api_opensearch */ class DateRangeTest extends UnitTestCase { /** * Test making date range field types compatible with OS. * * @covers ::preprocessIndexItems * @dataProvider dateValueDataProvider */ public function testPreProcessingDateRangeItems( array $extractItemResult, array $expectedResult ): void { $dataSource = $this->prophesize(DatasourceInterface::class); $dataSource->getPluginId()->willReturn('entity:node'); $index = $this->prophesize(IndexInterface::class); $indexId = "index_" . $this->randomMachineName(); $index->id()->willReturn($indexId); $itemId = "item1_" . $this->randomMachineName(); $item = (new Item($index->reveal(), $itemId, $dataSource->reveal())) ->setFieldsExtracted(TRUE) ->setField( 'event_date_range', (new Field($index->reveal(), 'event_date_range')) ->setType("search_api_opensearch_date_range") ->setPropertyPath('field_event_instance') ); $fieldsHelper = $this->prophesize(FieldsHelper::class); $fieldsHelper->extractItemValues([$item], [ 'entity:node' => [ 'field_event_instance:value' => 'start', 'field_event_instance:end_value' => 'end', ], ])->willReturn($extractItemResult); $dateRange = new DateRange([], 'search_api_opensearch_date_range', []); $dateRange->setFieldsHelper($fieldsHelper->reveal()); $dateRange->preprocessIndexItems([$item]); $fieldValues = $item->getField('event_date_range')->getValues(); $this->assertEquals($expectedResult, $fieldValues); } /** * Provides dummy date range data. */ public function dateValueDataProvider(): array { return [ 'Single date range' => [ [ [ 'start' => [ '2022-07-01T09:30:00', ], 'end' => [ '2022-07-01T13:00:00', ], ], ], [ [ 'gte' => '2022-07-01T09:30:00', 'lte' => '2022-07-01T13:00:00', ], ], ], 'Multiple date ranges' => [ [ [ 'start' => [ '2022-07-01T09:30:00', '2022-08-05T09:30:00', ], 'end' => [ '2022-07-01T13:00:00', '2022-08-05T13:00:00', ], ], ], [ [ 'gte' => '2022-07-01T09:30:00', 'lte' => '2022-07-01T13:00:00', ], [ 'gte' => '2022-08-05T09:30:00', 'lte' => '2022-08-05T13:00:00', ], ], ], 'No date ranges' => [ [ [ 'start' => [], 'end' => [], ], ], [], ], ]; } } Loading
src/Plugin/search_api/data_type/DateRangeDataType.php 0 → 100644 +20 −0 Original line number Diff line number Diff line <?php namespace Drupal\search_api_opensearch\Plugin\search_api\data_type; use Drupal\search_api\Plugin\search_api\data_type\DateDataType; /** * Provides a date range data type. * * @SearchApiDataType( * id = "search_api_opensearch_date_range", * label = @Translation("Date range"), * description = @Translation("Date field that contains date ranges."), * fallback = "date", * prefix = "dr" * ) */ class DateRangeDataType extends DateDataType { }
src/Plugin/search_api/processor/DateRange.php 0 → 100644 +55 −0 Original line number Diff line number Diff line <?php namespace Drupal\search_api_opensearch\Plugin\search_api\processor; use Drupal\search_api\Processor\ProcessorPluginBase; /** * Add date ranges to the index. * * @SearchApiProcessor( * id = "search_api_opensearch_date_range", * label = @Translation("Date ranges"), * description = @Translation("Date ranges."), * stages = { * "preprocess_index" = 0, * }, * locked = true, * hidden = true, * ) */ class DateRange extends ProcessorPluginBase { /** * {@inheritdoc} */ public function preprocessIndexItems(array $items) { foreach ($items as $item) { foreach ($item->getFields() as $field) { if ('search_api_opensearch_date_range' == $field->getType()) { $required_properties = [ $item->getDatasourceId() => [ $field->getPropertyPath() . ':value' => 'start', $field->getPropertyPath() . ':end_value' => 'end', ], ]; $item_values = $this->getFieldsHelper()->extractItemValues([$item], $required_properties); foreach ($item_values as $dates) { $start_dates = $dates['start']; $end_dates = $dates['end']; for ($i = 0, $n = count($start_dates); $i < $n; $i++) { $values[$i] = [ 'gte' => $start_dates[$i], 'lte' => $end_dates[$i], ]; } } if (!empty($values)) { $field->setValues($values); } } } } } }
src/SearchAPI/FieldMapper.php +4 −0 Original line number Diff line number Diff line Loading @@ -145,6 +145,10 @@ class FieldMapper { 'type' => 'date', 'format' => 'strict_date_optional_time||epoch_second', ], 'search_api_opensearch_date_range' => [ 'type' => 'date_range', 'format' => 'strict_date_optional_time||epoch_second', ], 'attachment' => ['type' => 'attachment'], 'object' => ['type' => 'nested'], 'location' => ['type' => 'geo_point'], Loading
tests/src/Kernel/DataTypeTest.php +13 −0 Original line number Diff line number Diff line Loading @@ -29,4 +29,17 @@ class DataTypeTest extends KernelTestBase { $this->assertEquals('search_api_opensearch', $definition['provider']); } /** * Tests the date range type is found. */ public function testHasDateRangeDataType() { /** @var \Drupal\search_api\DataType\DataTypePluginManager $manager */ $manager = $this->container->get('plugin.manager.search_api.data_type'); $definitions = $manager->getDefinitions(); $this->assertArrayHasKey('search_api_opensearch_date_range', $definitions); $definition = $definitions['search_api_opensearch_date_range']; $this->assertEquals('search_api_opensearch_date_range', $definition['id']); $this->assertEquals('search_api_opensearch', $definition['provider']); } }
tests/src/Unit/Plugin/processor/DateRangeTest.php 0 → 100644 +128 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\search_api_opensearch\Unit\Plugin\processor; use Drupal\search_api\Datasource\DatasourceInterface; use Drupal\search_api\IndexInterface; use Drupal\search_api\Item\Field; use Drupal\search_api\Item\Item; use Drupal\search_api\Utility\FieldsHelper; use Drupal\search_api_opensearch\Plugin\search_api\processor\DateRange; use Drupal\Tests\UnitTestCase; /** * Tests the date range processor. * * @coversDefaultClass \Drupal\search_api_opensearch\Plugin\search_api\processor\DateRange * @group search_api_opensearch */ class DateRangeTest extends UnitTestCase { /** * Test making date range field types compatible with OS. * * @covers ::preprocessIndexItems * @dataProvider dateValueDataProvider */ public function testPreProcessingDateRangeItems( array $extractItemResult, array $expectedResult ): void { $dataSource = $this->prophesize(DatasourceInterface::class); $dataSource->getPluginId()->willReturn('entity:node'); $index = $this->prophesize(IndexInterface::class); $indexId = "index_" . $this->randomMachineName(); $index->id()->willReturn($indexId); $itemId = "item1_" . $this->randomMachineName(); $item = (new Item($index->reveal(), $itemId, $dataSource->reveal())) ->setFieldsExtracted(TRUE) ->setField( 'event_date_range', (new Field($index->reveal(), 'event_date_range')) ->setType("search_api_opensearch_date_range") ->setPropertyPath('field_event_instance') ); $fieldsHelper = $this->prophesize(FieldsHelper::class); $fieldsHelper->extractItemValues([$item], [ 'entity:node' => [ 'field_event_instance:value' => 'start', 'field_event_instance:end_value' => 'end', ], ])->willReturn($extractItemResult); $dateRange = new DateRange([], 'search_api_opensearch_date_range', []); $dateRange->setFieldsHelper($fieldsHelper->reveal()); $dateRange->preprocessIndexItems([$item]); $fieldValues = $item->getField('event_date_range')->getValues(); $this->assertEquals($expectedResult, $fieldValues); } /** * Provides dummy date range data. */ public function dateValueDataProvider(): array { return [ 'Single date range' => [ [ [ 'start' => [ '2022-07-01T09:30:00', ], 'end' => [ '2022-07-01T13:00:00', ], ], ], [ [ 'gte' => '2022-07-01T09:30:00', 'lte' => '2022-07-01T13:00:00', ], ], ], 'Multiple date ranges' => [ [ [ 'start' => [ '2022-07-01T09:30:00', '2022-08-05T09:30:00', ], 'end' => [ '2022-07-01T13:00:00', '2022-08-05T13:00:00', ], ], ], [ [ 'gte' => '2022-07-01T09:30:00', 'lte' => '2022-07-01T13:00:00', ], [ 'gte' => '2022-08-05T09:30:00', 'lte' => '2022-08-05T13:00:00', ], ], ], 'No date ranges' => [ [ [ 'start' => [], 'end' => [], ], ], [], ], ]; } }