xref: /plugin/structpublish/meta/Revision.php (revision 421da0e6cbf4dd6dd8d62acd9d0b43b82124b221)
1c2f8a3c4SAnna Dabrowska<?php
2c2f8a3c4SAnna Dabrowska
3c2f8a3c4SAnna Dabrowskanamespace dokuwiki\plugin\structpublish\meta;
4c2f8a3c4SAnna Dabrowska
59ab8cbaeSanndause dokuwiki\plugin\struct\meta\Column;
6f734c62fSAnna Dabrowskause dokuwiki\plugin\sqlite\SQLiteDB;
7e394901aSAnna Dabrowskause dokuwiki\plugin\struct\meta\ConfigParser;
8e394901aSAnna Dabrowskause dokuwiki\plugin\struct\meta\Schema;
9e394901aSAnna Dabrowskause dokuwiki\plugin\struct\meta\SearchConfig;
10e394901aSAnna Dabrowskause dokuwiki\plugin\struct\meta\Value;
11e394901aSAnna Dabrowska
128903e50cSAndreas Gohr/**
138903e50cSAndreas Gohr * Object representing a page revision and its properties
148903e50cSAndreas Gohr */
15c2f8a3c4SAnna Dabrowskaclass Revision
16c2f8a3c4SAnna Dabrowska{
17f734c62fSAnna Dabrowska    /** @var SQLiteDB */
18c2f8a3c4SAnna Dabrowska    protected $sqlite;
19e7259784SAnna Dabrowska
20e7259784SAnna Dabrowska    protected $schema;
21e7259784SAnna Dabrowska
22c2f8a3c4SAnna Dabrowska    protected $id;
23c2f8a3c4SAnna Dabrowska    protected $rev;
249ab8cbaeSannda    protected $published = 0;
259ab8cbaeSannda    protected $status = Constants::STATUS_DRAFT;
26e394901aSAnna Dabrowska    protected $version;
27c2f8a3c4SAnna Dabrowska    protected $user;
28e6dd5f77SAnna Dabrowska    protected $datetime;
299ab8cbaeSannda    /** @var bool|Column */
30e7259784SAnna Dabrowska    protected $statusCol;
31e7259784SAnna Dabrowska    protected $versionCol;
32e7259784SAnna Dabrowska    protected $userCol;
33e6dd5f77SAnna Dabrowska    protected $datetimeCol;
34e7259784SAnna Dabrowska    protected $revisionCol;
35c2f8a3c4SAnna Dabrowska
36c2f8a3c4SAnna Dabrowska    /**
378903e50cSAndreas Gohr     * Constructor
388903e50cSAndreas Gohr     *
398903e50cSAndreas Gohr     * @param string $id page id
408903e50cSAndreas Gohr     * @param int $rev revision
41c2f8a3c4SAnna Dabrowska     */
42b476f81dSAnna Dabrowska    public function __construct($id, $rev)
43c2f8a3c4SAnna Dabrowska    {
44c2f8a3c4SAnna Dabrowska        $this->id = $id;
45c2f8a3c4SAnna Dabrowska        $this->rev = $rev;
46c2f8a3c4SAnna Dabrowska
47e7259784SAnna Dabrowska        $this->schema = new Schema('structpublish');
48e7259784SAnna Dabrowska        $this->statusCol = $this->schema->findColumn('status');
49e7259784SAnna Dabrowska        $this->versionCol = $this->schema->findColumn('version');
50e7259784SAnna Dabrowska        $this->userCol = $this->schema->findColumn('user');
51e6dd5f77SAnna Dabrowska        $this->datetimeCol = $this->schema->findColumn('datetime');
52e7259784SAnna Dabrowska        $this->revisionCol = $this->schema->findColumn('revision');
533449f9ceSAnna Dabrowska
54e394901aSAnna Dabrowska        /** @var Value[] $values */
55*421da0e6SAnna Dabrowska        $values = $this->getCoreData(['revision=' . $this->rev]);
56e394901aSAnna Dabrowska
57e394901aSAnna Dabrowska        if (!empty($values)) {
58e7259784SAnna Dabrowska            $this->status = $values[$this->statusCol->getColref() - 1]->getRawValue();
59e7259784SAnna Dabrowska            $this->version = $values[$this->versionCol->getColref() - 1]->getRawValue();
60e7259784SAnna Dabrowska            $this->user = $values[$this->userCol->getColref() - 1]->getRawValue();
61e6dd5f77SAnna Dabrowska            $this->datetime = $values[$this->datetimeCol->getColref() - 1]->getRawValue();
623449f9ceSAnna Dabrowska        }
63c2f8a3c4SAnna Dabrowska    }
64c2f8a3c4SAnna Dabrowska
658903e50cSAndreas Gohr    /**
668903e50cSAndreas Gohr     * Store the currently set structpublish meta data in the database
6731e730e1SAnna Dabrowska     *
688903e50cSAndreas Gohr     * @return void
698903e50cSAndreas Gohr     */
70c2f8a3c4SAnna Dabrowska    public function save()
71c2f8a3c4SAnna Dabrowska    {
72e31c94d7SAndreas Gohr        if ($this->status === Constants::STATUS_PUBLISHED) {
736a791fefSAnna Dabrowska            $this->published = 1;
746a791fefSAnna Dabrowska        }
753449f9ceSAnna Dabrowska
76e394901aSAnna Dabrowska        $this->updateCoreData($this->id);
77c2f8a3c4SAnna Dabrowska    }
78c2f8a3c4SAnna Dabrowska
79c2f8a3c4SAnna Dabrowska    /**
808903e50cSAndreas Gohr     * Return the version of a published revision
818903e50cSAndreas Gohr     *
828903e50cSAndreas Gohr     * @return string|null
83c2f8a3c4SAnna Dabrowska     */
84c2f8a3c4SAnna Dabrowska    public function getVersion()
85c2f8a3c4SAnna Dabrowska    {
868903e50cSAndreas Gohr        return $this->version;
87c2f8a3c4SAnna Dabrowska    }
88c2f8a3c4SAnna Dabrowska
89c2f8a3c4SAnna Dabrowska    /**
908903e50cSAndreas Gohr     * Set the version of a published revision
918903e50cSAndreas Gohr     *
928903e50cSAndreas Gohr     * @param string $version
93c2f8a3c4SAnna Dabrowska     */
948903e50cSAndreas Gohr    public function setVersion($version)
95c2f8a3c4SAnna Dabrowska    {
96c2f8a3c4SAnna Dabrowska        $this->version = $version;
97c2f8a3c4SAnna Dabrowska    }
98c2f8a3c4SAnna Dabrowska
99c2f8a3c4SAnna Dabrowska    /**
1008903e50cSAndreas Gohr     * The revision timestamp
1018903e50cSAndreas Gohr     *
1023449f9ceSAnna Dabrowska     * @return int
103c2f8a3c4SAnna Dabrowska     */
104c2f8a3c4SAnna Dabrowska    public function getRev()
105c2f8a3c4SAnna Dabrowska    {
106c2f8a3c4SAnna Dabrowska        return $this->rev;
107c2f8a3c4SAnna Dabrowska    }
108c2f8a3c4SAnna Dabrowska
109c2f8a3c4SAnna Dabrowska    /**
1108903e50cSAndreas Gohr     * Get the current status of this revision
1118903e50cSAndreas Gohr     *
1123449f9ceSAnna Dabrowska     * @return string
113c2f8a3c4SAnna Dabrowska     */
114c2f8a3c4SAnna Dabrowska    public function getStatus()
115c2f8a3c4SAnna Dabrowska    {
116e394901aSAnna Dabrowska        return $this->status;
117c2f8a3c4SAnna Dabrowska    }
118c2f8a3c4SAnna Dabrowska
119c2f8a3c4SAnna Dabrowska    /**
1208903e50cSAndreas Gohr     * Set the current status of this revision
1218903e50cSAndreas Gohr     *
1223449f9ceSAnna Dabrowska     * @param string $status
123c2f8a3c4SAnna Dabrowska     */
1248903e50cSAndreas Gohr    public function setStatus($status)
125c2f8a3c4SAnna Dabrowska    {
126c2f8a3c4SAnna Dabrowska        $this->status = $status;
127c2f8a3c4SAnna Dabrowska    }
128c2f8a3c4SAnna Dabrowska
129c2f8a3c4SAnna Dabrowska    /**
1308903e50cSAndreas Gohr     * Get the user that changed the status of this revision
1318903e50cSAndreas Gohr     *
1328903e50cSAndreas Gohr     * Not available for drafts
1338903e50cSAndreas Gohr     *
1348903e50cSAndreas Gohr     * @return string|null
135c2f8a3c4SAnna Dabrowska     */
136c2f8a3c4SAnna Dabrowska    public function getUser()
137c2f8a3c4SAnna Dabrowska    {
138c2f8a3c4SAnna Dabrowska        return $this->user;
139c2f8a3c4SAnna Dabrowska    }
140c2f8a3c4SAnna Dabrowska
141c2f8a3c4SAnna Dabrowska    /**
1428903e50cSAndreas Gohr     * Set the user that changed the revision status
1438903e50cSAndreas Gohr     *
1443449f9ceSAnna Dabrowska     * @param string $user
145c2f8a3c4SAnna Dabrowska     */
146c2f8a3c4SAnna Dabrowska    public function setUser($user): void
147c2f8a3c4SAnna Dabrowska    {
148c2f8a3c4SAnna Dabrowska        $this->user = $user;
149c2f8a3c4SAnna Dabrowska    }
1503449f9ceSAnna Dabrowska
1518903e50cSAndreas Gohr    /**
1528903e50cSAndreas Gohr     * The datetime when the status of this revision was changed
1538903e50cSAndreas Gohr     *
1548903e50cSAndreas Gohr     * Uses ISO Format. Not available for drafts
1558903e50cSAndreas Gohr     *
1568903e50cSAndreas Gohr     * @return string|null
1578903e50cSAndreas Gohr     */
158e6dd5f77SAnna Dabrowska    public function getDatetime()
159e394901aSAnna Dabrowska    {
160e6dd5f77SAnna Dabrowska        return $this->datetime;
161e394901aSAnna Dabrowska    }
162e394901aSAnna Dabrowska
1638903e50cSAndreas Gohr    /**
1648903e50cSAndreas Gohr     * The timestamp of when the status of this revision was changed
1658903e50cSAndreas Gohr     *
1668903e50cSAndreas Gohr     * Not available for drafts
1678903e50cSAndreas Gohr     *
1688903e50cSAndreas Gohr     * @return int|null
1698903e50cSAndreas Gohr     */
1705c2215e8SAndreas Gohr    public function getTimestamp()
1715c2215e8SAndreas Gohr    {
1728903e50cSAndreas Gohr        if ($this->datetime === null) {
1738903e50cSAndreas Gohr            return null;
1748903e50cSAndreas Gohr        }
1755c2215e8SAndreas Gohr        return strtotime($this->datetime);
1765c2215e8SAndreas Gohr    }
1775c2215e8SAndreas Gohr
1788903e50cSAndreas Gohr    /**
1798903e50cSAndreas Gohr     * Set the datetime when the status of this revision was changed
1808903e50cSAndreas Gohr     *
1818903e50cSAndreas Gohr     * Uses ISO Format
1828903e50cSAndreas Gohr     *
1838903e50cSAndreas Gohr     * @param string $time
1848903e50cSAndreas Gohr     */
185e6dd5f77SAnna Dabrowska    public function setDatetime($time)
186e394901aSAnna Dabrowska    {
1875c2215e8SAndreas Gohr        $this->datetime = $time;
1885c2215e8SAndreas Gohr    }
1895c2215e8SAndreas Gohr
1908903e50cSAndreas Gohr    /**
19122101782SAndreas Gohr     * Set the timestamp of when the status of this revision was changed
19222101782SAndreas Gohr     */
19322101782SAndreas Gohr    public function setTimestamp($timestamp)
19422101782SAndreas Gohr    {
19522101782SAndreas Gohr        $this->datetime = date('Y-m-d\TH:i', $timestamp);
19622101782SAndreas Gohr    }
19722101782SAndreas Gohr
19822101782SAndreas Gohr    /**
1998903e50cSAndreas Gohr     * The page ID this revision is for
20031e730e1SAnna Dabrowska     *
2018903e50cSAndreas Gohr     * @return string
2028903e50cSAndreas Gohr     */
2035c2215e8SAndreas Gohr    public function getId()
2045c2215e8SAndreas Gohr    {
2055c2215e8SAndreas Gohr        return $this->id;
206e394901aSAnna Dabrowska    }
207e394901aSAnna Dabrowska
2083449f9ceSAnna Dabrowska    /**
2093449f9ceSAnna Dabrowska     * Update publish status in the core table
2108903e50cSAndreas Gohr     *
2118903e50cSAndreas Gohr     * @param string $pid
2128903e50cSAndreas Gohr     * @param int $rid
2133449f9ceSAnna Dabrowska     */
214e394901aSAnna Dabrowska    protected function updateCoreData($pid, $rid = 0)
2153449f9ceSAnna Dabrowska    {
216e394901aSAnna Dabrowska        $data = [
217e394901aSAnna Dabrowska            'status' => $this->status,
218e394901aSAnna Dabrowska            'user' => $this->user,
2195c2215e8SAndreas Gohr            'datetime' => $this->datetime,
220e394901aSAnna Dabrowska            'revision' => $this->rev,
221e394901aSAnna Dabrowska            'version' => $this->version,
222e394901aSAnna Dabrowska        ];
2233231ebaeSAnna Dabrowska        $schema = new Schema('structpublish', 0);
2243231ebaeSAnna Dabrowska        $access = new AccessTableStructpublish($schema, $pid, 0, $rid);
2256a791fefSAnna Dabrowska        $access->setPublished($this->published);
226e394901aSAnna Dabrowska        $access->saveData($data);
227e394901aSAnna Dabrowska    }
228e394901aSAnna Dabrowska
2298903e50cSAndreas Gohr    /**
230fd06d74cSAnna Dabrowska     * Fetches data from the structpublish schema for the current page.
231fd06d74cSAnna Dabrowska     * Returns an array of struct Value objects, not literal values.
232fd06d74cSAnna Dabrowska     * $andFilters can be used to limit the search, e.g. by status or revision
23331e730e1SAnna Dabrowska     *
234fd06d74cSAnna Dabrowska     * @see https://www.dokuwiki.org/plugin:struct:filters
235fd06d74cSAnna Dabrowska     *
236fd06d74cSAnna Dabrowska     * @param array $andFilters
2378903e50cSAndreas Gohr     * @return array|Value[]
2388903e50cSAndreas Gohr     */
239fd06d74cSAnna Dabrowska    public function getCoreData($andFilters = [])
240e394901aSAnna Dabrowska    {
241e394901aSAnna Dabrowska        $lines = [
242e394901aSAnna Dabrowska            'schema: structpublish',
243e394901aSAnna Dabrowska            'cols: *',
244fd06d74cSAnna Dabrowska            'sort: revision',
245e394901aSAnna Dabrowska            'filter: %pageid% = $ID$'
246e394901aSAnna Dabrowska        ];
247e7259784SAnna Dabrowska
248fd06d74cSAnna Dabrowska        if (!empty($andFilters)) {
24931e730e1SAnna Dabrowska            foreach ($andFilters as $filter) {
250fd06d74cSAnna Dabrowska                $lines[] = 'filter: ' . $filter;
251e7259784SAnna Dabrowska            }
25231e730e1SAnna Dabrowska        }
253e7259784SAnna Dabrowska
254e394901aSAnna Dabrowska        $parser = new ConfigParser($lines);
255e394901aSAnna Dabrowska        $config = $parser->getConfig();
256fd06d74cSAnna Dabrowska        $search = new SearchConfig($config);
25792cbcc21SAnna Dabrowska        // disable 'latest' flag in select query
25892cbcc21SAnna Dabrowska        $search->setSelectLatest(false);
2599ab8cbaeSannda
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
28631e730e1SAnna Dabrowska        $published = new Revision(
28731e730e1SAnna Dabrowska            $this->id,
28831e730e1SAnna Dabrowska            $latestPublished[$this->revisionCol->getColref() - 1]->getRawValue()
28931e730e1SAnna 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