Merge pull request #4188 from dokuwiki/tablefix
[dokuwiki.git] / inc / Feed / FeedPageProcessor.php
blob25df6f4cc75320bd6692212756aab2a8782bc23b
1 <?php
3 namespace dokuwiki\Feed;
5 use Diff;
6 use dokuwiki\ChangeLog\PageChangeLog;
7 use TableDiffFormatter;
8 use UnifiedDiffFormatter;
10 /**
11 * Accept more or less arbitrary data to represent a page and provide lazy loading accessors
12 * to all the data we need for feed generation.
14 class FeedPageProcessor extends FeedItemProcessor
16 /** @var array[] metadata */
17 protected $meta;
19 // region data processors
21 /** @inheritdoc */
22 public function getURL($linkto)
24 switch ($linkto) {
25 case 'page':
26 $opt = ['rev' => $this->getRev()];
27 break;
28 case 'rev':
29 $opt = ['rev' => $this->getRev(), 'do' => 'revisions'];
30 break;
31 case 'current':
32 $opt = [];
33 break;
34 case 'diff':
35 default:
36 $opt = ['rev' => $this->getRev(), 'do' => 'diff'];
39 return wl($this->getId(), $opt, true, '&');
42 /** @inheritdoc */
43 public function getBody($content)
45 global $lang;
47 switch ($content) {
48 case 'diff':
49 $diff = $this->getDiff();
50 // note: diff output must be escaped, UnifiedDiffFormatter provides plain text
51 $udf = new UnifiedDiffFormatter();
52 return "<pre>\n" . hsc($udf->format($diff)) . "\n</pre>";
54 case 'htmldiff':
55 $diff = $this->getDiff();
56 // note: no need to escape diff output, TableDiffFormatter provides 'safe' html
57 $tdf = new TableDiffFormatter();
58 $content = '<table>';
59 $content .= '<tr><th colspan="2" width="50%">' . dformat($this->getPrev()) . '</th>';
60 $content .= '<th colspan="2" width="50%">' . $lang['current'] . '</th></tr>';
61 $content .= $tdf->format($diff);
62 $content .= '</table>';
63 return $content;
65 case 'html':
66 if ($this->isExisting()) {
67 $html = p_wiki_xhtml($this->getId(), '', false);
68 } else {
69 $html = p_wiki_xhtml($this->getId(), $this->getRev(), false);
71 return $this->cleanHTML($html);
73 case 'abstract':
74 default:
75 return $this->getAbstract();
79 /** @inheritdoc */
80 public function getCategory()
82 $meta = $this->getMetaData();
83 return (array)($meta['subject'] ?? (string)getNS($this->getId()));
86 // endregion
88 // region data accessors
90 /**
91 * Get the page abstract
93 * @return string
95 public function getAbstract()
97 if (!isset($this->data['abstract'])) {
98 $meta = $this->getMetaData();
99 if (isset($meta['description']['abstract'])) {
100 $this->data['abstract'] = (string)$meta['description']['abstract'];
101 } else {
102 $this->data['abstract'] = '';
105 return $this->data['abstract'];
108 /** @inheritdoc */
109 public function getRev()
111 $rev = parent::getRev();
112 if ($rev) return $rev;
114 if (page_exists($this->id)) {
115 $this->data['rev'] = filemtime(wikiFN($this->id));
116 $this->data['exists'] = true;
117 } else {
118 $this->loadRevisions();
120 return $this->data['rev'];
124 * Get the previous revision timestamp of this page
126 * @return int|null The previous revision or null if there is none
128 public function getPrev()
130 if ($this->data['prev'] ?? 0) return $this->data['prev'];
131 $this->loadRevisions();
132 return $this->data['prev'];
136 * Does this page exist?
138 * @return bool
140 public function isExisting()
142 if (!isset($this->data['exists'])) {
143 $this->data['exists'] = page_exists($this->id);
145 return $this->data['exists'];
149 * Get the title of this page
151 * @return string
153 public function getTitle()
155 global $conf;
156 if (!isset($this->data['title'])) {
157 if ($conf['useheading']) {
158 $this->data['title'] = p_get_first_heading($this->id);
159 } else {
160 $this->data['title'] = noNS($this->id);
163 return $this->data['title'];
166 // endregion
169 * Get the metadata of this page
171 * @return array[]
173 protected function getMetaData()
175 if (!isset($this->meta)) {
176 $this->meta = (array)p_get_metadata($this->id);
178 return $this->meta;
182 * Load the current and previous revision from the changelog
183 * @return void
185 protected function loadRevisions()
187 $changelog = new PageChangeLog($this->id);
188 $revs = $changelog->getRevisions(0, 2); // FIXME check that this returns the current one correctly
189 if (!isset($this->data['rev'])) {
190 // prefer an already set date, only set if missing
191 // it should usally not happen that neither is available
192 $this->data['rev'] = $revs[0] ?? 0;
194 // a previous revision might not exist
195 $this->data['prev'] = $revs[1] ?? null;
199 * Get a diff between this and the previous revision
201 * @return Diff
203 protected function getDiff()
205 $prev = $this->getPrev();
207 if ($prev) {
208 return new Diff(
209 explode("\n", rawWiki($this->getId(), $prev)),
210 explode("\n", rawWiki($this->getId(), ''))
213 return new Diff([''], explode("\n", rawWiki($this->getId(), '')));