104fd306cSNickeau<?php 204fd306cSNickeau/** 304fd306cSNickeau * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved. 404fd306cSNickeau * 504fd306cSNickeau * This source code is licensed under the GPL license found in the 604fd306cSNickeau * COPYING file in the root directory of this source tree. 704fd306cSNickeau * 804fd306cSNickeau * @license GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html) 904fd306cSNickeau * @author ComboStrap <support@combostrap.com> 1004fd306cSNickeau * 1104fd306cSNickeau * 1204fd306cSNickeau */ 1304fd306cSNickeau 14ad54dffdSgerardnicorequire_once(__DIR__ . '/../vendor/autoload.php'); 15ad54dffdSgerardnico 1604fd306cSNickeauuse ComboStrap\Console; 1704fd306cSNickeauuse ComboStrap\ExceptionCompile; 1804fd306cSNickeauuse ComboStrap\ExceptionNotFound; 192becc3acSgerardnicouse ComboStrap\ExceptionTimeOut; 2004fd306cSNickeauuse ComboStrap\ExecutionContext; 2104fd306cSNickeauuse ComboStrap\FileSystems; 222becc3acSgerardnicouse ComboStrap\Lock; 2304fd306cSNickeauuse ComboStrap\LogUtility; 2404fd306cSNickeauuse ComboStrap\MarkupPath; 2504fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDbStore; 2604fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDokuWikiStore; 2704fd306cSNickeauuse ComboStrap\PluginUtility; 2804fd306cSNickeauuse ComboStrap\Reference; 2904fd306cSNickeauuse ComboStrap\References; 3004fd306cSNickeau 3104fd306cSNickeau 3204fd306cSNickeau/** 3304fd306cSNickeau * Process metadata put them in the sqlite database (ie create derived index) 3404fd306cSNickeau * 3504fd306cSNickeau * 3604fd306cSNickeau * For the replication, this is the equivalent of the dokuwiki {@link \dokuwiki\Search\Indexer} 3704fd306cSNickeau * (textual search engine, plus metadata index) 3804fd306cSNickeau * 3904fd306cSNickeau * Note that you can disable a page to go into the index 4004fd306cSNickeau * via the `internal index` metadata. See {@link idx_addPage()} 4104fd306cSNickeau * ``` 4204fd306cSNickeau * $indexenabled = p_get_metadata($page, 'internal index', METADATA_RENDER_UNLIMITED); 4304fd306cSNickeau * ``` 4404fd306cSNickeau */ 4504fd306cSNickeauclass action_plugin_combo_indexer extends DokuWiki_Action_Plugin 4604fd306cSNickeau{ 4704fd306cSNickeau 4804fd306cSNickeau /** 4904fd306cSNickeau * Bad canonical for now as we will add the 5004fd306cSNickeau * {@link \ComboStrap\ComboFs} system 5104fd306cSNickeau * but it's still a valid page 5204fd306cSNickeau */ 5304fd306cSNickeau const CANONICAL = "replication"; 5404fd306cSNickeau 5504fd306cSNickeau public function register(Doku_Event_Handler $controller) 5604fd306cSNickeau { 5704fd306cSNickeau 5804fd306cSNickeau /** 5904fd306cSNickeau * We do it after because if there is an error 6004fd306cSNickeau * We will not stop the Dokuwiki Processing 6104fd306cSNickeau * 6204fd306cSNickeau * We could do it after 6304fd306cSNickeau * https://www.dokuwiki.org/devel:event:parser_metadata_render 6404fd306cSNickeau * but it would then not be async 6504fd306cSNickeau * 6604fd306cSNickeau * Note: We support other extension for markup 6704fd306cSNickeau * but dokuwiki does not index other extension 6804fd306cSNickeau * in {@link idx_addPage} (page is the id) 6904fd306cSNickeau */ 7004fd306cSNickeau $controller->register_hook('INDEXER_PAGE_ADD', 'AFTER', $this, 'indexViaIndexerAdd', array()); 7104fd306cSNickeau 7204fd306cSNickeau /** 7304fd306cSNickeau * 7404fd306cSNickeau * https://www.dokuwiki.org/devel:event:parser_metadata_render 7504fd306cSNickeau * 7604fd306cSNickeau */ 7704fd306cSNickeau 7804fd306cSNickeau 7904fd306cSNickeau 8004fd306cSNickeau } 8104fd306cSNickeau 8204fd306cSNickeau /** 8304fd306cSNickeau * @throws ExceptionCompile 8404fd306cSNickeau */ 8504fd306cSNickeau public function indexViaIndexerAdd(Doku_Event $event, $param) 8604fd306cSNickeau { 8704fd306cSNickeau 88*a183757cSNico 892becc3acSgerardnico $lock = Lock::create("combo-indexer"); 902becc3acSgerardnico try { 912becc3acSgerardnico $lock->acquire(); 922becc3acSgerardnico } catch (ExceptionTimeOut $e) { 932becc3acSgerardnico // process running 942becc3acSgerardnico return; 952becc3acSgerardnico } 962becc3acSgerardnico 97*a183757cSNico /** 98*a183757cSNico * Get the q flag of the indexer 99*a183757cSNico * php bin/indexer.php -q 100*a183757cSNico */ 101*a183757cSNico $verbose = true; 102*a183757cSNico if (PHP_SAPI === 'cli') { 103*a183757cSNico global $argv; 104*a183757cSNico foreach ($argv as $arg) { 105*a183757cSNico if ($arg === '-q') { 106*a183757cSNico // Script was started with the -q flag. 107*a183757cSNico $verbose = false; 108*a183757cSNico break; 109*a183757cSNico } 110*a183757cSNico } 111*a183757cSNico } 112*a183757cSNico 113*a183757cSNico if ($verbose) echo 'ComboIndexer(): Indexer started'. DOKU_LF; 114ea72c629Sgerardnico 1152becc3acSgerardnico try { 11604fd306cSNickeau /** 11704fd306cSNickeau * Check that the actual page has analytics data 11804fd306cSNickeau * (if there is a cache, it's pretty quick) 11904fd306cSNickeau */ 12004fd306cSNickeau $id = $event->data['page']; 12104fd306cSNickeau $page = MarkupPath::createMarkupFromId($id); 12204fd306cSNickeau 12304fd306cSNickeau /** 12404fd306cSNickeau * From {@link idx_addPage} 12504fd306cSNickeau * They receive even the deleted page 12604fd306cSNickeau */ 12704fd306cSNickeau $databasePage = $page->getDatabasePage(); 12804fd306cSNickeau if (!FileSystems::exists($page)) { 12904fd306cSNickeau $databasePage->delete(); 13004fd306cSNickeau return; 13104fd306cSNickeau } 13204fd306cSNickeau 13304fd306cSNickeau if ($databasePage->shouldReplicate()) { 13404fd306cSNickeau try { 13504fd306cSNickeau $databasePage->replicate(); 13604fd306cSNickeau } catch (ExceptionCompile $e) { 13704fd306cSNickeau if (PluginUtility::isDevOrTest()) { 13804fd306cSNickeau // to get the stack trace 13904fd306cSNickeau throw $e; 14004fd306cSNickeau } 14104fd306cSNickeau $message = "Error with the database replication for the page ($page). " . $e->getMessage(); 14204fd306cSNickeau if (Console::isConsoleRun()) { 14304fd306cSNickeau throw new ExceptionCompile($message); 14404fd306cSNickeau } else { 14504fd306cSNickeau LogUtility::error($message); 14604fd306cSNickeau } 14704fd306cSNickeau } 14804fd306cSNickeau } 14904fd306cSNickeau 1502becc3acSgerardnico } finally { 151*a183757cSNico if ($verbose) echo 'ComboIndexer(): Indexer finished'. DOKU_LF; 1522becc3acSgerardnico $lock->release(); 1532becc3acSgerardnico } 15404fd306cSNickeau 15504fd306cSNickeau } 15604fd306cSNickeau 15704fd306cSNickeau 15804fd306cSNickeau function indexViaMetadataRendering(Doku_Event $event, $params) 15904fd306cSNickeau { 16004fd306cSNickeau 16104fd306cSNickeau try { 16204fd306cSNickeau $wikiPath = ExecutionContext::getActualOrCreateFromEnv() 16304fd306cSNickeau ->getExecutingWikiPath(); 16404fd306cSNickeau } catch (ExceptionNotFound $e) { 16504fd306cSNickeau // markup string run 16604fd306cSNickeau return; 16704fd306cSNickeau } 16804fd306cSNickeau 16904fd306cSNickeau $page = MarkupPath::createPageFromPathObject($wikiPath); 17004fd306cSNickeau 17104fd306cSNickeau $references = References::createFromResource($page) 17204fd306cSNickeau ->setReadStore(MetadataDokuWikiStore::class); 17304fd306cSNickeau 17404fd306cSNickeau $internalIdReferences = $event->data['current']['relation']['references']; 17504fd306cSNickeau foreach ($internalIdReferences as $internalIdReferenceValue => $internalIdReferenceExist) { 17604fd306cSNickeau $ref = Reference::createFromResource($page) 17704fd306cSNickeau ->setReadStore(MetadataDokuWikiStore::class) 17804fd306cSNickeau ->setFromStoreValueWithoutException($internalIdReferenceValue); 17904fd306cSNickeau try { 18004fd306cSNickeau $references->addRow([$ref]); 18104fd306cSNickeau } catch (ExceptionNotFound $e) { 18204fd306cSNickeau LogUtility::internalError("The identifier and the value identifier should be known at this stage", self::CANONICAL, $e); 18304fd306cSNickeau } 18404fd306cSNickeau } 18504fd306cSNickeau 18604fd306cSNickeau try { 18704fd306cSNickeau // persist to database 18804fd306cSNickeau $references 18904fd306cSNickeau ->setWriteStore(MetadataDbStore::class) 19004fd306cSNickeau ->persist(); 19104fd306cSNickeau } catch (ExceptionCompile $e) { 19204fd306cSNickeau LogUtility::warning("Reference error when persisting to the file system store: " . $e->getMessage(), self::CANONICAL, $e); 19304fd306cSNickeau } 19404fd306cSNickeau 19504fd306cSNickeau } 19604fd306cSNickeau 19704fd306cSNickeau 19804fd306cSNickeau} 19904fd306cSNickeau 20004fd306cSNickeau 20104fd306cSNickeau 202