xref: /plugin/aichat/syntax/similar.php (revision 7ebc78955c65af90e7ee0afbd07adc15271113ba)
1<?php
2
3use dokuwiki\Extension\SyntaxPlugin;
4use dokuwiki\plugin\aichat\Chunk;
5use dokuwiki\Search\Indexer;
6
7/**
8 * DokuWiki Plugin aichat (Syntax Component)
9 *
10 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
11 * @author  Andreas Gohr <gohr@cosmocode.de>
12 */
13class syntax_plugin_aichat_similar extends SyntaxPlugin
14{
15    /** @inheritDoc */
16    public function getType()
17    {
18        return 'substition';
19    }
20
21    /** @inheritDoc */
22    public function getPType()
23    {
24        return 'block';
25    }
26
27    /** @inheritDoc */
28    public function getSort()
29    {
30        return 155;
31    }
32
33    /** @inheritDoc */
34    public function connectTo($mode)
35    {
36        $this->Lexer->addSpecialPattern('~~similar~~', $mode, 'plugin_aichat_similar');
37    }
38
39
40    /** @inheritDoc */
41    public function handle($match, $state, $pos, Doku_Handler $handler)
42    {
43        return [];
44    }
45
46    /** @inheritDoc */
47    public function render($mode, Doku_Renderer $renderer, $data)
48    {
49        global $INFO;
50
51        /** @var helper_plugin_aichat $helper */
52        $helper = $this->loadHelper('aichat');
53
54        $id = $INFO['id'];
55
56        $pages = (new Indexer())->getPages();
57        $pos = array_search($id, $pages);
58        if ($pos === false) return true;
59
60        $storage = $helper->getStorage();
61        $chunks = $storage->getPageChunks($id, $pos * 100);
62        $similar = [];
63        foreach ($chunks as $chunk) {
64            $similar += $storage->getSimilarChunks($chunk->getEmbedding(), 10);
65        }
66        $similar = array_unique($similar);
67        $similar = array_filter($similar, function ($chunk) use ($id) {
68            return $chunk->getPage() !== $id;
69        });
70        usort($similar, function ($a, $b) {
71            /** @var Chunk $a */
72            /** @var Chunk $b */
73            return $b->getScore() <=> $a->getScore();
74        });
75
76        if (!$similar) return true;
77
78        $similar = array_slice($similar, 0, 5);
79
80        $renderer->listu_open();
81        foreach ($similar as $chunk) {
82            $renderer->listitem_open(1);
83            $renderer->listcontent_open();
84            $renderer->internallink($chunk->getPage(), null, null, false, 'navigation');
85            $renderer->listcontent_close();
86            $renderer->listitem_close();
87        }
88        $renderer->listu_close();
89
90        return true;
91    }
92}
93