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