1<?php
2
3/**
4 * DokuWiki Plugin struct (Helper Component)
5 *
6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7 * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
8 */
9
10use dokuwiki\Extension\Plugin;
11use dokuwiki\ErrorHandler;
12use dokuwiki\plugin\sqlite\SQLiteDB;
13use dokuwiki\plugin\struct\meta\StructException;
14
15class helper_plugin_struct_db extends Plugin
16{
17    /** @var SQLiteDB */
18    protected $sqlite;
19
20    /**
21     * Initialize the database
22     *
23     * @throws Exception
24     */
25    protected function init()
26    {
27        $this->sqlite = new SQLiteDB('struct', DOKU_PLUGIN . 'struct/db/');
28
29        // register our JSON function with variable parameters
30        $this->sqlite->getPdo()->sqliteCreateFunction('STRUCT_JSON', [$this, 'STRUCT_JSON'], -1);
31
32        // register our JSON decode function with variable parameters
33        $this->sqlite->getPdo()->sqliteCreateFunction('STRUCT_LOOKUP', [$this, 'STRUCT_LOOKUP'], -1);
34
35        // this function is meant to be overwritten by plugins
36        $this->sqlite->getPdo()->sqliteCreateFunction('IS_PUBLISHER', [$this, 'IS_PUBLISHER'], -1);
37    }
38
39    /**
40     * @param bool $throw throw an Exception when sqlite not available or fails to load
41     * @return SQLiteDB|null
42     * @throws Exception
43     */
44    public function getDB($throw = true)
45    {
46        if (!$this->sqlite instanceof SQLiteDB) {
47            if (!class_exists(SQLiteDB::class)) {
48                if ($throw || defined('DOKU_UNITTEST')) throw new StructException('no sqlite');
49                return null;
50            }
51
52            try {
53                $this->init();
54            } catch (\Exception $exception) {
55                ErrorHandler::logException($exception);
56                if ($throw) throw $exception;
57                return null;
58            }
59        }
60        return $this->sqlite;
61    }
62
63    /**
64     * Completely remove the database and reinitialize it
65     *
66     * You do not want to call this except for testing!
67     */
68    public function resetDB()
69    {
70        if (!$this->sqlite) return;
71        $file = $this->sqlite->getDbFile();
72        if (!$file) return;
73        unlink($file);
74        clearstatcache(true, $file);
75        $this->sqlite = null;
76    }
77
78    /**
79     * Encodes all given arguments into a JSON encoded array
80     *
81     * @param string ...
82     * @return string
83     */
84    public function STRUCT_JSON(...$args) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
85    {
86        return json_encode($args, JSON_THROW_ON_ERROR);
87    }
88
89    /**
90     * Decodes a struct JSON structure and returns the requested value
91     *
92     * @param ...$args
93     * @return mixed|null
94     */
95    public function STRUCT_LOOKUP(...$args) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
96    {
97        $json = $args[0];
98        $field = $args[1];
99
100        try {
101            $vals = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
102        } catch (\JsonException $exception) {
103            return null;
104        }
105        return $vals[$field];
106    }
107
108    /**
109     * This dummy implementation can be overwritten by a plugin
110     *
111     * @return int
112     */
113    public function IS_PUBLISHER() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
114    {
115        return 1;
116    }
117}
118
119// vim:ts=4:sw=4:et:
120