xref: /dokuwiki/inc/Feed/FeedMediaProcessor.php (revision 093fe67e98c0cdb4b73fd46938e49b64971483c2)
1<?php
2
3namespace dokuwiki\Feed;
4
5use dokuwiki\ChangeLog\MediaChangeLog;
6use dokuwiki\File\MediaFile;
7use dokuwiki\Ui\Media\Display;
8
9class FeedMediaProcessor extends FeedItemProcessor
10{
11    /** @inheritdoc */
12    public function getURL($linkto)
13    {
14        $opt = match ($linkto) {
15            'page' => [
16                'image' => $this->getId(),
17                'ns' => getNS($this->getId()),
18                'rev' => $this->getRev()
19            ],
20            'rev' => [
21                'image' => $this->getId(),
22                'ns' => getNS($this->getId()),
23                'rev' => $this->getRev(),
24                'tab_details' => 'history'
25            ],
26            'current' => [
27                'image' => $this->getId(),
28                'ns' => getNS($this->getId())
29            ],
30            default => [
31                'image' => $this->getId(),
32                'ns' => getNS($this->getId()),
33                'rev' => $this->getRev(),
34                'tab_details' => 'history',
35                'media_do' => 'diff'
36            ],
37        };
38
39        return media_managerURL($opt, '&', true);
40    }
41
42    public function getBody($content)
43    {
44        switch ($content) {
45            case 'diff':
46            case 'htmldiff':
47                $prev = $this->getPrev();
48
49                if ($prev) {
50                    if ($this->isExisting()) {
51                        $src1 = new MediaFile($this->getId(), $prev);
52                        $src2 = new MediaFile($this->getId());
53                    } else {
54                        $src1 = new MediaFile($this->getId(), $prev);
55                        $src2 = null;
56                    }
57                } else {
58                    $src1 = null;
59                    $src2 = new MediaFile($this->getId());
60                }
61                return $this->createDiffTable($src1, $src2);
62
63            case 'abstract':
64            case 'html':
65            default:
66                $src = new Display(new MediaFile($this->getId()));
67                return $this->cleanHTML($src->getPreviewHtml(500, 500));
68        }
69    }
70
71    /**
72     * @inheritdoc
73     * @todo read exif keywords
74     */
75    public function getCategory()
76    {
77        return (array)getNS($this->getId());
78    }
79
80    /**
81     * Get the revision timestamp of this page
82     *
83     * Note: we only handle most current revisions in feeds, so the revision is usually just the
84     * lastmodifed timestamp of the page file. However, if the page does not exist, we need to
85     * determine the revision from the changelog.
86     * @return int
87     */
88    public function getRev()
89    {
90        $rev = parent::getRev();
91        if ($rev) return $rev;
92
93        if (media_exists($this->id)) {
94            $this->data['rev'] = filemtime(mediaFN($this->id));
95            $this->data['exists'] = true;
96        } else {
97            $this->loadRevisions();
98        }
99        return $this->data['rev'];
100    }
101
102    /**
103     * Get the previous revision timestamp of this page
104     *
105     * @return int|null The previous revision or null if there is none
106     */
107    public function getPrev()
108    {
109        if ($this->data['prev'] ?? 0) return $this->data['prev'];
110        $this->loadRevisions();
111        return $this->data['prev'];
112    }
113
114    /**
115     * Does this page exist?
116     *
117     * @return bool
118     */
119    public function isExisting()
120    {
121        if (!isset($this->data['exists'])) {
122            $this->data['exists'] = media_exists($this->id);
123        }
124        return $this->data['exists'];
125    }
126
127    /**
128     * Load the current and previous revision from the changelog
129     * @return void
130     */
131    protected function loadRevisions()
132    {
133        $changelog = new MediaChangeLog($this->id);
134        $revs = $changelog->getRevisions(-1, 2);
135        if (!isset($this->data['rev'])) {
136            // prefer an already set date, only set if missing
137            // it should usally not happen that neither is available
138            $this->data['rev'] = $revs[0] ?? 0;
139        }
140        // a previous revision might not exist
141        $this->data['prev'] = $revs[1] ?? null;
142    }
143
144    /**
145     * Create a table showing the two media files
146     *
147     * @param MediaFile|null $src1
148     * @param MediaFile|null $src2
149     * @return string
150     */
151    protected function createDiffTable($src1, $src2)
152    {
153        global $lang;
154
155        $content = '<table>';
156        $content .= '<tr>';
157        $content .= '<th width="50%">' . ($src1 ? $src1->getRev() : '') . '</th>';
158        $content .= '<th width="50%">' . $lang['current'] . '</th>';
159        $content .= '</tr>';
160        $content .= '<tr>';
161
162        $content .= '<td align="center">';
163        if ($src1) {
164            $display = new Display($src1);
165            $display->getPreviewHtml(300, 300);
166        }
167        $content .= '</td>';
168
169        $content .= '<td align="center">';
170        if ($src2) {
171            $display = new Display($src2);
172            $display->getPreviewHtml(300, 300);
173        }
174        $content .= '</td>';
175
176        $content .= '</tr>';
177        $content .= '</table>';
178
179        return $this->cleanHTML($content);
180    }
181}
182