Merge pull request #129 from Codappix/feature/cleanup

!!!|TASK: Cleanup Codebase
This commit is contained in:
Justus Leon Moroni 2018-03-08 18:55:10 +01:00 committed by GitHub
commit e25a9ed5b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 254 additions and 334 deletions

96
.phan/config.php Normal file
View file

@ -0,0 +1,96 @@
<?php
/**
* This configuration will be read and overlaid on top of the
* default configuration. Command line arguments will be applied
* after this file is read.
*/
return [
// Supported values: '7.0', '7.1', '7.2', null.
// If this is set to null,
// then Phan assumes the PHP version which is closest to the minor version
// of the php executable used to execute phan.
"target_php_version" => '7.0',
// Override to hardcode existence and types of (non-builtin) globals.
// Class names should be prefixed with '\\'.
// (E.g. ['_FOO' => '\\FooClass', 'page' => '\\PageClass', 'userId' => 'int'])
'globals_type_map' => [
'_EXTKEY' => 'string',
'EM_CONF' => 'array',
],
// A list of directories that should be parsed for class and
// method information. After excluding the directories
// defined in exclude_analysis_directory_list, the remaining
// files will be statically analyzed for errors.
//
// Thus, both first-party and third-party code being used by
// your application should be included in this list.
'directory_list' => [
'Classes',
'.Build/vendor',
],
// A list of files to include in analysis
'file_list' => [
'ext_emconf.php',
'ext_tables.php',
'ext_localconf.php',
],
// A directory list that defines files that will be excluded
// from static analysis, but whose class and method
// information should be included.
//
// Generally, you'll want to include the directories for
// third-party code (such as "vendor/") in this list.
//
// n.b.: If you'd like to parse but not analyze 3rd
// party code, directories containing that code
// should be added to the `directory_list` as
// to `exclude_analysis_directory_list`.
"exclude_analysis_directory_list" => [
'.Build/vendor'
],
// A list of directories that should be parsed for class and
// method information. After excluding the directories
// defined in exclude_analysis_directory_list, the remaining
// files will be statically analyzed for errors.
//
// Thus, both first-party and third-party code being used by
// your application should be included in this list.
'directory_list' => [
'Classes',
// 'Tests',
'.Build/vendor',
],
// The number of processes to fork off during the analysis phase.
'processes' => 3,
// Add any issue types (such as 'PhanUndeclaredMethod')
// here to inhibit them from being reported
'suppress_issue_types' => [
'PhanDeprecatedFunction', // For now
'PhanParamTooMany', // For now, due to ObjectManager->get()
],
// A list of plugin files to execute.
// See https://github.com/phan/phan/tree/master/.phan/plugins for even more.
// (Pass these in as relative paths.
// The 0.10.2 release will allow passing 'AlwaysReturnPlugin' if referring to a plugin that is bundled with Phan)
'plugins' => [
// checks if a function, closure or method unconditionally returns.
'AlwaysReturnPlugin', // can also be written as 'vendor/phan/phan/.phan/plugins/AlwaysReturnPlugin.php'
// Checks for syntactically unreachable statements in
// the global scope or function bodies.
'UnreachableCodePlugin',
'DollarDollarPlugin',
'DuplicateArrayKeyPlugin',
'PregRegexCheckerPlugin',
'PrintfCheckerPlugin',
],
];

View file

@ -1,3 +1,11 @@
build:
nodes:
analysis:
project_setup:
override: true
tests:
override: [php-scrutinizer-run]
filter:
excluded_paths:
- 'Configuration/*'

View file

