1*04fd306cSNickeau<?php 2*04fd306cSNickeau/** 3*04fd306cSNickeau * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved. 4*04fd306cSNickeau * 5*04fd306cSNickeau * This source code is licensed under the GPL license found in the 6*04fd306cSNickeau * COPYING file in the root directory of this source tree. 7*04fd306cSNickeau * 8*04fd306cSNickeau * @license GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html) 9*04fd306cSNickeau * @author ComboStrap <support@combostrap.com> 10*04fd306cSNickeau * 11*04fd306cSNickeau * 12*04fd306cSNickeau */ 13*04fd306cSNickeau 14*04fd306cSNickeauuse ComboStrap\Console; 15*04fd306cSNickeauuse ComboStrap\Event; 16*04fd306cSNickeauuse ComboStrap\ExceptionCompile; 17*04fd306cSNickeauuse ComboStrap\ExceptionNotFound; 18*04fd306cSNickeauuse ComboStrap\ExceptionRuntimeInternal; 19*04fd306cSNickeauuse ComboStrap\ExecutionContext; 20*04fd306cSNickeauuse ComboStrap\FileSystems; 21*04fd306cSNickeauuse ComboStrap\LogUtility; 22*04fd306cSNickeauuse ComboStrap\MarkupPath; 23*04fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDbStore; 24*04fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDokuWikiStore; 25*04fd306cSNickeauuse ComboStrap\PluginUtility; 26*04fd306cSNickeauuse ComboStrap\Reference; 27*04fd306cSNickeauuse ComboStrap\References; 28*04fd306cSNickeau 29*04fd306cSNickeau 30*04fd306cSNickeau/** 31*04fd306cSNickeau * Process metadata put them in the sqlite database (ie create derived index) 32*04fd306cSNickeau * 33*04fd306cSNickeau * 34*04fd306cSNickeau * For the replication, this is the equivalent of the dokuwiki {@link \dokuwiki\Search\Indexer} 35*04fd306cSNickeau * (textual search engine, plus metadata index) 36*04fd306cSNickeau * 37*04fd306cSNickeau * Note that you can disable a page to go into the index 38*04fd306cSNickeau * via the `internal index` metadata. See {@link idx_addPage()} 39*04fd306cSNickeau * ``` 40*04fd306cSNickeau * $indexenabled = p_get_metadata($page, 'internal index', METADATA_RENDER_UNLIMITED); 41*04fd306cSNickeau * ``` 42*04fd306cSNickeau */ 43*04fd306cSNickeauclass action_plugin_combo_indexer extends DokuWiki_Action_Plugin 44*04fd306cSNickeau{ 45*04fd306cSNickeau 46*04fd306cSNickeau /** 47*04fd306cSNickeau * Bad canonical for now as we will add the 48*04fd306cSNickeau * {@link \ComboStrap\ComboFs} system 49*04fd306cSNickeau * but it's still a valid page 50*04fd306cSNickeau */ 51*04fd306cSNickeau const CANONICAL = "replication"; 52*04fd306cSNickeau 53*04fd306cSNickeau public function register(Doku_Event_Handler $controller) 54*04fd306cSNickeau { 55*04fd306cSNickeau 56*04fd306cSNickeau /** 57*04fd306cSNickeau * We do it after because if there is an error 58*04fd306cSNickeau * We will not stop the Dokuwiki Processing 59*04fd306cSNickeau * 60*04fd306cSNickeau * We could do it after 61*04fd306cSNickeau * https://www.dokuwiki.org/devel:event:parser_metadata_render 62*04fd306cSNickeau * but it would then not be async 63*04fd306cSNickeau * 64*04fd306cSNickeau * Note: We support other extension for markup 65*04fd306cSNickeau * but dokuwiki does not index other extension 66*04fd306cSNickeau * in {@link idx_addPage} (page is the id) 67*04fd306cSNickeau */ 68*04fd306cSNickeau $controller->register_hook('INDEXER_PAGE_ADD', 'AFTER', $this, 'indexViaIndexerAdd', array()); 69*04fd306cSNickeau 70*04fd306cSNickeau /** 71*04fd306cSNickeau * 72*04fd306cSNickeau * https://www.dokuwiki.org/devel:event:parser_metadata_render 73*04fd306cSNickeau * 74*04fd306cSNickeau */ 75*04fd306cSNickeau 76*04fd306cSNickeau 77*04fd306cSNickeau 78*04fd306cSNickeau } 79*04fd306cSNickeau 80*04fd306cSNickeau /** 81*04fd306cSNickeau * @throws ExceptionCompile 82*04fd306cSNickeau */ 83*04fd306cSNickeau public function indexViaIndexerAdd(Doku_Event $event, $param) 84*04fd306cSNickeau { 85*04fd306cSNickeau 86*04fd306cSNickeau /** 87*04fd306cSNickeau * Check that the actual page has analytics data 88*04fd306cSNickeau * (if there is a cache, it's pretty quick) 89*04fd306cSNickeau */ 90*04fd306cSNickeau $id = $event->data['page']; 91*04fd306cSNickeau $page = MarkupPath::createMarkupFromId($id); 92*04fd306cSNickeau 93*04fd306cSNickeau /** 94*04fd306cSNickeau * From {@link idx_addPage} 95*04fd306cSNickeau * They receive even the deleted page 96*04fd306cSNickeau */ 97*04fd306cSNickeau $databasePage = $page->getDatabasePage(); 98*04fd306cSNickeau if (!FileSystems::exists($page)) { 99*04fd306cSNickeau $databasePage->delete(); 100*04fd306cSNickeau return; 101*04fd306cSNickeau } 102*04fd306cSNickeau 103*04fd306cSNickeau if ($databasePage->shouldReplicate()) { 104*04fd306cSNickeau try { 105*04fd306cSNickeau $databasePage->replicate(); 106*04fd306cSNickeau } catch (ExceptionCompile $e) { 107*04fd306cSNickeau if (PluginUtility::isDevOrTest()) { 108*04fd306cSNickeau // to get the stack trace 109*04fd306cSNickeau throw $e; 110*04fd306cSNickeau } 111*04fd306cSNickeau $message = "Error with the database replication for the page ($page). " . $e->getMessage(); 112*04fd306cSNickeau if (Console::isConsoleRun()) { 113*04fd306cSNickeau throw new ExceptionCompile($message); 114*04fd306cSNickeau } else { 115*04fd306cSNickeau LogUtility::error($message); 116*04fd306cSNickeau } 117*04fd306cSNickeau } 118*04fd306cSNickeau } 119*04fd306cSNickeau 120*04fd306cSNickeau 121*04fd306cSNickeau } 122*04fd306cSNickeau 123*04fd306cSNickeau 124*04fd306cSNickeau function indexViaMetadataRendering(Doku_Event $event, $params) 125*04fd306cSNickeau { 126*04fd306cSNickeau 127*04fd306cSNickeau try { 128*04fd306cSNickeau $wikiPath = ExecutionContext::getActualOrCreateFromEnv() 129*04fd306cSNickeau ->getExecutingWikiPath(); 130*04fd306cSNickeau } catch (ExceptionNotFound $e) { 131*04fd306cSNickeau // markup string run 132*04fd306cSNickeau return; 133*04fd306cSNickeau } 134*04fd306cSNickeau 135*04fd306cSNickeau $page = MarkupPath::createPageFromPathObject($wikiPath); 136*04fd306cSNickeau 137*04fd306cSNickeau $references = References::createFromResource($page) 138*04fd306cSNickeau ->setReadStore(MetadataDokuWikiStore::class); 139*04fd306cSNickeau 140*04fd306cSNickeau $internalIdReferences = $event->data['current']['relation']['references']; 141*04fd306cSNickeau foreach ($internalIdReferences as $internalIdReferenceValue => $internalIdReferenceExist) { 142*04fd306cSNickeau $ref = Reference::createFromResource($page) 143*04fd306cSNickeau ->setReadStore(MetadataDokuWikiStore::class) 144*04fd306cSNickeau ->setFromStoreValueWithoutException($internalIdReferenceValue); 145*04fd306cSNickeau try { 146*04fd306cSNickeau $references->addRow([$ref]); 147*04fd306cSNickeau } catch (ExceptionNotFound $e) { 148*04fd306cSNickeau LogUtility::internalError("The identifier and the value identifier should be known at this stage", self::CANONICAL, $e); 149*04fd306cSNickeau } 150*04fd306cSNickeau } 151*04fd306cSNickeau 152*04fd306cSNickeau try { 153*04fd306cSNickeau // persist to database 154*04fd306cSNickeau $references 155*04fd306cSNickeau ->setWriteStore(MetadataDbStore::class) 156*04fd306cSNickeau ->persist(); 157*04fd306cSNickeau } catch (ExceptionCompile $e) { 158*04fd306cSNickeau LogUtility::warning("Reference error when persisting to the file system store: " . $e->getMessage(), self::CANONICAL, $e); 159*04fd306cSNickeau } 160*04fd306cSNickeau 161*04fd306cSNickeau } 162*04fd306cSNickeau 163*04fd306cSNickeau 164*04fd306cSNickeau} 165*04fd306cSNickeau 166*04fd306cSNickeau 167*04fd306cSNickeau 168