1<?php
2
3namespace dokuwiki\plugin\struct\meta;
4
5/**
6 * Class AccessTableGlobal
7 *
8 * Load and (more importantly) save data for Global Schemas
9 *
10 * @package dokuwiki\plugin\struct\meta
11 */
12class AccessTableGlobal extends AccessTable
13{
14    public function __construct($table, $pid, $ts = 0, $rid = 0)
15    {
16        parent::__construct($table, $pid, $ts, $rid);
17    }
18
19    /**
20     * Remove the current data
21     */
22    public function clearData()
23    {
24        if (!$this->rid) return; // no data
25
26        /** @noinspection SqlResolve */
27        $sql = 'DELETE FROM data_' . $this->schema->getTable() . ' WHERE rid = ?';
28        $this->sqlite->query($sql, $this->rid);
29        $sql = 'DELETE FROM multi_' . $this->schema->getTable() . ' WHERE rid = ?';
30        $this->sqlite->query($sql, $this->rid);
31    }
32
33    /**
34     * @inheritDoc
35     */
36    protected function getLastRevisionTimestamp()
37    {
38        return 0;
39    }
40
41    /**
42     * @inheritDoc
43     */
44    protected function buildGetDataSQL($idColumn = 'rid')
45    {
46        return parent::buildGetDataSQL($idColumn);
47    }
48
49    /**
50     * @inheritDoc
51     */
52    protected function getSingleSql()
53    {
54        $cols = array_merge($this->getSingleNoninputCols(), $this->singleCols);
55        $cols = implode(',', $cols);
56
57        $vals = array_merge($this->getSingleNoninputValues(), $this->singleValues);
58        $rid = $this->getRid() ?: "(SELECT (COALESCE(MAX(rid), 0 ) + 1) FROM $this->stable)";
59
60        return "REPLACE INTO $this->stable (rid, $cols)
61                      VALUES ($rid," . trim(str_repeat('?,', count($vals)), ',') . ');';
62    }
63
64    /**
65     * @inheritDoc
66     */
67    protected function getMultiSql()
68    {
69        return "REPLACE INTO $this->mtable (pid, rid, rev, latest, colref, row, value) VALUES (?,?,?,?,?,?,?)";
70    }
71
72    /**
73     * @inheritDoc
74     */
75    protected function validateTypeData($data)
76    {
77        // we do not store completely empty rows
78        $isempty = array_reduce(
79            $data,
80            static fn($isempty, $cell) => $isempty && ($cell === '' || $cell === [] || $cell === null),
81            true
82        );
83
84        return !$isempty;
85    }
86
87    /**
88     * @inheritDoc
89     */
90    protected function getSingleNoninputCols()
91    {
92        return ['pid', 'rev', 'latest'];
93    }
94
95    /**
96     * @inheritDoc
97     */
98    protected function getSingleNoninputValues()
99    {
100        return [$this->pid, AccessTable::DEFAULT_REV, AccessTable::DEFAULT_LATEST];
101    }
102
103    /**
104     * @inheritDoc
105     */
106    protected function getMultiNoninputValues()
107    {
108        return [$this->pid, $this->rid, AccessTable::DEFAULT_REV, AccessTable::DEFAULT_LATEST];
109    }
110
111    /**
112     * Set new rid if this is a new insert
113     * @return bool
114     */
115    protected function afterSingleSave()
116    {
117        $ok = true;
118        if (!$this->rid) {
119            $this->rid = $this->sqlite->queryValue("SELECT rid FROM $this->stable WHERE ROWID = last_insert_rowid()");
120            if (!$this->rid) {
121                $ok = false;
122            }
123        }
124
125        // FIXME this might replace handleEmptyMulti() but would it always be safe? in remote API context?
126        if (!empty($this->multiValues)) {
127            $ok = $ok && $this->clearMulti();
128        }
129
130        return $ok;
131    }
132
133    /**
134     * Add an optional query to clear any previous multi values if the first one is empty.
135     * Allows for deleting multi values from the inline editor.
136     *
137     * @param string $pid
138     * @param int $rid
139     * @param int $colref
140     */
141    protected function handleEmptyMulti($pid, $rid, $colref)
142    {
143        $table = 'multi_' . $this->schema->getTable();
144        $this->optQueries[] = [
145            "DELETE FROM $table WHERE pid = ? AND rid = ? AND colref = ?",
146            $pid, $rid, $colref
147        ];
148    }
149}
150