@ -22,7 +22,6 @@ namespace Codappix\SearchCore\Command;
use Codappix\SearchCore\Domain\Index\IndexerFactory;
use Codappix\SearchCore\Domain\Index\NoMatchingIndexerException;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
/**
@ -48,7 +47,7 @@ class IndexCommandController extends CommandController
*
* @param string $identifier
*/
public function indexCommand($identifier)
public function indexCommand(string $identifier)
{
try {
$this->indexerFactory->getIndexer($identifier)->indexAllDocuments();
@ -63,7 +62,7 @@ class IndexCommandController extends CommandController
*
* @param string $identifier
*/
public function deleteCommand($identifier)
public function deleteCommand(string $identifier)
{
try {
$this->indexerFactory->getIndexer($identifier)->delete();

View file

@ -39,7 +39,6 @@ class ConfigurationContainer implements ConfigurationContainerInterface
/**
* Inject settings via ConfigurationManager.
*
* @param ConfigurationManagerInterface $configurationManager
* @throws NoConfigurationException
*/
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager)
@ -59,7 +58,7 @@ class ConfigurationContainer implements ConfigurationContainerInterface
* @return mixed
* @throws InvalidArgumentException
*/
public function get($path)
public function get(string $path)
{
$value = ArrayUtility::getValueByPath($this->settings, $path);
@ -77,7 +76,7 @@ class ConfigurationContainer implements ConfigurationContainerInterface
* @param string $path In dot notation.
* @return mixed
*/
public function getIfExists($path)
public function getIfExists(string $path)
{
return ArrayUtility::getValueByPath($this->settings, $path);
}

View file

@ -37,7 +37,7 @@ interface ConfigurationContainerInterface extends Singleton
*
* @throws InvalidArgumentException
*/
public function get($path);
public function get(string $path);
/**
* Same as get but will not throw an exception but return null.
@ -45,5 +45,5 @@ interface ConfigurationContainerInterface extends Singleton
* @param string $path In dot notation.
* @return mixed|null
*/
public function getIfExists($path);
public function getIfExists(string $path);
}

View file

@ -28,62 +28,44 @@ interface ConnectionInterface
/**
* Will add a new document.
*
* @param string $documentType
* @param array $document
*
* @return void
*/
public function addDocument($documentType, array $document);
public function addDocument(string $documentType, array $document);
/**
* Add the given documents.
*
* @param string $documentType
* @param array $documents
*
* @return void
*/
public function addDocuments($documentType, array $documents);
public function addDocuments(string $documentType, array $documents);
/**
* Will update an existing document.
*
* NOTE: Batch updating is not yet supported.
*
* @param string $documentType
* @param array $document
*
* @return void
*/
public function updateDocument($documentType, array $document);
public function updateDocument(string $documentType, array $document);
/**
* Will remove an existing document.
*
* NOTE: Batch deleting is not yet supported.
*
* @param string $documentType
* @param int $identifier
*
* @return void
*/
public function deleteDocument($documentType, $identifier);
public function deleteDocument(string $documentType, string $identifier);
/**
* Search by given request and return result.
*
* @param SearchRequestInterface $searchRequest
*
* @return SearchResultInterface
*/
public function search(SearchRequestInterface $searchRequest);
public function search(SearchRequestInterface $searchRequest) : SearchResultInterface;
/**
* Will delete the whole index / db.
*
* @param string $documentType
*
* @return void
*/
public function deleteIndex($documentType);
public function deleteIndex(string $documentType);
}

View file

@ -112,7 +112,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
$this->queryFactory = $queryFactory;
}
public function addDocument($documentType, array $document)
public function addDocument(string $documentType, array $document)
{
$this->withType(
$documentType,
@ -122,7 +122,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
);
}
public function deleteDocument($documentType, $identifier)
public function deleteDocument(string $documentType, string $identifier)
{
try {
$this->withType(
@ -139,7 +139,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
}
}
public function updateDocument($documentType, array $document)
public function updateDocument(string $documentType, array $document)
{
$this->withType(
$documentType,
@ -149,7 +149,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
);
}
public function addDocuments($documentType, array $documents)
public function addDocuments(string $documentType, array $documents)
{
$this->withType(
$documentType,
@ -159,7 +159,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
);
}
public function deleteIndex($documentType)
public function deleteIndex(string $documentType)
{
$index = $this->connection->getClient()->getIndex('typo3content');
@ -173,11 +173,8 @@ class Elasticsearch implements Singleton, ConnectionInterface
/**
* Execute given callback with Elastica Type based on provided documentType
*
* @param string $documentType
* @param callable $callback
*/
protected function withType($documentType, callable $callback)
protected function withType(string $documentType, callable $callback)
{
$type = $this->getType($documentType);
// TODO: Check whether it's to heavy to send it so often e.g. for every single document.
@ -191,12 +188,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
$type->getIndex()->refresh();
}
/**
* @param SearchRequestInterface $searchRequest
*
* @return SearchResultInterface
*/
public function search(SearchRequestInterface $searchRequest)
public function search(SearchRequestInterface $searchRequest) : SearchResultInterface
{
$this->logger->debug('Search for', [$searchRequest->getSearchTerm()]);
@ -207,12 +199,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
return $this->objectManager->get(SearchResult::class, $searchRequest, $search->search());
}
/**
* @param string $documentType
*
* @return \Elastica\Type
*/
protected function getType($documentType)
protected function getType(string $documentType) : \Elastica\Type
{
return $this->typeFactory->getType(
$this->indexFactory->getIndex(

View file

@ -44,7 +44,7 @@ class Connection implements Singleton
/**
* @param ConfigurationContainerInterface $configuration
* @param \Elastica\Client $elasticaClient
* @param \Elastica\Client|null $elasticaClient
*/
public function __construct(
ConfigurationContainerInterface $configuration,
@ -52,9 +52,8 @@ class Connection implements Singleton
) {
$this->configuration = $configuration;
$this->elasticaClient = $elasticaClient;
if ($this->elasticaClient === null) {
$this->elasticaClient = new \Elastica\Client([
if ($elasticaClient === null) {
$elasticaClient = new \Elastica\Client([
'host' => $this->configuration->get('connections.elasticsearch.host'),
'port' => $this->configuration->get('connections.elasticsearch.port'),
// TODO: Make configurable
@ -63,14 +62,13 @@ class Connection implements Singleton
// TODO: Make configurable.
// new \Elastica\Log($this->elasticaClient);
}
$this->elasticaClient = $elasticaClient;
}
/**
* Get the concrete client for internal usage!
*
* @return \Elastica\Client
*/
public function getClient()
public function getClient() : \Elastica\Client
{
return $this->elasticaClient;
}

View file

@ -44,13 +44,8 @@ class DocumentFactory implements Singleton
/**
* Creates document from document.
*
* @param string $documentType
* @param array $document
*
* @return \Elastica\Document
*/
public function getDocument($documentType, array $document)
public function getDocument(string $documentType, array $document) : \Elastica\Document
{
// TODO: Use DocumentType for further configuration.
@ -70,13 +65,8 @@ class DocumentFactory implements Singleton
/**
* Creates documents based on documents.
*
* @param string $documentType
* @param array $documents
*
* @return array
*/
public function getDocuments($documentType, array $documents)
public function getDocuments(string $documentType, array $documents) : array
{
foreach ($documents as &$document) {
$document = $this->getDocument($documentType, $document);

View file

@ -22,6 +22,7 @@ namespace Codappix\SearchCore\Connection\Elasticsearch;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Connection\FacetInterface;
use Codappix\SearchCore\Connection\FacetOptionInterface;
class Facet implements FacetInterface
{

View file

@ -22,10 +22,8 @@ namespace Codappix\SearchCore\Connection\Elasticsearch;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\InvalidArgumentException;
use Elastica\Exception\ResponseException;
use TYPO3\CMS\Core\SingletonInterface as Singleton;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
/**
* Factory to get indexes.
@ -49,13 +47,8 @@ class IndexFactory implements Singleton
/**
* Get an index bases on TYPO3 table name.
*
* @param Connection $connection
* @param string $documentType
*
* @return \Elastica\Index
*/
public function getIndex(Connection $connection, $documentType)
public function getIndex(Connection $connection, string $documentType) : \Elastica\Index
{
$index = $connection->getClient()->getIndex('typo3content');
@ -66,12 +59,7 @@ class IndexFactory implements Singleton
return $index;
}
/**
* @param string $documentType
*
* @return array
*/
protected function getConfigurationFor($documentType)
protected function getConfigurationFor(string $documentType) : array
{
try {
$configuration = $this->configuration->get('indexing.' . $documentType . '.index');
@ -88,12 +76,7 @@ class IndexFactory implements Singleton
}
}
/**
* @param array $analyzer
*
* @return array
*/
protected function prepareAnalyzerConfiguration(array $analyzer)
protected function prepareAnalyzerConfiguration(array $analyzer) : array
{
$fieldsToExplode = ['char_filter', 'filter'];

View file

@ -44,12 +44,8 @@ class MappingFactory implements Singleton
/**
* Get an mapping based on type.
*
* @param \Elastica\Type $type
*
* @return \Elastica\Mapping
*/
public function getMapping(\Elastica\Type $type)
public function getMapping(\Elastica\Type $type) : \Elastica\Type\Mapping
{
$mapping = new \Elastica\Type\Mapping();
$mapping->setType($type);
@ -64,11 +60,7 @@ class MappingFactory implements Singleton
return $mapping;
}
/**
* @param string $identifier
* @return array
*/
protected function getConfiguration($identifier)
protected function getConfiguration(string $identifier) : array
{
try {
return $this->configuration->get('indexing.' . $identifier . '.mapping');

View file

@ -77,7 +77,7 @@ class SearchResult implements SearchResultInterface
/**
* @return array<ResultItemInterface>
*/
public function getResults()
public function getResults() : array
{
$this->initResults();
@ -89,14 +89,14 @@ class SearchResult implements SearchResultInterface
*
* @return array<FacetInterface>
*/
public function getFacets()
public function getFacets() : array
{
$this->initFacets();
return $this->facets;
}
public function getCurrentCount()
public function getCurrentCount() : int
{
return $this->result->count();
}

View file

@ -21,7 +21,6 @@ namespace Codappix\SearchCore\Connection\Elasticsearch;
*/
use TYPO3\CMS\Core\SingletonInterface as Singleton;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
/**
* Factory to get indexes.
@ -32,13 +31,8 @@ class TypeFactory implements Singleton
{
/**
* Get an index bases on TYPO3 table name.
*
* @param \Elastica\Index $index
* @param string $documentType
*
* @return \Elastica\Type
*/
public function getType(\Elastica\Index $index, $documentType)
public function getType(\Elastica\Index $index, string $documentType) : \Elastica\Type
{
return $index->getType($documentType);
}

View file

@ -25,15 +25,12 @@ namespace Codappix\SearchCore\Connection;
*/
interface FacetInterface
{
/**
* @return string
*/
public function getName();
public function getName() : string;
/**
* Returns all possible options for this facet.
*
* @return array<FacetOptionInterface>
*/
public function getOptions();
public function getOptions() : array;
}

View file

@ -20,6 +20,8 @@ namespace Codappix\SearchCore\Connection;
* 02110-1301, USA.
*/
use Codappix\SearchCore\Connection\ConnectionInterface;
use Codappix\SearchCore\Connection\FacetRequestInterface;
use Codappix\SearchCore\Domain\Search\SearchService;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
@ -27,24 +29,38 @@ interface SearchRequestInterface extends QueryInterface
{
/**
* Returns the actual string the user searched for.
*
* @return string
*/
public function getSearchTerm();
public function getSearchTerm() : string;
public function hasFilter() : bool;
public function getFilter() : array;
public function setFilter(array $filter);
/**
* @return bool
* @return void
*/
public function hasFilter();
public function addFacet(FacetRequestInterface $facet);
/**
* @return array
* @return array<FacetRequestInterface>
*/
public function getFilter();
public function getFacets() : array;
/**
* Workaround for paginate widget support which will
* use the request to build another search.
*
* @return void
*/
public function setConnection(ConnectionInterface $connection);
/**
* Workaround for paginate widget support which will
* use the request to build another search.
*
* @return void
*/
public function setSearchService(SearchService $searchService);
}

View file

@ -30,19 +30,17 @@ interface SearchResultInterface extends \Iterator, \Countable, QueryResultInterf
/**
* @return array<ResultItemInterface>
*/
public function getResults();
public function getResults() : array;
/**
* Return all facets, if any.
*
* @return array<FacetInterface>
*/
public function getFacets();
public function getFacets() : array;
/**
* Returns the number of results in current result
*
* @return int
*/
public function getCurrentCount();
public function getCurrentCount() : int;
}

View file

@ -21,7 +21,7 @@ namespace Codappix\SearchCore\DataProcessing;
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Service\TypoScriptService;
use TYPO3\CMS\Core\TypoScript\TypoScriptService;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
/**

View file

@ -27,7 +27,7 @@ class GeoPointProcessor implements ProcessorInterface
{
public function processData(array $record, array $configuration) : array
{
if (! $this->canApply($record, $configuration)) {
if (! $this->isApplyable($record, $configuration)) {
return $record;
}
@ -39,7 +39,7 @@ class GeoPointProcessor implements ProcessorInterface
return $record;
}
protected function canApply(array $record, array $configuration) : bool
protected function isApplyable(array $record, array $configuration) : bool
{
if (!isset($record[$configuration['lat']])
|| !is_numeric($record[$configuration['lat']])

View file

@ -23,7 +23,6 @@ namespace Codappix\SearchCore\Domain\Index;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\InvalidArgumentException;
use Codappix\SearchCore\Connection\ConnectionInterface;
use Codappix\SearchCore\DataProcessing\ProcessorInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
abstract class AbstractIndexer implements IndexerInterface
@ -64,7 +63,7 @@ abstract class AbstractIndexer implements IndexerInterface
$this->logger = $logManager->getLogger(__CLASS__);
}
public function setIdentifier($identifier)
public function setIdentifier(string $identifier)
{
$this->identifier = $identifier;
}
@ -97,11 +96,11 @@ abstract class AbstractIndexer implements IndexerInterface
$this->logger->info('Finish indexing');
}
public function indexDocument($identifier)
public function indexDocument(string $identifier)
{
$this->logger->info('Start indexing single record.', [$identifier]);
try {
$record = $this->getRecord($identifier);
$record = $this->getRecord((int) $identifier);
$this->prepareRecord($record);
$this->connection->addDocument($this->getDocumentName(), $record);
@ -119,10 +118,7 @@ abstract class AbstractIndexer implements IndexerInterface
$this->logger->info('Finish deletion.');
}
/**
* @return \Generator
*/
protected function getRecordGenerator()
protected function getRecordGenerator() : \Generator
{
$offset = 0;
$limit = $this->getLimit();
@ -133,9 +129,6 @@ abstract class AbstractIndexer implements IndexerInterface
}
}
/**
* @param array &$record
*/
protected function prepareRecord(array &$record)
{
try {
@ -149,9 +142,6 @@ abstract class AbstractIndexer implements IndexerInterface
$this->handleAbstract($record);
}
/**
* @param array &$record
*/
protected function handleAbstract(array &$record)
{
$record['search_abstract'] = '';
@ -161,7 +151,7 @@ abstract class AbstractIndexer implements IndexerInterface
',',
$this->configuration->get('indexing.' . $this->identifier . '.abstractFields')
);
if (!$fieldsToUse) {
if ($fieldsToUse === []) {
return;
}
foreach ($fieldsToUse as $fieldToUse) {
@ -177,31 +167,22 @@ abstract class AbstractIndexer implements IndexerInterface
/**
* Returns the limit to use to fetch records.
*
* @return int
*/
protected function getLimit()
protected function getLimit() : int
{
// TODO: Make configurable.
return 50;
}
/**
* @param int $offset
* @param int $limit
* @return array|null
*/
abstract protected function getRecords($offset, $limit);
abstract protected function getRecords(int $offset, int $limit);
/**
* @param int $identifier
* @return array
* @throws NoRecordFoundException If record could not be found.
*/
abstract protected function getRecord($identifier);
abstract protected function getRecord(int $identifier) : array;
/**
* @return string
*/
abstract protected function getDocumentName();
abstract protected function getDocumentName() : string;
}

View file

@ -56,12 +56,9 @@ class IndexerFactory implements Singleton
}
/**
* @param string $identifier
*
* @return IndexerInterface
* @throws NoMatchingIndexer
*/
public function getIndexer($identifier)
public function getIndexer(string $identifier) : IndexerInterface
{
try {
return $this->buildIndexer($this->configuration->get('indexing.' . $identifier . '.indexer'), $identifier);
@ -75,13 +72,9 @@ class IndexerFactory implements Singleton
}
/**
* @param string $indexerClass
* @param string $identifier
*
* @return IndexerInterface
* @throws NoMatchingIndexer
*/
protected function buildIndexer($indexerClass, $identifier)
protected function buildIndexer(string $indexerClass, string $identifier) : IndexerInterface
{
$indexer = null;
if (is_subclass_of($indexerClass, TcaIndexer\PagesIndexer::class)

View file

@ -35,20 +35,16 @@ interface IndexerInterface
/**
* Fetches a single document and pushes it to the connection.
*
* @param string $identifier
*
* @return void
*/
public function indexDocument($identifier);
public function indexDocument(string $identifier);
/**
* Recieves the identifier of the indexer itself.
*
* @param string $identifier
*
* @return void
*/
public function setIdentifier($identifier);
public function setIdentifier(string $identifier);
/**
* Delete the whole index.

View file

@ -22,6 +22,7 @@ namespace Codappix\SearchCore\Domain\Index;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Connection\ConnectionInterface;
use Codappix\SearchCore\Domain\Index\TcaIndexer\TcaTableService;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
@ -46,17 +47,14 @@ class TcaIndexer extends AbstractIndexer
ConnectionInterface $connection,
ConfigurationContainerInterface $configuration
) {
parent::__construct($connection, $configuration);
$this->tcaTableService = $tcaTableService;
$this->connection = $connection;
$this->configuration = $configuration;
}
/**
* @param int $offset
* @param int $limit
* @return array|null
*/
protected function getRecords($offset, $limit)
protected function getRecords(int $offset, int $limit)
{
$records = $this->getQuery()
->setFirstResult($offset)
@ -77,14 +75,12 @@ class TcaIndexer extends AbstractIndexer
}
/**
* @param int $identifier
* @return array
* @throws NoRecordFoundException If record could not be found.
*/
protected function getRecord($identifier)
protected function getRecord(int $identifier) : array
{
$query = $this->getQuery();
$query = $query->andWhere($this->tcaTableService->getTableName() . '.uid = ' . (int) $identifier);
$query = $query->andWhere($this->tcaTableService->getTableName() . '.uid = ' . $identifier);
$record = $query->execute()->fetch();
if ($record === false || $record === null) {
@ -98,15 +94,12 @@ class TcaIndexer extends AbstractIndexer
return $record;
}
/**
* @return string
*/
protected function getDocumentName()
protected function getDocumentName() : string
{
return $this->tcaTableService->getTableName();
}
protected function getQuery($tcaTableService = null) : QueryBuilder
protected function getQuery(TcaTableService $tcaTableService = null) : QueryBuilder
{
if ($tcaTableService === null) {
$tcaTableService = $this->tcaTableService;
@ -126,7 +119,7 @@ class TcaIndexer extends AbstractIndexer
return $query;
}
protected function getDatabaseConnection()
protected function getDatabaseConnection() : ConnectionPool
{
return GeneralUtility::makeInstance(ConnectionPool::class);
}

View file

@ -36,7 +36,7 @@ class PagesIndexer extends TcaIndexer
/**
* @param TcaTableService $tcaTableService
* @param TcaTableService $tcaTableService
* @param TcaTableService $contentTableService
* @param ConnectionInterface $connection
* @param ConfigurationContainerInterface $configuration
*/
@ -46,15 +46,10 @@ class PagesIndexer extends TcaIndexer
ConnectionInterface $connection,
ConfigurationContainerInterface $configuration
) {
$this->tcaTableService = $tcaTableService;
parent::__construct($tcaTableService, $connection, $configuration);
$this->contentTableService = $contentTableService;
$this->connection = $connection;
$this->configuration = $configuration;
}
/**
* @param array &$record
*/
protected function prepareRecord(array &$record)
{
$possibleTitleFields = ['nav_title', 'tx_tqseo_pagetitle_rel', 'title'];
@ -69,11 +64,7 @@ class PagesIndexer extends TcaIndexer
parent::prepareRecord($record);
}
/**
* @param int $uid
* @return string
*/
protected function fetchContentForPage($uid)
protected function fetchContentForPage(int $uid) : string
{
$contentElements = $this->getQuery($this->contentTableService)->execute()->fetchAll();

View file

@ -21,7 +21,7 @@ namespace Codappix\SearchCore\Domain\Index\TcaIndexer;
*/
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\InvalidArgumentException as InvalidConfigurationArgumentException;
use Codappix\SearchCore\Domain\Index\TcaIndexer\InvalidArgumentException;
use Codappix\SearchCore\Database\Doctrine\Join;
use Codappix\SearchCore\Database\Doctrine\Where;
use Codappix\SearchCore\Domain\Index\IndexingException;
@ -107,17 +107,11 @@ class TcaTableService
$this->relationResolver = $relationResolver;
}
/**
* @return string
*/
public function getTableName() : string
{
return $this->tableName;
}
/**
* @return string
*/
public function getTableClause() : string
{
return $this->tableName;
@ -125,9 +119,6 @@ class TcaTableService
/**
* Filter the given records by root line blacklist settings.
*
* @param array &$records
* @return void
*/
public function filterRecordsByRootLineBlacklist(array &$records)
{
@ -139,9 +130,6 @@ class TcaTableService
);
}
/**
* @param array &$record
*/
public function prepareRecord(array &$record)
{
$this->relationResolver->resolveRelationsForRecord($this, $record);
@ -166,8 +154,8 @@ class TcaTableService
$whereClause .= ' AND ' . $userDefinedWhere;
}
if ($this->isBlacklistedRootLineConfigured()) {
$parameters[':blacklistedRootLine'] = $this->getBlacklistedRootLine();
if ($this->isBlackListedRootLineConfigured()) {
$parameters[':blacklistedRootLine'] = $this->getBlackListedRootLine();
$whereClause .= ' AND pages.uid NOT IN (:blacklistedRootLine)'
. ' AND pages.pid NOT IN (:blacklistedRootLine)';
}
@ -231,11 +219,7 @@ class TcaTableService
return $whereClause;
}
/**
* @param string
* @return bool
*/
protected function isSystemField($columnName) : bool
protected function isSystemField(string $columnName) : bool
{
$systemFields = [
// Versioning fields,
@ -267,11 +251,9 @@ class TcaTableService
}
/**
* @param string $columnName
* @return array
* @throws InvalidArgumentException
*/
public function getColumnConfig($columnName) : array
public function getColumnConfig(string $columnName) : array
{
if (!isset($this->tca['columns'][$columnName])) {
throw new InvalidArgumentException(
@ -290,9 +272,6 @@ class TcaTableService
* Also further TYPO3 mechanics are taken into account. Does a valid root
* line exist, is page inside a recycler, is inherited start- endtime
* excluded, etc.
*
* @param array &$record
* @return bool
*/
protected function isRecordBlacklistedByRootline(array &$record) : bool
{
@ -348,8 +327,6 @@ class TcaTableService
/**
* Checks whether any page uids are black listed.
*
* @return bool
*/
protected function isBlackListedRootLineConfigured() : bool
{

View file

@ -72,56 +72,39 @@ class SearchRequest implements SearchRequestInterface
/**
* @param string $query
*/
public function __construct($query = '')
public function __construct(string $query = '')
{
$this->query = (string) $query;
$this->query = $query;
}
/**
* @return string
*/
public function getQuery()
public function getQuery() : string
{
return $this->query;
}
/**
* @return string
*/
public function getSearchTerm()
public function getSearchTerm() : string
{
return $this->query;
}
/**
* @param array $filter
*/
public function setFilter(array $filter)
{
$filter = \TYPO3\CMS\Core\Utility\ArrayUtility::removeArrayEntryByValue($filter, '');
$this->filter = \TYPO3\CMS\Extbase\Utility\ArrayUtility::removeEmptyElementsRecursively($filter);
}
/**
* @return bool
*/
public function hasFilter()
public function hasFilter() : bool
{
return count($this->filter) > 0;
}
/**
* @return array
*/
public function getFilter()
public function getFilter() : array
{
return $this->filter;
}
/**
* Add a facet to gather in this search request.
*
* @param FacetRequestInterface $facet
*/
public function addFacet(FacetRequestInterface $facet)
{
@ -130,10 +113,8 @@ class SearchRequest implements SearchRequestInterface
/**
* Returns all configured facets to fetch in this search request.
*
* @return array
*/
public function getFacets()
public function getFacets() : array
{
return $this->facets;
}
@ -141,8 +122,6 @@ class SearchRequest implements SearchRequestInterface
/**
* Define connection to use for this request.
* Necessary to allow implementation of execute for interface.
*
* @param ConnectionInterface $connection
*/
public function setConnection(ConnectionInterface $connection)
{
@ -177,11 +156,15 @@ class SearchRequest implements SearchRequestInterface
public function setLimit($limit)
{
$this->limit = (int) $limit;
return $this;
}
public function setOffset($offset)
{
$this->offset = (int) $offset;
return $this;
}
public function getLimit()

View file

@ -62,7 +62,7 @@ class SearchResult implements SearchResultInterface
/**
* @return array<ResultItemInterface>
*/
public function getResults()
public function getResults() : array
{
$this->initResults();
@ -80,12 +80,12 @@ class SearchResult implements SearchResultInterface
}
}
public function getFacets()
public function getFacets() : array
{
return $this->originalSearchResult->getFacets();
}
public function getCurrentCount()
public function getCurrentCount() : int
{
return $this->originalSearchResult->getCurrentCount();
}

View file

@ -23,8 +23,6 @@ namespace Codappix\SearchCore\Domain\Search;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\ConfigurationUtility;
use Codappix\SearchCore\Configuration\InvalidArgumentException;
use Codappix\SearchCore\Connection\ConnectionInterface;
use Codappix\SearchCore\Connection\Elasticsearch\Query;
use Codappix\SearchCore\Connection\SearchRequestInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Utility\ArrayUtility;

View file

@ -74,11 +74,7 @@ class SearchService
$this->dataProcessorService = $dataProcessorService;
}
/**
* @param SearchRequestInterface $searchRequest
* @return SearchResultInterface
*/
public function search(SearchRequestInterface $searchRequest)
public function search(SearchRequestInterface $searchRequest) : SearchResultInterface
{
$this->addSize($searchRequest);
$this->addConfiguredFacets($searchRequest);
@ -93,8 +89,6 @@ class SearchService
/**
* Add configured size of search result items to request.
*
* @param SearchRequestInterface $searchRequest
*/
protected function addSize(SearchRequestInterface $searchRequest)
{
@ -105,8 +99,6 @@ class SearchService
/**
* Add facets from configuration to request.
*
* @param SearchRequestInterface $searchRequest
*/
protected function addConfiguredFacets(SearchRequestInterface $searchRequest)
{
@ -126,8 +118,6 @@ class SearchService
/**
* Add filters from configuration, e.g. flexform or TypoScript.
*
* @param SearchRequestInterface $searchRequest
*/
protected function addConfiguredFilters(SearchRequestInterface $searchRequest)
{

View file

@ -22,10 +22,9 @@ namespace Codappix\SearchCore\Domain\Service;
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Domain\Index\IndexerFactory;
use Codappix\SearchCore\Domain\Index\IndexerInterface;
use Codappix\SearchCore\Domain\Index\NoMatchingIndexerException;
use Codappix\SearchCore\Domain\Index\TcaIndexer;
use TYPO3\CMS\Core\SingletonInterface as Singleton;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Handles all data related things like updates, deletes and inserts.
@ -83,41 +82,27 @@ class DataHandler implements Singleton
$this->indexerFactory = $indexerFactory;
}
/**
* @param string $table
*/
public function update($table, array $record)
public function update(string $table, array $record)
{
$this->logger->debug('Record received for update.', [$table, $record]);
$this->getIndexer($table)->indexDocument($record['uid']);
}
/**
* @param string $table
* @param int $identifier
*/
public function delete($table, $identifier)
public function delete(string $table, string $identifier)
{
$this->logger->debug('Record received for delete.', [$table, $identifier]);
$this->connection->deleteDocument($table, $identifier);
}
/**
* @param string $table
* @return IndexerInterface
*
* @throws NoMatchingIndexerException
*/
protected function getIndexer($table)
protected function getIndexer(string $table) : IndexerInterface
{
return $this->indexerFactory->getIndexer($table);
}
/**
* @param string $table
* @return bool
*/
public function canHandle($table)
public function supportsTable(string $table) : bool
{
try {
$this->getIndexer($table);
@ -125,7 +110,5 @@ class DataHandler implements Singleton
} catch (NoMatchingIndexerException $e) {
return false;
}
return false;
}
}

View file

@ -21,7 +21,6 @@ namespace Codappix\SearchCore\Hook;
*/
use Codappix\SearchCore\Configuration\NoConfigurationException;
use Codappix\SearchCore\Domain\Index\NoMatchingIndexerException;
use Codappix\SearchCore\Domain\Service\DataHandler as OwnDataHandler;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\DataHandling\DataHandler as CoreDataHandler;
@ -49,46 +48,38 @@ class DataHandler implements Singleton
/**
* Dependency injection as TYPO3 doesn't provide it on it's own.
* Still you can submit your own dataHandler.
*
* @param OwnDataHandler $dataHandler
* @param Logger $logger
*/
public function __construct(OwnDataHandler $dataHandler = null, Logger $logger = null)
{
$this->dataHandler = $dataHandler;
if ($this->dataHandler === null) {
if ($dataHandler === null) {
try {
$this->dataHandler = GeneralUtility::makeInstance(ObjectManager::class)
$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->dataHandler = $dataHandler;
$this->logger = $logger;
if ($this->logger === null) {
$this->logger = GeneralUtility::makeInstance(LogManager::class)
if ($logger === null) {
$logger = GeneralUtility::makeInstance(LogManager::class)
->getLogger(__CLASS__);
}
$this->logger = $logger;
}
/**
* Called by CoreDataHandler on deletion of records.
*
* @param string $table
* @param int $uid
*
* @return bool False if hook was not processed.
*/
public function processCmdmap_deleteAction($table, $uid)
public function processCmdmap_deleteAction(string $table, int $uid) : bool
{
if (! $this->shouldProcessHookForTable($table)) {
$this->logger->debug('Delete not processed.', [$table, $uid]);
return false;
}
$this->dataHandler->delete($table, $uid);
$this->dataHandler->delete($table, (string) $uid);
return true;
}
@ -98,8 +89,8 @@ class DataHandler implements Singleton
$uid = key($record);
$fieldData = current($record);
if (isset($fieldArray['uid'])) {
$uid = $fieldArray['uid'];
if (isset($fieldData['uid'])) {
$uid = $fieldData['uid'];
} elseif (isset($dataHandler->substNEWwithIDs[$uid])) {
$uid = $dataHandler->substNEWwithIDs[$uid];
}
@ -125,17 +116,13 @@ class DataHandler implements Singleton
return false;
}
/**
* @param string $table
* @return bool
*/
protected function shouldProcessHookForTable($table)
protected function shouldProcessHookForTable(string $table) : bool
{
if ($this->dataHandler === null) {
$this->logger->debug('Datahandler could not be setup.');
return false;
}
if (! $this->dataHandler->canHandle($table)) {
if (! $this->dataHandler->supportsTable($table)) {
$this->logger->debug('Table is not allowed.', [$table]);
return false;
}
@ -146,11 +133,9 @@ class DataHandler implements Singleton
/**
* Wrapper to allow unit testing.
*
* @param string $table
* @param int $uid
* @return null|array<String>
* @return array|null
*/
protected function getRecord($table, $uid)
protected function getRecord(string $table, int $uid)
{
return BackendUtility::getRecord($table, $uid);
}

View file

@ -62,7 +62,7 @@ class DataHandlerFinisher extends AbstractFinisher
$this->dataHandler->update($tableName, $record);
break;
case 'delete':
$this->dataHandler->delete($tableName, $record['uid']);
$this->dataHandler->delete($tableName, (string) $record['uid']);
break;
}
}

View file

@ -29,10 +29,7 @@ use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
*/
class FrontendUtility extends BackendUtility
{
/**
* @return TypoScriptFrontendController
*/
protected static function getLanguageService()
protected static function getLanguageService() : TypoScriptFrontendController
{
return $GLOBALS['TSFE'];
}

View file

@ -5,4 +5,5 @@ Changelog
:maxdepth: 1
:glob:
changelog/*
changelog/20180408-introduce-php70-type-hints
changelog/20180406-120-facet-configuration

View file

@ -0,0 +1,12 @@
Breacking Change "Introduce PHP 7.0 TypeHints"
==============================================
As PHP evolved, we now migrate the whole code base to use PHP 7.0 type hints.
We do not use PHP 7.1 Type Hints, as some customers still need PHP 7.0 support.
Also we added missing methods to interfaces, that were already used in code.
As this leads to changed method signatures, most custom implementations of interfaces, or overwrites
of existing methods are broken.
To fix, just update the signatures as pointed out by PHP while running the code.