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 * The page ID this revision is for 194 * @return string 195 */ 196 public function getId() 197 { 198 return $this->id; 199 } 200 201 /** 202 * Update publish status in the core table 203 * 204 * @param string $pid 205 * @param int $rid 206 */ 207 protected function updateCoreData($pid, $rid = 0) 208 { 209 $data = [ 210 'status' => $this->status, 211 'user' => $this->user, 212 'datetime' => $this->datetime, 213 'revision' => $this->rev, 214 'version' => $this->version, 215 ]; 216 $schema = new Schema('structpublish', 0); 217 $access = new AccessTableStructpublish($schema, $pid, 0, $rid); 218 $access->setPublished($this->published); 219 $access->saveData($data); 220 } 221 222 /** 223 * @param string $andFilter 224 * @return array|Value[] 225 * @fixme fix fixme, update doc block 226 */ 227 public function getCoreData($andFilter = '') 228 { 229 $lines = [ 230 'schema: structpublish', 231 'cols: *', 232 'filter: %pageid% = $ID$' 233 ]; 234 235 if ($andFilter) { 236 $lines[] = 'filter: ' . $andFilter; 237 } 238 239 $parser = new ConfigParser($lines); 240 $config = $parser->getConfig(); 241 $search = new SearchConfig($config, $this->sqlite); 242 $data = $search->execute(); 243 if (!empty($data)) { 244 // FIXME 245 return $data[array_key_last($data)]; 246 } 247 return []; 248 } 249 250 /** 251 * Return "latest" published revision of a given page. 252 * If $rev is specified, "latest" means relative to the $rev revision. 253 * 254 * @param int|null $rev 255 * @return Revision|null 256 */ 257 public function getLatestPublishedRevision($rev = null) 258 { 259 $andFilter = 'status=' . Constants::STATUS_PUBLISHED; 260 if ($rev) { 261 $andFilter .= ' AND revision < ' . $rev; 262 } 263 $latestPublished = $this->getCoreData($andFilter); 264 265 if (empty($latestPublished)) { 266 return null; 267 } 268 269 $published = new Revision($this->sqlite, $this->id, 270 $latestPublished[$this->revisionCol->getColref() - 1]->getRawValue()); 271 272 $published->setStatus($latestPublished[$this->statusCol->getColref() - 1]->getRawValue()); 273 $published->setUser($latestPublished[$this->userCol->getColref() - 1]->getRawValue()); 274 $published->setDatetime($latestPublished[$this->datetimeCol->getColref() - 1]->getRawValue()); 275 $published->setVersion($latestPublished[$this->versionCol->getColref() - 1]->getRawValue()); 276 277 return $published; 278 } 279} 280