Skip to content

Commit

Permalink
Merge pull request #914 from timohund/task/master/903-introduce-TCASe…
Browse files Browse the repository at this point in the history
…rvice

[TASK] Introduce TCAService
  • Loading branch information
timohund committed Jan 23, 2017
2 parents 1a207ca + 431fb19 commit b9fc318
Show file tree
Hide file tree
Showing 5 changed files with 610 additions and 178 deletions.
157 changes: 28 additions & 129 deletions Classes/GarbageCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

use ApacheSolrForTypo3\Solr\GarbageCollectorPostProcessor;
use ApacheSolrForTypo3\Solr\IndexQueue\Queue;
use ApacheSolrForTypo3\Solr\System\TCA\TCAService;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\SingletonInterface;
Expand All @@ -42,8 +43,25 @@
*/
class GarbageCollector extends AbstractDataHandlerListener implements SingletonInterface
{
/**
* @var array
*/
protected $trackedRecords = [];

/**
* @var TCAService
*/
protected $tcaService;

/**
* GarbageCollector constructor.
* @param TCAService|null $TCAService
*/
public function __construct(TCAService $TCAService = null)
{
$this->tcaService = is_null($TCAService) ? GeneralUtility::makeInstance(TCAService::class) : $TCAService;
}

/**
* Hooks into TCE main and tracks record deletion commands.
*
Expand Down Expand Up @@ -286,80 +304,24 @@ public function processDatamap_preProcessFieldArray(
return;
}

$visibilityAffectingFields = $this->getVisibilityAffectingFieldsByTable($table);
$hasConfiguredEnableColumnForFeGroup = $this->tcaService->isEnableColumn($table, 'fe_group');

if (isset($GLOBALS['TCA'][$table]['ctrl']['enablecolumns'])
&& array_key_exists('fe_group',
$GLOBALS['TCA'][$table]['ctrl']['enablecolumns'])
) {
if ($hasConfiguredEnableColumnForFeGroup) {
$visibilityAffectingFields = $this->tcaService->getVisibilityAffectingFieldsByTable($table);
$record = BackendUtility::getRecord(
$table,
$uid,
$visibilityAffectingFields,
'',
false
);
$record = $this->normalizeFrontendGroupField($table, $record);
$record = $this->tcaService->normalizeFrontendGroupField($table, $record);

// keep previous state of important fields for later comparison
$this->trackedRecords[$table][$uid] = $record;
}
}

/**
* Compiles a list of visibility affecting fields of a table so that it can
* be used in SQL queries.
*
* @param string $table Table name to retrieve visibility affecting fields for
* @return string Comma separated list of field names that affect the visibility of a record on the website
*/
protected function getVisibilityAffectingFieldsByTable($table)
{
static $visibilityAffectingFields;

if (!isset($visibilityAffectingFields[$table])) {
// we always want to get the uid and pid although they do not affect visibility
$fields = ['uid', 'pid'];
if (isset($GLOBALS['TCA'][$table]['ctrl']['enablecolumns'])) {
$fields = array_merge($fields,
$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']);
}

if (isset($GLOBALS['TCA'][$table]['ctrl']['delete'])) {
$fields[] = $GLOBALS['TCA'][$table]['ctrl']['delete'];
}

if ($table == 'pages') {
$fields[] = 'no_search';
$fields[] = 'doktype';
}

$visibilityAffectingFields[$table] = implode(', ', $fields);
}

return $visibilityAffectingFields[$table];
}

/**
* Makes sure that "empty" frontend group fields are always the same value.
*
* @param string $table The record's table name.
* @param array $record the record array.
* @return array The cleaned record
*/
protected function normalizeFrontendGroupField($table, $record)
{
if (isset($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group'])) {
$frontendGroupsField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group'];

if ($record[$frontendGroupsField] == '') {
$record[$frontendGroupsField] = '0';
}
}

return $record;
}

/**
* Hooks into TCE Main and watches all record updates. If a change is
* detected that would remove the record from the website, we try to find
Expand Down Expand Up @@ -388,15 +350,14 @@ public function processDatamap_afterDatabaseOperations(
return;
}

$garbageCollectionRelevantFields = $this->getVisibilityAffectingFieldsByTable($table);
$garbageCollectionRelevantFields = $this->tcaService->getVisibilityAffectingFieldsByTable($table);

$record = BackendUtility::getRecord($table, $uid,
$garbageCollectionRelevantFields, '', false);
$record = $this->normalizeFrontendGroupField($table, $record);
$record = BackendUtility::getRecord($table, $uid, $garbageCollectionRelevantFields, '', false);
$record = $this->tcaService->normalizeFrontendGroupField($table, $record);

if ($this->isHidden($table, $record)
|| (($this->isStartTimeInFuture($table, $record)
|| $this->isEndTimeInPast($table, $record))
if ($this->tcaService->isHidden($table, $record)
|| (($this->tcaService->isStartTimeInFuture($table, $record)
|| $this->tcaService->isEndTimeInPast($table, $record))
&& $this->isMarkedAsIndexed($table, $record)
)
|| $this->hasFrontendGroupsRemoved($table, $record)
Expand All @@ -411,68 +372,6 @@ public function processDatamap_afterDatabaseOperations(
}
}

/**
* Checks whether a hidden field exists for the current table and if so
* determines whether it is set on the current record.
*
* @param string $table The table name.
* @param array $record An array with record fields that may affect visibility.
* @return bool True if the record is hidden, FALSE otherwise.
*/
protected function isHidden($table, $record)
{
$hidden = false;

if (isset($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'])) {
$hiddenField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
$hidden = (boolean)$record[$hiddenField];
}

return $hidden;
}

/**
* Checks whether a start time field exists for the record's table and if so
* determines if a time is set and whether that time is in the future,
* making the record invisible on the website.
*
* @param string $table The table name.
* @param array $record An array with record fields that may affect visibility.
* @return bool True if the record's start time is in the future, FALSE otherwise.
*/
protected function isStartTimeInFuture($table, $record)
{
$startTimeInFuture = false;

if (isset($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['starttime'])) {
$startTimeField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['starttime'];
$startTimeInFuture = $record[$startTimeField] > time();
}

return $startTimeInFuture;
}

/**
* Checks whether a end time field exists for the record's table and if so
* determines if a time is set and whether that time is in the past,
* making the record invisible on the website.
*
* @param string $table The table name.
* @param array $record An array with record fields that may affect visibility.
* @return bool True if the record's end time is in the past, FALSE otherwise.
*/
protected function isEndTimeInPast($table, $record)
{
$endTimeInPast = false;

if (isset($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime'])) {
$endTimeField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime'];
$endTimeInPast = $record[$endTimeField] < time();
}

return $endTimeInPast;
}

/**
* Checks whether the record is in the Index Queue and whether it has been
* indexed already.
Expand Down
2 changes: 1 addition & 1 deletion Classes/IndexQueue/Queue.php
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ public function getItem($itemId)
*
* @param string $itemType item type, usually the table name
* @param int $itemUid item uid
* @return array An array of items matching $itemType and $itemUid
* @return Item[] An array of items matching $itemType and $itemUid
*/
public function getItems($itemType, $itemUid)
{
Expand Down
67 changes: 19 additions & 48 deletions Classes/IndexQueue/RecordMonitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use ApacheSolrForTypo3\Solr\GarbageCollector;
use ApacheSolrForTypo3\Solr\IndexQueue\Queue;
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration;
use ApacheSolrForTypo3\Solr\System\TCA\TCAService;
use ApacheSolrForTypo3\Solr\Util;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\DataHandling\DataHandler;
Expand Down Expand Up @@ -64,16 +65,26 @@ class RecordMonitor extends AbstractDataHandlerListener
*/
protected $mountPageUpdater;


/**
* TCA Service
*
* @var TCAService
*/
protected $tcaService;

/**
* RecordMonitor constructor.
*
* @param Queue|null $indexQueue
* @param MountPagesUpdater|null $mountPageUpdater
* @param TCAService|null $TCAService
*/
public function __construct(Queue $indexQueue = null, MountPagesUpdater $mountPageUpdater = null)
public function __construct(Queue $indexQueue = null, MountPagesUpdater $mountPageUpdater = null, TCAService $TCAService = null)
{
$this->indexQueue = is_null($indexQueue) ? GeneralUtility::makeInstance(Queue::class) : $indexQueue;
$this->mountPageUpdater = is_null($mountPageUpdater) ? GeneralUtility::makeInstance(MountPagesUpdater::class) : $mountPageUpdater;
$this->tcaService = is_null($TCAService) ? GeneralUtility::makeInstance(TCAService::class) : $TCAService;
}

/**
Expand Down Expand Up @@ -158,11 +169,8 @@ public function processCmdmap_postProcess(
$this->solrConfiguration = Util::getSolrConfigurationFromPageId($uid);
$record = $this->getRecord($table, $uid);

if (!empty($record) && $this->isEnabledRecord($table,
$record)
) {
if (!empty($record) && $this->tcaService->isEnabledRecord($table, $record)) {
$this->mountPageUpdater->update($uid);

$this->indexQueue->updateItem($table, $uid);
} else {
// TODO should be moved to garbage collector
Expand All @@ -179,9 +187,7 @@ public function processCmdmap_postProcess(
if ($isMonitoredTable) {
$record = $this->getRecord($table, $uid);

if (!empty($record) && $this->isEnabledRecord($table,
$record)
) {
if (!empty($record) && $this->tcaService->isEnabledRecord($table, $record)) {
if (Util::isLocalizedRecord($table, $record)) {
// if it's a localization overlay, update the original record instead
$uid = $record[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']];
Expand All @@ -205,7 +211,7 @@ public function processCmdmap_postProcess(
// moving pages in LIVE workspace
$this->solrConfiguration = Util::getSolrConfigurationFromPageId($uid);
$record = $this->getRecord('pages', $uid);
if (!empty($record) && $this->isEnabledRecord($table, $record)) {
if (!empty($record) && $this->tcaService->isEnabledRecord($table, $record)) {
$this->indexQueue->updateItem('pages', $uid);
} else {
// check if the item should be removed from the index because it no longer matches the conditions
Expand Down Expand Up @@ -312,7 +318,7 @@ protected function processRecord($recordTable, $recordPageId, $recordUid, $field
// we have a localized record without a visible parent record. Nothing to do.
return;
}
if ($this->isEnabledRecord($recordTable, $record)) {
if ($this->tcaService->isEnabledRecord($recordTable, $record)) {
$configurationName = $this->getIndexingConfigurationName($recordTable, $recordUid);

$this->indexQueue->updateItem($recordTable, $recordUid, $configurationName);
Expand All @@ -335,7 +341,7 @@ protected function getIsTranslationParentRecordEnabled($recordTable, $recordUid)
{
$tableEnableFields = implode(', ', $GLOBALS['TCA'][$recordTable]['ctrl']['enablecolumns']);
$l10nParentRecord = BackendUtility::getRecord($recordTable, $recordUid, $tableEnableFields, '', false);
return $this->isEnabledRecord($recordTable, $l10nParentRecord);
return $this->tcaService->isEnabledRecord($recordTable, $l10nParentRecord);
}

/**
Expand Down Expand Up @@ -367,14 +373,8 @@ protected function doPagesPostUpdateOperations(array $fields, $recordUid)
*
* @return int
*/
protected function getRecordPageId(
$status,
$recordTable,
$recordUid,
$originalUid,
array $fields,
DataHandler $tceMain
) {
protected function getRecordPageId($status, $recordTable, $recordUid, $originalUid, array $fields, DataHandler $tceMain)
{
if ($status == 'update' && !isset($fields['pid'])) {
$recordPageId = $this->getValidatedPid($tceMain, $recordTable, $recordUid);
if ($recordTable == 'pages' && Util::isRootPage($recordUid)) {
Expand Down Expand Up @@ -477,35 +477,6 @@ protected function getValidatedPid(DataHandler $tceMain, $table, $uid)
return $pid;
}

/**
* Checks if a record is "enabled"
*
* A record is considered "enabled" if
* - it is not hidden
* - it is not deleted
* - as a page it is not set to be excluded from search
*
* @param string $table The record's table name
* @param array $record The record to check
* @return bool TRUE if the record is enabled, FALSE otherwise
*/
protected function isEnabledRecord($table, $record)
{
$recordEnabled = true;

if (
(isset($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']) && !empty($record[$GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']]))
||
(isset($GLOBALS['TCA'][$table]['ctrl']['delete']) && !empty($record[$GLOBALS['TCA'][$table]['ctrl']['delete']]))
||
($table == 'pages' && !empty($record['no_search']))
) {
$recordEnabled = false;
}

return $recordEnabled;
}

/**
* Retrieves the name of the Indexing Queue Configuration for a record
*
Expand Down

0 comments on commit b9fc318

Please sign in to comment.