Merge remote-tracking branch 'origin/support/76' into feature/merge-with-features

Conflicts:
    Classes/Domain/Index/TcaIndexer/TcaTableService.php
    Classes/Domain/Search/QueryFactory.php
    Tests/Functional/Connection/Elasticsearch/IndexTcaTableTest.php
    Tests/Functional/Hooks/DataHandler/ProcessesAllowedTablesTest.php
    Tests/Unit/Domain/Search/QueryFactoryTest.php
This commit is contained in:
Daniel Siepmann 2018-01-30 20:22:09 +01:00
commit 810439cc80
Signed by: Daniel Siepmann
GPG key ID: 33D6629915560EF4
27 changed files with 250 additions and 108 deletions

View file

@ -11,7 +11,9 @@ before_install:
language: php language: php
php: php:
- 7.0
- 7.1 - 7.1
- 7.2
env: env:
global: global:

View file

@ -39,6 +39,21 @@ class IndexFactory implements Singleton
*/ */
protected $configuration; protected $configuration;
/**
* @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 ConfigurationContainerInterface $configuration * @param ConfigurationContainerInterface $configuration
*/ */
@ -60,7 +75,10 @@ class IndexFactory implements Singleton
$index = $connection->getClient()->getIndex('typo3content'); $index = $connection->getClient()->getIndex('typo3content');
if ($index->exists() === false) { if ($index->exists() === false) {
$index->create($this->getConfigurationFor($documentType)); $config = $this->getConfigurationFor($documentType);
$this->logger->debug(sprintf('Create index %s.', $documentType), [$documentType, $config]);
$index->create($config);
$this->logger->debug(sprintf('Created index %s.', $documentType), [$documentType]);
} }
return $index; return $index;
@ -76,9 +94,11 @@ class IndexFactory implements Singleton
try { try {
$configuration = $this->configuration->get('indexing.' . $documentType . '.index'); $configuration = $this->configuration->get('indexing.' . $documentType . '.index');
if (isset($configuration['analysis']['analyzer'])) { foreach (['analyzer', 'filter'] as $optionsToExpand) {
foreach ($configuration['analysis']['analyzer'] as $key => $analyzer) { if (isset($configuration['analysis'][$optionsToExpand])) {
$configuration['analysis']['analyzer'][$key] = $this->prepareAnalyzerConfiguration($analyzer); foreach ($configuration['analysis'][$optionsToExpand] as $key => $options) {
$configuration['analysis'][$optionsToExpand][$key] = $this->prepareOptions($options);
}
} }
} }
@ -89,20 +109,20 @@ class IndexFactory implements Singleton
} }
/** /**
* @param array $analyzer * @param array $options
* *
* @return array * @return array
*/ */
protected function prepareAnalyzerConfiguration(array $analyzer) protected function prepareOptions(array $options)
{ {
$fieldsToExplode = ['char_filter', 'filter']; $fieldsToExplode = ['char_filter', 'filter', 'word_list'];
foreach ($fieldsToExplode as $fieldToExplode) { foreach ($fieldsToExplode as $fieldToExplode) {
if (isset($analyzer[$fieldToExplode])) { if (isset($options[$fieldToExplode])) {
$analyzer[$fieldToExplode] = GeneralUtility::trimExplode(',', $analyzer[$fieldToExplode], true); $options[$fieldToExplode] = GeneralUtility::trimExplode(',', $options[$fieldToExplode], true);
} }
} }
return $analyzer; return $options;
} }
} }

View file

@ -36,15 +36,19 @@ class CopyToProcessor implements ProcessorInterface
return $record; return $record;
} }
protected function addArray(array &$target, array $from) /**
* @param array &$to
* @param array $from
*/
protected function addArray(array &$to, array $from)
{ {
foreach ($from as $value) { foreach ($from as $value) {
if (is_array($value)) { if (is_array($value)) {
$this->addArray($target, $value); $this->addArray($to, $value);
continue; continue;
} }
$target[] = (string) $value; $to[] = (string) $value;
} }
} }
} }

View file

