[TYPO3-Solr] Custom Index on tt_content is not refreshe automatically
Holger
hbirkner at gv-bayern.de
Tue Nov 5 14:53:08 CET 2013
Hi there I chaged the code of class.tx_solr_indexqueue_recordmonitor.php
<?php
/***************************************************************
* Copyright notice
*
* (c) 2009-2012 Ingo Renner <ingo (at) typo3.org>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project 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.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script 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.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* A class that monitors changes to records so that the changed record gets
* passed to the index queue to update the according index document.
*
* @author Ingo Renner <ingo (at) typo3.org>
* @package TYPO3
* @subpackage solr
*/
class tx_solr_indexqueue_RecordMonitor {
/**
* Solr TypoScript configuration
*
* TODO check whether we need this or whether it's better to retrieve each time as in getMonitoredTables()
*
* @var array
*/
protected $solrConfiguration;
/**
* Index Queue
*
* @var tx_solr_indexqueue_Queue
*/
protected $indexQueue;
/**
* Constructor
*
*/
public function __construct() {
$this->indexQueue = t3lib_div::makeInstance('tx_solr_indexqueue_Queue');
}
/**
* Hooks into TCE main and tracks record deletion commands.
*
* @param string The command.
* @param string The table the record belongs to
* @param integer The record's uid
* @param string
* @param t3lib_TCEmain TYPO3 Core Engine parent object
*/
public function processCmdmap_preProcess($command, $table, $uid, $value, t3lib_TCEmain $tceMain) {
if ($command == 'delete' && $table == 'tt_content' && $GLOBALS['BE_USER']->workspace == 0) {
// skip workspaces: index only LIVE workspace
// hier ein Schalter, der tt_content als normale Tabelle behandeln soll?
$this->indexQueue->deleteItem('tt_content', $uid);// aenderung Holger
// $this->indexQueue->updateItem('pages', $tceMain->getPID($table, $uid));// aenderung Holger
}
}
/**
* Hooks into TCE main and tracks workspace publish/swap events and
* page move commands in LIVE workspace.
*
* @param string The command.
* @param string The table the record belongs to
* @param integer The record's uid
* @param string
* @param t3lib_TCEmain TYPO3 Core Engine parent object
*/
public function processCmdmap_postProcess($command, $table, $uid, $value, t3lib_TCEmain $tceMain) {
//t3lib_div::devLog($command.'->'.$table.'->'.$uid, 'solr', 2);
if (tx_solr_Util::isDraftRecord($table, $uid)) {
// skip workspaces: index only LIVE workspace
return;
}
// track publish / swap events for records (workspace support)
// command "version"
if ($command == 'version' && $value['action'] == 'swap') {
switch ($table) {
case 'tt_content':// aenderung Holger
// hier ein Schalter, der tt_content als normale Tabelle behandeln soll?
$uid = $uid; // $tceMain->getPID($table, $uid);// aenderung Holger
$table = 'tt_content';// aenderung Holger
case 'pages':
$this->solrConfiguration = tx_solr_Util::getSolrConfigurationFromPageId($uid);
$record = $this->getRecord($table, $uid);
if (!empty($record) && $this->isEnabledRecord($table, $record)) {
$this->updateMountPages($uid);
$this->indexQueue->updateItem($table, $uid);
} else {
// TODO should be moved to garbage collector
if ($this->indexQueue->containsItem($table, $uid)) {
$this->removeFromIndexAndQueue($table, $uid);
}
}
break;
default:
$recordPageId = $tceMain->getPID($table, $uid);
$this->solrConfiguration = tx_solr_Util::getSolrConfigurationFromPageId($recordPageId);
$monitoredTables = $this->getMonitoredTables($recordPageId);
if (in_array($table, $monitoredTables)) {
$record = $this->getRecord($table, $uid);
if (!empty($record) && $this->isEnabledRecord($table, $record)) {
if ($this->isLocalizedRecord($table, $record)) {
// if it's a localization overlay, update the original record instead
$uid = $record[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']];
}
$this->indexQueue->updateItem($table, $uid);
} else {
// TODO should be moved to garbage collector
if ($this->indexQueue->containsItem($table, $uid)) {
$this->removeFromIndexAndQueue($table, $uid);
}
}
}
}
}
if ($command == 'move' && $table == 'pages' && $GLOBALS['BE_USER']->workspace == 0) {
// moving pages in LIVE workspace
$this->solrConfiguration = tx_solr_Util::getSolrConfigurationFromPageId($uid);
$record = $this->getRecord('pages', $uid);
if (!empty($record)) {
$this->indexQueue->updateItem('pages', $uid);
} else {
// check if the item should be removed from the index because it no longer matches the conditions
if ($this->indexQueue->containsItem('pages', $uid)) {
$this->removeFromIndexAndQueue('pages', $uid);
}
}
}
}
/**
* Hooks into TCE Main and watches all record creations and updates. If it
* detects that the new/updated record belongs to a table configured for
* indexing through Solr, we add the record to the index queue.
*
* @param string Status of the current operation, 'new' or 'update'
* @param string The table the record belongs to
* @param mixed The record's uid, [integer] or [string] (like 'NEW...')
* @param array The record's data
* @param t3lib_TCEmain TYPO3 Core Engine parent object
* @return void
*/
public function processDatamap_afterDatabaseOperations($status, $table, $uid, array $fields, t3lib_TCEmain $tceMain) {
$recordTable = $table;
$recordUid = $uid;
$recordPageId = 0;
//t3lib_div::devLog($status.'->'.$table.'->'.$uid, 'solr', 2);
if ($status == 'new') {
$recordUid = $tceMain->substNEWwithIDs[$recordUid];
}
if (tx_solr_Util::isDraftRecord($table, $recordUid)) {
// skip workspaces: index only LIVE workspace
return;
}
if ($status == 'update' && !isset($fields['pid'])) {
$recordPageId = $tceMain->getPID($recordTable, $recordUid);
} else {
$recordPageId = $fields['pid'];
}
// when a content element changes we need to updated the page instead
if ($recordTable == 'tt_content') {
$recordTable = 'tt_content';// aenderung Holger
$recordUid = $recordUid;// aenderung Holger
}
$this->solrConfiguration = tx_solr_Util::getSolrConfigurationFromPageId($recordPageId);
$monitoredTables = $this->getMonitoredTables($recordPageId);
if (in_array($recordTable, $monitoredTables, TRUE)) {
$record = $this->getRecord($recordTable, $recordUid);
if (!empty($record)) {
// only update/insert the item if we actually found a record
if ($this->isLocalizedRecord($recordTable, $record)) {
// if it's a localization overlay, update the original record instead
$recordUid = $record[$GLOBALS['TCA'][$recordTable]['ctrl']['transOrigPointerField']];
if ($recordTable == 'pages_language_overlay') {
$recordTable = 'pages';
}
}
$this->indexQueue->updateItem($recordTable, $recordUid);
if ($recordTable == 'pages') {
$this->updateMountPages($recordUid);
}
} else {
// TODO move this part to the garbage collector
// check if the item should be removed from the index because it no longer matches the conditions
if ($this->indexQueue->containsItem($recordTable, $recordUid)) {
$this->removeFromIndexAndQueue($recordTable, $recordUid);
}
}
}
}
/**
* Removes record from the index queue and from the solr index
*
* @param string $recordTable Name of table where the record lives
* @param int $recordUid Id of record
*/
protected function removeFromIndexAndQueue($recordTable, $recordUid) {
//t3lib_div::devLog('removeFromIndexAndQueue->'.$recordTable.'->'.$recordUid, 'solr', 2);
$garbageCollector = t3lib_div::makeInstance('tx_solr_GarbageCollector');
$garbageCollector->collectGarbage($recordTable, $recordUid);
}
/**
* Retrieves a record, taking into account the additionalWhereClauses of the
* Indexing Queue configurations.
*
* @param string $recordTable Table to read from
* @param int $recordUid Id of the record
* @return array Record if found, otherwise empty array
*/
protected function getRecord($recordTable, $recordUid) {
//t3lib_div::devLog('getRecord->'.$recordTable.'->'.$recordUid, 'solr', 2);
$record = array();
$indexingConfigurations = $this->indexQueue->getTableIndexingConfigurations($this->solrConfiguration);
foreach ($indexingConfigurations as $indexingConfigurationName) {
$tableToIndex = $indexingConfigurationName;
if (!empty($this->solrConfiguration['index.']['queue.'][$indexingConfigurationName . '.']['table'])) {
// table has been set explicitly. Allows to index the same table with different configurations
$tableToIndex = $this->solrConfiguration['index.']['queue.'][$indexingConfigurationName . '.']['table'];
}
if ($tableToIndex === $recordTable) {
$recordWhereClause = $this->buildUserWhereClause($indexingConfigurationName);
$record = t3lib_BEfunc::getRecord($recordTable, $recordUid, '*', $recordWhereClause);
if (!empty($record)) {
// if we found a record which matches the conditions, we can continue
break;
}
}
}
return $record;
}
/**
* Build additional where clause from index queue configuration
*
* @param string $indexingConfigurationName Indexing configuration name
* @return string Optional extra where clause
*/
protected function buildUserWhereClause($indexingConfigurationName){
//t3lib_div::devLog('buildUserWhereClause->'.$indexingConfigurationName, 'solr', 2);
$condition = '';
// FIXME replace this with the mechanism described in tx_solr_indexqueue_initializer_Abstract::buildUserWhereClause()
if (isset($this->solrConfiguration['index.']['queue.'][$indexingConfigurationName . '.']['additionalWhereClause'])) {
$condition = ' AND ' . $this->solrConfiguration['index.']['queue.'][$indexingConfigurationName . '.']['additionalWhereClause'];
}
return $condition;
}
/**
* Gets an array of tables configured for indexing by the Index Queue. The
* record monitor must watch these tables for manipulation.
*
* @param integer The page id for which we need to retrieve the configuration for
* @return array Array of table names to be watched by the record monitor.
*/
protected function getMonitoredTables($pageId) {
//t3lib_div::devLog('getMonitoredTables'.$pageId, 'solr', 2);
$monitoredTables = array();
// FIXME!! $pageId might be outside of a site root and thus might not know about solr configuration
// -> leads to record not being queued for reindexing
$solrConfiguration = tx_solr_Util::getSolrConfigurationFromPageId($pageId);
$indexingConfigurations = t3lib_div::makeInstance('tx_solr_indexqueue_Queue')
->getTableIndexingConfigurations($solrConfiguration);
foreach ($indexingConfigurations as $indexingConfigurationName) {
$monitoredTable = $indexingConfigurationName;
if (!empty($solrConfiguration['index.']['queue.'][$indexingConfigurationName . '.']['table'])) {
// table has been set explicitly. Allows to index the same table with different configurations
$monitoredTable = $solrConfiguration['index.']['queue.'][$indexingConfigurationName . '.']['table'];
}
$monitoredTables[] = $monitoredTable;
if ($monitoredTable == 'pages') {
// when monitoring pages, also monitor creation of translations
$monitoredTables[] = 'pages_language_overlay';
}
}
return array_unique($monitoredTables);
}
// Mount Page Handling
/**
* Handles updates of the Index Queue in case a newly created or changed
* page is part of a tree that is mounted into a another site.
*
* @param integer $pageId Page Id (uid).
*/
protected function updateMountPages($pageId) {
//t3lib_div::devLog('updateMountPages->'.$pageId, 'solr', 9);
// get the root line of the page, every parent page could be a Mount Page source
$pageSelect = t3lib_div::makeInstance('t3lib_pageSelect');
$rootLine = $pageSelect->getRootLine($pageId);
// remove the current page / newly created page
array_shift($rootLine);
$destinationMountProperties = $this->getDestinationMountPropertiesByRootLine($rootLine);
if (!empty($destinationMountProperties)) {
foreach ($destinationMountProperties as $destinationMount) {
$this->addPageToMountingSiteIndexQueue($pageId, $destinationMount);
}
}
}
/**
* Finds Mount Pages that mount pages in a given root line.
*
* @param array $rootLine Root line of pages to check for usage as mount source
* @return array Array of pages found to be mounting pages from the root line.
*/
protected function getDestinationMountPropertiesByRootLine(array $rootLine) {
//t3lib_div::devLog('getDestinationMountPropertiesByRootLine->'.$rootLine, 'solr', 10);
$mountPages = array();
$pageIds = array();
if (!empty($rootLine)) {
foreach ($rootLine as $pageRecord) {
$pageIds[] = $pageRecord['uid'];
if ($pageRecord['is_siteroot']) {
break;
}
}
$mountPages = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
'uid, uid AS mountPageDestination, mount_pid AS mountPageSource, mount_pid_ol AS mountPageOverlayed',
'pages',
'doktype = 7 AND mount_pid IN(' . implode(',', $pageIds) . ')'
. t3lib_BEfunc::deleteClause('pages')
);
}
return $mountPages;
}
/**
* Adds a page to the Index Queue of a site mounting the page.
*
* @param integer $mountedPageId ID (uid) of the mounted page.
* @param array $mountProperties Array of mount point properties mountPageSource, mountPageDestination, and mountPageOverlayed
*/
protected function addPageToMountingSiteIndexQueue($mountedPageId, array $mountProperties) {
//t3lib_div::devLog('addPageToMountingSiteIndexQueue->'.mountedPageId, 'solr', 2);
$mountingSite = tx_solr_Site::getSiteByPageId($mountProperties['mountPageDestination']);
$pageInitializer = t3lib_div::makeInstance('tx_solr_indexqueue_initializer_Page');
$pageInitializer->setSite($mountingSite);
$pageInitializer->initializeMountedPage($mountProperties, $mountedPageId);
}
/**
* Checks whether a record is a localization overlay.
*
* @param string $table The record's table name
* @param array $record The record to check
* @return boolean TRUE if the record is a language overlay, FALSE otherwise
*/
protected function isLocalizedRecord($table, array $record) {
//t3lib_div::devLog('isLocalizedRecord', 'solr', 2);
$isLocalizedRecord = FALSE;
$translationOriginalPointerField = '';
if (isset($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'])) {
$translationOriginalPointerField = $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'];
if ($record[$translationOriginalPointerField] > 0) {
$isLocalizedRecord = TRUE;
}
}
return $isLocalizedRecord;
}
/**
* Checks if a record is "enabled"
*
* A record is considered "enabeled" 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 boolean TRUE if the record is enabled, FALSE otherwise
*/
protected function isEnabledRecord($table, $record) {
//t3lib_div::devLog('isEnabledRecord', 'solr', 2);
$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;
}
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/solr/classes/indexqueue/class.tx_solr_indexqueue_recordmonitor.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/solr/classes/indexqueue/class.tx_solr_indexqueue_recordmonitor.php']);
}
?>
More information about the TYPO3-project-solr
mailing list