380 lines
16 KiB
PHP
380 lines
16 KiB
PHP
<?php
|
|
|
|
/**
|
|
* (c) Kitodo. Key to digital objects e.V. <contact@kitodo.org>
|
|
*
|
|
* This file is part of the Kitodo and TYPO3 projects.
|
|
*
|
|
* @license GNU General Public License version 3 or later.
|
|
* For the full copyright and license information, please read the
|
|
* LICENSE.txt file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Kitodo\Dlf\Hooks;
|
|
|
|
use Kitodo\Dlf\Common\Document;
|
|
use Kitodo\Dlf\Common\Helper;
|
|
use Kitodo\Dlf\Common\Indexer;
|
|
use Kitodo\Dlf\Common\Solr;
|
|
use TYPO3\CMS\Core\Database\ConnectionPool;
|
|
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|
|
|
/**
|
|
* Hooks and helper for \TYPO3\CMS\Core\DataHandling\DataHandler
|
|
*
|
|
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
|
* @package TYPO3
|
|
* @subpackage dlf
|
|
* @access public
|
|
*/
|
|
class DataHandler
|
|
{
|
|
/**
|
|
* Field post-processing hook for the process_datamap() method.
|
|
*
|
|
* @access public
|
|
*
|
|
* @param string $status: 'new' or 'update'
|
|
* @param string $table: The destination table
|
|
* @param int $id: The uid of the record
|
|
* @param array &$fieldArray: Array of field values
|
|
*
|
|
* @return void
|
|
*/
|
|
public function processDatamap_postProcessFieldArray($status, $table, $id, &$fieldArray)
|
|
{
|
|
if ($status == 'new') {
|
|
switch ($table) {
|
|
// Field post-processing for table "tx_dlf_documents".
|
|
case 'tx_dlf_documents':
|
|
// Set sorting field if empty.
|
|
if (
|
|
empty($fieldArray['title_sorting'])
|
|
&& !empty($fieldArray['title'])
|
|
) {
|
|
$fieldArray['title_sorting'] = $fieldArray['title'];
|
|
}
|
|
break;
|
|
// Field post-processing for table "tx_dlf_metadata".
|
|
case 'tx_dlf_metadata':
|
|
// Store field in index if it should appear in lists.
|
|
if (!empty($fieldArray['is_listed'])) {
|
|
$fieldArray['index_stored'] = 1;
|
|
}
|
|
// Index field in index if it should be used for auto-completion.
|
|
if (!empty($fieldArray['index_autocomplete'])) {
|
|
$fieldArray['index_indexed'] = 1;
|
|
}
|
|
// Field post-processing for tables "tx_dlf_metadata", "tx_dlf_collections", "tx_dlf_libraries" and "tx_dlf_structures".
|
|
case 'tx_dlf_collections':
|
|
case 'tx_dlf_libraries':
|
|
case 'tx_dlf_structures':
|
|
// Set label as index name if empty.
|
|
if (
|
|
empty($fieldArray['index_name'])
|
|
&& !empty($fieldArray['label'])
|
|
) {
|
|
$fieldArray['index_name'] = $fieldArray['label'];
|
|
}
|
|
// Set index name as label if empty.
|
|
if (
|
|
empty($fieldArray['label'])
|
|
&& !empty($fieldArray['index_name'])
|
|
) {
|
|
$fieldArray['label'] = $fieldArray['index_name'];
|
|
}
|
|
// Ensure that index names don't get mixed up with sorting values.
|
|
if (substr($fieldArray['index_name'], -8) == '_sorting') {
|
|
$fieldArray['index_name'] .= '0';
|
|
}
|
|
break;
|
|
// Field post-processing for table "tx_dlf_solrcores".
|
|
case 'tx_dlf_solrcores':
|
|
// Create new Solr core.
|
|
$fieldArray['index_name'] = Solr::createCore();
|
|
if (empty($fieldArray['index_name'])) {
|
|
Helper::devLog('Could not create new Apache Solr core', DEVLOG_SEVERITY_ERROR);
|
|
// Solr core could not be created, thus unset field array.
|
|
$fieldArray = [];
|
|
}
|
|
break;
|
|
}
|
|
} elseif ($status == 'update') {
|
|
switch ($table) {
|
|
// Field post-processing for table "tx_dlf_metadata".
|
|
case 'tx_dlf_metadata':
|
|
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
|
->getQueryBuilderForTable($table);
|
|
|
|
// Store field in index if it should appear in lists.
|
|
if (!empty($fieldArray['is_listed'])) {
|
|
$fieldArray['index_stored'] = 1;
|
|
}
|
|
if (
|
|
isset($fieldArray['index_stored'])
|
|
&& $fieldArray['index_stored'] == 0
|
|
&& !isset($fieldArray['is_listed'])
|
|
) {
|
|
// Get current configuration.
|
|
$result = $queryBuilder
|
|
->select($table . '.is_listed AS is_listed')
|
|
->from($table)
|
|
->where(
|
|
$queryBuilder->expr()->eq($table . '.uid', intval($id)),
|
|
Helper::whereExpression($table)
|
|
)
|
|
->setMaxResults(1)
|
|
->execute();
|
|
|
|
if ($resArray = $result->fetch()) {
|
|
// Reset storing to current.
|
|
$fieldArray['index_stored'] = $resArray['is_listed'];
|
|
}
|
|
}
|
|
// Index field in index if it should be used for auto-completion.
|
|
if (!empty($fieldArray['index_autocomplete'])) {
|
|
$fieldArray['index_indexed'] = 1;
|
|
}
|
|
if (
|
|
isset($fieldArray['index_indexed'])
|
|
&& $fieldArray['index_indexed'] == 0
|
|
&& !isset($fieldArray['index_autocomplete'])
|
|
) {
|
|
// Get current configuration.
|
|
$result = $queryBuilder
|
|
->select($table . '.index_autocomplete AS index_autocomplete')
|
|
->from($table)
|
|
->where(
|
|
$queryBuilder->expr()->eq($table . '.uid', intval($id)),
|
|
Helper::whereExpression($table)
|
|
)
|
|
->setMaxResults(1)
|
|
->execute();
|
|
|
|
if ($resArray = $result->fetch()) {
|
|
// Reset indexing to current.
|
|
$fieldArray['index_indexed'] = $resArray['index_autocomplete'];
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* After database operations hook for the process_datamap() method.
|
|
*
|
|
* @access public
|
|
*
|
|
* @param string $status: 'new' or 'update'
|
|
* @param string $table: The destination table
|
|
* @param int $id: The uid of the record
|
|
* @param array &$fieldArray: Array of field values
|
|
*
|
|
* @return void
|
|
*/
|
|
public function processDatamap_afterDatabaseOperations($status, $table, $id, &$fieldArray)
|
|
{
|
|
if ($status == 'update') {
|
|
switch ($table) {
|
|
// After database operations for table "tx_dlf_documents".
|
|
case 'tx_dlf_documents':
|
|
// Delete/reindex document in Solr if "hidden" status or collections have changed.
|
|
if (
|
|
isset($fieldArray['hidden'])
|
|
|| isset($fieldArray['collections'])
|
|
) {
|
|
// Get Solr-Core.
|
|
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
|
->getQueryBuilderForTable('tx_dlf_solrcores');
|
|
|
|
$result = $queryBuilder
|
|
->select(
|
|
'tx_dlf_solrcores.uid AS core',
|
|
'tx_dlf_solrcores.index_name',
|
|
'tx_dlf_documents_join.hidden AS hidden'
|
|
)
|
|
->innerJoin(
|
|
'tx_dlf_solrcores',
|
|
'tx_dlf_documents',
|
|
'tx_dlf_documents_join',
|
|
$queryBuilder->expr()->eq(
|
|
'tx_dlf_documents_join.solrcore',
|
|
'tx_dlf_solrcores.uid'
|
|
)
|
|
)
|
|
->from('tx_dlf_solrcores')
|
|
->where(
|
|
$queryBuilder->expr()->eq(
|
|
'tx_dlf_documents_join.uid',
|
|
intval($id)
|
|
)
|
|
)
|
|
->setMaxResults(1)
|
|
->execute();
|
|
|
|
$allResults = $result->fetchAll();
|
|
|
|
if (count($allResults) == 1) {
|
|
$resArray = $allResults[0];
|
|
if ($resArray['hidden']) {
|
|
// Establish Solr connection.
|
|
$solr = Solr::getInstance($resArray['core']);
|
|
if ($solr->ready) {
|
|
// Delete Solr document.
|
|
$updateQuery = $solr->service->createUpdate();
|
|
$updateQuery->addDeleteQuery('uid:' . $id);
|
|
$updateQuery->addCommit();
|
|
$solr->service->update($updateQuery);
|
|
}
|
|
} else {
|
|
// Reindex document.
|
|
$doc = Document::getInstance($id);
|
|
if ($doc->ready) {
|
|
Indexer::add($doc, $resArray['core']);
|
|
} else {
|
|
Helper::devLog('Failed to re-index document with UID ' . $id, DEVLOG_SEVERITY_ERROR);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Post-processing hook for the process_cmdmap() method.
|
|
*
|
|
* @access public
|
|
*
|
|
* @param string $command: 'move', 'copy', 'localize', 'inlineLocalizeSynchronize', 'delete' or 'undelete'
|
|
* @param string $table: The destination table
|
|
* @param int $id: The uid of the record
|
|
*
|
|
* @return void
|
|
*/
|
|
public function processCmdmap_postProcess($command, $table, $id)
|
|
{
|
|
if (
|
|
in_array($command, ['move', 'delete', 'undelete'])
|
|
&& $table == 'tx_dlf_documents'
|
|
) {
|
|
// Get Solr core.
|
|
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
|
->getQueryBuilderForTable('tx_dlf_solrcores');
|
|
// Record in "tx_dlf_documents" is already deleted at this point.
|
|
$queryBuilder
|
|
->getRestrictions()
|
|
->removeByType(DeletedRestriction::class);
|
|
|
|
$result = $queryBuilder
|
|
->select(
|
|
'tx_dlf_solrcores.uid AS core'
|
|
)
|
|
->innerJoin(
|
|
'tx_dlf_solrcores',
|
|
'tx_dlf_documents',
|
|
'tx_dlf_documents_join',
|
|
$queryBuilder->expr()->eq(
|
|
'tx_dlf_documents_join.solrcore',
|
|
'tx_dlf_solrcores.uid'
|
|
)
|
|
)
|
|
->from('tx_dlf_solrcores')
|
|
->where(
|
|
$queryBuilder->expr()->eq(
|
|
'tx_dlf_documents_join.uid',
|
|
intval($id)
|
|
)
|
|
)
|
|
->setMaxResults(1)
|
|
->execute();
|
|
|
|
$allResults = $result->fetchAll();
|
|
|
|
if (count($allResults) == 1) {
|
|
$resArray = $allResults[0];
|
|
switch ($command) {
|
|
case 'move':
|
|
case 'delete':
|
|
// Establish Solr connection.
|
|
$solr = Solr::getInstance($resArray['core']);
|
|
if ($solr->ready) {
|
|
// Delete Solr document.
|
|
$updateQuery = $solr->service->createUpdate();
|
|
$updateQuery->addDeleteQuery('uid:' . $id);
|
|
$updateQuery->addCommit();
|
|
$solr->service->update($updateQuery);
|
|
if ($command == 'delete') {
|
|
break;
|
|
}
|
|
}
|
|
case 'undelete':
|
|
// Reindex document.
|
|
$doc = Document::getInstance($id);
|
|
if ($doc->ready) {
|
|
Indexer::add($doc, $resArray['core']);
|
|
} else {
|
|
Helper::devLog('Failed to re-index document with UID ' . $id, DEVLOG_SEVERITY_ERROR);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (
|
|
$command === 'delete'
|
|
&& $table == 'tx_dlf_solrcores'
|
|
) {
|
|
// Is core deletion allowed in extension configuration?
|
|
$extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['dlf']);
|
|
if (!empty($extConf['solrAllowCoreDelete'])) {
|
|
// Delete core from Apache Solr as well.
|
|
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
|
->getQueryBuilderForTable('tx_dlf_solrcores');
|
|
// Record in "tx_dlf_solrcores" is already deleted at this point.
|
|
$queryBuilder
|
|
->getRestrictions()
|
|
->removeByType(DeletedRestriction::class);
|
|
|
|
$result = $queryBuilder
|
|
->select(
|
|
'tx_dlf_solrcores.index_name AS core'
|
|
)
|
|
->from('tx_dlf_solrcores')
|
|
->where($queryBuilder->expr()->eq('tx_dlf_solrcores.uid', intval($id)))
|
|
->setMaxResults(1)
|
|
->execute();
|
|
|
|
$allResults = $result->fetchAll();
|
|
|
|
if (count($allResults) == 1) {
|
|
$resArray = $allResults[0];
|
|
// Establish Solr connection.
|
|
$solr = Solr::getInstance();
|
|
if ($solr->ready) {
|
|
// Delete Solr core.
|
|
$query = $solr->service->createCoreAdmin();
|
|
$action = $query->createUnload();
|
|
$action->setCore($resArray['core']);
|
|
$action->setDeleteDataDir(true);
|
|
$action->setDeleteIndex(true);
|
|
$action->setDeleteInstanceDir(true);
|
|
$query->setAction($action);
|
|
try {
|
|
$response = $solr->service->coreAdmin($query);
|
|
if ($response->getWasSuccessful()) {
|
|
return;
|
|
}
|
|
} catch (\Exception $e) {
|
|
// Nothing to do here.
|
|
}
|
|
}
|
|
Helper::devLog('Core ' . $resArray['core'] . ' could not be deleted from Apache Solr', DEVLOG_SEVERITY_WARNING);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|