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