Mithilfe der Erweiterung können einfache (https://metallmaschinen.at/suche) bis hin zu sehr komplexen Suchen (https://www.vkbimmobilien.at/suchergebnisse/#q=neu) auf TYPO3-Websites realisiert werden. Auf letzerer Seite haben wir eine Fragmentierung in 3 Bereiche:
- Immobilien (Extbase-Objekte)
- Inhaltsseiten (Normale Seiten)
- Blog (Unsere Blogartikel sind auch als normale Seiten umgesetzt)
Die Unterscheidung gelingt anhand FreeIndexUid, damit werden die verschiedenen Typen segmentiert.
Zuerst muss die Indizierung aktiviert werden:
config {
index_enable = 1
index_externals = 1
index_metatags = 1
}
Nun wird indexed_search konfiguriert:
#############################################
#######-INDEXED SEARCH CONFIGURATION-########
#############################################
plugin {
tx_indexedsearch {
view{
templateRootPaths.20 = EXT:xxx/Resources/Private/Templates/IndexedSearch/
partialRootPaths.20 = EXT:xxx/Resources/Private/Partials/IndexedSearch/
partialRootPaths.40 = EXT:xxx/Resources/Private/Partials/
layoutRootPaths.20 = EXT:xxx/Resources/Private/Layouts/
}
settings{
displayLevel1Sections = 0
defaultFreeIndexUidList = 1,2,3
rootPidList = 1
displayRules = 0
results {
titleCropAfter = 50
summaryCropAfter = 100
markupSW_summaryMax = 200
}
blind {
defaultOperand = 1
searchType = 1
sections = 1
freeIndexUid = 0
.......
}
}
}
}
Crawler configuration (Indizierungseinstellungen)
Im TYPO3-Backend müssen nun die Indizierungseinstellungen erstellt werden (auf der HOME-Seite):
Und auch noch die Indizierungseinstellung für die Artikelseiten.
Nun müssen wir die Seiten noch aufrufen, damit der Index auch richtig aufgebaut wird. Dies kann entweder über die crawler Erweiterung erfolgen oder aber über einen eigenen Task. Die crawler-Extension (Site Crawler) ist zurzeit leider noch nicht TYPO3 9 kompatibel und auch fragwürdig, ob das überhaupt noch passiert. Theoretisch wird der Index auch aufgebaut, wenn man die Seite aufruft (Achtung: Dies passiert nicht, wenn man im Backend angemeldet ist).
UPDATE (02.06.2020): Die crawler-Extension ist mittlerweise für TYPO3 9 und 10 erschienen: https://extensions.typo3.org/extension/crawler.
Eigener Indexer/Crawler
Wir machen es immer so, dass wir einmal in der Nacht alle caches/indexes löschen und den gesamten Index/Cache wieder neu aufbauen. Dazu haben wir uns einen eigenen Task für den Scheduler erstellt.
public function execute()
{
$objectManager =
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
$propertyRepository = $objectManager->get(\Varioous\VaVkbImmo\Domain\Repository\PropertyRepository::class);
$persistenceManager = $objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
$baseUrl = self::getBaseUrl();
//empty cache tables
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cache_treelist')
->truncate('cache_treelist');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_cache_hash')
->truncate('cf_cache_hash');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_cache_hash_tags')
->truncate('cf_cache_hash_tags');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_cache_imagesizes')
->truncate('cf_cache_imagesizes');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_cache_imagesizes_tags')
->truncate('cf_cache_imagesizes_tags');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_cache_pages')
->truncate('cf_cache_pages');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_cache_pagesection')
->truncate('cf_cache_pagesection');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_cache_pagesection_tags')
->truncate('cf_cache_pagesection_tags');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_cache_pages_tags')
->truncate('cf_cache_pages_tags');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_cache_rootline')
->truncate('cf_cache_rootline');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_cache_rootline_tags')
->truncate('cf_cache_rootline_tags');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_extbase_datamapfactory_datamap')
->truncate('cf_extbase_datamapfactory_datamap');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_extbase_datamapfactory_datamap_tags')
->truncate('cf_extbase_datamapfactory_datamap_tags');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_vhs_main')
->truncate('cf_vhs_main');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_vhs_main_tags')
->truncate('cf_vhs_main_tags');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_vhs_markdown')
->truncate('cf_vhs_markdown');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cf_vhs_markdown_tags')
->truncate('cf_vhs_markdown_tags');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_vavkbimmo_domain_model_propertycache')
->truncate('tx_vavkbimmo_domain_model_propertycache');
//index tables
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('index_fulltext')
->truncate('index_fulltext');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('index_grlist')
->truncate('index_grlist');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('index_phash')
->truncate('index_phash');
GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('index_rel')->truncate('index_rel');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('index_section')
->truncate('index_section');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('index_stat_search')
->truncate('index_stat_search');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('index_stat_word')
->truncate('index_stat_word');
GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('index_words')
->truncate('index_words');
//call all pages
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
$result = $queryBuilder->select('uid')->from('pages')->execute();
while ($row = $result->fetch()) {
self::crawlPage(intval($row['uid']), $baseUrl);
}
//call all properties
$queryBuilderProperty = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tx_vavkbimmo_domain_model_property');
//index all properties
$crawlerHook = GeneralUtility::makeInstance(\TYPO3\CMS\IndexedSearch\Hook\CrawlerHook::class);
$queryBuilderIndexcfg =
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('index_config');
$resultIndexConfigs =
$queryBuilderIndexcfg->select('*')->from('index_config')->where($queryBuilderIndexcfg->expr()
->eq('uid', $queryBuilderIndexcfg->createNamedParameter(2, \PDO::PARAM_INT)))->execute();
$resultProperties =
$queryBuilderProperty->select('*')->from('tx_vavkbimmo_domain_model_property')->where($queryBuilder->expr()
->eq('remove_marked', 0))->execute();
$cfgRecProperties = null;
while ($cfgRec = $resultIndexConfigs->fetch()) {
$cfgRecProperties = $cfgRec;
}
while ($propertyRec = $resultProperties->fetch()) {
if (!is_null($cfgRecProperties)) {
$crawlerHook->indexSingleRecord($propertyRec, $cfgRecProperties);
}
}
$resultPropertiesAll =
$queryBuilderProperty->select('*')->from('tx_vavkbimmo_domain_model_property')->execute();
while ($propertyRec = $resultPropertiesAll->fetch()) {
self::crawlProperty($propertyRec['slug'], $baseUrl);
}
return true;
}
private static function crawlPage($pageUid, $baseUrl)
{
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $baseUrl . 'index.php?id=' . intval($pageUid),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_POSTFIELDS => "",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache"
),
));
curl_exec($curl);
curl_close($curl);
}
private static function crawlProperty($slug, $baseUrl)
{
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $baseUrl . 'expose/' . $slug,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_POSTFIELDS => "",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache"
),
));
curl_exec($curl);
curl_close($curl);
}
private static function getBaseUrl()
{
//get base url
$siteFinder = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Site\SiteFinder::class);
$site = $siteFinder->getSiteByPageId(1);
return $site->getConfiguration()['base'];
}
Indexer
Nun gibt es noch ein Problem mit dem Indexer. Dieser setzt bei mir immer die falsche FreeIndexUid. Deshalb habe ich mittels XClass die Methode submitPage des Indexeres überschrieben. Dazu muss in der ext_localconf.php folgendes registriert werden:
/************************************************************************
* XCLASS
************************************************************************/
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\\CMS\\IndexedSearch\\Indexer'] = array(
'className' => 'Varioous\\XXXXXXXX\\Xclass\\Indexer'
);
Und hier nun noch die Indexer-Klasse:
class Indexer extends \TYPO3\CMS\IndexedSearch\Indexer
{
public function submitPage()
{
// get page repository
$objectManager =
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$pageRepository = $objectManager->get('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
//get database
$connectionPool =
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable('index_config');
//get all index configuration
$runningIndexingConfigurations = $queryBuilder->select('*')->from('index_config')->where($queryBuilder->expr()
->neq('uid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)))->execute()->fetchAll();
//save index configurations
$indexconfigs = array();
foreach ($runningIndexingConfigurations as $cfgRec) {
$indexconfigs[intval($cfgRec['uid'])] = intval($cfgRec['alternative_source_pid']);
}
//get current page and start here
$currentPage = intval($this->conf['id']);
//traverse through page tree
while ($currentPage > 0) {
if (self::isPageUidInIndex($currentPage)) {
//set correct freeIndexUid
$this->conf['freeIndexUid'] = self::isPageUidInIndex($currentPage);
break;
}
$currentPageObject = $pageRepository->getRecordsByField('pages', 'uid', intval($currentPage));
if ($currentPageObject && !is_null($currentPageObject)) {
if (count($currentPageObject) == 1) {
$currentPage = intval($currentPageObject[0]['pid']);
} else {
break;
}
} else {
break;
}
}
parent::submitPage();
}
public static function isPageUidInIndex($page)
{
//check if property
if (intval($page)
== intval(\Varioous\VaBase\Configuration\ExtensionConfiguration::get('config.pid.property',
'xxxxx'))) {
//property
return intval(\Varioous\VaBase\Configuration\ExtensionConfiguration::get('config.search.immoFreeIndexUid',
'xxxxx'));
}
// get page repository
$objectManager =
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$pageRepository = $objectManager->get('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
$pageObject = $pageRepository->getRecordsByField('pages', 'uid', intval($page));
//check if article
if (intval($pageObject[0]['pid'])
== intval(\Varioous\VaBase\Configuration\ExtensionConfiguration::get('config.pid.article',
'xxxxx'))) {
return intval(\Varioous\VaBase\Configuration\ExtensionConfiguration::get('config.search.articleFreeIndexUid',
'xxxxx'));
}
//it must be normal content page
return intval(\Varioous\VaBase\Configuration\ExtensionConfiguration::get('config.search.pageFreeIndexUid',
'xxxxx'));
}
}
Wenn man nun den Task ausführt oder die Website über das Frontend aufruft, müssen Index Einträge erstellt werden. Dies kann man am besten direkt in der DB überprüft werden, dazu einfach in der Tabelle index_phash nachsehen:
Tipp: Wenn man den Cache nicht aller Extbase-Objekte auf einmal leeren will, sondern nur von einzelnen, ist dies mit einem kleinen Trick möglich. Weitere Informationen dazu findest du in diesem Blogbeitrag.
Weitere Informationen / Links
Wir entwickeln digitale Lösungen mit Leidenschaft
Warum wir das tun? Weil die Verwirklichung Ihrer Vision unser größter Anspruch und die schönste Anerkennung ist. Deshalb nehmen wir uns gerne ausreichend Zeit für die Realisierung Ihres digitalen Projekts.
Kontaktieren Sie uns, wir sind gerne für Ihre Fragen da: