1<?php 2 3namespace dokuwiki\plugin\structpublish\meta; 4 5use dokuwiki\plugin\struct\meta\ConfigParser; 6use dokuwiki\plugin\struct\meta\Schema; 7use dokuwiki\plugin\struct\meta\SearchConfig; 8use dokuwiki\plugin\struct\meta\Value; 9 10/** 11 * Object representing a page revision and its properties 12 */ 13class Revision 14{ 15 /** @var \helper_plugin_sqlite */ 16 protected $sqlite; 17 18 protected $schema; 19 20 protected $id; 21 protected $rev; 22 protected $published; 23 protected $status; 24 protected $version; 25 protected $user; 26 protected $datetime; 27 /** @var bool|\dokuwiki\plugin\struct\meta\Column */ 28 protected $statusCol; 29 protected $versionCol; 30 protected $userCol; 31 protected $datetimeCol; 32 protected $revisionCol; 33 34 /** 35 * Constructor 36 * 37 * @param \helper_plugin_sqlite $sqlite 38 * @param string $id page id 39 * @param int $rev revision 40 */ 41 public function __construct($sqlite, $id, $rev) 42 { 43 $this->sqlite = $sqlite; 44 $this->id = $id; 45 $this->rev = $rev; 46 $this->published = 0; 47 $this->status = Constants::STATUS_DRAFT; 48 49 $this->schema = new Schema('structpublish'); 50 $this->statusCol = $this->schema->findColumn('status'); 51 $this->versionCol = $this->schema->findColumn('version'); 52 $this->userCol = $this->schema->findColumn('user'); 53 $this->datetimeCol = $this->schema->findColumn('datetime'); 54 $this->revisionCol = $this->schema->findColumn('revision'); 55 56 /** @var Value[] $values */ 57 $values = $this->getCoreData('revision=' . $this->rev); 58 59 if (!empty($values)) { 60 $this->status = $values[$this->statusCol->getColref() - 1]->getRawValue(); 61 $this->version = $values[$this->versionCol->getColref() - 1]->getRawValue(); 62 $this->user = $values[$this->userCol->getColref() - 1]->getRawValue(); 63 $this->datetime = $values[$this->datetimeCol->getColref() - 1]->getRawValue(); 64 } 65 } 66 67 /** 68 * Store the currently set structpublish meta data in the database 69 * @return void 70 */ 71 public function save() 72 { 73 if ($this->status === Constants::STATUS_PUBLISHED) { 74 $this->published = 1; 75 } 76 77 $this->updateCoreData($this->id); 78 // TODO reset publish status of older revisions 79 } 80 81 /** 82 * Return the version of a published revision 83 * 84 * @return string|null 85 */ 86 public function getVersion() 87 { 88 return $this->version; 89 } 90 91 /** 92 * Set the version of a published revision 93 * 94 * @param string $version 95 */ 96 public function setVersion($version) 97 { 98 $this->version = $version; 99 } 100 101 /** 102 * The revision timestamp 103 * 104 * @return int 105 */ 106 public function getRev() 107 { 108 return $this->rev; 109 } 110 111 /** 112 * Get the current status of this revision 113 * 114 * @return string 115 */ 116 public function getStatus() 117 { 118 return $this->status; 119 } 120 121 /** 122 * Set the current status of this revision 123 * 124 * @param string $status 125 */ 126 public function setStatus($status) 127 { 128 $this->status = $status; 129 } 130 131 /** 132 * Get the user that changed the status of this revision 133 * 134 * Not available for drafts 135 * 136 * @return string|null 137 */ 138 public function getUser() 139 { 140 return $this->user; 141 } 142 143 /** 144 * Set the user that changed the revision status 145 * 146 * @param string $user 147 */ 148 public function setUser($user): void 149 { 150 $this->user = $user; 151 } 152 153 /** 154 * The datetime when the status of this revision was changed 155 * 156 * Uses ISO Format. Not available for drafts 157 * 158 * @return string|null 159 */ 160 public function getDatetime() 161 { 162 return $this->datetime; 163 } 164 165 /** 166 * The timestamp of when the status of this revision was changed 167 * 168 * Not available for drafts 169 * 170 * @return int|null 171 */ 172 public function getTimestamp() 173 { 174 if ($this->datetime === null) { 175 return null; 176 } 177 return strtotime($this->datetime); 178 } 179 180 /** 181 * Set the datetime when the status of this revision was changed 182 * 183 * Uses ISO Format 184 * 185 * @param string $time 186 */ 187 public function setDatetime($time) 188 { 189 $this->datetime = $time; 190 } 191 192 /** 193 * Set the timestamp of when the status of this revision was changed 194 */ 195 public function setTimestamp($timestamp) 196 { 197 $this->datetime = date('Y-m-d\TH:i', $timestamp); 198 } 199 200 /** 201 * The page ID this revision is for 202 * @return string 203 */ 204 public function getId() 205 { 206 return $this->id; 207 } 208 209 /** 210 * Update publish status in the core table 211 * 212 * @param string $pid 213 * @param int $rid 214 */ 215 protected function updateCoreData($pid, $rid = 0) 216 { 217 $data = [ 218 'status' => $this->status, 219 'user' => $this->user, 220 'datetime' => $this->datetime, 221 'revision' => $this->rev, 222 'version' => $this->version, 223 ]; 224 $schema = new Schema('structpublish', 0); 225 $access = new AccessTableStructpublish($schema, $pid, 0, $rid); 226 $access->setPublished($this->published); 227 $access->saveData($data); 228 } 229 230 /** 231 * @param string $andFilter 232 * @return array|Value[] 233 * @fixme fix fixme, update doc block 234 */ 235 public function getCoreData($andFilter = '') 236 { 237 $lines = [ 238 'schema: structpublish', 239 'cols: *', 240 'filter: %pageid% = $ID$' 241 ]; 242 243 if ($andFilter) { 244 $lines[] = 'filter: ' . $andFilter; 245 } 246 247 $parser = new ConfigParser($lines); 248 $config = $parser->getConfig(); 249 $search = new SearchConfig($config, $this->sqlite); 250 $data = $search->execute(); 251 if (!empty($data)) { 252 // FIXME 253 return $data[array_key_last($data)]; 254 } 255 return []; 256 } 257 258 /** 259 * Return "latest" published revision of a given page. 260 * If $rev is specified, "latest" means relative to the $rev revision. 261 * 262 * @param int|null $rev 263 * @return Revision|null 264 */ 265 public function getLatestPublishedRevision($rev = null) 266 { 267 $andFilter = 'status=' . Constants::STATUS_PUBLISHED; 268 if ($rev) { 269 $andFilter .= ' AND revision < ' . $rev; 270 } 271 $latestPublished = $this->getCoreData($andFilter); 272 273 if (empty($latestPublished)) { 274 return null; 275 } 276 277 $published = new Revision($this->sqlite, $this->id, 278 $latestPublished[$this->revisionCol->getColref() - 1]->getRawValue()); 279 280 $published->setStatus($latestPublished[$this->statusCol->getColref() - 1]->getRawValue()); 281 $published->setUser($latestPublished[$this->userCol->getColref() - 1]->getRawValue()); 282 $published->setDatetime($latestPublished[$this->datetimeCol->getColref() - 1]->getRawValue()); 283 $published->setVersion($latestPublished[$this->versionCol->getColref() - 1]->getRawValue()); 284 285 return $published; 286 } 287} 288