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