xref: /plugin/structpublish/meta/Revision.php (revision 364fb00a76700441fe173fe52b5398f15985dc8a)
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