mirror of
https://github.com/Codappix/search_core.git
synced 2024-11-22 14:56:12 +01:00
Merge pull request #44 from DanielSiepmann/feature/integration-into-project
Feature/integration into project
This commit is contained in:
commit
418251facf
10 changed files with 167 additions and 37 deletions
|
@ -40,6 +40,7 @@ class ConfigurationContainer implements ConfigurationContainerInterface
|
|||
* Inject settings via ConfigurationManager.
|
||||
*
|
||||
* @param ConfigurationManagerInterface $configurationManager
|
||||
* @throws NoConfigurationException
|
||||
*/
|
||||
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager)
|
||||
{
|
||||
|
@ -48,6 +49,9 @@ class ConfigurationContainer implements ConfigurationContainerInterface
|
|||
'SearchCore',
|
||||
'search'
|
||||
);
|
||||
if ($this->settings === null) {
|
||||
throw new NoConfigurationException('Could not fetch configuration.', 1484226842);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
25
Classes/Configuration/NoConfigurationException.php
Normal file
25
Classes/Configuration/NoConfigurationException.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
namespace Leonmrni\SearchCore\Configuration;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class NoConfigurationException extends \InvalidArgumentException
|
||||
{
|
||||
}
|
|
@ -92,12 +92,16 @@ class Elasticsearch implements Singleton, ConnectionInterface
|
|||
|
||||
public function deleteDocument($documentType, $identifier)
|
||||
{
|
||||
try {
|
||||
$this->withType(
|
||||
$documentType,
|
||||
function ($type) use ($identifier) {
|
||||
$type->deleteById($identifier);
|
||||
}
|
||||
);
|
||||
} catch (\Elastica\Exception\NotFoundException $exception) {
|
||||
$this->logger->debug('Tried to delete document in index, which does not exist.', [$documentType, $identifier]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateDocument($documentType, array $document)
|
||||
|
|
25
Classes/Domain/Index/NoRecordFoundException.php
Normal file
25
Classes/Domain/Index/NoRecordFoundException.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
class NoRecordFoundException extends IndexingException
|
||||
{
|
||||
}
|
|
@ -82,7 +82,11 @@ class TcaIndexer implements IndexerInterface
|
|||
public function indexDocument($identifier)
|
||||
{
|
||||
$this->logger->info('Start indexing single record.', [$identifier]);
|
||||
try {
|
||||
$this->connection->addDocument($this->tcaTableService->getTableName(), $this->getRecord($identifier));
|
||||
} catch (NoRecordFoundException $e) {
|
||||
$this->logger->info('Could not index document.', [$e->getMessage()]);
|
||||
}
|
||||
$this->logger->info('Finish indexing');
|
||||
}
|
||||
|
||||
|
@ -116,8 +120,11 @@ class TcaIndexer implements IndexerInterface
|
|||
'',
|
||||
(int) $offset . ',' . (int) $limit
|
||||
);
|
||||
$this->tcaTableService->filterRecordsByRootLineBlacklist($records);
|
||||
if ($records === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->tcaTableService->filterRecordsByRootLineBlacklist($records);
|
||||
foreach ($records as &$record) {
|
||||
$this->tcaTableService->prepareRecord($record);
|
||||
}
|
||||
|
@ -128,6 +135,7 @@ class TcaIndexer implements IndexerInterface
|
|||
/**
|
||||
* @param int $identifier
|
||||
* @return array
|
||||
* @throws NoRecordFoundException If record could not be found.
|
||||
*/
|
||||
protected function getRecord($identifier)
|
||||
{
|
||||
|
@ -137,6 +145,13 @@ class TcaIndexer implements IndexerInterface
|
|||
$this->tcaTableService->getWhereClause()
|
||||
. ' AND ' . $this->tcaTableService->getTableName() . '.uid = ' . (int) $identifier
|
||||
);
|
||||
|
||||
if ($record === false || $record === null) {
|
||||
throw new NoRecordFoundException(
|
||||
'Record could not be fetched from database: "' . $identifier . '". Perhaps record is not active.',
|
||||
1484225364
|
||||
);
|
||||
}
|
||||
$this->tcaTableService->prepareRecord($record);
|
||||
|
||||
return $record;
|
||||
|
|
|
@ -151,9 +151,9 @@ class TcaTableService
|
|||
. ' AND pages.no_search = 0'
|
||||
;
|
||||
|
||||
$userDefinedWhere = $this->configuration->getIfExists('indexer.tca.' . $this->tableName);
|
||||
$userDefinedWhere = $this->configuration->getIfExists('indexer.tca.' . $this->tableName . '.additionalWhereClause');
|
||||
if (is_string($userDefinedWhere)) {
|
||||
$whereClause .= $userDefinedWhere;
|
||||
$whereClause .= ' AND ' . $userDefinedWhere;
|
||||
}
|
||||
|
||||
if ($this->isBlacklistedRootLineConfigured()) {
|
||||
|
@ -236,22 +236,28 @@ class TcaTableService
|
|||
* Checks whether the given record was blacklisted by root line.
|
||||
* This can be configured by typoscript as whole root lines can be black listed.
|
||||
*
|
||||
* NOTE: Does not support pages yet. We have to add a switch once we
|
||||
* support them to use uid instead.
|
||||
*
|
||||
* @param array &$record
|
||||
* @return bool
|
||||
*/
|
||||
protected function isRecordBlacklistedByRootline(array &$record)
|
||||
{
|
||||
// NOTE: Does not support pages yet. We have to add a switch once we
|
||||
// support them to use uid instead.
|
||||
if (! $this->isBlackListedRootLineConfigured()) {
|
||||
return false;
|
||||
// If no rootline exists, the record is on a unreachable page and therefore blacklisted.
|
||||
$rootline = BackendUtility::BEgetRootLine($record['pid']);
|
||||
if (!isset($rootline[0])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (BackendUtility::BEgetRootLine($record['uid']) as $pageInRootLine) {
|
||||
// Check configured black list if present.
|
||||
if ($this->isBlackListedRootLineConfigured()) {
|
||||
foreach ($rootline as $pageInRootLine) {
|
||||
if (in_array($pageInRootLine['uid'], $this->getBlackListedRootLine())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ namespace Leonmrni\SearchCore\Hook;
|
|||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use Leonmrni\SearchCore\Configuration\NoConfigurationException;
|
||||
use Leonmrni\SearchCore\Domain\Service\DataHandler as OwnDataHandler;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\DataHandling\DataHandler as CoreDataHandler;
|
||||
use TYPO3\CMS\Core\Log\LogManager;
|
||||
|
@ -27,7 +29,6 @@ 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\Domain\Service\DataHandler as OwnDataHandler;
|
||||
|
||||
/**
|
||||
* Wrapper for TYPO3 Hooks to internal API.
|
||||
|
@ -55,8 +56,13 @@ class DataHandler implements Singleton
|
|||
{
|
||||
$this->dataHandler = $dataHandler;
|
||||
if ($this->dataHandler === null) {
|
||||
try {
|
||||
$this->dataHandler = GeneralUtility::makeInstance(ObjectManager::class)
|
||||
->get(OwnDataHandler::class);
|
||||
} catch (NoConfigurationException $e) {
|
||||
// We have no configuration. That's fine, hooks will not be
|
||||
// executed due to check for existing DataHandler.
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger = $logger;
|
||||
|
@ -76,8 +82,8 @@ class DataHandler implements Singleton
|
|||
*/
|
||||
public function processCmdmap_deleteAction($table, $uid)
|
||||
{
|
||||
if (! $this->shouldProcessTable($table)) {
|
||||
$this->logger->debug('Delete not processed, cause table is not allowed.', [$table]);
|
||||
if (! $this->shouldProcessHookForTable($table)) {
|
||||
$this->logger->debug('Delete not processed.', [$table, $uid]);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -98,8 +104,8 @@ class DataHandler implements Singleton
|
|||
*/
|
||||
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]);
|
||||
if (! $this->shouldProcessHookForTable($table)) {
|
||||
$this->logger->debug('Database update not processed.', [$table, $uid]);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -124,6 +130,24 @@ class DataHandler implements Singleton
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $table
|
||||
* @return bool
|
||||
*/
|
||||
protected function shouldProcessHookForTable($table)
|
||||
{
|
||||
if ($this->dataHandler === null) {
|
||||
$this->logger->debug('Datahandler could not be setup.');
|
||||
return false;
|
||||
}
|
||||
if (! $this->shouldProcessTable($table)) {
|
||||
$this->logger->debug('Table is not allowed.', [$table]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $table
|
||||
* @return bool
|
||||
|
|
29
Configuration/TypoScript/constants.txt
Normal file → Executable file
29
Configuration/TypoScript/constants.txt
Normal file → Executable file
|
@ -0,0 +1,29 @@
|
|||
plugin {
|
||||
tx_searchcore {
|
||||
settings {
|
||||
connections {
|
||||
elasticsearch {
|
||||
host = localhost
|
||||
port = 9200
|
||||
}
|
||||
}
|
||||
|
||||
indexer {
|
||||
tca {
|
||||
# Pages are not supported yet, see
|
||||
# https://github.com/DanielSiepmann/search_core/issues/24 but
|
||||
# should also be added, together with additionalWhereClause
|
||||
# based on doktypes
|
||||
allowedTables = tt_content
|
||||
|
||||
tt_content {
|
||||
additionalWhereClause (
|
||||
pages.doktype NOT IN (3, 199)
|
||||
AND tt_content.CType NOT IN ('gridelements_pi1', 'list', 'div', 'menu', 'shortcut', 'search', 'login')
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
12
Configuration/TypoScript/setup.txt
Normal file → Executable file
12
Configuration/TypoScript/setup.txt
Normal file → Executable file
|
@ -3,21 +3,17 @@ plugin {
|
|||
settings {
|
||||
connections {
|
||||
elasticsearch {
|
||||
host = localhost
|
||||
port = 9200
|
||||
host = {$plugin.tx_searchcore.settings.connections.elasticsearch.host}
|
||||
port = {$plugin.tx_searchcore.settings.connections.elasticsearch.port}
|
||||
}
|
||||
}
|
||||
|
||||
indexer {
|
||||
tca {
|
||||
# Pages are not supported yet, see
|
||||
# https://github.com/DanielSiepmann/search_core/issues/24 but
|
||||
# should also be added, together with additionalWhereClause
|
||||
# based on doktypes
|
||||
allowedTables = tt_content
|
||||
allowedTables = {$plugin.tx_searchcore.settings.indexer.tca.allowedTables}
|
||||
|
||||
tt_content {
|
||||
additionalWhereClause = tt_content.CType NOT IN ('gridelements_pi1', 'list', 'div', 'menu')
|
||||
additionalWhereClause = {$plugin.tx_searchcore.settings.indexer.tca.tt_content.additionalWhereClause}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,14 +15,16 @@ mode of TYPO3. Do so by placing the following line at the end::
|
|||
|
||||
We will use references inside the extension to make the above unnecessary in the future.
|
||||
|
||||
Currently no constants are available, but this will change in the near future to make configuration
|
||||
easier.
|
||||
|
||||
The structure is following TYPO3 Extbase conventions. All settings are placed inside of::
|
||||
|
||||
plugin.tx_searchcore.settings
|
||||
|
||||
Here is the example default configuration that's provided through static setup:
|
||||
Here is the example default configuration that's provided through static include:
|
||||
|
||||
.. literalinclude:: ../../Configuration/TypoScript/constants.txt
|
||||
:language: typoscript
|
||||
:linenos:
|
||||
:caption: Static TypoScript Constants
|
||||
|
||||
.. literalinclude:: ../../Configuration/TypoScript/setup.txt
|
||||
:language: typoscript
|
||||
|
@ -145,7 +147,7 @@ The following settings are available. For each setting its documented which inde
|
|||
The page attribute *No Search* is also taken into account to prevent indexing records from only one
|
||||
page without recursion.
|
||||
|
||||
Contains a comma separated list of table names. Spaces are trimmed.
|
||||
Contains a comma separated list of page uids. Spaces are trimmed.
|
||||
|
||||
Example::
|
||||
|
||||
|
|
Loading…
Reference in a new issue