xref: /plugin/combo/action/indexer.php (revision ad54dffd2a785f08006601bf247e440e47fc7b18)
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
14*ad54dffdSgerardnicorequire_once(__DIR__ . '/../vendor/autoload.php');
15*ad54dffdSgerardnico
1604fd306cSNickeauuse ComboStrap\Console;
1704fd306cSNickeauuse ComboStrap\ExceptionCompile;
1804fd306cSNickeauuse ComboStrap\ExceptionNotFound;
1904fd306cSNickeauuse ComboStrap\ExecutionContext;
2004fd306cSNickeauuse ComboStrap\FileSystems;
2104fd306cSNickeauuse ComboStrap\LogUtility;
2204fd306cSNickeauuse ComboStrap\MarkupPath;
2304fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDbStore;
2404fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDokuWikiStore;
2504fd306cSNickeauuse ComboStrap\PluginUtility;
2604fd306cSNickeauuse ComboStrap\Reference;
2704fd306cSNickeauuse ComboStrap\References;
2804fd306cSNickeau
2904fd306cSNickeau
3004fd306cSNickeau/**
3104fd306cSNickeau * Process metadata put them in the sqlite database (ie create derived index)
3204fd306cSNickeau *
3304fd306cSNickeau *
3404fd306cSNickeau * For the replication, this is the equivalent of the dokuwiki {@link \dokuwiki\Search\Indexer}
3504fd306cSNickeau * (textual search engine, plus metadata index)
3604fd306cSNickeau *
3704fd306cSNickeau * Note that you can disable a page to go into the index
3804fd306cSNickeau * via the `internal index` metadata. See {@link idx_addPage()}
3904fd306cSNickeau * ```
4004fd306cSNickeau * $indexenabled = p_get_metadata($page, 'internal index', METADATA_RENDER_UNLIMITED);
4104fd306cSNickeau * ```
4204fd306cSNickeau */
4304fd306cSNickeauclass action_plugin_combo_indexer extends DokuWiki_Action_Plugin
4404fd306cSNickeau{
4504fd306cSNickeau
4604fd306cSNickeau    /**
4704fd306cSNickeau     * Bad canonical for now as we will add the
4804fd306cSNickeau     * {@link \ComboStrap\ComboFs} system
4904fd306cSNickeau     * but it's still a valid page
5004fd306cSNickeau     */
5104fd306cSNickeau    const CANONICAL = "replication";
5204fd306cSNickeau
5304fd306cSNickeau    public function register(Doku_Event_Handler $controller)
5404fd306cSNickeau    {
5504fd306cSNickeau
5604fd306cSNickeau        /**
5704fd306cSNickeau         * We do it after because if there is an error
5804fd306cSNickeau         * We will not stop the Dokuwiki Processing
5904fd306cSNickeau         *
6004fd306cSNickeau         * We could do it after
6104fd306cSNickeau         * https://www.dokuwiki.org/devel:event:parser_metadata_render
6204fd306cSNickeau         * but it would then not be async
6304fd306cSNickeau         *
6404fd306cSNickeau         * Note: We support other extension for markup
6504fd306cSNickeau         * but dokuwiki does not index other extension
6604fd306cSNickeau         * in {@link idx_addPage} (page is the id)
6704fd306cSNickeau         */
6804fd306cSNickeau        $controller->register_hook('INDEXER_PAGE_ADD', 'AFTER', $this, 'indexViaIndexerAdd', array());
6904fd306cSNickeau
7004fd306cSNickeau        /**
7104fd306cSNickeau         *
7204fd306cSNickeau         * https://www.dokuwiki.org/devel:event:parser_metadata_render
7304fd306cSNickeau         *
7404fd306cSNickeau         */
7504fd306cSNickeau
7604fd306cSNickeau
7704fd306cSNickeau
7804fd306cSNickeau    }
7904fd306cSNickeau
8004fd306cSNickeau    /**
8104fd306cSNickeau     * @throws ExceptionCompile
8204fd306cSNickeau     */
8304fd306cSNickeau    public function indexViaIndexerAdd(Doku_Event $event, $param)
8404fd306cSNickeau    {
8504fd306cSNickeau
8604fd306cSNickeau        /**
8704fd306cSNickeau         * Check that the actual page has analytics data
8804fd306cSNickeau         * (if there is a cache, it's pretty quick)
8904fd306cSNickeau         */
9004fd306cSNickeau        $id = $event->data['page'];
9104fd306cSNickeau        $page = MarkupPath::createMarkupFromId($id);
9204fd306cSNickeau
9304fd306cSNickeau        /**
9404fd306cSNickeau         * From {@link idx_addPage}
9504fd306cSNickeau         * They receive even the deleted page
9604fd306cSNickeau         */
9704fd306cSNickeau        $databasePage = $page->getDatabasePage();
9804fd306cSNickeau        if (!FileSystems::exists($page)) {
9904fd306cSNickeau            $databasePage->delete();
10004fd306cSNickeau            return;
10104fd306cSNickeau        }
10204fd306cSNickeau
10304fd306cSNickeau        if ($databasePage->shouldReplicate()) {
10404fd306cSNickeau            try {
10504fd306cSNickeau                $databasePage->replicate();
10604fd306cSNickeau            } catch (ExceptionCompile $e) {
10704fd306cSNickeau                if (PluginUtility::isDevOrTest()) {
10804fd306cSNickeau                    // to get the stack trace
10904fd306cSNickeau                    throw $e;
11004fd306cSNickeau                }
11104fd306cSNickeau                $message = "Error with the database replication for the page ($page). " . $e->getMessage();
11204fd306cSNickeau                if (Console::isConsoleRun()) {
11304fd306cSNickeau                    throw new ExceptionCompile($message);
11404fd306cSNickeau                } else {
11504fd306cSNickeau                    LogUtility::error($message);
11604fd306cSNickeau                }
11704fd306cSNickeau            }
11804fd306cSNickeau        }
11904fd306cSNickeau
12004fd306cSNickeau
12104fd306cSNickeau    }
12204fd306cSNickeau
12304fd306cSNickeau
12404fd306cSNickeau    function indexViaMetadataRendering(Doku_Event $event, $params)
12504fd306cSNickeau    {
12604fd306cSNickeau
12704fd306cSNickeau        try {
12804fd306cSNickeau            $wikiPath = ExecutionContext::getActualOrCreateFromEnv()
12904fd306cSNickeau                ->getExecutingWikiPath();
13004fd306cSNickeau        } catch (ExceptionNotFound $e) {
13104fd306cSNickeau            // markup string run
13204fd306cSNickeau            return;
13304fd306cSNickeau        }
13404fd306cSNickeau
13504fd306cSNickeau        $page = MarkupPath::createPageFromPathObject($wikiPath);
13604fd306cSNickeau
13704fd306cSNickeau        $references = References::createFromResource($page)
13804fd306cSNickeau            ->setReadStore(MetadataDokuWikiStore::class);
13904fd306cSNickeau
14004fd306cSNickeau        $internalIdReferences = $event->data['current']['relation']['references'];
14104fd306cSNickeau        foreach ($internalIdReferences as $internalIdReferenceValue => $internalIdReferenceExist) {
14204fd306cSNickeau            $ref = Reference::createFromResource($page)
14304fd306cSNickeau                ->setReadStore(MetadataDokuWikiStore::class)
14404fd306cSNickeau                ->setFromStoreValueWithoutException($internalIdReferenceValue);
14504fd306cSNickeau            try {
14604fd306cSNickeau                $references->addRow([$ref]);
14704fd306cSNickeau            } catch (ExceptionNotFound $e) {
14804fd306cSNickeau                LogUtility::internalError("The identifier and the value identifier should be known at this stage", self::CANONICAL, $e);
14904fd306cSNickeau            }
15004fd306cSNickeau        }
15104fd306cSNickeau
15204fd306cSNickeau        try {
15304fd306cSNickeau            // persist to database
15404fd306cSNickeau            $references
15504fd306cSNickeau                ->setWriteStore(MetadataDbStore::class)
15604fd306cSNickeau                ->persist();
15704fd306cSNickeau        } catch (ExceptionCompile $e) {
15804fd306cSNickeau            LogUtility::warning("Reference error when persisting to the file system store: " . $e->getMessage(), self::CANONICAL, $e);
15904fd306cSNickeau        }
16004fd306cSNickeau
16104fd306cSNickeau    }
16204fd306cSNickeau
16304fd306cSNickeau
16404fd306cSNickeau}
16504fd306cSNickeau
16604fd306cSNickeau
16704fd306cSNickeau
168