mirror of
https://github.com/Codappix/search_core.git
synced 2024-11-21 13:16:12 +01:00
TASK: Migrate existing code (#2)
This commit is contained in:
parent
d89e616a4f
commit
b079dd8125
28 changed files with 1355 additions and 30 deletions
|
@ -20,6 +20,7 @@ namespace Leonmrni\SearchCore\Command;
|
|||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use Leonmrni\SearchCore\Domain\Index\IndexerFactory;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
|
||||
|
||||
/**
|
||||
|
@ -27,6 +28,19 @@ use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
|
|||
*/
|
||||
class IndexCommandController extends CommandController
|
||||
{
|
||||
/**
|
||||
* @var IndexerFactory
|
||||
*/
|
||||
protected $indexerFactory;
|
||||
|
||||
/**
|
||||
* @param IndexerFactory $factory
|
||||
*/
|
||||
public function injectIndexerFactory(IndexerFactory $factory)
|
||||
{
|
||||
$this->indexerFactory = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will index the given table or everything.
|
||||
*
|
||||
|
@ -36,5 +50,6 @@ class IndexCommandController extends CommandController
|
|||
{
|
||||
// TODO: Allow to index multiple tables at once?
|
||||
// TODO: Also allow to index everything?
|
||||
$this->indexerFactory->getIndexer($table)->index();
|
||||
}
|
||||
}
|
||||
|
|
75
Classes/Connection/ConnectionInterface.php
Normal file
75
Classes/Connection/ConnectionInterface.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Connection;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines interface for connections to storage backend for interacting with documents.
|
||||
*/
|
||||
interface ConnectionInterface
|
||||
{
|
||||
/**
|
||||
* Will add a new document, based on his identifier and record type.
|
||||
*
|
||||
* @param string $recordType
|
||||
* @param int $identifier
|
||||
* @param array $record
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public function add($recordType, $identifier, array $record);
|
||||
|
||||
/**
|
||||
* Add the given records.
|
||||
*
|
||||
* @param string $recordType
|
||||
* @param array $records
|
||||
*/
|
||||
public function addDocuments($recordType, array $records);
|
||||
|
||||
/**
|
||||
* Will update an existing document, based on his identifier and record type.
|
||||
*
|
||||
* @param string $recordType
|
||||
* @param int $identifier
|
||||
* @param array $record
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public function update($recordType, $identifier, array $record);
|
||||
|
||||
/**
|
||||
* Will remove an existing document, based on his identifier and record type.
|
||||
*
|
||||
* @param string $recordType
|
||||
* @param int $identifier
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public function delete($recordType, $identifier);
|
||||
|
||||
/**
|
||||
* Search by given request and return result.
|
||||
*
|
||||
* @param SearchRequestInterface $searchRequest
|
||||
* @return SearchResultInterface
|
||||
*/
|
||||
public function search(SearchRequestInterface $searchRequest);
|
||||
}
|
140
Classes/Connection/Elasticsearch.php
Normal file
140
Classes/Connection/Elasticsearch.php
Normal file
|
@ -0,0 +1,140 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Connection;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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\Core\SingletonInterface as Singleton;
|
||||
|
||||
/**
|
||||
* Outer wrapper to elasticsearch.
|
||||
*/
|
||||
class Elasticsearch implements Singleton, ConnectionInterface
|
||||
{
|
||||
/**
|
||||
* @var Elasticsearch\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var IndexFactory
|
||||
*/
|
||||
protected $indexFactory;
|
||||
|
||||
/**
|
||||
* @var TypeFactory
|
||||
*/
|
||||
protected $typeFactory;
|
||||
|
||||
/**
|
||||
* @var DocumentFactory
|
||||
*/
|
||||
protected $documentFactory;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Log\Logger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* 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 Elasticsearch\Connection $connection
|
||||
* @param Elasticsearch\IndexFactory $indexFactory
|
||||
* @param Elasticsearch\TypeFactory $typeFactory
|
||||
* @param Elasticsearch\DocumentFactory $documentFactory
|
||||
*/
|
||||
public function __construct(
|
||||
Elasticsearch\Connection $connection,
|
||||
Elasticsearch\IndexFactory $indexFactory,
|
||||
Elasticsearch\TypeFactory $typeFactory,
|
||||
Elasticsearch\DocumentFactory $documentFactory
|
||||
) {
|
||||
$this->connection = $connection;
|
||||
$this->indexFactory = $indexFactory;
|
||||
$this->typeFactory = $typeFactory;
|
||||
$this->documentFactory = $documentFactory;
|
||||
}
|
||||
|
||||
public function add($recordType, $identifier, array $record)
|
||||
{
|
||||
throw new \Exception('Implement', 1481190734);
|
||||
}
|
||||
|
||||
public function delete($recordType, $identifier)
|
||||
{
|
||||
throw new \Exception('Implement', 1481190734);
|
||||
}
|
||||
|
||||
public function update($tableName, $identifier, array $record)
|
||||
{
|
||||
$this->addDocument($tableName, $identifier, $record);
|
||||
}
|
||||
|
||||
protected function addDocument($tableName, $identifier, array $record)
|
||||
{
|
||||
throw new \Exception('Implement', 1481192791);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given records to elasticsearch.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param array $records
|
||||
*/
|
||||
public function addDocuments($tableName, array $records)
|
||||
{
|
||||
$type = $this->typeFactory->getType(
|
||||
$this->indexFactory->getIndex(
|
||||
$this->connection,
|
||||
$tableName
|
||||
),
|
||||
$tableName
|
||||
);
|
||||
|
||||
$type->addDocuments(
|
||||
$this->documentFactory->getDocuments($tableName, $records)
|
||||
);
|
||||
|
||||
$type->getIndex()->refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SearchRequestInterface $searchRequest
|
||||
* @return SearchResultInterface
|
||||
*/
|
||||
public function search(SearchRequestInterface $searchRequest)
|
||||
{
|
||||
$this->logger->debug('Search for', [$searchRequest->getSearchTerm()]);
|
||||
|
||||
$search = new \Elastica\Search($this->connection->getClient());
|
||||
$search->addIndex('typo3content');
|
||||
|
||||
// TODO: Return wrapped result to implement our interface.
|
||||
return $search->search($searchRequest->getSearchTerm());
|
||||
}
|
||||
}
|
95
Classes/Connection/Elasticsearch/Connection.php
Normal file
95
Classes/Connection/Elasticsearch/Connection.php
Normal file
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Connection\Elasticsearch;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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\Core\SingletonInterface as Singleton;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
|
||||
/**
|
||||
* The current connection to elasticsearch.
|
||||
*
|
||||
* Wrapper for Elastica\Client.
|
||||
*/
|
||||
class Connection implements Singleton
|
||||
{
|
||||
/**
|
||||
* @var \Elastica\Client
|
||||
*/
|
||||
protected $elasticaClient;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @param \Elastica\Client $elasticaClient
|
||||
*/
|
||||
public function __construct(\Elastica\Client $elasticaClient = null)
|
||||
{
|
||||
$this->elasticaClient = $elasticaClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject news settings via ConfigurationManager.
|
||||
*
|
||||
* TODO: Refactor to configuration object to have a singleton holding the
|
||||
* settings with validation and propper getter?
|
||||
*
|
||||
* @param \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface $configurationManager
|
||||
*/
|
||||
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager)
|
||||
{
|
||||
$this->settings = $configurationManager->getConfiguration(
|
||||
ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS,
|
||||
'SearchCore',
|
||||
'search'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to configure elasticaClient if no one was injected. Will use
|
||||
* injected settings for configuration.
|
||||
*/
|
||||
public function initializeObject()
|
||||
{
|
||||
if ($this->elasticaClient === null) {
|
||||
$this->elasticaClient = new \Elastica\Client([
|
||||
'host' => $this->settings['host'],
|
||||
'port' => $this->settings['port'],
|
||||
// TODO: Make configurable
|
||||
// 'log' => 'file',
|
||||
]);
|
||||
// TODO: Make configurable.
|
||||
// new \Elastica\Log($this->elasticaClient);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the concrete client for internal usage!
|
||||
*
|
||||
* @return \Elastica\Client
|
||||
*/
|
||||
public function getClient()
|
||||
{
|
||||
return $this->elasticaClient;
|
||||
}
|
||||
}
|
82
Classes/Connection/Elasticsearch/DocumentFactory.php
Normal file
82
Classes/Connection/Elasticsearch/DocumentFactory.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Connection\Elasticsearch;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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\Core\SingletonInterface as Singleton;
|
||||
|
||||
/**
|
||||
* Factory to create documents to index in Elasticsearch.
|
||||
*/
|
||||
class DocumentFactory implements Singleton
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Log\Logger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* 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__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates document from record.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param array $record
|
||||
*
|
||||
* @return \Elastica\Document
|
||||
*/
|
||||
public function getDocument($tableName, array $record)
|
||||
{
|
||||
if (!isset($record['search_identifier'])) {
|
||||
throw new \Exception('No search_identifier provided for record.', 1481194385);
|
||||
}
|
||||
|
||||
$identifier = $record['search_identifier'];
|
||||
unset($record['search_identifier']);
|
||||
|
||||
$this->logger->debug('Convert record to document', [$identifier, $record]);
|
||||
return new \Elastica\Document($identifier, $record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates documents based on records.
|
||||
*
|
||||
* @param string $tableName
|
||||
* @param array $records
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDocuments($tableName, array $records)
|
||||
{
|
||||
foreach ($records as &$record) {
|
||||
$record = $this->getDocument($tableName, $record);
|
||||
}
|
||||
|
||||
return $records;
|
||||
}
|
||||
}
|
58
Classes/Connection/Elasticsearch/IndexFactory.php
Normal file
58
Classes/Connection/Elasticsearch/IndexFactory.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Connection\Elasticsearch;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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\Core\SingletonInterface as Singleton;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
|
||||
/**
|
||||
* Factory to get indexes.
|
||||
*
|
||||
* The factory will take care of configuration and creation of index if necessary.
|
||||
*/
|
||||
class IndexFactory implements Singleton
|
||||
{
|
||||
/**
|
||||
* Get an index bases on TYPO3 table name.
|
||||
*
|
||||
* @param Connection $connection
|
||||
* @param string $tableName
|
||||
*
|
||||
* @return \Elastica\Index
|
||||
*/
|
||||
public function getIndex(Connection $connection, $tableName)
|
||||
{
|
||||
// TODO: Fetch index name from configuration, based on $tableName.
|
||||
$index = $connection->getClient()->getIndex('typo3content');
|
||||
|
||||
try {
|
||||
// TODO: Provide configuration?!
|
||||
// http://elastica.io/getting-started/storing-and-indexing-documents.html#section-analysis
|
||||
$index->create();
|
||||
} catch (\Elastica\Exception\ResponseException $exception) {
|
||||
if (stripos($exception->getMessage(), 'already exists') === false) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
return $index;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Tests\Fakes;
|
||||
namespace Leonmrni\SearchCore\Connection\Elasticsearch;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Daniel Siepmann <daniel.siepmann@typo3.org>
|
||||
* Copyright (C) 2016 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
|
||||
|
@ -20,20 +20,12 @@ namespace Leonmrni\SearchCore\Tests\Fakes;
|
|||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Log\LogManager;
|
||||
use Leonmrni\SearchCore\Connection\SearchResultInterface;
|
||||
|
||||
/**
|
||||
* Fakes the LogManager to prevent dependencies and logging during tests.
|
||||
*
|
||||
*/
|
||||
class FakeLogManager extends LogManager
|
||||
class SearchResult extends \Elastica\SearchResult implements SearchResultInterface
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->loggers['fake'] = new Logger('fake');
|
||||
}
|
||||
|
||||
public function getLogger($name = '')
|
||||
{
|
||||
return $this->loggers['fake'];
|
||||
}
|
||||
}
|
45
Classes/Connection/Elasticsearch/TypeFactory.php
Normal file
45
Classes/Connection/Elasticsearch/TypeFactory.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Connection\Elasticsearch;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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\Core\SingletonInterface as Singleton;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
|
||||
/**
|
||||
* Factory to get indexes.
|
||||
*
|
||||
* The factory will take care of configuration and creation of index if necessary.
|
||||
*/
|
||||
class TypeFactory implements Singleton
|
||||
{
|
||||
/**
|
||||
* Get an index bases on TYPO3 table name.
|
||||
*
|
||||
* @param \Elastica\Index $index
|
||||
* @param string $tableName
|
||||
*
|
||||
* @return \Elastica\Type
|
||||
*/
|
||||
public function getType(\Elastica\Index $index, $tableName)
|
||||
{
|
||||
return $index->getType($tableName);
|
||||
}
|
||||
}
|
34
Classes/Connection/SearchRequestInterface.php
Normal file
34
Classes/Connection/SearchRequestInterface.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Connection;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
interface SearchRequestInterface
|
||||
{
|
||||
/**
|
||||
* Returns the actual string the user searched for.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSearchTerm();
|
||||
}
|
29
Classes/Connection/SearchResultInterface.php
Normal file
29
Classes/Connection/SearchResultInterface.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Connection;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
interface SearchResultInterface extends \Iterator, \Countable, \ArrayAccess
|
||||
{
|
||||
|
||||
}
|
64
Classes/Controller/SearchController.php
Normal file
64
Classes/Controller/SearchController.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Controller;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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 Leonmrni\SearchCore\Domain\Model\SearchRequest;
|
||||
use Leonmrni\SearchCore\Domain\Search\SearchService;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||
|
||||
/**
|
||||
* Handling search logic in TYPO3 Frontend.
|
||||
*/
|
||||
class SearchController extends ActionController
|
||||
{
|
||||
/**
|
||||
* @var SearchService
|
||||
*/
|
||||
protected $searchService;
|
||||
|
||||
/**
|
||||
* @param SearchService $searchService
|
||||
*/
|
||||
public function __construct(SearchService $searchService)
|
||||
{
|
||||
$this->searchService = $searchService;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a search and deliver original request and result to view.
|
||||
*
|
||||
* @param SearchRequest $searchRequest
|
||||
*/
|
||||
public function searchAction(SearchRequest $searchRequest = null)
|
||||
{
|
||||
$searchResult = null;
|
||||
if ($searchRequest !== null) {
|
||||
$searchResult = $this->searchService->search($searchRequest);
|
||||
}
|
||||
|
||||
$this->view->assignMultiple([
|
||||
'searchRequest' => $searchRequest,
|
||||
'searchResult' => $searchResult,
|
||||
]);
|
||||
}
|
||||
}
|
60
Classes/Domain/Index/IndexerFactory.php
Normal file
60
Classes/Domain/Index/IndexerFactory.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Domain\Index;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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\Core\SingletonInterface as Singleton;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
|
||||
|
||||
/**
|
||||
* Factory to get configured indexer based on configuration.
|
||||
*/
|
||||
class IndexerFactory implements Singleton
|
||||
{
|
||||
/**
|
||||
* @var ObjectManager
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* @param ObjectManagerInterface $objectManager
|
||||
*/
|
||||
public function __construct(ObjectManagerInterface $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tableName
|
||||
*
|
||||
* @return IndexerInterface
|
||||
*/
|
||||
public function getIndexer($tableName)
|
||||
{
|
||||
// This is the place to use configuration to return different indexer.
|
||||
return $this->objectManager->get(
|
||||
TcaIndexer::Class,
|
||||
$this->objectManager->get(
|
||||
TcaIndexer\TcaTableService::class,
|
||||
$tableName
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
32
Classes/Domain/Index/IndexerInterface.php
Normal file
32
Classes/Domain/Index/IndexerInterface.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Domain\Index;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface that all indexer should implement.
|
||||
*/
|
||||
interface IndexerInterface
|
||||
{
|
||||
/**
|
||||
* Index the index.
|
||||
*/
|
||||
public function index();
|
||||
}
|
29
Classes/Domain/Index/IndexingException.php
Normal file
29
Classes/Domain/Index/IndexingException.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Domain\Index;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception thrown on errors while indexing.
|
||||
*/
|
||||
class IndexingException extends \Exception
|
||||
{
|
||||
const CODE_UNKOWN_TCA_TABLE = 1481190283;
|
||||
}
|
117
Classes/Domain/Index/TcaIndexer.php
Normal file
117
Classes/Domain/Index/TcaIndexer.php
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Domain\Index;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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\Extbase\Object\ObjectManagerInterface;
|
||||
use Leonmrni\SearchCore\Connection\ConnectionInterface;
|
||||
|
||||
/**
|
||||
* Will index the given table using configuration from TCA.
|
||||
*/
|
||||
class TcaIndexer implements IndexerInterface
|
||||
{
|
||||
/**
|
||||
* @var ConnectionInterface
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var TcaIndexer\TcaTableService
|
||||
*/
|
||||
protected $tcaTableService;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Log\Logger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* 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 $tableName
|
||||
* @param ConnectionInterface $connection
|
||||
*/
|
||||
public function __construct(
|
||||
TcaIndexer\TcaTableService $tcaTableService,
|
||||
ConnectionInterface $connection
|
||||
) {
|
||||
$this->tcaTableService = $tcaTableService;
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->logger->info('Start indexing');
|
||||
foreach ($this->getRecordGenerator() as $records) {
|
||||
$this->logger->debug('Index records.', [$records]);
|
||||
$this->connection->addDocuments($this->tcaTableService->getTableName(), $records);
|
||||
}
|
||||
$this->logger->info('Finish indexing');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Iterator
|
||||
*/
|
||||
protected function getRecordGenerator()
|
||||
{
|
||||
$offset = 0;
|
||||
// TODO: Make configurable.
|
||||
$limit = 50;
|
||||
|
||||
while (($records = $this->getRecords($offset, $limit)) !== []) {
|
||||
yield $records;
|
||||
$offset += $limit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $limit
|
||||
* @return array
|
||||
*/
|
||||
protected function getRecords($offset, $limit)
|
||||
{
|
||||
$records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
|
||||
$this->tcaTableService->getFields(),
|
||||
$this->tcaTableService->getTableName(),
|
||||
$this->tcaTableService->getWhereClause(),
|
||||
'',
|
||||
'',
|
||||
(int) $offset . ',' . (int) $limit
|
||||
);
|
||||
|
||||
foreach ($records as &$record) {
|
||||
$this->tcaTableService->prepareRecord($record);
|
||||
}
|
||||
|
||||
// TODO: Ignore records from sys folder?
|
||||
|
||||
return $records;
|
||||
}
|
||||
}
|
167
Classes/Domain/Index/TcaIndexer/TcaTableService.php
Normal file
167
Classes/Domain/Index/TcaIndexer/TcaTableService.php
Normal file
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Domain\Index\TcaIndexer;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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\Backend\Utility\BackendUtility;
|
||||
use Leonmrni\SearchCore\Domain\Index\IndexingException;
|
||||
|
||||
/**
|
||||
* Encapsulate logik related to tca configuration.
|
||||
*/
|
||||
class TcaTableService
|
||||
{
|
||||
/**
|
||||
* TCA for current table.
|
||||
* !REFERENCE! To save memory.
|
||||
* @var array
|
||||
*/
|
||||
protected $tca;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tableName;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Log\Logger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* 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__);
|
||||
}
|
||||
|
||||
public function __construct($tableName)
|
||||
{
|
||||
if (!isset($GLOBALS['TCA'][$tableName])) {
|
||||
throw new IndexingException(
|
||||
'Table "' . $tableName . '" is not configured in TCA.',
|
||||
IndexingException::CODE_UNKOWN_TCA_TABLE
|
||||
);
|
||||
}
|
||||
|
||||
$this->tableName = $tableName;
|
||||
$this->tca = &$GLOBALS['TCA'][$this->tableName];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTableName()
|
||||
{
|
||||
return $this->tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust record accordingly to configuration.
|
||||
* @param array &$record
|
||||
*/
|
||||
public function prepareRecord(array &$record)
|
||||
{
|
||||
// TODO: Resolve values from 'items' like static select, radio or checkbox.
|
||||
|
||||
if (isset($record['uid']) && !isset($record['search_identifier'])) {
|
||||
$record['search_identifier'] = $record['uid'];
|
||||
}
|
||||
if (isset($record[$this->tca['ctrl']['label']]) && !isset($record['search_title'])) {
|
||||
$record['search_title'] = $record[$this->tca['ctrl']['label']];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getWhereClause()
|
||||
{
|
||||
$whereClause = '1=1 '
|
||||
. BackendUtility::BEenableFields($this->tableName)
|
||||
. BackendUtility::deleteClause($this->tableName)
|
||||
;
|
||||
|
||||
$this->logger->debug('Generated where clause.', [$this->tableName, $whereClause]);
|
||||
return $whereClause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFields()
|
||||
{
|
||||
$fields = 'uid,pid,' . implode(
|
||||
',',
|
||||
array_filter(
|
||||
array_keys($this->tca['columns']),
|
||||
function ($columnName) {
|
||||
$columnConfig = $this->tca['columns'][$columnName]['config'];
|
||||
return !$this->isRelation($columnConfig) && !$this->isSystemField($columnName);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$this->logger->debug('Generated fields.', [$this->tableName, $fields]);
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array
|
||||
* @return bool
|
||||
*/
|
||||
protected function isRelation(array &$columnConfig)
|
||||
{
|
||||
if (isset($columnConfig['foreign_table'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
protected function isSystemField($columnName)
|
||||
{
|
||||
$systemFields = [
|
||||
// Versioning fields,
|
||||
// https://docs.typo3.org/typo3cms/TCAReference/Reference/Ctrl/Index.html#versioningws
|
||||
't3ver_oid', 't3ver_id', 't3ver_label', 't3ver_wsid',
|
||||
't3ver_state', 't3ver_stage', 't3ver_count', 't3ver_tstamp',
|
||||
't3ver_move_id', 't3ver_swapmode',
|
||||
$this->tca['ctrl']['transOrigDiffSourceField'],
|
||||
$this->tca['ctrl']['cruser_id'],
|
||||
$this->tca['ctrl']['fe_cruser_id'],
|
||||
$this->tca['ctrl']['fe_crgroup_id'],
|
||||
$this->tca['ctrl']['languageField'],
|
||||
$this->tca['ctrl']['origUid'],
|
||||
];
|
||||
if (in_array($columnName, $systemFields)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
60
Classes/Domain/Model/SearchRequest.php
Normal file
60
Classes/Domain/Model/SearchRequest.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Domain\Model;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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 Leonmrni\SearchCore\Connection\SearchRequestInterface;
|
||||
|
||||
/**
|
||||
* Represents a search request used to process an actual search.
|
||||
*/
|
||||
class SearchRequest implements SearchRequestInterface
|
||||
{
|
||||
/**
|
||||
* The search string provided by the user, the actual term to search for.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
*/
|
||||
public function __construct($query)
|
||||
{
|
||||
$this->query = $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getQuery()
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSearchTerm()
|
||||
{
|
||||
return '"' . $this->query . '"';
|
||||
}
|
||||
}
|
69
Classes/Domain/Search/SearchService.php
Normal file
69
Classes/Domain/Search/SearchService.php
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Domain\Search;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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 Leonmrni\SearchCore\Connection\ConnectionInterface;
|
||||
use Leonmrni\SearchCore\Connection\SearchRequestInterface;
|
||||
use Leonmrni\SearchCore\Connection\SearchResultInterface;
|
||||
use Leonmrni\SearchCore\Domain\Model\SearchRequest;
|
||||
|
||||
/**
|
||||
* Service to process a search request.
|
||||
*/
|
||||
class SearchService
|
||||
{
|
||||
/**
|
||||
* @var ConnectionInterface
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Log\Logger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* 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 ConnectionInterface $connection
|
||||
*/
|
||||
public function __construct(ConnectionInterface $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SearchRequestInterface $searchRequest
|
||||
* @return SearchResultInterface
|
||||
*/
|
||||
public function search(SearchRequestInterface $searchRequest)
|
||||
{
|
||||
return $this->connection->search($searchRequest);
|
||||
}
|
||||
}
|
84
Classes/Domain/Service/DataHandler.php
Normal file
84
Classes/Domain/Service/DataHandler.php
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Domain\Service;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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\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 \Leonmrni\SearchCore\Connection\ConnectionInterface
|
||||
* @inject
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Log\Logger
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ use TYPO3\CMS\Core\Log\Logger;
|
|||
use TYPO3\CMS\Core\SingletonInterface as Singleton;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||
use Leonmrni\SearchCore\Service\DataHandler as OwnDataHandler;
|
||||
use Leonmrni\SearchCore\Domain\Service\DataHandler as OwnDataHandler;
|
||||
|
||||
/**
|
||||
* Wrapper for TYPO3 Hooks to internal API.
|
||||
|
|
0
Configuration/TypoScript/constants.txt
Normal file
0
Configuration/TypoScript/constants.txt
Normal file
12
Configuration/TypoScript/setup.txt
Normal file
12
Configuration/TypoScript/setup.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
plugin {
|
||||
tx_searchcore {
|
||||
settings {
|
||||
connection {
|
||||
host = localhost
|
||||
port = 9200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.tx_searchcore < plugin.tx_searchcore
|
13
Resources/Private/Templates/Search/Search.html
Normal file
13
Resources/Private/Templates/Search/Search.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<f:form name="searchRequest" object="{searchRequest}">
|
||||
|
||||
<f:form.textfield property="query" />
|
||||
<f:form.submit value="search" />
|
||||
|
||||
</f:form>
|
||||
|
||||
<f:for each="{searchResult}" as="result">
|
||||
<f:link.page pageUid="{result.hit._source.pid}">
|
||||
{result.id} [{result.type}] - {result.hit._source.search_title}
|
||||
</f:link.page>
|
||||
<br>
|
||||
</f:for>
|
|
@ -20,12 +20,10 @@ namespace Leonmrni\SearchCore\Tests\Unit\Hook;
|
|||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use Leonmrni\SearchCore\Hook\DataHandler as Hook;
|
||||
use Leonmrni\SearchCore\Service\DataHandler;
|
||||
use Leonmrni\SearchCore\Tests\Fakes\FakeLogManager;
|
||||
use TYPO3\CMS\Core\DataHandling\DataHandler as CoreDataHandler;
|
||||
use TYPO3\CMS\Core\Log\LogManager;
|
||||
use TYPO3\CMS\Core\Tests\UnitTestCase;
|
||||
use Leonmrni\SearchCore\Domain\Service\DataHandler;
|
||||
use Leonmrni\SearchCore\Hook\DataHandler as Hook;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -47,9 +45,6 @@ class DataHandlerTest extends UnitTestCase
|
|||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\Container\Container')
|
||||
->registerImplementation(LogManager::class, FakeLogManager::class);
|
||||
|
||||
$this->subject = $this->getAccessibleMock(DataHandler::class);
|
||||
$this->hook = $this->getAccessibleMock(
|
||||
Hook::class,
|
||||
|
@ -57,9 +52,7 @@ class DataHandlerTest extends UnitTestCase
|
|||
'getTablesToProcess',
|
||||
'getRecord'
|
||||
],
|
||||
[
|
||||
$this->subject,
|
||||
]
|
||||
[$this->subject]
|
||||
);
|
||||
|
||||
$this->hook->method('getTablesToProcess')
|
||||
|
@ -82,7 +75,7 @@ class DataHandlerTest extends UnitTestCase
|
|||
$this->subject->expects($this->exactly(0))->method('add');
|
||||
$this->subject->expects($this->exactly(0))->method('update');
|
||||
|
||||
$dataHandler = $this->getAccessibleMock(CoreDataHandler::class, [], [], '', false);
|
||||
$dataHandler = new CoreDataHandler();
|
||||
$dataHandler->substNEWwithIDs = ['NEW34' => $recordUid];
|
||||
|
||||
$this->hook->processCmdmap_deleteAction($table, $recordUid, [], false, $dataHandler);
|
||||
|
@ -101,7 +94,7 @@ class DataHandlerTest extends UnitTestCase
|
|||
$this->subject->expects($this->once())->method('add');
|
||||
$this->subject->expects($this->once())->method('update');
|
||||
|
||||
$dataHandler = $this->getAccessibleMock(CoreDataHandler::class, [], [], '', false);
|
||||
$dataHandler = new CoreDataHandler();
|
||||
$dataHandler->substNEWwithIDs = ['NEW34' => $recordUid];
|
||||
|
||||
$this->hook->processCmdmap_deleteAction($table, $recordUid, [], false, $dataHandler);
|
||||
|
|
|
@ -15,13 +15,12 @@
|
|||
"TYPO3\\CMS\\Core\\Tests\\": ".Build/vendor/typo3/cms/typo3/sysext/core/Tests/"
|
||||
}
|
||||
},
|
||||
|
||||
"require" : {
|
||||
"php": ">=5.6.0",
|
||||
"typo3/cms": ">=6.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.8.0"
|
||||
"phpunit/phpunit": "~4.8.0"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
|
|
|
@ -6,8 +6,8 @@ $EM_CONF[$_EXTKEY] = [
|
|||
'category' => 'be',
|
||||
'constraints' => [
|
||||
'depends' => [
|
||||
'typo3' => '6.2.0-8.99.99',
|
||||
'php' => '5.6.0-7.99.99'
|
||||
'typo3' => '7.6.2-8.99.99',
|
||||
'php' => '7.0.0-7.99.99'
|
||||
],
|
||||
'conflicts' => [],
|
||||
],
|
||||
|
|
48
ext_localconf.php
Normal file
48
ext_localconf.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
call_user_func(
|
||||
function ($extensionKey) {
|
||||
// TODO: Add hook for Extbase -> to handle records modified through
|
||||
// Frontend and backend modules not using datahandler
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS'] = TYPO3\CMS\Extbase\Utility\ArrayUtility::arrayMergeRecursiveOverrule(
|
||||
$GLOBALS['TYPO3_CONF_VARS'],
|
||||
[
|
||||
'SC_OPTIONS' => [
|
||||
'extbase' => [
|
||||
'commandControllers' => [
|
||||
Leonmrni\SearchCore\Command\IndexCommandController::class,
|
||||
],
|
||||
],
|
||||
// Not yet, first finish whole indexing through command controller as it's more important.
|
||||
// 't3lib/class.t3lib_tcemain.php' => [
|
||||
// 'processCmdmapClass' => [
|
||||
// $extensionKey => \Leonmrni\SearchCore\Hook\DataHandler::class,
|
||||
// ],
|
||||
// 'processDatamapClass' => [
|
||||
// $extensionKey => \Leonmrni\SearchCore\Hook\DataHandler::class,
|
||||
// ],
|
||||
// ],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
|
||||
'Leonmrni.' . $extensionKey,
|
||||
'search',
|
||||
[
|
||||
'Search' => 'search'
|
||||
],
|
||||
[
|
||||
'Search' => 'search' // TODO: Enable caching. But submitting form results in previous result?!
|
||||
]
|
||||
);
|
||||
|
||||
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\Container\Container')
|
||||
->registerImplementation(
|
||||
'Leonmrni\SearchCore\Connection\ConnectionInterface',
|
||||
'Leonmrni\SearchCore\Connection\Elasticsearch'
|
||||
);
|
||||
},
|
||||
$_EXTKEY
|
||||
);
|
13
ext_tables.php
Normal file
13
ext_tables.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile(
|
||||
$_EXTKEY,
|
||||
'Configuration/TypoScript/',
|
||||
'Search Core'
|
||||
);
|
||||
|
||||
TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||
'Leonmrni.' . $_EXTKEY,
|
||||
'search',
|
||||
'Search Core'
|
||||
);
|
Loading…
Reference in a new issue