1<?php 2 3namespace dokuwiki\plugin\struct\meta; 4 5/** 6 * Class AccessTableData 7 * @package dokuwiki\plugin\struct\meta 8 * 9 * This class is for accessing the data stored for a page in a schema 10 * 11 */ 12class AccessTablePage extends AccessTable 13{ 14 public const DEFAULT_PAGE_RID = 0; 15 16 public function __construct($schema, $pid, $ts = 0, $rid = 0) 17 { 18 $ts = $ts ?: time(); 19 parent::__construct($schema, $pid, $ts, $rid); 20 } 21 22 /** 23 * adds an empty data set for this schema and page 24 * 25 * This is basically a delete for the schema fields of a page 26 * 27 * @return bool 28 */ 29 public function clearData() 30 { 31 $data = []; 32 33 foreach ($this->schema->getColumns() as $col) { 34 if ($col->isMulti()) { 35 $data[$col->getLabel()] = []; 36 } else { 37 $data[$col->getLabel()] = ''; 38 } 39 } 40 41 return $this->saveData($data); 42 } 43 44 /** 45 * @return int|bool 46 */ 47 protected function getLastRevisionTimestamp() 48 { 49 $table = 'data_' . $this->schema->getTable(); 50 $where = "WHERE pid = ?"; 51 $opts = [$this->pid]; 52 if ($this->ts) { 53 $where .= " AND REV > 0 AND rev <= ?"; 54 $opts[] = $this->ts; 55 } 56 57 /** @noinspection SqlResolve */ 58 $sql = "SELECT rev FROM $table $where ORDER BY rev DESC LIMIT 1"; 59 $ret = $this->sqlite->queryValue($sql, $opts); 60 // make sure we don't cast empty result to 0 (serial data has rev = 0) 61 if ($ret !== false) $ret = (int)$ret; 62 return $ret; 63 } 64 65 /** 66 * @inheritDoc 67 */ 68 protected function validateTypeData($data) 69 { 70 if ($this->ts == 0) { 71 throw new StructException("Saving with zero timestamp does not work."); 72 } 73 return true; 74 } 75 76 /** 77 * Remove latest status from previous page data 78 */ 79 protected function beforeSave() 80 { 81 /** @noinspection SqlResolve */ 82 $ok = $this->sqlite->query( 83 "UPDATE $this->stable SET latest = 0 WHERE latest = 1 AND pid = ? AND rid = 0", 84 [$this->pid] 85 ); 86 /** @noinspection SqlResolve */ 87 return $ok && $this->sqlite->query( 88 "UPDATE $this->mtable SET latest = 0 WHERE latest = 1 AND pid = ? AND rid = 0", 89 [$this->pid] 90 ); 91 } 92 93 /** 94 * Names of non-input columns to be inserted into SQL query. 95 * Field 'published' is skipped because only plugins use it and 96 * we don't want to interfere with the default NULL value 97 */ 98 protected function getSingleNoninputCols() 99 { 100 return ['rid, pid, rev, latest']; 101 } 102 103 /** 104 * @inheritDoc 105 */ 106 protected function getSingleNoninputValues() 107 { 108 return [self::DEFAULT_PAGE_RID, $this->pid, $this->ts, 1]; 109 } 110 111 /** 112 * @inheritDoc 113 */ 114 protected function getMultiSql() 115 { 116 /** @noinspection SqlResolve */ 117 return "INSERT INTO $this->mtable (latest, rev, pid, rid, colref, row, value) VALUES (?,?,?,?,?,?,?)"; 118 } 119 120 /** 121 * @inheritDoc 122 */ 123 protected function getMultiNoninputValues() 124 { 125 return [AccessTable::DEFAULT_LATEST, $this->ts, $this->pid, self::DEFAULT_PAGE_RID]; 126 } 127} 128