xref: /plugin/combo/action/indexer.php (revision 2becc3acd0acebb427d949b7ba2fe780d5404275)
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;
19*2becc3acSgerardnicouse ComboStrap\ExceptionTimeOut;
2004fd306cSNickeauuse ComboStrap\ExecutionContext;
2104fd306cSNickeauuse ComboStrap\FileSystems;
22*2becc3acSgerardnicouse 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*2becc3acSgerardnico        $lock = Lock::create("combo-indexer");
89*2becc3acSgerardnico        try {
90*2becc3acSgerardnico            $lock->acquire();
91*2becc3acSgerardnico        } catch (ExceptionTimeOut $e) {
92*2becc3acSgerardnico            // process running
93*2becc3acSgerardnico            return;
94*2becc3acSgerardnico        }
95*2becc3acSgerardnico
96*2becc3acSgerardnico        try {
9704fd306cSNickeau            /**
9804fd306cSNickeau             * Check that the actual page has analytics data
9904fd306cSNickeau             * (if there is a cache, it's pretty quick)
10004fd306cSNickeau             */
10104fd306cSNickeau            $id = $event->data['page'];
10204fd306cSNickeau            $page = MarkupPath::createMarkupFromId($id);
10304fd306cSNickeau
10404fd306cSNickeau            /**
10504fd306cSNickeau             * From {@link idx_addPage}
10604fd306cSNickeau             * They receive even the deleted page
10704fd306cSNickeau             */
10804fd306cSNickeau            $databasePage = $page->getDatabasePage();
10904fd306cSNickeau            if (!FileSystems::exists($page)) {
11004fd306cSNickeau                $databasePage->delete();
11104fd306cSNickeau                return;
11204fd306cSNickeau            }
11304fd306cSNickeau
11404fd306cSNickeau            if ($databasePage->shouldReplicate()) {
11504fd306cSNickeau                try {
11604fd306cSNickeau                    $databasePage->replicate();
11704fd306cSNickeau                } catch (ExceptionCompile $e) {
11804fd306cSNickeau                    if (PluginUtility::isDevOrTest()) {
11904fd306cSNickeau                        // to get the stack trace
12004fd306cSNickeau                        throw $e;
12104fd306cSNickeau                    }
12204fd306cSNickeau                    $message = "Error with the database replication for the page ($page). " . $e->getMessage();
12304fd306cSNickeau                    if (Console::isConsoleRun()) {
12404fd306cSNickeau                        throw new ExceptionCompile($message);
12504fd306cSNickeau                    } else {
12604fd306cSNickeau                        LogUtility::error($message);
12704fd306cSNickeau                    }
12804fd306cSNickeau                }
12904fd306cSNickeau            }
13004fd306cSNickeau
131*2becc3acSgerardnico        } finally {
132*2becc3acSgerardnico            $lock->release();
133*2becc3acSgerardnico        }
13404fd306cSNickeau
13504fd306cSNickeau    }
13604fd306cSNickeau
13704fd306cSNickeau
13804fd306cSNickeau    function indexViaMetadataRendering(Doku_Event $event, $params)
13904fd306cSNickeau    {
14004fd306cSNickeau
14104fd306cSNickeau        try {
14204fd306cSNickeau            $wikiPath = ExecutionContext::getActualOrCreateFromEnv()
14304fd306cSNickeau                ->getExecutingWikiPath();
14404fd306cSNickeau        } catch (ExceptionNotFound $e) {
14504fd306cSNickeau            // markup string run
14604fd306cSNickeau            return;
14704fd306cSNickeau        }
14804fd306cSNickeau
14904fd306cSNickeau        $page = MarkupPath::createPageFromPathObject($wikiPath);
15004fd306cSNickeau
15104fd306cSNickeau        $references = References::createFromResource($page)
15204fd306cSNickeau            ->setReadStore(MetadataDokuWikiStore::class);
15304fd306cSNickeau
15404fd306cSNickeau        $internalIdReferences = $event->data['current']['relation']['references'];
15504fd306cSNickeau        foreach ($internalIdReferences as $internalIdReferenceValue => $internalIdReferenceExist) {
15604fd306cSNickeau            $ref = Reference::createFromResource($page)
15704fd306cSNickeau                ->setReadStore(MetadataDokuWikiStore::class)
15804fd306cSNickeau                ->setFromStoreValueWithoutException($internalIdReferenceValue);
15904fd306cSNickeau            try {
16004fd306cSNickeau                $references->addRow([$ref]);
16104fd306cSNickeau            } catch (ExceptionNotFound $e) {
16204fd306cSNickeau                LogUtility::internalError("The identifier and the value identifier should be known at this stage", self::CANONICAL, $e);
16304fd306cSNickeau            }
16404fd306cSNickeau        }
16504fd306cSNickeau
16604fd306cSNickeau        try {
16704fd306cSNickeau            // persist to database
16804fd306cSNickeau            $references
16904fd306cSNickeau                ->setWriteStore(MetadataDbStore::class)
17004fd306cSNickeau                ->persist();
17104fd306cSNickeau        } catch (ExceptionCompile $e) {
17204fd306cSNickeau            LogUtility::warning("Reference error when persisting to the file system store: " . $e->getMessage(), self::CANONICAL, $e);
17304fd306cSNickeau        }
17404fd306cSNickeau
17504fd306cSNickeau    }
17604fd306cSNickeau
17704fd306cSNickeau
17804fd306cSNickeau}
17904fd306cSNickeau
18004fd306cSNickeau
18104fd306cSNickeau
182