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($data, function ($isempty, $cell) { 79 return $isempty && ($cell === '' || $cell === [] || $cell === null); 80 }, true); 81 82 return !$isempty; 83 } 84 85 /** 86 * @inheritDoc 87 */ 88 protected function getSingleNoninputCols() 89 { 90 return ['pid', 'rev', 'latest']; 91 } 92 93 /** 94 * @inheritDoc 95 */ 96 protected function getSingleNoninputValues() 97 { 98 return [$this->pid, AccessTable::DEFAULT_REV, AccessTable::DEFAULT_LATEST]; 99 } 100 101 /** 102 * @inheritDoc 103 */ 104 protected function getMultiNoninputValues() 105 { 106 return [$this->pid, $this->rid, AccessTable::DEFAULT_REV, AccessTable::DEFAULT_LATEST]; 107 } 108 109 /** 110 * Set new rid if this is a new insert 111 * @return bool 112 */ 113 protected function afterSingleSave() 114 { 115 $ok = true; 116 if (!$this->rid) { 117 $this->rid = $this->sqlite->queryValue("SELECT rid FROM $this->stable WHERE ROWID = last_insert_rowid()"); 118 if (!$this->rid) { 119 $ok = false; 120 } 121 } 122 123 // FIXME this might replace handleEmptyMulti() but would it always be safe? in remote API context? 124 if (!empty($this->multiValues)) { 125 $ok = $ok && $this->clearMulti(); 126 } 127 128 return $ok; 129 } 130 131 /** 132 * Add an optional query to clear any previous multi values if the first one is empty. 133 * Allows for deleting multi values from the inline editor. 134 * 135 * @param string $pid 136 * @param int $rid 137 * @param int $colref 138 */ 139 protected function handleEmptyMulti($pid, $rid, $colref) 140 { 141 $table = 'multi_' . $this->schema->getTable(); 142 $this->optQueries[] = [ 143 "DELETE FROM $table WHERE pid = ? AND rid = ? AND colref = ?", 144 $pid, $rid, $colref 145 ]; 146 } 147} 148