1c2f8a3c4SAnna Dabrowska<?php 2c2f8a3c4SAnna Dabrowska 3c2f8a3c4SAnna Dabrowskanamespace dokuwiki\plugin\structpublish\meta; 4c2f8a3c4SAnna Dabrowska 5f734c62fSAnna Dabrowskause dokuwiki\plugin\sqlite\SQLiteDB; 6e394901aSAnna Dabrowskause dokuwiki\plugin\struct\meta\ConfigParser; 7e394901aSAnna Dabrowskause dokuwiki\plugin\struct\meta\Schema; 8e394901aSAnna Dabrowskause dokuwiki\plugin\struct\meta\SearchConfig; 9e394901aSAnna Dabrowskause dokuwiki\plugin\struct\meta\Value; 10e394901aSAnna Dabrowska 118903e50cSAndreas Gohr/** 128903e50cSAndreas Gohr * Object representing a page revision and its properties 138903e50cSAndreas Gohr */ 14c2f8a3c4SAnna Dabrowskaclass Revision 15c2f8a3c4SAnna Dabrowska{ 16f734c62fSAnna Dabrowska /** @var SQLiteDB */ 17c2f8a3c4SAnna Dabrowska protected $sqlite; 18e7259784SAnna Dabrowska 19e7259784SAnna Dabrowska protected $schema; 20e7259784SAnna Dabrowska 21c2f8a3c4SAnna Dabrowska protected $id; 22c2f8a3c4SAnna Dabrowska protected $rev; 236a791fefSAnna Dabrowska protected $published; 24c2f8a3c4SAnna Dabrowska protected $status; 25e394901aSAnna Dabrowska protected $version; 26c2f8a3c4SAnna Dabrowska protected $user; 27e6dd5f77SAnna Dabrowska protected $datetime; 288903e50cSAndreas Gohr /** @var bool|\dokuwiki\plugin\struct\meta\Column */ 29e7259784SAnna Dabrowska protected $statusCol; 30e7259784SAnna Dabrowska protected $versionCol; 31e7259784SAnna Dabrowska protected $userCol; 32e6dd5f77SAnna Dabrowska protected $datetimeCol; 33e7259784SAnna Dabrowska protected $revisionCol; 34c2f8a3c4SAnna Dabrowska 35c2f8a3c4SAnna Dabrowska /** 368903e50cSAndreas Gohr * Constructor 378903e50cSAndreas Gohr * 388903e50cSAndreas Gohr * @param string $id page id 398903e50cSAndreas Gohr * @param int $rev revision 40c2f8a3c4SAnna Dabrowska */ 41b476f81dSAnna Dabrowska public function __construct($id, $rev) 42c2f8a3c4SAnna Dabrowska { 43c2f8a3c4SAnna Dabrowska $this->id = $id; 44c2f8a3c4SAnna Dabrowska $this->rev = $rev; 456a791fefSAnna Dabrowska $this->published = 0; 46e6dd5f77SAnna Dabrowska $this->status = Constants::STATUS_DRAFT; 47c2f8a3c4SAnna Dabrowska 48e7259784SAnna Dabrowska $this->schema = new Schema('structpublish'); 49e7259784SAnna Dabrowska $this->statusCol = $this->schema->findColumn('status'); 50e7259784SAnna Dabrowska $this->versionCol = $this->schema->findColumn('version'); 51e7259784SAnna Dabrowska $this->userCol = $this->schema->findColumn('user'); 52e6dd5f77SAnna Dabrowska $this->datetimeCol = $this->schema->findColumn('datetime'); 53e7259784SAnna Dabrowska $this->revisionCol = $this->schema->findColumn('revision'); 543449f9ceSAnna Dabrowska 55e394901aSAnna Dabrowska /** @var Value[] $values */ 56fd06d74cSAnna Dabrowska $values = $this->getCoreData(['revision=' . $this->rev]); 57e394901aSAnna Dabrowska 58e394901aSAnna Dabrowska if (!empty($values)) { 59e7259784SAnna Dabrowska $this->status = $values[$this->statusCol->getColref() - 1]->getRawValue(); 60e7259784SAnna Dabrowska $this->version = $values[$this->versionCol->getColref() - 1]->getRawValue(); 61e7259784SAnna Dabrowska $this->user = $values[$this->userCol->getColref() - 1]->getRawValue(); 62e6dd5f77SAnna Dabrowska $this->datetime = $values[$this->datetimeCol->getColref() - 1]->getRawValue(); 633449f9ceSAnna Dabrowska } 64c2f8a3c4SAnna Dabrowska } 65c2f8a3c4SAnna Dabrowska 668903e50cSAndreas Gohr /** 678903e50cSAndreas Gohr * Store the currently set structpublish meta data in the database 68*31e730e1SAnna Dabrowska * 698903e50cSAndreas Gohr * @return void 708903e50cSAndreas Gohr */ 71c2f8a3c4SAnna Dabrowska public function save() 72c2f8a3c4SAnna Dabrowska { 73e31c94d7SAndreas Gohr if ($this->status === Constants::STATUS_PUBLISHED) { 746a791fefSAnna Dabrowska $this->published = 1; 756a791fefSAnna Dabrowska } 763449f9ceSAnna Dabrowska 77e394901aSAnna Dabrowska $this->updateCoreData($this->id); 78c2f8a3c4SAnna Dabrowska } 79c2f8a3c4SAnna Dabrowska 80c2f8a3c4SAnna Dabrowska /** 818903e50cSAndreas Gohr * Return the version of a published revision 828903e50cSAndreas Gohr * 838903e50cSAndreas Gohr * @return string|null 84c2f8a3c4SAnna Dabrowska */ 85c2f8a3c4SAnna Dabrowska public function getVersion() 86c2f8a3c4SAnna Dabrowska { 878903e50cSAndreas Gohr return $this->version; 88c2f8a3c4SAnna Dabrowska } 89c2f8a3c4SAnna Dabrowska 90c2f8a3c4SAnna Dabrowska /** 918903e50cSAndreas Gohr * Set the version of a published revision 928903e50cSAndreas Gohr * 938903e50cSAndreas Gohr * @param string $version 94c2f8a3c4SAnna Dabrowska */ 958903e50cSAndreas Gohr public function setVersion($version) 96c2f8a3c4SAnna Dabrowska { 97c2f8a3c4SAnna Dabrowska $this->version = $version; 98c2f8a3c4SAnna Dabrowska } 99c2f8a3c4SAnna Dabrowska 100c2f8a3c4SAnna Dabrowska /** 1018903e50cSAndreas Gohr * The revision timestamp 1028903e50cSAndreas Gohr * 1033449f9ceSAnna Dabrowska * @return int 104c2f8a3c4SAnna Dabrowska */ 105c2f8a3c4SAnna Dabrowska public function getRev() 106c2f8a3c4SAnna Dabrowska { 107c2f8a3c4SAnna Dabrowska return $this->rev; 108c2f8a3c4SAnna Dabrowska } 109c2f8a3c4SAnna Dabrowska 110c2f8a3c4SAnna Dabrowska /** 1118903e50cSAndreas Gohr * Get the current status of this revision 1128903e50cSAndreas Gohr * 1133449f9ceSAnna Dabrowska * @return string 114c2f8a3c4SAnna Dabrowska */ 115c2f8a3c4SAnna Dabrowska public function getStatus() 116c2f8a3c4SAnna Dabrowska { 117e394901aSAnna Dabrowska return $this->status; 118c2f8a3c4SAnna Dabrowska } 119c2f8a3c4SAnna Dabrowska 120c2f8a3c4SAnna Dabrowska /** 1218903e50cSAndreas Gohr * Set the current status of this revision 1228903e50cSAndreas Gohr * 1233449f9ceSAnna Dabrowska * @param string $status 124c2f8a3c4SAnna Dabrowska */ 1258903e50cSAndreas Gohr public function setStatus($status) 126c2f8a3c4SAnna Dabrowska { 127c2f8a3c4SAnna Dabrowska $this->status = $status; 128c2f8a3c4SAnna Dabrowska } 129c2f8a3c4SAnna Dabrowska 130c2f8a3c4SAnna Dabrowska /** 1318903e50cSAndreas Gohr * Get the user that changed the status of this revision 1328903e50cSAndreas Gohr * 1338903e50cSAndreas Gohr * Not available for drafts 1348903e50cSAndreas Gohr * 1358903e50cSAndreas Gohr * @return string|null 136c2f8a3c4SAnna Dabrowska */ 137c2f8a3c4SAnna Dabrowska public function getUser() 138c2f8a3c4SAnna Dabrowska { 139c2f8a3c4SAnna Dabrowska return $this->user; 140c2f8a3c4SAnna Dabrowska } 141c2f8a3c4SAnna Dabrowska 142c2f8a3c4SAnna Dabrowska /** 1438903e50cSAndreas Gohr * Set the user that changed the revision status 1448903e50cSAndreas Gohr * 1453449f9ceSAnna Dabrowska * @param string $user 146c2f8a3c4SAnna Dabrowska */ 147c2f8a3c4SAnna Dabrowska public function setUser($user): void 148c2f8a3c4SAnna Dabrowska { 149c2f8a3c4SAnna Dabrowska $this->user = $user; 150c2f8a3c4SAnna Dabrowska } 1513449f9ceSAnna Dabrowska 1528903e50cSAndreas Gohr /** 1538903e50cSAndreas Gohr * The datetime when the status of this revision was changed 1548903e50cSAndreas Gohr * 1558903e50cSAndreas Gohr * Uses ISO Format. Not available for drafts 1568903e50cSAndreas Gohr * 1578903e50cSAndreas Gohr * @return string|null 1588903e50cSAndreas Gohr */ 159e6dd5f77SAnna Dabrowska public function getDatetime() 160e394901aSAnna Dabrowska { 161e6dd5f77SAnna Dabrowska return $this->datetime; 162e394901aSAnna Dabrowska } 163e394901aSAnna Dabrowska 1648903e50cSAndreas Gohr /** 1658903e50cSAndreas Gohr * The timestamp of when the status of this revision was changed 1668903e50cSAndreas Gohr * 1678903e50cSAndreas Gohr * Not available for drafts 1688903e50cSAndreas Gohr * 1698903e50cSAndreas Gohr * @return int|null 1708903e50cSAndreas Gohr */ 1715c2215e8SAndreas Gohr public function getTimestamp() 1725c2215e8SAndreas Gohr { 1738903e50cSAndreas Gohr if ($this->datetime === null) { 1748903e50cSAndreas Gohr return null; 1758903e50cSAndreas Gohr } 1765c2215e8SAndreas Gohr return strtotime($this->datetime); 1775c2215e8SAndreas Gohr } 1785c2215e8SAndreas Gohr 1798903e50cSAndreas Gohr /** 1808903e50cSAndreas Gohr * Set the datetime when the status of this revision was changed 1818903e50cSAndreas Gohr * 1828903e50cSAndreas Gohr * Uses ISO Format 1838903e50cSAndreas Gohr * 1848903e50cSAndreas Gohr * @param string $time 1858903e50cSAndreas Gohr */ 186e6dd5f77SAnna Dabrowska public function setDatetime($time) 187e394901aSAnna Dabrowska { 1885c2215e8SAndreas Gohr $this->datetime = $time; 1895c2215e8SAndreas Gohr } 1905c2215e8SAndreas Gohr 1918903e50cSAndreas Gohr /** 19222101782SAndreas Gohr * Set the timestamp of when the status of this revision was changed 19322101782SAndreas Gohr */ 19422101782SAndreas Gohr public function setTimestamp($timestamp) 19522101782SAndreas Gohr { 19622101782SAndreas Gohr $this->datetime = date('Y-m-d\TH:i', $timestamp); 19722101782SAndreas Gohr } 19822101782SAndreas Gohr 19922101782SAndreas Gohr /** 2008903e50cSAndreas Gohr * The page ID this revision is for 201*31e730e1SAnna Dabrowska * 2028903e50cSAndreas Gohr * @return string 2038903e50cSAndreas Gohr */ 2045c2215e8SAndreas Gohr public function getId() 2055c2215e8SAndreas Gohr { 2065c2215e8SAndreas Gohr return $this->id; 207e394901aSAnna Dabrowska } 208e394901aSAnna Dabrowska 2093449f9ceSAnna Dabrowska /** 2103449f9ceSAnna Dabrowska * Update publish status in the core table 2118903e50cSAndreas Gohr * 2128903e50cSAndreas Gohr * @param string $pid 2138903e50cSAndreas Gohr * @param int $rid 2143449f9ceSAnna Dabrowska */ 215e394901aSAnna Dabrowska protected function updateCoreData($pid, $rid = 0) 2163449f9ceSAnna Dabrowska { 217e394901aSAnna Dabrowska $data = [ 218e394901aSAnna Dabrowska 'status' => $this->status, 219e394901aSAnna Dabrowska 'user' => $this->user, 2205c2215e8SAndreas Gohr 'datetime' => $this->datetime, 221e394901aSAnna Dabrowska 'revision' => $this->rev, 222e394901aSAnna Dabrowska 'version' => $this->version, 223e394901aSAnna Dabrowska ]; 2243231ebaeSAnna Dabrowska $schema = new Schema('structpublish', 0); 2253231ebaeSAnna Dabrowska $access = new AccessTableStructpublish($schema, $pid, 0, $rid); 2266a791fefSAnna Dabrowska $access->setPublished($this->published); 227e394901aSAnna Dabrowska $access->saveData($data); 228e394901aSAnna Dabrowska } 229e394901aSAnna Dabrowska 2308903e50cSAndreas Gohr /** 231fd06d74cSAnna Dabrowska * Fetches data from the structpublish schema for the current page. 232fd06d74cSAnna Dabrowska * Returns an array of struct Value objects, not literal values. 233fd06d74cSAnna Dabrowska * $andFilters can be used to limit the search, e.g. by status or revision 234*31e730e1SAnna Dabrowska * 235fd06d74cSAnna Dabrowska * @see https://www.dokuwiki.org/plugin:struct:filters 236fd06d74cSAnna Dabrowska * 237fd06d74cSAnna Dabrowska * @param array $andFilters 2388903e50cSAndreas Gohr * @return array|Value[] 2398903e50cSAndreas Gohr */ 240fd06d74cSAnna Dabrowska public function getCoreData($andFilters = []) 241e394901aSAnna Dabrowska { 242e394901aSAnna Dabrowska $lines = [ 243e394901aSAnna Dabrowska 'schema: structpublish', 244e394901aSAnna Dabrowska 'cols: *', 245fd06d74cSAnna Dabrowska 'sort: revision', 246e394901aSAnna Dabrowska 'filter: %pageid% = $ID$' 247e394901aSAnna Dabrowska ]; 248e7259784SAnna Dabrowska 249fd06d74cSAnna Dabrowska if (!empty($andFilters)) { 250*31e730e1SAnna Dabrowska foreach ($andFilters as $filter) { 251fd06d74cSAnna Dabrowska $lines[] = 'filter: ' . $filter; 252e7259784SAnna Dabrowska } 253*31e730e1SAnna Dabrowska } 254e7259784SAnna Dabrowska 255e394901aSAnna Dabrowska $parser = new ConfigParser($lines); 256e394901aSAnna Dabrowska $config = $parser->getConfig(); 257fd06d74cSAnna Dabrowska $search = new SearchConfig($config); 25892cbcc21SAnna Dabrowska // disable 'latest' flag in select query 25992cbcc21SAnna Dabrowska $search->setSelectLatest(false); 260e394901aSAnna Dabrowska $data = $search->execute(); 261e394901aSAnna Dabrowska if (!empty($data)) { 262c7d3717dSAnna Dabrowska return array_pop($data); 263e394901aSAnna Dabrowska } 264e394901aSAnna Dabrowska return []; 2653449f9ceSAnna Dabrowska } 266e7259784SAnna Dabrowska 2678d2065f7SAnna Dabrowska /** 2680dcf68caSAnna Dabrowska * Return "latest" published revision of a given page. 2690dcf68caSAnna Dabrowska * If $rev is specified, "latest" means relative to the $rev revision. 2708d2065f7SAnna Dabrowska * 2710dcf68caSAnna Dabrowska * @param int|null $rev 272ecad4fdbSAnna Dabrowska * @return Revision|null 2738d2065f7SAnna Dabrowska */ 2740dcf68caSAnna Dabrowska public function getLatestPublishedRevision($rev = null) 275e7259784SAnna Dabrowska { 276fd06d74cSAnna Dabrowska $andFilters[] = 'status=' . Constants::STATUS_PUBLISHED; 2770dcf68caSAnna Dabrowska if ($rev) { 278fd06d74cSAnna Dabrowska $andFilters[] .= 'revision<' . $rev; 2790dcf68caSAnna Dabrowska } 280fd06d74cSAnna Dabrowska $latestPublished = $this->getCoreData($andFilters); 281d00ea115SAnna Dabrowska 282ecad4fdbSAnna Dabrowska if (empty($latestPublished)) { 283ecad4fdbSAnna Dabrowska return null; 284ecad4fdbSAnna Dabrowska } 285ecad4fdbSAnna Dabrowska 286*31e730e1SAnna Dabrowska $published = new Revision( 287*31e730e1SAnna Dabrowska $this->id, 288*31e730e1SAnna Dabrowska $latestPublished[$this->revisionCol->getColref() - 1]->getRawValue() 289*31e730e1SAnna Dabrowska ); 290ecad4fdbSAnna Dabrowska 2910dcf68caSAnna Dabrowska $published->setStatus($latestPublished[$this->statusCol->getColref() - 1]->getRawValue()); 2920dcf68caSAnna Dabrowska $published->setUser($latestPublished[$this->userCol->getColref() - 1]->getRawValue()); 293e6dd5f77SAnna Dabrowska $published->setDatetime($latestPublished[$this->datetimeCol->getColref() - 1]->getRawValue()); 2940dcf68caSAnna Dabrowska $published->setVersion($latestPublished[$this->versionCol->getColref() - 1]->getRawValue()); 295e7259784SAnna Dabrowska 2960dcf68caSAnna Dabrowska return $published; 297e7259784SAnna Dabrowska } 298c2f8a3c4SAnna Dabrowska} 299