Last active
May 2, 2024 11:08
-
-
Save cepheiVV/2e585eacfdc8a7f0682eb8522c25de59 to your computer and use it in GitHub Desktop.
ke_search custom indexer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Vendor\MyExt\Indexer; | |
use Doctrine\DBAL\DBALException; | |
use Doctrine\DBAL\Result; | |
use TYPO3\CMS\Core\Utility\GeneralUtility; | |
use TYPO3\CMS\Core\Database\ConnectionPool; | |
/** | |
* Abstract class for custom indexers | |
*/ | |
abstract class AbstractIndexer | |
{ | |
/** | |
* require custom indexers to implement a registerIndexerConfiguration method | |
*/ | |
abstract public function registerIndexerConfiguration(&$params, $pObj); | |
/** | |
* require custom indexers to implement a customIndexer method | |
*/ | |
abstract public function customIndexer(&$indexerConfig, &$indexerObject); | |
/** | |
* get mm relation UID and add them as tags | |
* @param array $tags | |
* @param int $foreignUid | |
* @param string $tagName | |
* @param string $mmTable | |
* @return array $tags | |
* @throws DBALException | |
*/ | |
public function addCategoryTags(array $tags, int $foreignUid, string $tagName, string $mmTable='sys_category_record_mm'): array | |
{ | |
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($mmTable); | |
$relations = $queryBuilder | |
->select('uid_local') | |
->from($mmTable) | |
->where('uid_foreign=' . $foreignUid. ' AND tablenames LIKE "' . $this->table . '"') | |
->execute() | |
->fetchAll(); | |
if ($relations) { | |
foreach ($relations as $relation) { | |
if ($relation['uid_local']) { | |
$tags[] = '#'. $tagName . '-' .$relation['uid_local'] . '#'; | |
} | |
} | |
} | |
return $tags; | |
} | |
/** | |
* get all the entries to index | |
* don't index hidden or deleted elements, but | |
* get the elements with frontend user group access restrictions | |
* or time (start / stop) restrictions, in order to copy those restrictions to the index. | |
* @param string $table | |
* @param int $sysFolderUid | |
* @return Result|int | |
* @throws DBALException | |
*/ | |
public function getIndexData(string $table, int $sysFolderUid): int|Result | |
{ | |
$queryBuilder = GeneralUtility::makeInstance( | |
ConnectionPool::class | |
)->getQueryBuilderForTable($table); | |
$queryBuilder->select('*') | |
->from($table) | |
->where('pid IN (' . $sysFolderUid . ')'); | |
return $queryBuilder->execute(); | |
} | |
/** | |
* build response message that is displayed after the indexing is complete | |
* | |
* @param string $indexerTitle name of the indexer | |
* @param int $counter count of indexed records | |
* @return string response message | |
*/ | |
public function createResponseMessage(string $indexerTitle, int $counter): string | |
{ | |
return '<p><b>Indexer "' . $indexerTitle . '": ' . $counter . ' elements have been indexed.</b></p><br>'; | |
} | |
/** | |
* validate the indexer configuration | |
* | |
* @param array $indexerConfig Configuration from TYPO3 Backend Indexer | |
* @throws \Exception | |
*/ | |
protected function validateConfiguration(array $indexerConfig): void | |
{ | |
if (!$indexerConfig['sysfolder'] || | |
!$indexerConfig['targetpid'] || | |
!$indexerConfig['storagepid']) { | |
throw new \Exception("Missing configuration for ke_search indexer: " . $this->indexerConfigurationKey); | |
} | |
} | |
/** | |
* check if page UID is not deleted | |
* | |
* @param int $pageUid | |
* @return bool | |
* @throws DBALException | |
*/ | |
public function targetPageExists(int $pageUid): bool | |
{ | |
$pageExists = true; | |
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages'); | |
$queryBuilder->select('*') | |
->from('pages') | |
->where('uid='.$pageUid) | |
->setMaxResults(1); | |
$page = $queryBuilder->execute()->fetch(); | |
if ($page) { | |
// page has been deleted or hidden | |
if ($page['deleted'] || $page['hidden']) { | |
$pageExists = false; | |
} | |
} else { | |
// no record found | |
$pageExists = false; | |
} | |
return $pageExists; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Vendor\MyExt\Indexer; | |
use Vendor\MyExt\Indexer\AbstractIndexer; | |
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; | |
class CustomIndexer extends AbstractIndexer | |
{ | |
protected $indexerConfigurationKey = 'customindexer'; | |
protected $table = 'tx_myext_domain_model_custom'; | |
/** | |
* | |
* @param array $params | |
* @param type $pObj | |
*/ | |
public function registerIndexerConfiguration(&$params, $pObj) | |
{ | |
$params['items'][] = [ | |
'MyExt: Custom', | |
$this->indexerConfigurationKey, | |
ExtensionManagementUtility::extPath('myext') . 'Resources/Public/Icons/CustomIndexer.gif' | |
]; | |
} | |
/** | |
* Custom indexer for ke_search | |
* | |
* @param array $indexerConfig Configuration from TYPO3 Backend | |
* @param array $indexerObject Reference to indexer class. | |
* @return string Message containing indexed elements | |
*/ | |
public function customIndexer(&$indexerConfig, &$indexerObject) | |
{ | |
$response = ''; | |
if ($indexerConfig['type'] == $this->indexerConfigurationKey && $this->targetPageExists(intval($indexerConfig['targetpid']))) { | |
$result = $this->getIndexData( | |
$this->table, | |
$indexerConfig['sysfolder'] | |
); | |
if ($result) { | |
$counter = 0; | |
while ($record = $result->fetch()) { | |
$title = strip_tags($record['title']); | |
$content = ''; | |
if ($record['short_description']) { | |
$content .= strip_tags($record['short_description']) . ', '; | |
} | |
if ($record['description']) { | |
$content .= strip_tags($record['description']) . ', '; | |
} | |
$content = rtrim($content, ', '); // trim trailing commas | |
if ($record['short_description']) { | |
$abstract = substr($record['short_description'], 0, 160) . '...'; | |
$fullContent = $title . "\n" . $record['short_description'] . "\n" . $content; | |
} else { | |
$abstract = substr($content, 0, 160) . '...'; | |
$fullContent = $title . "\n" . $content; | |
} | |
// build target link | |
$params = '&tx_myext_pluginname[custom]=' . $record['uid'] | |
. '&tx_myext_pluginname[controller]=Custom&tx_myext_pluginname[action]=show'; | |
// add faceted search tags | |
$tags = []; | |
$tags[] = '#search-result#'; | |
$tags[] = '#custom#'; | |
$tags[] = '#custom-type-'.$record['type'].'#'; | |
$tags = $this->addCategoryTags( | |
$tags, | |
'sys_category_record_mm', | |
$record['uid'], | |
'category' | |
); | |
$tags = implode(',', $tags); | |
// additional information | |
$additionalFields = [ | |
'orig_uid' => $record['uid'], | |
'orig_pid' => $record['pid'], | |
'sortdate' => $record['start'], | |
]; | |
// write to index | |
$indexerObject->storeInIndex( | |
$indexerConfig['storagepid'], // storage PID | |
$title, // record title | |
$this->indexerConfigurationKey, // content type | |
$indexerConfig['targetpid'], // target PID | |
$fullContent, // indexed content, includes the title | |
$tags, // tags for faceted search | |
$params, // typolink params for singleview | |
$abstract, // abstract; shown in result list if not empty | |
$record['sys_language_uid'], // language uid | |
$record['starttime'], // starttime | |
$record['endtime'], // endtime | |
$record['fe_group'], // fe_group | |
false, // debug only | |
$additionalFields // additionalFields | |
); | |
$counter++; | |
} | |
$response = $this->createResponseMessage($indexerConfig['title'], $counter); | |
} | |
} | |
return $response; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
defined('TYPO3_MODE') or die(); | |
// enable field sysfolder in Indexer Configuration | |
$enableField = 'sysfolder'; | |
$indexers = [ | |
'customindexer' | |
]; | |
foreach ($indexers as $indexer) { | |
$GLOBALS['TCA']['tx_kesearch_indexerconfig']['columns'][$enableField]['displayCond'] .= ','.$indexer; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
defined('TYPO3_MODE') or die(); | |
/** | |
* register custom search indexers | |
*/ | |
$customIndexers = [ | |
\Vensor\MyExt\Indexer\CustomIndexer::class, | |
]; | |
foreach ($customIndexers as $customIndexerClassName) { | |
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['registerIndexerConfiguration'][] = $customIndexerClassName; | |
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['customIndexer'][] = $customIndexerClassName; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You'll need to
$tags[]
to your needs$record
like e.g.$record['type']
or$record['short_description']
$params = '&tx_myext_pluginname[custom] ...