1<?php
2
3use dokuwiki\Extension\SyntaxPlugin;
4
5/**
6 * CSV Plugin: displays a single value from a CSV file
7 *
8 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
9 * @author     Andreas Gohr <gohr@cosmocode.de>
10 */
11/**
12 * Display a single CSV value
13 */
14class syntax_plugin_csv_value extends SyntaxPlugin
15{
16    protected $rowcache = [];
17
18    /** @inheritdoc */
19    public function getType()
20    {
21        return 'substition';
22    }
23
24    /** @inheritdoc */
25    public function getSort()
26    {
27        return 155;
28    }
29
30    /** @inheritdoc */
31    public function getPType()
32    {
33        return 'normal';
34    }
35
36    /** @inheritdoc */
37    public function connectTo($mode)
38    {
39        $this->Lexer->addSpecialPattern('<csvval[^>]*>', $mode, 'plugin_csv_value');
40    }
41
42    /** @inheritdoc */
43    public function handle($match, $state, $pos, Doku_Handler $handler)
44    {
45        $optstr = substr($match, 7, -1); // <csvval ... >
46        $opt = helper_plugin_csv::parseOptions($optstr);
47
48        return $opt;
49    }
50
51    /**
52     * @param array $opt
53     * @return string
54     */
55    public function getCachedValue($opt)
56    {
57        $r = $opt['outr'] + $opt['hdr_rows'];
58        $c = $opt['outc'];
59        unset($opt['output']);
60        unset($opt['outr']);
61        unset($opt['outc']);
62
63        $cache = md5(serialize($opt));
64        if (!isset($this->rowcache[$cache])) {
65            try {
66                $content = helper_plugin_csv::loadContent($opt['file']);
67            } catch (\Exception $e) {
68                return $e->getMessage();
69            }
70            $this->rowcache[$cache] = helper_plugin_csv::prepareData($content, $opt);
71        }
72
73        if (isset($this->rowcache[$cache][$r][$c])) {
74            return $this->rowcache[$cache][$r][$c];
75        } else {
76            return 'Failed to find requested value';
77        }
78    }
79
80    /** @inheritdoc */
81    public function render($mode, Doku_Renderer $renderer, $opt)
82    {
83        if ($mode == 'metadata') return false;
84
85        if ($opt['file'] === '') {
86            $renderer->cdata('no csv file given');
87            return true;
88        }
89
90        if (!media_ispublic($opt['file'])) $renderer->info['cache'] = false;
91
92        $value = $this->getCachedValue($opt);
93        $renderer->cdata($value);
94        return true;
95    }
96}
97