@ -21,8 +21,8 @@ namespace Codappix\SearchCore\DataProcessing;
*/ */
/** /**
* All DataProcessing Processors should implement this interface, otherwise they * All DataProcessing Processors should implement this interface, otherwise
* will not be executed. * they will not be executed.
*/ */
interface ProcessorInterface interface ProcessorInterface
{ {

View file

@ -22,8 +22,6 @@ namespace Codappix\SearchCore\Domain\Index;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface; use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\InvalidArgumentException; use Codappix\SearchCore\Configuration\InvalidArgumentException;
use Codappix\SearchCore\Domain\Index\IndexerInterface;
use Codappix\SearchCore\Domain\Index\TcaIndexer;
use Codappix\SearchCore\Domain\Index\TcaIndexer\TcaTableService; use Codappix\SearchCore\Domain\Index\TcaIndexer\TcaTableService;
use TYPO3\CMS\Core\SingletonInterface as Singleton; use TYPO3\CMS\Core\SingletonInterface as Singleton;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface; use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
@ -56,12 +54,9 @@ class IndexerFactory implements Singleton
} }
/** /**
* @param string $identifier
*
* @return IndexerInterface
* @throws NoMatchingIndexer * @throws NoMatchingIndexer
*/ */
public function getIndexer($identifier) public function getIndexer(string $identifier) : IndexerInterface
{ {
try { try {
return $this->buildIndexer($this->configuration->get('indexing.' . $identifier . '.indexer'), $identifier); return $this->buildIndexer($this->configuration->get('indexing.' . $identifier . '.indexer'), $identifier);
@ -75,13 +70,9 @@ class IndexerFactory implements Singleton
} }
/** /**
* @param string $indexerClass
* @param string $identifier
*
* @return IndexerInterface
* @throws NoMatchingIndexer * @throws NoMatchingIndexer
*/ */
protected function buildIndexer($indexerClass, $identifier) protected function buildIndexer(string $indexerClass, string $identifier) : IndexerInterface
{ {
$indexer = null; $indexer = null;
if (is_subclass_of($indexerClass, TcaIndexer\PagesIndexer::class) if (is_subclass_of($indexerClass, TcaIndexer\PagesIndexer::class)

View file

@ -34,6 +34,12 @@ class PagesIndexer extends TcaIndexer
*/ */
protected $contentTableService; protected $contentTableService;
/**
* @var \TYPO3\CMS\Core\Resource\FileRepository
* @inject
*/
protected $fileRepository;
/** /**
* @param TcaTableService $tcaTableService * @param TcaTableService $tcaTableService
* @param TcaTableService $tcaTableService * @param TcaTableService $tcaTableService
@ -52,9 +58,6 @@ class PagesIndexer extends TcaIndexer
$this->configuration = $configuration; $this->configuration = $configuration;
} }
/**
* @param array &$record
*/
protected function prepareRecord(array &$record) protected function prepareRecord(array &$record)
{ {
$possibleTitleFields = ['nav_title', 'tx_tqseo_pagetitle_rel', 'title']; $possibleTitleFields = ['nav_title', 'tx_tqseo_pagetitle_rel', 'title'];
@ -65,32 +68,62 @@ class PagesIndexer extends TcaIndexer
} }
} }
$record['content'] = $this->fetchContentForPage($record['uid']); $record['media'] = $this->fetchMediaForPage($record['uid']);
$content = $this->fetchContentForPage($record['uid']);
if ($content !== []) {
$record['content'] = $content['content'];
$record['media'] = array_values(array_unique(array_merge($record['media'], $content['images'])));
}
parent::prepareRecord($record); parent::prepareRecord($record);
} }
/** protected function fetchContentForPage(int $uid) : array
* @param int $uid
* @return string
*/
protected function fetchContentForPage($uid)
{ {
$contentElements = $this->getQuery($this->contentTableService)->execute()->fetchAll(); $contentElements = $this->getQuery($this->contentTableService)->execute()->fetchAll();
if ($contentElements === null) { if ($contentElements === null) {
$this->logger->debug('No content for page ' . $uid); $this->logger->debug('No content for page ' . $uid);
return ''; return [];
} }
$this->logger->debug('Fetched content for page ' . $uid); $this->logger->debug('Fetched content for page ' . $uid);
$images = [];
$content = []; $content = [];
foreach ($contentElements as $contentElement) { foreach ($contentElements as $contentElement) {
$images = array_merge(
$images,
$this->getContentElementImages($contentElement['uid'])
);
$content[] = $contentElement['bodytext']; $content[] = $contentElement['bodytext'];
} }
// Remove Tags. return [
// Interpret escaped new lines and special chars. // Remove Tags.
// Trim, e.g. trailing or leading new lines. // Interpret escaped new lines and special chars.
return trim(stripcslashes(strip_tags(implode(' ', $content)))); // Trim, e.g. trailing or leading new lines.
'content' => trim(stripcslashes(strip_tags(implode(' ', $content)))),
'images' => $images,
];
}
protected function getContentElementImages(int $uidOfContentElement) : array
{
return $this->fetchSysFileReferenceUids($uidOfContentElement, 'tt_content', 'image');
}
protected function fetchMediaForPage(int $uid) : array
{
return $this->fetchSysFileReferenceUids($uid, 'pages', 'media');
}
protected function fetchSysFileReferenceUids(int $uid, string $tablename, string $fieldname) : array
{
$imageRelationUids = [];
$imageRelations = $this->fileRepository->findByRelation($tablename, $fieldname, $uid);
foreach ($imageRelations as $relation) {
$imageRelationUids[] = $relation->getUid();
}
return $imageRelationUids;
} }
} }

