Merge pull request #96 from Codappix/feature/refactor-dataprocessing

!!!|FEATURE: Make data processing available to all indexer
This commit is contained in:
Daniel Siepmann 2017-11-10 22:05:49 +01:00 committed by GitHub
commit 689d8f0c53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\InvalidArgumentException; use Codappix\SearchCore\Configuration\InvalidArgumentException;
use Codappix\SearchCore\Connection\ConnectionInterface; 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 abstract class AbstractIndexer implements IndexerInterface
{ {
@ -130,6 +131,32 @@ abstract class AbstractIndexer implements IndexerInterface
* @param array &$record * @param array &$record
*/ */
protected function prepareRecord(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'] = ''; $record['search_abstract'] = '';

View file

@ -22,7 +22,6 @@ namespace Codappix\SearchCore\Domain\Index\TcaIndexer;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface; use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\InvalidArgumentException as InvalidConfigurationArgumentException; use Codappix\SearchCore\Configuration\InvalidArgumentException as InvalidConfigurationArgumentException;
use Codappix\SearchCore\DataProcessing\ProcessorInterface;
use Codappix\SearchCore\Database\Doctrine\Join; use Codappix\SearchCore\Database\Doctrine\Join;
use Codappix\SearchCore\Database\Doctrine\Where; use Codappix\SearchCore\Database\Doctrine\Where;
use Codappix\SearchCore\Domain\Index\IndexingException; use Codappix\SearchCore\Domain\Index\IndexingException;
@ -141,31 +140,12 @@ class TcaTableService
} }
/** /**
* Adjust record accordingly to configuration.
* @param array &$record * @param array &$record
*/ */
public function prepareRecord(array &$record) : void public function prepareRecord(array &$record) : void
{ {
$this->relationResolver->resolveRelationsForRecord($this, $record); $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'])) { if (isset($record['uid']) && !isset($record['search_identifier'])) {
$record['search_identifier'] = $record['uid']; $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']); 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.'
);
}
} }