diff --git a/Classes/Connection/Elasticsearch.php b/Classes/Connection/Elasticsearch.php
index 3c518e7..82945a6 100644
--- a/Classes/Connection/Elasticsearch.php
+++ b/Classes/Connection/Elasticsearch.php
@@ -82,17 +82,32 @@ class Elasticsearch implements Singleton, ConnectionInterface
public function add($documentType, array $document)
{
- throw new \Exception('Implement', 1481190734);
+ $this->withType(
+ $documentType,
+ function ($type) use($document) {
+ $type->addDocument($this->documentFactory->getDocument($documentType, $document));
+ }
+ );
}
public function delete($documentType, $identifier)
{
- throw new \Exception('Implement', 1481190734);
+ $this->withType(
+ $documentType,
+ function ($type) use($identifier) {
+ $type->deleteById($identifier);
+ }
+ );
}
public function update($documentType, array $document)
{
- throw new \Exception('Implement', 1481190734);
+ $this->withType(
+ $documentType,
+ function ($type) use($documentType) {
+ $type->updateDocument($this->documentFactory->getDocument($documentType, $document));
+ }
+ );
}
/**
@@ -103,18 +118,24 @@ class Elasticsearch implements Singleton, ConnectionInterface
*/
public function addDocuments($documentType, array $documents)
{
- $type = $this->typeFactory->getType(
- $this->indexFactory->getIndex(
- $this->connection,
- $documentType
- ),
- $documentType
- );
-
- $type->addDocuments(
- $this->documentFactory->getDocuments($documentType, $documents)
+ $this->withType(
+ $documentType,
+ function ($type) use($documents) {
+ $type->addDocuments($this->documentFactory->getDocuments($documentType, $documents));
+ }
);
+ }
+ /**
+ * Execute given callback with Elastica Type based on provided documentType
+ *
+ * @param string $documentType
+ * @param callable $callback
+ */
+ protected function withType($documentType, callable $callback)
+ {
+ $type = $this->getType($documentType);
+ $callback($type);
$type->getIndex()->refresh();
}
@@ -132,4 +153,20 @@ class Elasticsearch implements Singleton, ConnectionInterface
// TODO: Return wrapped result to implement our interface.
return $search->search($searchRequest->getSearchTerm());
}
+
+ /**
+ * @param string $documentType
+ *
+ * @return \Elastica\Type
+ */
+ protected function getType($documentType)
+ {
+ return $this->typeFactory->getType(
+ $this->indexFactory->getIndex(
+ $this->connection,
+ $documentType
+ ),
+ $documentType
+ );
+ }
}
diff --git a/Classes/Domain/Index/IndexerInterface.php b/Classes/Domain/Index/IndexerInterface.php
index af5ceca..88972dd 100644
--- a/Classes/Domain/Index/IndexerInterface.php
+++ b/Classes/Domain/Index/IndexerInterface.php
@@ -31,4 +31,11 @@ interface IndexerInterface
* @return void
*/
public function index();
+
+ /**
+ * Index a single record.
+ *
+ * @return void
+ */
+ public function indexRecord($identifier);
}
diff --git a/Classes/Domain/Index/TcaIndexer.php b/Classes/Domain/Index/TcaIndexer.php
index 7e6671a..0205836 100644
--- a/Classes/Domain/Index/TcaIndexer.php
+++ b/Classes/Domain/Index/TcaIndexer.php
@@ -75,6 +75,13 @@ class TcaIndexer implements IndexerInterface
$this->logger->info('Finish indexing');
}
+ public function indexRecord($identifier)
+ {
+ $this->logger->info('Start indexing single record.', [$identifier]);
+ $this->connection->add($this->tcaTableService->getTableName(), $this->getRecord($identifier));
+ $this->logger->info('Finish indexing');
+ }
+
/**
* @return \Generator
*/
@@ -114,4 +121,20 @@ class TcaIndexer implements IndexerInterface
return $records;
}
+
+ /**
+ * @param int $identifier
+ * @return array
+ */
+ protected function getRecord($identifier)
+ {
+ $record = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
+ $this->tcaTableService->getFields(),
+ $this->tcaTableService->getTableName(),
+ $this->tcaTableService->getWhereClause() . ' AND uid = ' . (int) $identifier
+ );
+ $this->tcaTableService->prepareRecord($record);
+
+ return $record;
+ }
}
diff --git a/Classes/Domain/Service/DataHandler.php b/Classes/Domain/Service/DataHandler.php
index 66913e1..6446979 100644
--- a/Classes/Domain/Service/DataHandler.php
+++ b/Classes/Domain/Service/DataHandler.php
@@ -36,6 +36,12 @@ class DataHandler implements Singleton
*/
protected $connection;
+ /**
+ * @var \Leonmrni\SearchCore\Domain\Index\IndexerFactory
+ * @inject
+ */
+ protected $indexerFactory;
+
/**
* @var \TYPO3\CMS\Core\Log\Logger
*/
@@ -51,16 +57,6 @@ class DataHandler implements Singleton
$this->logger = $logManager->getLogger(__CLASS__);
}
- /**
- * @param string $table
- * @param int $identifier
- */
- public function delete($table, $identifier)
- {
- $this->logger->debug('Record received for delete.', [$table, $identifier]);
- $this->connection->delete($table, $identifier);
- }
-
/**
* @param string $table
* @param array $record
@@ -68,7 +64,7 @@ class DataHandler implements Singleton
public function add($table, array $record)
{
$this->logger->debug('Record received for add.', [$table, $record]);
- $this->connection->add($table, $record);
+ $this->indexerFactory->getIndexer($table)->indexRecord($record['uid']);
}
/**
@@ -77,6 +73,16 @@ class DataHandler implements Singleton
public function update($table, array $record)
{
$this->logger->debug('Record received for update.', [$table, $record]);
- $this->connection->update($table, $record);
+ $this->indexerFactory->getIndexer($table)->indexRecord($record['uid']);
+ }
+
+ /**
+ * @param string $table
+ * @param int $identifier
+ */
+ public function delete($table, $identifier)
+ {
+ $this->logger->debug('Record received for delete.', [$table, $identifier]);
+ $this->connection->delete($table, $identifier);
}
}
diff --git a/Classes/Hook/DataHandler.php b/Classes/Hook/DataHandler.php
index a413aa2..c085d90 100644
--- a/Classes/Hook/DataHandler.php
+++ b/Classes/Hook/DataHandler.php
@@ -74,12 +74,14 @@ class DataHandler implements Singleton
*
* @param string $table
* @param int $uid
+ *
+ * @return bool False if hook was not processed.
*/
public function processCmdmap_deleteAction($table, $uid)
{
if (! $this->shouldProcessTable($table)) {
$this->logger->debug('Delete not processed, cause table is not allowed.', [$table]);
- return;
+ return false;
}
$this->dataHandler->delete($table, $uid);
@@ -93,18 +95,20 @@ class DataHandler implements Singleton
* @param string|int $uid
* @param array $fieldArray
* @param CoreDataHandler $dataHandler
+ *
+ * @return bool False if hook was not processed.
*/
public function processDatamap_afterDatabaseOperations($status, $table, $uid, array $fieldArray, CoreDataHandler $dataHandler)
{
if (! $this->shouldProcessTable($table)) {
$this->logger->debug('Database update not processed, cause table is not allowed.', [$table]);
- return;
+ return false;
}
if ($status === 'new') {
$fieldArray['uid'] = $dataHandler->substNEWwithIDs[$uid];
$this->dataHandler->add($table, $fieldArray);
- return;
+ return false;
}
if ($status === 'update') {
@@ -112,7 +116,7 @@ class DataHandler implements Singleton
if ($record !== null) {
$this->dataHandler->update($table, $record);
}
- return;
+ return false;
}
$this->logger->debug(
diff --git a/Classes/Service/DataHandler.php b/Classes/Service/DataHandler.php
deleted file mode 100644
index 0febc5a..0000000
--- a/Classes/Service/DataHandler.php
+++ /dev/null
@@ -1,80 +0,0 @@
-
- *
- * 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\Core\SingletonInterface as Singleton;
-
-/**
- * Handles all data related things like updates, deletes and inserts.
- *
- * This is the place to add mappings of further parts to adjust the data before
- * sending ot to connection.
- */
-class DataHandler implements Singleton
-{
- /**
- * @var \TYPO3\CMS\Core\Log\Logger
- */
- protected $logger;
-
- // TODO: Write construct with inject of connection
-
- /**
- * Inject log manager to get concrete logger from it.
- *
- * @param \TYPO3\CMS\Core\Log\LogManager $logManager
- */
- public function injectLogger(\TYPO3\CMS\Core\Log\LogManager $logManager)
- {
- $this->logger = $logManager->getLogger(__CLASS__);
- }
-
- /**
- * @param string $table
- * @param int $identifier
- */
- public function delete($table, $identifier)
- {
- $this->logger->debug('Record received for delete.', [$table, $identifier]);
- // $this->connection->delete($table, $identifier);
- }
-
- /**
- * @param string $table
- * @param int $identifier
- * @param array $record
- */
- public function add($table, $identifier, array $record)
- {
- $this->logger->debug('Record received for add.', [$table, $identifier, $record]);
- // $this->connection->add($table, $identifier, $record);
- }
-
- /**
- * @param string $table
- * @param int $identifier
- */
- public function update($table, $identifier, array $record)
- {
- $this->logger->debug('Record received for update.', [$table, $identifier, $record]);
- // $this->connection->update($table, $identifier, $record);
- }
-}
diff --git a/Tests/Functional/Fixtures/Hooks/DataHandler.xml b/Tests/Functional/Fixtures/Hooks/DataHandler.xml
new file mode 100644
index 0000000..db3f5ba
--- /dev/null
+++ b/Tests/Functional/Fixtures/Hooks/DataHandler.xml
@@ -0,0 +1,22 @@
+
+
+
+ 6
+ 1
+ 1480686370
+ 1480686370
+ 0
+ 72
+ textmedia
+
+ this is the content of textmedia content element that should get indexed
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
diff --git a/Tests/Functional/Hooks/DataHandlerTest.php b/Tests/Functional/Hooks/DataHandlerTest.php
new file mode 100644
index 0000000..9ca4326
--- /dev/null
+++ b/Tests/Functional/Hooks/DataHandlerTest.php
@@ -0,0 +1,110 @@
+
+ *
+ * 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 Leonmrni\SearchCore\Hook\DataHandler as Hook;
+use Leonmrni\SearchCore\Tests\Functional\FunctionalTestCase;
+use TYPO3\CMS\Core\DataHandling\DataHandler as CoreDataHandler;
+use TYPO3\CMS\Extbase\Object\ObjectManager;
+
+/**
+ *
+ */
+class DataHandlerTest extends FunctionalTestCase
+{
+ public function setUp()
+ {
+ parent::setUp();
+ $this->importDataSet('Tests/Functional/Fixtures/Hooks/DataHandler.xml');
+ }
+
+ /**
+ * @test
+ */
+ public function nonAllowedTablesWillNotBeProcessed()
+ {
+ $dataHandler = new CoreDataHandler();
+
+ $hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class);
+ $this->assertFalse($hook->processDatamap_afterDatabaseOperations('new', 'some_strange_table', 'NEW34', [], $dataHandler));
+ $this->assertFalse($hook->processDatamap_afterDatabaseOperations('update', 'some_strange_table', 6, [], $dataHandler));
+ $this->assertFalse($hook->processCmdmap_deleteAction('some_strange_table', 6, [], false, $dataHandler));
+ }
+
+ /**
+ * @test
+ */
+ public function addNewElement()
+ {
+ $dataHandler = new CoreDataHandler();
+ $dataHandler->substNEWwithIDs = ['NEW34' => 6];
+
+ $hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class);
+ $hook->processDatamap_afterDatabaseOperations('new', 'tt_content', 'NEW34', [], $dataHandler);
+
+ $response = $this->client->request('typo3content/_search?q=*:*');
+ $this->assertTrue($response->isOK());
+ $this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document was indexed.');
+ }
+
+ /**
+ * @test
+ * TODO: Make sure the indexed document was updated, e.g. by changing some content.
+ */
+ public function updateExistingElement()
+ {
+ $dataHandler = new CoreDataHandler();
+ $hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class);
+ $hook->processDatamap_afterDatabaseOperations('update', 'tt_content', 6, [], $dataHandler);
+
+ $response = $this->client->request('typo3content/_search?q=*:*');
+ $this->assertTrue($response->isOK());
+ $this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document was indexed.');
+ }
+
+ /**
+ * @test
+ */
+ public function deleteExistingElement()
+ {
+ $this->addNewElement();
+ $dataHandler = new CoreDataHandler();
+ $hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class);
+ $hook->processCmdmap_deleteAction('tt_content', 6, [], false, $dataHandler);
+
+ $response = $this->client->request('typo3content/_search?q=*:*');
+ $this->assertTrue($response->isOK());
+ $this->assertSame($response->getData()['hits']['total'], 0, 'Not exactly 0 document was indexed.');
+ }
+
+ /**
+ * @test
+ * @expectedException \Elastica\Exception\ResponseException
+ */
+ public function someUnkownOperationDoesNotBreakSomething()
+ {
+ $dataHandler = new CoreDataHandler();
+ $hook = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(Hook::class);
+ $hook->processDatamap_afterDatabaseOperations('something', 'tt_content', 6, [], $dataHandler);
+
+ $response = $this->client->request('typo3content/_search?q=*:*');
+ }
+}
diff --git a/Tests/Functional/Indexing/IndexTcaTableTest.php b/Tests/Functional/Indexing/IndexTcaTableTest.php
index 96d113f..fc2ce65 100644
--- a/Tests/Functional/Indexing/IndexTcaTableTest.php
+++ b/Tests/Functional/Indexing/IndexTcaTableTest.php
@@ -85,6 +85,4 @@ class IndexTcaTableTest extends FunctionalTestCase
$this->assertTrue($response->isOK());
$this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document was indexed.');
}
-
- // TODO: Add tests for hook.
}
diff --git a/Tests/Unit/UnitTests.xml b/Tests/Unit/UnitTests.xml
index 63627f9..67719fc 100644
--- a/Tests/Unit/UnitTests.xml
+++ b/Tests/Unit/UnitTests.xml
@@ -27,8 +27,8 @@
-
-
+
+