View file

@ -33,7 +33,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
*/ */
class RelationResolver implements Singleton class RelationResolver implements Singleton
{ {
public function resolveRelationsForRecord(TcaTableService $service, array &$record) : void public function resolveRelationsForRecord(TcaTableService $service, array &$record)
{ {
foreach (array_keys($record) as $column) { foreach (array_keys($record) as $column) {
// TODO: Define / configure fields to exclude?! // TODO: Define / configure fields to exclude?!
@ -97,7 +97,7 @@ class RelationResolver implements Singleton
return array_map('trim', explode(',', $value)); return array_map('trim', explode(',', $value));
} }
protected function getUtilityForMode(): string protected function getUtilityForMode() : string
{ {
if (TYPO3_MODE === 'BE') { if (TYPO3_MODE === 'BE') {
return BackendUtility::class; return BackendUtility::class;

View file

@ -22,6 +22,7 @@ namespace Codappix\SearchCore\Domain\Index\TcaIndexer;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface; use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\InvalidArgumentException as InvalidConfigurationArgumentException; use Codappix\SearchCore\Configuration\InvalidArgumentException as InvalidConfigurationArgumentException;
use Codappix\SearchCore\DataProcessing\ProcessorInterface;
use Codappix\SearchCore\Database\Doctrine\Join; use Codappix\SearchCore\Database\Doctrine\Join;
use Codappix\SearchCore\Database\Doctrine\Where; use Codappix\SearchCore\Database\Doctrine\Where;
use Codappix\SearchCore\Domain\Index\IndexingException; use Codappix\SearchCore\Domain\Index\IndexingException;
@ -125,11 +126,8 @@ class TcaTableService
/** /**
* Filter the given records by root line blacklist settings. * Filter the given records by root line blacklist settings.
*
* @param array &$records
* @return void
*/ */
public function filterRecordsByRootLineBlacklist(array &$records) : void public function filterRecordsByRootLineBlacklist(array &$records)
{ {
$records = array_filter( $records = array_filter(
$records, $records,
@ -140,12 +138,23 @@ class TcaTableService
} }
/** /**
* @param array &$record * Adjust record accordingly to configuration.
*/ */
public function prepareRecord(array &$record) : void public function prepareRecord(array &$record)
{ {
$this->relationResolver->resolveRelationsForRecord($this, $record); $this->relationResolver->resolveRelationsForRecord($this, $record);
try {
foreach ($this->configuration->get('indexing.' . $this->tableName . '.dataProcessing') as $configuration) {
$dataProcessor = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($configuration['_typoScriptNodeValue']);
if ($dataProcessor instanceof ProcessorInterface) {
$record = $dataProcessor->processRecord($record, $configuration);
}
}
} catch (InvalidConfigurationArgumentException $e) {
// Nothing to do.
}
if (isset($record['uid']) && !isset($record['search_identifier'])) { if (isset($record['uid']) && !isset($record['search_identifier'])) {
$record['search_identifier'] = $record['uid']; $record['search_identifier'] = $record['uid'];
} }
@ -229,11 +238,7 @@ class TcaTableService
return $whereClause; return $whereClause;
} }
/** protected function isSystemField(string $columnName) : bool
* @param string
* @return bool
*/
protected function isSystemField($columnName) : bool
{ {
$systemFields = [ $systemFields = [
// Versioning fields, // Versioning fields,
@ -265,11 +270,9 @@ class TcaTableService
} }
/** /**
* @param string $columnName
* @return array
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
public function getColumnConfig($columnName) : array public function getColumnConfig(string $columnName) : array
{ {
if (!isset($this->tca['columns'][$columnName])) { if (!isset($this->tca['columns'][$columnName])) {
throw new InvalidArgumentException( throw new InvalidArgumentException(
@ -288,9 +291,6 @@ class TcaTableService
* Also further TYPO3 mechanics are taken into account. Does a valid root * Also further TYPO3 mechanics are taken into account. Does a valid root
* line exist, is page inside a recycler, is inherited start- endtime * line exist, is page inside a recycler, is inherited start- endtime
* excluded, etc. * excluded, etc.
*
* @param array &$record
* @return bool
*/ */
protected function isRecordBlacklistedByRootline(array &$record) : bool protected function isRecordBlacklistedByRootline(array &$record) : bool
{ {
@ -346,8 +346,6 @@ class TcaTableService
/** /**
* Checks whether any page uids are black listed. * Checks whether any page uids are black listed.
*
* @return bool
*/ */
protected function isBlackListedRootLineConfigured() : bool protected function isBlackListedRootLineConfigured() : bool
{ {
@ -356,8 +354,6 @@ class TcaTableService
/** /**
* Get the list of black listed root line page uids. * Get the list of black listed root line page uids.
*
* @return array<Int>
*/ */
protected function getBlackListedRootLine() : array protected function getBlackListedRootLine() : array
{ {

View file

@ -23,7 +23,6 @@ namespace Codappix\SearchCore\Domain\Search;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface; use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\ConfigurationUtility; use Codappix\SearchCore\Configuration\ConfigurationUtility;
use Codappix\SearchCore\Configuration\InvalidArgumentException; use Codappix\SearchCore\Configuration\InvalidArgumentException;
use Codappix\SearchCore\Connection\ConnectionInterface;
use Codappix\SearchCore\Connection\Elasticsearch\Query; use Codappix\SearchCore\Connection\Elasticsearch\Query;
use Codappix\SearchCore\Connection\SearchRequestInterface; use Codappix\SearchCore\Connection\SearchRequestInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
@ -134,13 +133,15 @@ class QueryFactory
]; ];
} }
$query = ArrayUtility::arrayMergeRecursiveOverrule($query, [ if (!empty($boostQueryParts)) {
'query' => [ $query = ArrayUtility::arrayMergeRecursiveOverrule($query, [
'bool' => [ 'query' => [
'should' => $boostQueryParts, 'bool' => [
'should' => $boostQueryParts,
],
], ],
], ]);
]); }
} }
protected function addFactorBoost(array &$query) protected function addFactorBoost(array &$query)

View file

@ -23,7 +23,6 @@ namespace Codappix\SearchCore\Domain\Service;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface; use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Domain\Index\IndexerFactory; use Codappix\SearchCore\Domain\Index\IndexerFactory;
use Codappix\SearchCore\Domain\Index\NoMatchingIndexerException; use Codappix\SearchCore\Domain\Index\NoMatchingIndexerException;
use Codappix\SearchCore\Domain\Index\TcaIndexer;
use TYPO3\CMS\Core\SingletonInterface as Singleton; use TYPO3\CMS\Core\SingletonInterface as Singleton;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;

View file

@ -21,7 +21,6 @@ namespace Codappix\SearchCore\Hook;
*/ */
use Codappix\SearchCore\Configuration\NoConfigurationException; use Codappix\SearchCore\Configuration\NoConfigurationException;
use Codappix\SearchCore\Domain\Index\NoMatchingIndexerException;
use Codappix\SearchCore\Domain\Service\DataHandler as OwnDataHandler; use Codappix\SearchCore\Domain\Service\DataHandler as OwnDataHandler;
use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\DataHandling\DataHandler as CoreDataHandler; use TYPO3\CMS\Core\DataHandling\DataHandler as CoreDataHandler;

View file

@ -28,4 +28,3 @@ We are also focusing on Code Quality and Testing through `travis ci`_, `scrutini
.. _travis ci: https://travis-ci.org/Codappix/search_core .. _travis ci: https://travis-ci.org/Codappix/search_core
.. _scrutinizer: https://scrutinizer-ci.com/g/Codappix/search_core/inspections .. _scrutinizer: https://scrutinizer-ci.com/g/Codappix/search_core/inspections
.. _codacy: https://www.codacy.com/app/Codappix/search_core/dashboard .. _codacy: https://www.codacy.com/app/Codappix/search_core/dashboard

View file

@ -5,14 +5,14 @@ TYPO3_WEB_DIR := $(current_dir).Build/web
TYPO3_PATH_ROOT := $(current_dir).Build/web TYPO3_PATH_ROOT := $(current_dir).Build/web
# Allow different versions on travis # Allow different versions on travis
TYPO3_VERSION ?= ~8.7 TYPO3_VERSION ?= ~8.7
typo3DatabaseName ?= "searchcore_test2" typo3DatabaseName ?= "searchcore_test"
typo3DatabaseUsername ?= "dev" typo3DatabaseUsername ?= "dev"
typo3DatabasePassword ?= "dev" typo3DatabasePassword ?= "dev"
typo3DatabaseHost ?= "127.0.0.1" typo3DatabaseHost ?= "127.0.0.1"
.PHONY: install .PHONY: install
install: clean install: clean
COMPOSER_PROCESS_TIMEOUT=1000 composer require -vv --dev --prefer-dist --ignore-platform-reqs typo3/cms="$(TYPO3_VERSION)" COMPOSER_PROCESS_TIMEOUT=1000 composer require -vv --dev typo3/cms="$(TYPO3_VERSION)"
git checkout composer.json git checkout composer.json
functionalTests: functionalTests:

View file

@ -48,14 +48,14 @@ class FilterTest extends AbstractFunctionalTestCase
$searchService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class) $searchService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class)
->get(SearchService::class); ->get(SearchService::class);
$searchRequest = new SearchRequest('Search Word'); $searchRequest = new SearchRequest();
$result = $searchService->search($searchRequest); $result = $searchService->search($searchRequest);
$this->assertSame(2, count($result), 'Did not receive both indexed elements without filter.'); $this->assertSame(2, count($result), 'Did not receive both indexed elements without filter.');
$searchRequest->setFilter(['CType' => 'HTML']); $searchRequest->setFilter(['CType' => 'HTML']);
$result = $searchService->search($searchRequest); $result = $searchService->search($searchRequest);
$this->assertSame(5, $result->getResults()[0]['uid'], 'Did not get the expected result entry.'); $this->assertSame(5, (int) $result->getResults()[0]['uid'], 'Did not get the expected result entry.');
$this->assertSame(1, count($result), 'Did not receive the single filtered element.'); $this->assertSame(1, count($result), 'Did not receive the single filtered element.');
} }
@ -73,7 +73,7 @@ class FilterTest extends AbstractFunctionalTestCase
$searchService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class) $searchService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class)
->get(SearchService::class); ->get(SearchService::class);
$searchRequest = new SearchRequest('Search Word'); $searchRequest = new SearchRequest();
$result = $searchService->search($searchRequest); $result = $searchService->search($searchRequest);
$this->assertSame(1, count($result->getFacets()), 'Did not receive the single defined facet.'); $this->assertSame(1, count($result->getFacets()), 'Did not receive the single defined facet.');

View file

@ -175,7 +175,7 @@ class IndexTcaTableTest extends AbstractFunctionalTestCase
['_source' => [ ['_source' => [
'uid' => '11', 'uid' => '11',
'CType' => 'Header', // Testing items 'CType' => 'Header', // Testing items
'categories' => ['Category 2', 'Category 1'], // Testing mm 'categories' => ['Category 2', 'Category 1'], // Testing mm (with sorting)
]], ]],
$response->getData()['hits']['hits'][0], $response->getData()['hits']['hits'][0],
false, false,
@ -236,4 +236,33 @@ class IndexTcaTableTest extends AbstractFunctionalTestCase
$response = $this->client->request('typo3content/_search?q=*:*'); $response = $this->client->request('typo3content/_search?q=*:*');
$this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document is in index.'); $this->assertSame($response->getData()['hits']['total'], 1, 'Not exactly 1 document is in index.');
} }
/**
* @test
*/
public function indexPagesMedia()
{
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class)
->get(IndexerFactory::class)
->getIndexer('pages')
->indexAllDocuments()
;
$response = $this->client->request('typo3content/_search?q=*:*');
$this->assertTrue($response->isOK(), 'Elastica did not answer with ok code.');
$this->assertSame($response->getData()['hits']['total'], 2, 'Not exactly 2 documents were indexed.');
$this->assertArraySubset(
[
'_source' => [
'media' => [
10, 1
]
]
],
$response->getData()['hits']['hits'][0],
false,
'Record was not indexed.'
);
}
} }

View file

@ -37,6 +37,7 @@ plugin {
} }
searching { searching {
fields = search_title
facets { facets {
contentTypes { contentTypes {
field = CType field = CType

View file

@ -29,7 +29,7 @@
<sorting>72</sorting> <sorting>72</sorting>
<CType>header</CType> <CType>header</CType>
<header>endtime hidden record</header> <header>endtime hidden record</header>
<bodytext></bodytext> <bodytext>Some content</bodytext>
<media>0</media> <media>0</media>
<layout>0</layout> <layout>0</layout>
<deleted>0</deleted> <deleted>0</deleted>
@ -49,7 +49,7 @@
<sorting>72</sorting> <sorting>72</sorting>
<CType>header</CType> <CType>header</CType>
<header>Hidden record</header> <header>Hidden record</header>
<bodytext></bodytext> <bodytext>Some content</bodytext>
<media>0</media> <media>0</media>
<layout>0</layout> <layout>0</layout>
<deleted>0</deleted> <deleted>0</deleted>
@ -99,4 +99,71 @@
<colPos>0</colPos> <colPos>0</colPos>
<filelink_sorting>0</filelink_sorting> <filelink_sorting>0</filelink_sorting>
</tt_content> </tt_content>
<pages>
<uid>2</uid>
<pid>1</pid>
<title>Example page with </title>
<description>Used as abstract as no abstract is defined.</description>
<media>2</media>
</pages>
<sys_file_reference>
<uid>1</uid>
<pid>1</pid>
<uid_local>1</uid_local>
<uid_foreign>2</uid_foreign>
<tablenames>pages</tablenames>
<fieldname>media</fieldname>
<sorting_foreign>2</sorting_foreign>
<table_local>sys_file</table_local>
<l10n_diffsource></l10n_diffsource>
</sys_file_reference>
<sys_file_reference>
<uid>10</uid>
<pid>1</pid>
<uid_local>2</uid_local>
<uid_foreign>2</uid_foreign>
<tablenames>pages</tablenames>
<fieldname>media</fieldname>
<sorting_foreign>1</sorting_foreign>
<table_local>sys_file</table_local>
<l10n_diffsource></l10n_diffsource>
</sys_file_reference>
<sys_file>
<uid>1</uid>
<pid>0</pid>
<storage>1</storage>
<type>2</type>
<identifier>full/file/path.png</identifier>
<identifier_hash>94dd1f9645114cf1344438ac7188db972768f59f</identifier_hash>
<folder_hash>67887283a03f465f1004d1d43a157ee1f1c59be5</folder_hash>
<extension>png</extension>
<mime_type>image/png</mime_type>
<name>path2.png</name>
<sha1>c1dd34eb34d651ee6ca6ac52dea595db75d8e9d2</sha1>
<size>3044</size>
<creation_date>1432306303</creation_date>
<modification_date>1432306303</modification_date>
</sys_file>
<sys_file>
<uid>2</uid>
<pid>0</pid>
<storage>1</storage>
<type>2</type>
<identifier>full/file/path2.png</identifier>
<identifier_hash>94dd1f9645114cf1344438ac7188db972768f59f</identifier_hash>
<folder_hash>67887283a03f465f1004d1d43a157ee1f1c59be5</folder_hash>
<extension>png</extension>
<mime_type>image/png</mime_type>
<name>path2.png</name>
<sha1>c1dd34eb34d651ee6ca6ac52dea595db75d8e9d2</sha1>
<size>3044</size>
<creation_date>1432306303</creation_date>
<modification_date>1432306303</modification_date>
</sys_file>
</dataset> </dataset>

View file

@ -9,7 +9,7 @@
<sorting>72</sorting> <sorting>72</sorting>
<CType>header</CType> <CType>header</CType>
<header>Also indexable record</header> <header>Also indexable record</header>
<bodytext></bodytext> <bodytext>Some content</bodytext>
<media>0</media> <media>0</media>
<layout>0</layout> <layout>0</layout>
<deleted>0</deleted> <deleted>0</deleted>
@ -29,7 +29,7 @@
<sorting>72</sorting> <sorting>72</sorting>
<CType>div</CType> <CType>div</CType>
<header>Not indexed by user where ctype condition</header> <header>Not indexed by user where ctype condition</header>
<bodytext></bodytext> <bodytext>Some content</bodytext>
<media>0</media> <media>0</media>
<layout>0</layout> <layout>0</layout>
<deleted>0</deleted> <deleted>0</deleted>

View file

@ -72,9 +72,9 @@ class ProcessesAllowedTablesTest extends AbstractDataHandlerTest
->with( ->with(
$this->equalTo('tt_content'), $this->equalTo('tt_content'),
$this->callback(function ($record) { $this->callback(function ($record) {
return isset($record['uid']) && $record['uid'] === 1 return isset($record['uid']) && $record['uid'] == 1
&& isset($record['pid']) && $record['pid'] === 1 && isset($record['pid']) && $record['pid'] == 1
&& isset($record['colPos']) && $record['colPos'] === 1 && isset($record['colPos']) && $record['colPos'] == 1
; ;
}) })
); );
@ -100,9 +100,9 @@ class ProcessesAllowedTablesTest extends AbstractDataHandlerTest
->with( ->with(
$this->equalTo('tt_content'), $this->equalTo('tt_content'),
$this->callback(function ($record) { $this->callback(function ($record) {
return isset($record['uid']) && $record['uid'] === 2 return isset($record['uid']) && $record['uid'] == 2
&& isset($record['pid']) && $record['pid'] === 1 && isset($record['pid']) && $record['pid'] == 1
&& isset($record['header']) && $record['header'] === 'a new record' && isset($record['header']) && $record['header'] == 'a new record'
; ;
}) })
); );

View file

@ -1,5 +1,5 @@
<?php <?php
namespace Codappix\SearchCore\Tests\Indexing; namespace Codappix\SearchCore\Tests\Functional\Indexing;
/* /*
* Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de> * Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de>
@ -48,7 +48,7 @@ class PagesIndexerTest extends AbstractFunctionalTestCase
->with( ->with(
$this->stringContains($tableName), $this->stringContains($tableName),
$this->callback(function ($documents) { $this->callback(function ($documents) {
return count($documents) === 1 return count($documents) === 2
&& isset($documents[0]['content']) && $documents[0]['content'] === && isset($documents[0]['content']) && $documents[0]['content'] ===
'this is the content of header content element that should get indexed Some text in paragraph' 'this is the content of header content element that should get indexed Some text in paragraph'
&& isset($documents[0]['search_abstract']) && $documents[0]['search_abstract'] === && isset($documents[0]['search_abstract']) && $documents[0]['search_abstract'] ===

View file

@ -1,5 +1,5 @@
<?php <?php
namespace Codappix\SearchCore\Tests\Indexing\TcaIndexer; namespace Codappix\SearchCore\Tests\Indexing\Functional\TcaIndexer;
/* /*
* Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de> * Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de>

View file

@ -1,5 +1,5 @@
<?php <?php
namespace Codappix\SearchCore\Tests\Indexing; namespace Codappix\SearchCore\Tests\Functional\Indexing;
/* /*
* Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de> * Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de>

View file

@ -38,6 +38,7 @@ class IndexFactoryTest extends AbstractUnitTestCase
$this->configuration = $this->getMockBuilder(ConfigurationContainerInterface::class)->getMock(); $this->configuration = $this->getMockBuilder(ConfigurationContainerInterface::class)->getMock();
$this->subject = new IndexFactory($this->configuration); $this->subject = new IndexFactory($this->configuration);
$this->subject->injectLogger($this->getMockedLogger());
} }
/** /**

View file

@ -106,7 +106,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
$query = $this->subject->create($searchRequest); $query = $this->subject->create($searchRequest);
$this->assertSame( $this->assertSame(
null, null,
$query->toArray()['query']['bool']['filter'], $query->toArray()['query']['function_score']['query']['bool']['filter'],
'Filter was added to query, even if no filter exists.' 'Filter was added to query, even if no filter exists.'
); );
} }
@ -181,7 +181,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
'type' => 'most_fields', 'type' => 'most_fields',
'query' => 'SearchWord', 'query' => 'SearchWord',
'fields' => [ 'fields' => [
'_all', 0 => 'test_field',
], ],
], ],
], ],
@ -212,7 +212,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
$this->configureConfigurationMockWithDefault(); $this->configureConfigurationMockWithDefault();
$query = $this->subject->create($searchRequest); $query = $this->subject->create($searchRequest);
$this->assertArraySubset( $this->assertSame(
[ [
'bool' => [ 'bool' => [
'must' => [ 'must' => [
@ -221,7 +221,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
'type' => 'most_fields', 'type' => 'most_fields',
'query' => 'SearchWord', 'query' => 'SearchWord',
'fields' => [ 'fields' => [
'_all', 'test_field',
], ],
'minimum_should_match' => '50%', 'minimum_should_match' => '50%',
], ],
@ -251,7 +251,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
['searching.fieldValueFactor'] ['searching.fieldValueFactor']
) )
->will($this->onConsecutiveCalls( ->will($this->onConsecutiveCalls(
'_all', 'test_field',
[ [
'search_title' => 3, 'search_title' => 3,
'search_abstract' => 1.5, 'search_abstract' => 1.5,
@ -308,7 +308,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
['searching.fieldValueFactor'] ['searching.fieldValueFactor']
) )
->will($this->onConsecutiveCalls( ->will($this->onConsecutiveCalls(
'_all', 'test_field',
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
@ -327,7 +327,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
'type' => 'most_fields', 'type' => 'most_fields',
'query' => 'SearchWord', 'query' => 'SearchWord',
'fields' => [ 'fields' => [
'_all', 0 => 'test_field',
], ],
], ],
], ],
@ -376,7 +376,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
['searching.fieldValueFactor'] ['searching.fieldValueFactor']
) )
->will($this->onConsecutiveCalls( ->will($this->onConsecutiveCalls(
'_all, field1, field2', 'test_field, field1, field2',
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
@ -393,7 +393,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
'type' => 'most_fields', 'type' => 'most_fields',
'query' => 'SearchWord', 'query' => 'SearchWord',
'fields' => [ 'fields' => [
'_all', 'test_field',
'field1', 'field1',
'field2', 'field2',
], ],
@ -483,7 +483,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
['searching.fieldValueFactor'] ['searching.fieldValueFactor']
) )
->will($this->onConsecutiveCalls( ->will($this->onConsecutiveCalls(
'_all', 'test_field',
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
$this->throwException(new InvalidArgumentException), $this->throwException(new InvalidArgumentException),
[ [
@ -616,7 +616,7 @@ class QueryFactoryTest extends AbstractUnitTestCase
->method('get') ->method('get')
->will($this->returnCallback(function ($configName) { ->will($this->returnCallback(function ($configName) {
if ($configName === 'searching.fields.query') { if ($configName === 'searching.fields.query') {
return '_all'; return 'test_field';
} }
throw new InvalidArgumentException(); throw new InvalidArgumentException();

View file

@ -16,7 +16,7 @@
} }
}, },
"require" : { "require" : {
"php": ">=7.1.0", "php": ">=7.0",
"typo3/cms": "~8.7", "typo3/cms": "~8.7",
"ruflin/elastica": "~3.2" "ruflin/elastica": "~3.2"
}, },

View file

@ -8,7 +8,7 @@ $EM_CONF[$_EXTKEY] = [
'constraints' => [ 'constraints' => [
'depends' => [ 'depends' => [
'typo3' => '8.7.0-8.7.99', 'typo3' => '8.7.0-8.7.99',
'php' => '7.1.0-7.99.99' 'php' => '7.0.0-7.99.99'
], ],
'conflicts' => [], 'conflicts' => [],
], ],

View file

@ -11,7 +11,7 @@ call_user_func(
'SC_OPTIONS' => [ 'SC_OPTIONS' => [
'extbase' => [ 'extbase' => [
'commandControllers' => [ 'commandControllers' => [
Codappix\SearchCore\Command\IndexCommandController::class, $extensionKey . '::index' => Codappix\SearchCore\Command\IndexCommandController::class,
], ],
], ],
't3lib/class.t3lib_tcemain.php' => [ 't3lib/class.t3lib_tcemain.php' => [