xref: /plugin/struct/helper/db.php (revision 3f594db8bf8e43ac461d652e6f9892b886db0456)
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\Event;
11use dokuwiki\plugin\struct\meta\StructException;
12
13class helper_plugin_struct_db extends DokuWiki_Plugin
14{
15    /** @var helper_plugin_sqlite */
16    protected $sqlite;
17
18    /**
19     * helper_plugin_struct_db constructor.
20     */
21    public function __construct()
22    {
23        $this->init();
24    }
25
26    /**
27     * Initialize the database
28     *
29     * @throws Exception
30     */
31    protected function init()
32    {
33        /** @var helper_plugin_sqlite $sqlite */
34        $this->sqlite = plugin_load('helper', 'sqlite');
35        if (!$this->sqlite) {
36            if (defined('DOKU_UNITTEST')) throw new \Exception('Couldn\'t load sqlite.');
37            return;
38        }
39
40        if ($this->sqlite->getAdapter() === null) {
41            if (defined('DOKU_UNITTEST')) throw new \Exception('Couldn\'t load PDO sqlite.');
42            $this->sqlite = null;
43            return;
44        }
45
46        if ($this->sqlite->getAdapter()->getName() != DOKU_EXT_PDO) {
47            if (defined('DOKU_UNITTEST')) throw new \Exception('Couldn\'t load PDO sqlite.');
48            $this->sqlite = null;
49            return;
50        }
51        $this->sqlite->getAdapter()->setUseNativeAlter(true);
52
53        // initialize the database connection
54        if (!$this->sqlite->init('struct', DOKU_PLUGIN . 'struct/db/')) {
55            if (defined('DOKU_UNITTEST')) throw new \Exception('Couldn\'t init sqlite.');
56            $this->sqlite = null;
57            return;
58        }
59
60        // register our JSON function with variable parameters
61        // todo this might be useful to be moved into the sqlite plugin
62        $this->sqlite->create_function('STRUCT_JSON', array($this, 'STRUCT_JSON'), -1);
63
64        // this function is meant to be overwritten by plugins
65        $this->sqlite->create_function('IS_PUBLISHER', array($this, 'IS_PUBLISHER'), -1);
66
67        // collect and register custom functions from other plugins
68        $functions = [];
69        Event::createAndTrigger('STRUCT_PLUGIN_SQLITE_FUNCTION', $functions);
70        foreach ($functions as $fn) {
71            if (isset($fn['obj']) && isset($fn['name']) && is_callable([$fn['obj'], $fn['name']])) {
72                $this->sqlite->create_function($fn['name'], [$fn['obj'], $fn['name']], -1);
73            }
74        }
75    }
76
77    /**
78     * @param bool $throw throw an Exception when sqlite not available?
79     * @return helper_plugin_sqlite|null
80     */
81    public function getDB($throw = true)
82    {
83        global $conf;
84        $len = strlen($conf['metadir']);
85        if ($this->sqlite && $conf['metadir'] != substr($this->sqlite->getAdapter()->getDbFile(), 0, $len)) {
86            $this->init();
87        }
88        if (!$this->sqlite && $throw) {
89            throw new StructException('no sqlite');
90        }
91        return $this->sqlite;
92    }
93
94    /**
95     * Completely remove the database and reinitialize it
96     *
97     * You do not want to call this except for testing!
98     */
99    public function resetDB()
100    {
101        if (!$this->sqlite) return;
102        $file = $this->sqlite->getAdapter()->getDbFile();
103        if (!$file) return;
104        unlink($file);
105        clearstatcache(true, $file);
106        $this->init();
107    }
108
109    /**
110     * Encodes all given arguments into a JSON encoded array
111     *
112     * @param string ...
113     * @return string
114     */
115    public function STRUCT_JSON() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
116    {
117        $args = func_get_args();
118        return json_encode($args);
119    }
120
121    /**
122     * This dummy implementation can be overwritten by a plugin
123     *
124     * @return int
125     */
126    public function IS_PUBLISHER() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
127    {
128        return 1;
129    }
130}
131
132// vim:ts=4:sw=4:et:
133