mirror of
https://github.com/Codappix/search_core.git
synced 2024-11-22 14:16:11 +01:00
FEATURE: Provide form finisher for integration into form extension
Provide a finisher, working as a proxy, to internal data handler, which is already used for Hooks in TYPO3 backend.
This commit is contained in:
parent
ea8eb8148e
commit
31202f8882
5 changed files with 278 additions and 0 deletions
71
Classes/Integration/Form/Finisher/DataHandlerFinisher.php
Normal file
71
Classes/Integration/Form/Finisher/DataHandlerFinisher.php
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
namespace Codappix\SearchCore\Integration\Form\Finisher;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher;
|
||||||
|
use TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integrates search_core indexing into TYPO3 Form extension.
|
||||||
|
*
|
||||||
|
* Add this finisher AFTER all database operations, as search_core will fetch
|
||||||
|
* information from database.
|
||||||
|
*/
|
||||||
|
class DataHandlerFinisher extends AbstractFinisher
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Codappix\SearchCore\Domain\Service\DataHandler
|
||||||
|
* @inject
|
||||||
|
*/
|
||||||
|
protected $dataHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $defaultOptions = [
|
||||||
|
'indexIdentifier' => null,
|
||||||
|
'recordUid' => null,
|
||||||
|
'action' => '',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected function executeInternal()
|
||||||
|
{
|
||||||
|
$action = $this->parseOption('action');
|
||||||
|
$record = ['uid' => (int) $this->parseOption('recordUid')];
|
||||||
|
$tableName = $this->parseOption('indexIdentifier');
|
||||||
|
|
||||||
|
if ($action === '' || $tableName === '' || !is_string($tableName) || $record['uid'] === 0) {
|
||||||
|
throw new FinisherException('Not all necessary options were set.', 1510313095);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($action) {
|
||||||
|
case 'update':
|
||||||
|
$this->dataHandler->update($tableName, $record);
|
||||||
|
break;
|
||||||
|
case 'add':
|
||||||
|
$this->dataHandler->add($tableName, $record);
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
$this->dataHandler->delete($tableName, $record['uid']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,8 @@ configuration needs. Still it's possible to configure the indexer.
|
||||||
|
|
||||||
Also custom classes can be used as indexers.
|
Also custom classes can be used as indexers.
|
||||||
|
|
||||||
|
Furthermore a finisher for TYPO3 Form-Extension is provided to integrate indexing.
|
||||||
|
|
||||||
.. _features_search:
|
.. _features_search:
|
||||||
|
|
||||||
Searching
|
Searching
|
||||||
|
|
|
@ -30,6 +30,34 @@ The tables have to be configured via :ref:`configuration_options_index`.
|
||||||
|
|
||||||
Not all hook operations are supported yet, see :issue:`27`.
|
Not all hook operations are supported yet, see :issue:`27`.
|
||||||
|
|
||||||
|
.. _usage_form_finisher:
|
||||||
|
|
||||||
|
Form finisher
|
||||||
|
-------------
|
||||||
|
|
||||||
|
A form finisher is provided to integrate indexing into form extension.
|
||||||
|
|
||||||
|
Add form finisher to your available finishers and configure it like:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
:linenos:
|
||||||
|
|
||||||
|
-
|
||||||
|
identifier: SearchCoreIndexer
|
||||||
|
options:
|
||||||
|
action: 'delete'
|
||||||
|
indexIdentifier: 'fe_users'
|
||||||
|
recordUid: '{FeUser.user.uid}'
|
||||||
|
|
||||||
|
All three options are necessary, where
|
||||||
|
|
||||||
|
``action``
|
||||||
|
Is one of ``delete``, ``update`` or ``add``.
|
||||||
|
``indexIdentifier``
|
||||||
|
Is a configured index identifier.
|
||||||
|
``recordUid``
|
||||||
|
Has to be the uid of the record to index.
|
||||||
|
|
||||||
.. _usage_searching:
|
.. _usage_searching:
|
||||||
|
|
||||||
Searching / Frontend Plugin
|
Searching / Frontend Plugin
|
||||||
|
|
|
@ -21,13 +21,23 @@ namespace Codappix\SearchCore\Tests\Unit;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use TYPO3\CMS\Core\Tests\UnitTestCase as CoreTestCase;
|
use TYPO3\CMS\Core\Tests\UnitTestCase as CoreTestCase;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||||
|
use TYPO3\CMS\Form\Service\TranslationService;
|
||||||
|
|
||||||
abstract class AbstractUnitTestCase extends CoreTestCase
|
abstract class AbstractUnitTestCase extends CoreTestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var array A backup of registered singleton instances
|
||||||
|
*/
|
||||||
|
protected $singletonInstances = [];
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->singletonInstances = GeneralUtility::getSingletonInstances();
|
||||||
|
|
||||||
// Disable caching backends to make TYPO3 parts work in unit test mode.
|
// Disable caching backends to make TYPO3 parts work in unit test mode.
|
||||||
|
|
||||||
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
|
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
|
||||||
|
@ -39,6 +49,12 @@ abstract class AbstractUnitTestCase extends CoreTestCase
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function tearDown()
|
||||||
|
{
|
||||||
|
GeneralUtility::resetSingletonInstances($this->singletonInstances);
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \TYPO3\CMS\Core\Log\LogManager
|
* @return \TYPO3\CMS\Core\Log\LogManager
|
||||||
*/
|
*/
|
||||||
|
@ -58,4 +74,25 @@ abstract class AbstractUnitTestCase extends CoreTestCase
|
||||||
|
|
||||||
return $logger;
|
return $logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure translation service mock for Form Finisher.
|
||||||
|
*
|
||||||
|
* This way parseOption will always return the configured value.
|
||||||
|
*/
|
||||||
|
protected function configureMockedTranslationService()
|
||||||
|
{
|
||||||
|
$translationService = $this->getMockBuilder(TranslationService::class)->getMock();
|
||||||
|
$translationService->expects($this->any())
|
||||||
|
->method('translateFinisherOption')
|
||||||
|
->willReturnCallback(function ($formRuntime, $finisherIdentifier, $optionKey, $optionValue) {
|
||||||
|
return $optionValue;
|
||||||
|
});
|
||||||
|
$objectManager = $this->getMockBuilder(ObjectManager::class)->getMock();
|
||||||
|
$objectManager->expects($this->any())
|
||||||
|
->method('get')
|
||||||
|
->with(TranslationService::class)
|
||||||
|
->willReturn($translationService);
|
||||||
|
GeneralUtility::setSingletonInstance(ObjectManager::class, $objectManager);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
140
Tests/Unit/Integration/Form/Finisher/DataHandlerFinisherTest.php
Normal file
140
Tests/Unit/Integration/Form/Finisher/DataHandlerFinisherTest.php
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
<?php
|
||||||
|
namespace Codappix\SearchCore\Tests\Unit\Integration\Form\Finisher;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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\Domain\Service\DataHandler;
|
||||||
|
use Codappix\SearchCore\Integration\Form\Finisher\DataHandlerFinisher;
|
||||||
|
use Codappix\SearchCore\Tests\Unit\AbstractUnitTestCase;
|
||||||
|
use TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException;
|
||||||
|
use TYPO3\CMS\Form\Domain\Finishers\FinisherContext;
|
||||||
|
|
||||||
|
class DataHandlerFinisherTest extends AbstractUnitTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var DataHandlerFinisher
|
||||||
|
*/
|
||||||
|
protected $subject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DataHandler
|
||||||
|
*/
|
||||||
|
protected $dataHandlerMock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FinisherContext
|
||||||
|
*/
|
||||||
|
protected $finisherContextMock;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->configureMockedTranslationService();
|
||||||
|
$this->dataHandlerMock = $this->getMockBuilder(DataHandler::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$this->finisherContextMock = $this->getMockBuilder(FinisherContext::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$this->subject = new DataHandlerFinisher();
|
||||||
|
$this->inject($this->subject, 'dataHandler', $this->dataHandlerMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @dataProvider possibleFinisherSetup
|
||||||
|
*/
|
||||||
|
public function validConfiguration(string $action, array $nonCalledActions, $expectedSecondArgument)
|
||||||
|
{
|
||||||
|
$this->subject->setOptions([
|
||||||
|
'indexIdentifier' => 'test_identifier',
|
||||||
|
'recordUid' => '23',
|
||||||
|
'action' => $action,
|
||||||
|
]);
|
||||||
|
|
||||||
|
foreach ($nonCalledActions as $nonCalledAction) {
|
||||||
|
$this->dataHandlerMock->expects($this->never())->method($nonCalledAction);
|
||||||
|
}
|
||||||
|
$this->dataHandlerMock->expects($this->once())->method($action)
|
||||||
|
->with('test_identifier', $expectedSecondArgument);
|
||||||
|
|
||||||
|
$this->subject->execute($this->finisherContextMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function possibleFinisherSetup() : array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'valid add configuration' => [
|
||||||
|
'action' => 'add',
|
||||||
|
'nonCalledActions' => ['delete', 'update'],
|
||||||
|
'expectedSecondArgument' => ['uid' => 23],
|
||||||
|
],
|
||||||
|
'valid update configuration' => [
|
||||||
|
'action' => 'update',
|
||||||
|
'nonCalledActions' => ['delete', 'add'],
|
||||||
|
'expectedSecondArgument' => ['uid' => 23],
|
||||||
|
],
|
||||||
|
'valid delete configuration' => [
|
||||||
|
'action' => 'delete',
|
||||||
|
'nonCalledActions' => ['update', 'add'],
|
||||||
|
'expectedSecondArgument' => 23,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @dataProvider invalidFinisherSetup
|
||||||
|
*/
|
||||||
|
public function nothingHappensIfUnknownActionIsConfigured(array $options)
|
||||||
|
{
|
||||||
|
$this->subject->setOptions($options);
|
||||||
|
|
||||||
|
foreach (['add', 'update', 'delete'] as $nonCalledAction) {
|
||||||
|
$this->dataHandlerMock->expects($this->never())->method($nonCalledAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->expectException(FinisherException::class);
|
||||||
|
$this->subject->execute($this->finisherContextMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function invalidFinisherSetup() : array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'missing options' => [
|
||||||
|
'options' => [],
|
||||||
|
],
|
||||||
|
'missing action option' => [
|
||||||
|
'options' => [
|
||||||
|
'indexIdentifier' => 'identifier',
|
||||||
|
'recordUid' => '20',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'missing record uid option' => [
|
||||||
|
'options' => [
|
||||||
|
'indexIdentifier' => 'identifier',
|
||||||
|
'action' => 'update',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue