xref: /template/strap/action/indexer.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
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