1<?php
2/**
3 * Action module for yatp plugin: Handles backlink indexing at page indexing time
4 */
5
6use dokuwiki\Extension\ActionPlugin;
7use dokuwiki\Extension\EventHandler;
8use dokuwiki\Indexer\Indexer;
9
10require_once(DOKU_INC . 'inc/indexer.php');
11
12class action_plugin_yatp_indexer extends ActionPlugin
13{
14    public function register(EventHandler $controller)
15    {
16        $controller->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, 'handle_indexer', ['priority' => 100]);
17    }
18
19    public function handle_indexer(Doku_Event $event, $param)
20    {
21        $pageId = $event->data['page'];
22        $helper = plugin_load('helper', 'yatp');
23        $text = rawWiki($pageId);
24
25        if (!preg_match_all('/\{\{template>([^#|}]+)(?:\|([^#}]*))?(?:#([^\}]+))?\}\}/', $text, $matches, PREG_SET_ORDER)) {
26            return;
27        }
28
29        p_set_metadata($pageId, [
30            'relation' => [
31                'references' => []
32            ]
33        ], false, true);
34
35        $metadata = p_get_metadata($pageId, 'relation');
36        $existingRefs = isset($metadata['references']) ? $metadata['references'] : [];
37
38        foreach ($matches as $match) {
39            $templateName = $match[1];
40            $templateId = $helper->getTemplateFile($templateName);
41            if (!$templateId) continue;
42
43            $rawFile = $helper->getTemplate($templateId);
44            if (!$rawFile) continue;
45
46            $replacers = $helper->messageReplacers(preg_split('/(?<!\\\\)\|/', $match[2]));
47
48            if(!empty($replacers['keys']) && !empty($replacers['vals'])) {
49                $rawFile = str_replace($replacers['keys'], $replacers['vals'], $rawFile);
50            }
51
52            $instr = p_get_instructions($rawFile);
53
54            foreach ($instr as $instruction) {
55                list($cmd, $params) = $instruction;
56
57                if ($cmd === 'internallink') {
58                    $pageIdInInstruction = $params[0];
59                    $linkID = cleanID($pageIdInInstruction);
60
61                    if (!$linkID) continue;
62
63                    $existingRefs[$linkID] = page_exists($linkID);
64                }
65            }
66        }
67        p_set_metadata($pageId, [
68            'relation' => [
69                'references' => $existingRefs
70            ]
71        ], true, true);
72        idx_get_indexer()->addMetaKeys($pageId, 'relation references', $existingRefs);
73    }
74}
75