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 ? WHERE rid = ?'; 28 $this->sqlite->query($sql, 'data_' . $this->schema->getTable(), $this->rid); 29 $this->sqlite->query($sql, 'multi_' . $this->schema->getTable(), $this->rid); 30 } 31 32 protected function getLastRevisionTimestamp() 33 { 34 return 0; 35 } 36 37 /** 38 * @inheritDoc 39 */ 40 protected function buildGetDataSQL($idColumn = 'rid') 41 { 42 return parent::buildGetDataSQL($idColumn); 43 } 44 45 /** 46 * @inheritDoc 47 */ 48 protected function getSingleSql() 49 { 50 $cols = array_merge($this->getSingleNoninputCols(), $this->singleCols); 51 $cols = join(',', $cols); 52 $vals = array_merge($this->getSingleNoninputValues(), $this->singleValues); 53 $rid = $this->getRid() ?: "(SELECT (COALESCE(MAX(rid), 0 ) + 1) FROM $this->stable)"; 54 55 return "REPLACE INTO $this->stable (rid, $cols) VALUES ($rid," . trim(str_repeat('?,', count($vals)), ',') . ');'; 56 } 57 58 /** 59 * @inheritDoc 60 */ 61 protected function getMultiSql() 62 { 63 return "REPLACE INTO $this->mtable (pid, rid, rev, latest, colref, row, value) VALUES (?,?,?,?,?,?,?)"; 64 } 65 66 /** 67 * @inheritDoc 68 */ 69 protected function validateTypeData($data) 70 { 71 // we do not store completely empty rows 72 $isempty = array_reduce($data, function ($isempty, $cell) { 73 return $isempty && ($cell === '' || $cell === [] || $cell === null); 74 }, true); 75 76 return !$isempty; 77 } 78 79 /** 80 * @inheritDoc 81 */ 82 protected function getSingleNoninputCols() 83 { 84 return ['pid', 'rev', 'latest']; 85 } 86 87 /** 88 * @inheritDoc 89 */ 90 protected function getSingleNoninputValues() 91 { 92 return [$this->pid, AccessTable::DEFAULT_REV, AccessTable::DEFAULT_LATEST]; 93 } 94 95 /** 96 * @inheritDoc 97 */ 98 protected function getMultiNoninputValues() 99 { 100 return [$this->pid, $this->rid, AccessTable::DEFAULT_REV, AccessTable::DEFAULT_LATEST]; 101 } 102 103 /** 104 * Set new rid if this is a new insert 105 * @return bool 106 */ 107 protected function afterSingleSave() 108 { 109 $ok = true; 110 if (!$this->rid) { 111 $res = $this->sqlite->query("SELECT rid FROM $this->stable WHERE ROWID = last_insert_rowid()"); 112 $this->rid = $this->sqlite->res2single($res); 113 $this->sqlite->res_close($res); 114 if (!$this->rid) { 115 $ok = false; 116 } 117 } 118 119 // FIXME this might replace handleEmptyMulti() but would it always be safe? in remote API context? 120 if (!empty($this->multiValues)) { 121 $ok = $ok && $this->clearMulti(); 122 } 123 124 return $ok; 125 } 126 127 /** 128 * Add an optional query to clear any previous multi values if the first one is empty. 129 * Allows for deleting multi values from the inline editor. 130 * 131 * @param string $pid 132 * @param int $rid 133 * @param int $colref 134 */ 135 protected function handleEmptyMulti($pid, $rid, $colref) 136 { 137 $this->optQueries[] = [ 138 "DELETE FROM ? WHERE pid = ? AND rid = ? AND colref = ?", 139 'multi_' . $this->schema->getTable(), $pid, $rid, $colref 140 ]; 141 } 142} 143