!!!|FEATURE: Make data processing available to all indexer

Before data processing was applied for TCA only, through tca table
service.
Now it's applied much later in process and in abstract indexer.
Therefore all indexer will run data processing if configured.
This commit is contained in:
Daniel Siepmann 2017-11-08 21:05:53 +01:00
parent 43ec410eb5
commit e1a14b2f04
Signed by: Daniel Siepmann
GPG key ID: 33D6629915560EF4
4 changed files with 149 additions and 94 deletions

View file

@ -23,7 +23,8 @@ namespace Codappix\SearchCore\Domain\Index;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\InvalidArgumentException;
use Codappix\SearchCore\Connection\ConnectionInterface;
use \TYPO3\CMS\Core\Utility\GeneralUtility;
use Codappix\SearchCore\DataProcessing\ProcessorInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
abstract class AbstractIndexer implements IndexerInterface
{
@ -122,6 +123,32 @@ abstract class AbstractIndexer implements IndexerInterface
* @param array &$record
*/
protected function prepareRecord(array &$record)
{
try {
foreach ($this->configuration->get('indexing.' . $this->identifier . '.dataProcessing') as $configuration) {
$className = '';
if (is_string($configuration)) {
$className = $configuration;
$configuration = [];
} else {
$className = $configuration['_typoScriptNodeValue'];
}
$dataProcessor = GeneralUtility::makeInstance($className);
if ($dataProcessor instanceof ProcessorInterface) {
$record = $dataProcessor->processRecord($record, $configuration);
}
}
} catch (InvalidArgumentException $e) {
// Nothing to do.
}
$this->handleAbstract($record);
}
/**
* @param array &$record
*/
protected function handleAbstract(array &$record)
{
$record['search_abstract'] = '';

View file

@ -22,7 +22,6 @@ namespace Codappix\SearchCore\Domain\Index\TcaIndexer;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\InvalidArgumentException as InvalidConfigurationArgumentException;
use Codappix\SearchCore\DataProcessing\ProcessorInterface;
use Codappix\SearchCore\Database\Doctrine\Join;
use Codappix\SearchCore\Database\Doctrine\Where;
use Codappix\SearchCore\Domain\Index\IndexingException;
@ -141,31 +140,12 @@ class TcaTableService
}
/**
* Adjust record accordingly to configuration.
* @param array &$record
*/
public function prepareRecord(array &$record) : void
{
$this->relationResolver->resolveRelationsForRecord($this, $record);
try {
foreach ($this->configuration->get('indexing.' . $this->tableName . '.dataProcessing') as $configuration) {
$className = '';
if (is_string($configuration)) {
$className = $configuration;
$configuration = [];
} else {
$className = $configuration['_typoScriptNodeValue'];
}
$dataProcessor = GeneralUtility::makeInstance($className);
if ($dataProcessor instanceof ProcessorInterface) {
$record = $dataProcessor->processRecord($record, $configuration);
}
}
} catch (InvalidConfigurationArgumentException $e) {
// Nothing to do.
}
if (isset($record['uid']) && !isset($record['search_identifier'])) {
$record['search_identifier'] = $record['uid'];
}

View file

@ -0,0 +1,121 @@
<?php
namespace Codappix\SearchCore\Tests\Unit\Domain\Index;
/*
* Copyright (C) 2017 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\InvalidArgumentException;
use Codappix\SearchCore\Connection\ConnectionInterface;
use Codappix\SearchCore\DataProcessing\CopyToProcessor;
use Codappix\SearchCore\Domain\Index\AbstractIndexer;
use Codappix\SearchCore\Tests\Unit\AbstractUnitTestCase;
class AbstractIndexerTest extends AbstractUnitTestCase
{
/**
* @var TcaTableService
*/
protected $subject;
/**
* @var ConfigurationContainerInterface
*/
protected $configuration;
/**
* @var ConnectionInterface
*/
protected $connection;
public function setUp()
{
parent::setUp();
$this->configuration = $this->getMockBuilder(ConfigurationContainerInterface::class)->getMock();
$this->connection = $this->getMockBuilder(ConnectionInterface::class)->getMock();
$this->subject = $this->getMockForAbstractClass(AbstractIndexer::class, [
$this->connection,
$this->configuration
]);
$this->subject->injectLogger($this->getMockedLogger());
$this->subject->setIdentifier('testTable');
$this->subject->expects($this->any())
->method('getDocumentName')
->willReturn('testTable');
}
/**
* @test
*/
public function executesConfiguredDataProcessingWithConfiguration()
{
$record = ['field 1' => 'test'];
$expectedRecord = $record;
$expectedRecord['new_test_field'] = 'test';
$expectedRecord['new_test_field2'] = 'test' . PHP_EOL . 'test';
$expectedRecord['search_abstract'] = '';
$this->configuration->expects($this->exactly(2))
->method('get')
->withConsecutive(['indexing.testTable.dataProcessing'], ['indexing.testTable.abstractFields'])
->will($this->onConsecutiveCalls([
'1' => [
'_typoScriptNodeValue' => CopyToProcessor::class,
'to' => 'new_test_field',
],
'2' => [
'_typoScriptNodeValue' => CopyToProcessor::class,
'to' => 'new_test_field2',
],
], $this->throwException(new InvalidArgumentException)));
$this->subject->expects($this->once())
->method('getRecord')
->with(1)
->willReturn($record)
;
$this->connection->expects($this->once())->method('addDocument')->with('testTable', $expectedRecord);
$this->subject->indexDocument(1);
}
/**
* @test
*/
public function executesNoDataProcessingForMissingConfiguration()
{
$record = ['field 1' => 'test'];
$expectedRecord = $record;
$expectedRecord['search_abstract'] = '';
$this->configuration->expects($this->exactly(2))
->method('get')
->withConsecutive(['indexing.testTable.dataProcessing'], ['indexing.testTable.abstractFields'])
->will($this->throwException(new InvalidArgumentException));
$this->subject->expects($this->once())
->method('getRecord')
->with(1)
->willReturn($record)
;
$this->connection->expects($this->once())->method('addDocument')->with('testTable', $expectedRecord);
$this->subject->indexDocument(1);
}
}

View file

@ -148,77 +148,4 @@ class TcaTableServiceTest extends AbstractUnitTestCase
);
unset($GLOBALS['TCA']['test_table']);
}
/**
* @test
*/
public function executesConfiguredDataProcessingWithConfiguration()
{
$this->configuration->expects($this->exactly(1))
->method('get')
->with('indexing.testTable.dataProcessing')
->will($this->returnValue([
'1' => [
'_typoScriptNodeValue' => CopyToProcessor::class,
'to' => 'new_test_field',
],
'2' => [
'_typoScriptNodeValue' => CopyToProcessor::class,
'to' => 'new_test_field2',
],
]));
$subject = $this->getMockBuilder(TcaTableService::class)
->disableOriginalConstructor()
->setMethodsExcept(['prepareRecord'])
->getMock();
$this->inject($subject, 'configuration', $this->configuration);
$this->inject($subject, 'tableName', 'testTable');
$this->inject($subject, 'relationResolver', $this->getMockBuilder(RelationResolver::class)->getMock());
$record = ['field 1' => 'test'];
$expectedRecord = $record;
$expectedRecord['new_test_field'] = 'test';
$expectedRecord['new_test_field2'] = 'test' . PHP_EOL . 'test';
$subject->prepareRecord($record);
$this->assertSame(
$expectedRecord,
$record,
'Dataprocessing is not executed by TcaTableService as expected.'
);
}
/**
* @test
*/
public function executesConfiguredDataProcessingWithoutConfiguration()
{
$this->configuration->expects($this->exactly(1))
->method('get')
->with('indexing.testTable.dataProcessing')
->will($this->returnValue([CopyToProcessor::class]));
$subject = $this->getMockBuilder(TcaTableService::class)
->disableOriginalConstructor()
->setMethodsExcept(['prepareRecord'])
->getMock();
$this->inject($subject, 'configuration', $this->configuration);
$this->inject($subject, 'tableName', 'testTable');
$this->inject($subject, 'relationResolver', $this->getMockBuilder(RelationResolver::class)->getMock());
$record = ['field 1' => 'test'];
$expectedRecord = $record;
$expectedRecord[''] = 'test';
$expectedRecord['search_title'] = 'test';
$subject->prepareRecord($record);
$this->assertSame(
$expectedRecord,
$record,
'Dataprocessing is not executed by TcaTableService as expected.'
);
}
}