xref: /dokuwiki/inc/Ui/MediaDiff.php (revision 2db397b22226ed4e263b2424d6f089cbe6624adf)
163ab9afeSSatoshi Sahara<?php
263ab9afeSSatoshi Sahara
363ab9afeSSatoshi Saharanamespace dokuwiki\Ui;
463ab9afeSSatoshi Sahara
563ab9afeSSatoshi Saharause dokuwiki\ChangeLog\MediaChangeLog;
663ab9afeSSatoshi Saharause dokuwiki\Extension\Event;
763ab9afeSSatoshi Saharause dokuwiki\Form\Form;
863ab9afeSSatoshi Sahara
963ab9afeSSatoshi Sahara/**
1063ab9afeSSatoshi Sahara * DokuWiki MediaDiff Interface
1163ab9afeSSatoshi Sahara *
1263ab9afeSSatoshi Sahara * @package dokuwiki\Ui
1363ab9afeSSatoshi Sahara */
1463ab9afeSSatoshi Saharaclass MediaDiff extends Diff
1563ab9afeSSatoshi Sahara{
1663ab9afeSSatoshi Sahara    /* @var string */
1763ab9afeSSatoshi Sahara    protected $id;
1863ab9afeSSatoshi Sahara
1963ab9afeSSatoshi Sahara    /**
2063ab9afeSSatoshi Sahara     * MediaDiff Ui constructor
2163ab9afeSSatoshi Sahara     *
22edb50e6aSSatoshi Sahara     * @param string $id  media id
2363ab9afeSSatoshi Sahara     */
24edb50e6aSSatoshi Sahara    public function __construct($id)
2563ab9afeSSatoshi Sahara    {
2663ab9afeSSatoshi Sahara        $this->id = $id;
27edb50e6aSSatoshi Sahara
28edb50e6aSSatoshi Sahara        $this->preference['fromAjax'] = false; // see doluwiki\Ajax::callMediadiff()
29edb50e6aSSatoshi Sahara        $this->preference['showIntro'] = false;
30edb50e6aSSatoshi Sahara        $this->preference['difftype'] = null;  // both, opacity or portions. see lib/scripts/media.js
3163ab9afeSSatoshi Sahara    }
3263ab9afeSSatoshi Sahara
3363ab9afeSSatoshi Sahara    /**
3463ab9afeSSatoshi Sahara     * Shows difference between two revisions of media
3563ab9afeSSatoshi Sahara     */
3663ab9afeSSatoshi Sahara    public function show()
3763ab9afeSSatoshi Sahara    {
3863ab9afeSSatoshi Sahara        $ns = getNS($this->id);
3963ab9afeSSatoshi Sahara        $auth = auth_quickaclcheck("$ns:*");
40*2db397b2SSatoshi Sahara        $this->media_diff($this->id, $ns, $auth, $this->preference['fromAjax']);
41*2db397b2SSatoshi Sahara    }
42*2db397b2SSatoshi Sahara
43*2db397b2SSatoshi Sahara    /**
44*2db397b2SSatoshi Sahara     * Shows difference between two revisions of file
45*2db397b2SSatoshi Sahara     *
46*2db397b2SSatoshi Sahara     * @author Kate Arzamastseva <pshns@ukr.net>
47*2db397b2SSatoshi Sahara     *
48*2db397b2SSatoshi Sahara     * @param string $image  image id
49*2db397b2SSatoshi Sahara     * @param string $ns
50*2db397b2SSatoshi Sahara     * @param int $auth permission level
51*2db397b2SSatoshi Sahara     * @param bool $fromajax
52*2db397b2SSatoshi Sahara     * @return false|null|string
53*2db397b2SSatoshi Sahara     */
54*2db397b2SSatoshi Sahara    protected function media_diff($image, $ns, $auth, $fromajax = false)
55*2db397b2SSatoshi Sahara    {
56*2db397b2SSatoshi Sahara        global $conf;
57*2db397b2SSatoshi Sahara        global $INPUT;
58*2db397b2SSatoshi Sahara
59*2db397b2SSatoshi Sahara        if ($auth < AUTH_READ || !$image || !$conf['mediarevisions']) return '';
60*2db397b2SSatoshi Sahara
61*2db397b2SSatoshi Sahara        $rev1 = $INPUT->int('rev');
62*2db397b2SSatoshi Sahara
63*2db397b2SSatoshi Sahara        $rev2 = $INPUT->ref('rev2');
64*2db397b2SSatoshi Sahara        if (is_array($rev2)) {
65*2db397b2SSatoshi Sahara            $rev1 = (int) $rev2[0];
66*2db397b2SSatoshi Sahara            $rev2 = (int) $rev2[1];
67*2db397b2SSatoshi Sahara
68*2db397b2SSatoshi Sahara            if (!$rev1) {
69*2db397b2SSatoshi Sahara                $rev1 = $rev2;
70*2db397b2SSatoshi Sahara                unset($rev2);
71*2db397b2SSatoshi Sahara            }
72*2db397b2SSatoshi Sahara        } else {
73*2db397b2SSatoshi Sahara            $rev2 = $INPUT->int('rev2');
74*2db397b2SSatoshi Sahara        }
75*2db397b2SSatoshi Sahara
76*2db397b2SSatoshi Sahara        if ($rev1 && !file_exists(mediaFN($image, $rev1))) $rev1 = false;
77*2db397b2SSatoshi Sahara        if ($rev2 && !file_exists(mediaFN($image, $rev2))) $rev2 = false;
78*2db397b2SSatoshi Sahara
79*2db397b2SSatoshi Sahara        if ($rev1 && $rev2) {  // two specific revisions wanted
80*2db397b2SSatoshi Sahara            // make sure order is correct (older on the left)
81*2db397b2SSatoshi Sahara            if ($rev1 < $rev2) {
82*2db397b2SSatoshi Sahara                $l_rev = $rev1;
83*2db397b2SSatoshi Sahara                $r_rev = $rev2;
84*2db397b2SSatoshi Sahara            } else {
85*2db397b2SSatoshi Sahara                $l_rev = $rev2;
86*2db397b2SSatoshi Sahara                $r_rev = $rev1;
87*2db397b2SSatoshi Sahara            }
88*2db397b2SSatoshi Sahara        } elseif ($rev1) {     // single revision given, compare to current
89*2db397b2SSatoshi Sahara            $r_rev = '';
90*2db397b2SSatoshi Sahara            $l_rev = $rev1;
91*2db397b2SSatoshi Sahara        } else {               // no revision was given, compare previous to current
92*2db397b2SSatoshi Sahara            $r_rev = '';
93*2db397b2SSatoshi Sahara            $medialog = new MediaChangeLog($image);
94*2db397b2SSatoshi Sahara            $revs = $medialog->getRevisions(0, 1);
95*2db397b2SSatoshi Sahara            if (file_exists(mediaFN($image, $revs[0]))) {
96*2db397b2SSatoshi Sahara                $l_rev = $revs[0];
97*2db397b2SSatoshi Sahara            } else {
98*2db397b2SSatoshi Sahara                $l_rev = '';
99*2db397b2SSatoshi Sahara            }
100*2db397b2SSatoshi Sahara        }
101*2db397b2SSatoshi Sahara
102*2db397b2SSatoshi Sahara        // prepare event data
103*2db397b2SSatoshi Sahara        $data = array();
104*2db397b2SSatoshi Sahara        $data[0] = $image;
105*2db397b2SSatoshi Sahara        $data[1] = $l_rev;
106*2db397b2SSatoshi Sahara        $data[2] = $r_rev;
107*2db397b2SSatoshi Sahara        $data[3] = $ns;
108*2db397b2SSatoshi Sahara        $data[4] = $auth;
109*2db397b2SSatoshi Sahara        $data[5] = $fromajax;
110*2db397b2SSatoshi Sahara
111*2db397b2SSatoshi Sahara        // trigger event
112*2db397b2SSatoshi Sahara        return Event::createAndTrigger('MEDIA_DIFF', $data, [$this,'_media_file_diff'], true);
113*2db397b2SSatoshi Sahara    }
114*2db397b2SSatoshi Sahara
115*2db397b2SSatoshi Sahara    /**
116*2db397b2SSatoshi Sahara     * Callback for media file diff
117*2db397b2SSatoshi Sahara     *
118*2db397b2SSatoshi Sahara     * @param array $data event data
119*2db397b2SSatoshi Sahara     * @return false|null
120*2db397b2SSatoshi Sahara     */
121*2db397b2SSatoshi Sahara    public function _media_file_diff($data)
122*2db397b2SSatoshi Sahara    {
123*2db397b2SSatoshi Sahara        if (is_array($data) && count($data) === 6) {
124*2db397b2SSatoshi Sahara            $this->media_file_diff($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]);
125*2db397b2SSatoshi Sahara        } else {
126*2db397b2SSatoshi Sahara            return false;
127*2db397b2SSatoshi Sahara        }
128*2db397b2SSatoshi Sahara    }
129*2db397b2SSatoshi Sahara
130*2db397b2SSatoshi Sahara    /**
131*2db397b2SSatoshi Sahara     * Shows difference between two revisions of image
132*2db397b2SSatoshi Sahara     *
133*2db397b2SSatoshi Sahara     * @author Kate Arzamastseva <pshns@ukr.net>
134*2db397b2SSatoshi Sahara     *
135*2db397b2SSatoshi Sahara     * @param string $image
136*2db397b2SSatoshi Sahara     * @param string|int $l_rev revision timestamp, or empty string
137*2db397b2SSatoshi Sahara     * @param string|int $r_rev revision timestamp, or empty string
138*2db397b2SSatoshi Sahara     * @param string $ns
139*2db397b2SSatoshi Sahara     * @param int $auth permission level
140*2db397b2SSatoshi Sahara     * @param bool $fromajax
141*2db397b2SSatoshi Sahara     */
142*2db397b2SSatoshi Sahara    protected function media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax)
143*2db397b2SSatoshi Sahara    {
144*2db397b2SSatoshi Sahara        global $lang;
145*2db397b2SSatoshi Sahara        global $INPUT;
146*2db397b2SSatoshi Sahara
147*2db397b2SSatoshi Sahara        $l_meta = new \JpegMeta(mediaFN($image, $l_rev));
148*2db397b2SSatoshi Sahara        $r_meta = new \JpegMeta(mediaFN($image, $r_rev));
149*2db397b2SSatoshi Sahara
150*2db397b2SSatoshi Sahara        $is_img = preg_match('/\.(jpe?g|gif|png)$/', $image);
151*2db397b2SSatoshi Sahara        if ($is_img) {
152*2db397b2SSatoshi Sahara            $l_size = media_image_preview_size($image, $l_rev, $l_meta);
153*2db397b2SSatoshi Sahara            $r_size = media_image_preview_size($image, $r_rev, $r_meta);
154*2db397b2SSatoshi Sahara            $is_img = ($l_size && $r_size && ($l_size[0] >= 30 || $r_size[0] >= 30));
155*2db397b2SSatoshi Sahara
156*2db397b2SSatoshi Sahara            $difftype = $INPUT->str('difftype');
157*2db397b2SSatoshi Sahara
158*2db397b2SSatoshi Sahara            if (!$fromajax) {
159*2db397b2SSatoshi Sahara                $form = new Form([
160*2db397b2SSatoshi Sahara                    'id' => 'mediamanager__form_diffview',
161*2db397b2SSatoshi Sahara                    'action' => media_managerURL([], '&'),
162*2db397b2SSatoshi Sahara                    'method' => 'get',
163*2db397b2SSatoshi Sahara                    'class' => 'diffView',
164*2db397b2SSatoshi Sahara                ]);
165*2db397b2SSatoshi Sahara                $form->addTagOpen('div')->addClass('no');
166*2db397b2SSatoshi Sahara                $form->setHiddenField('sectok', null);
167*2db397b2SSatoshi Sahara                $form->setHiddenField('mediado', 'diff');
168*2db397b2SSatoshi Sahara                $form->setHiddenField('rev2[0]', $l_rev);
169*2db397b2SSatoshi Sahara                $form->setHiddenField('rev2[1]', $r_rev);
170*2db397b2SSatoshi Sahara                $form->addTagClose('div');
171*2db397b2SSatoshi Sahara                echo $form->toHTML();
172*2db397b2SSatoshi Sahara
173*2db397b2SSatoshi Sahara                echo NL.'<div id="mediamanager__diff" >'.NL;
174*2db397b2SSatoshi Sahara            }
175*2db397b2SSatoshi Sahara
176*2db397b2SSatoshi Sahara            if ($difftype == 'opacity' || $difftype == 'portions') {
177*2db397b2SSatoshi Sahara                $this->media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $difftype);
178*2db397b2SSatoshi Sahara                if (!$fromajax) echo '</div>';
179*2db397b2SSatoshi Sahara                return;
180*2db397b2SSatoshi Sahara            }
181*2db397b2SSatoshi Sahara        }
182*2db397b2SSatoshi Sahara
183*2db397b2SSatoshi Sahara        $medialog = new MediaChangeLog($image);
184*2db397b2SSatoshi Sahara
185*2db397b2SSatoshi Sahara        list($l_head, $r_head) = $this->diffHead($medialog, $l_rev, $r_rev);
186*2db397b2SSatoshi Sahara
187*2db397b2SSatoshi Sahara        echo '<div class="table">';
188*2db397b2SSatoshi Sahara        echo '<table>';
189*2db397b2SSatoshi Sahara        echo '<tr>';
190*2db397b2SSatoshi Sahara        echo '<th>'. $l_head .'</th>';
191*2db397b2SSatoshi Sahara        echo '<th>'. $r_head .'</th>';
192*2db397b2SSatoshi Sahara        echo '</tr>'.NL;
193*2db397b2SSatoshi Sahara
194*2db397b2SSatoshi Sahara        echo '<tr class="image">';
195*2db397b2SSatoshi Sahara        echo '<td>';
196*2db397b2SSatoshi Sahara        media_preview($image, $auth, $l_rev, $l_meta);
197*2db397b2SSatoshi Sahara        echo '</td>';
198*2db397b2SSatoshi Sahara
199*2db397b2SSatoshi Sahara        echo '<td>';
200*2db397b2SSatoshi Sahara        media_preview($image, $auth, $r_rev, $r_meta);
201*2db397b2SSatoshi Sahara        echo '</td>';
202*2db397b2SSatoshi Sahara        echo '</tr>'.NL;
203*2db397b2SSatoshi Sahara
204*2db397b2SSatoshi Sahara        echo '<tr class="actions">';
205*2db397b2SSatoshi Sahara        echo '<td>';
206*2db397b2SSatoshi Sahara        media_preview_buttons($image, $auth, $l_rev);
207*2db397b2SSatoshi Sahara        echo '</td>';
208*2db397b2SSatoshi Sahara
209*2db397b2SSatoshi Sahara        echo '<td>';
210*2db397b2SSatoshi Sahara        media_preview_buttons($image, $auth, $r_rev);
211*2db397b2SSatoshi Sahara        echo '</td>';
212*2db397b2SSatoshi Sahara        echo '</tr>'.NL;
213*2db397b2SSatoshi Sahara
214*2db397b2SSatoshi Sahara        $l_tags = media_file_tags($l_meta);
215*2db397b2SSatoshi Sahara        $r_tags = media_file_tags($r_meta);
216*2db397b2SSatoshi Sahara        // FIXME r_tags-only stuff
217*2db397b2SSatoshi Sahara        foreach ($l_tags as $key => $l_tag) {
218*2db397b2SSatoshi Sahara            if ($l_tag['value'] != $r_tags[$key]['value']) {
219*2db397b2SSatoshi Sahara                $r_tags[$key]['highlighted'] = true;
220*2db397b2SSatoshi Sahara                $l_tags[$key]['highlighted'] = true;
221*2db397b2SSatoshi Sahara            } elseif (!$l_tag['value'] || !$r_tags[$key]['value']) {
222*2db397b2SSatoshi Sahara                unset($r_tags[$key]);
223*2db397b2SSatoshi Sahara                unset($l_tags[$key]);
224*2db397b2SSatoshi Sahara            }
225*2db397b2SSatoshi Sahara        }
226*2db397b2SSatoshi Sahara
227*2db397b2SSatoshi Sahara        echo '<tr>';
228*2db397b2SSatoshi Sahara        foreach (array($l_tags, $r_tags) as $tags) {
229*2db397b2SSatoshi Sahara            echo '<td>'.NL;
230*2db397b2SSatoshi Sahara
231*2db397b2SSatoshi Sahara            echo '<dl class="img_tags">';
232*2db397b2SSatoshi Sahara            foreach ($tags as $tag) {
233*2db397b2SSatoshi Sahara                $value = cleanText($tag['value']);
234*2db397b2SSatoshi Sahara                if (!$value) $value = '-';
235*2db397b2SSatoshi Sahara                echo '<dt>'.$lang[$tag['tag'][1]].'</dt>';
236*2db397b2SSatoshi Sahara                echo '<dd>';
237*2db397b2SSatoshi Sahara                if ($tag['highlighted']) echo '<strong>';
238*2db397b2SSatoshi Sahara                if ($tag['tag'][2] == 'date') {
239*2db397b2SSatoshi Sahara                    echo dformat($value);
240*2db397b2SSatoshi Sahara                } else {
241*2db397b2SSatoshi Sahara                    echo hsc($value);
242*2db397b2SSatoshi Sahara                }
243*2db397b2SSatoshi Sahara                if ($tag['highlighted']) echo '</strong>';
244*2db397b2SSatoshi Sahara                echo '</dd>';
245*2db397b2SSatoshi Sahara            }
246*2db397b2SSatoshi Sahara            echo '</dl>'.NL;
247*2db397b2SSatoshi Sahara
248*2db397b2SSatoshi Sahara            echo '</td>';
249*2db397b2SSatoshi Sahara        }
250*2db397b2SSatoshi Sahara        echo '</tr>'.NL;
251*2db397b2SSatoshi Sahara
252*2db397b2SSatoshi Sahara        echo '</table>'.NL;
253*2db397b2SSatoshi Sahara        echo '</div>'.NL;
254*2db397b2SSatoshi Sahara
255*2db397b2SSatoshi Sahara        if ($is_img && !$fromajax) echo '</div>';
256*2db397b2SSatoshi Sahara    }
257*2db397b2SSatoshi Sahara
258*2db397b2SSatoshi Sahara    /**
259*2db397b2SSatoshi Sahara     * Prints two images side by side
260*2db397b2SSatoshi Sahara     * and slider
261*2db397b2SSatoshi Sahara     *
262*2db397b2SSatoshi Sahara     * @author Kate Arzamastseva <pshns@ukr.net>
263*2db397b2SSatoshi Sahara     *
264*2db397b2SSatoshi Sahara     * @param string $image   image id
265*2db397b2SSatoshi Sahara     * @param int    $l_rev   revision timestamp, or empty string
266*2db397b2SSatoshi Sahara     * @param int    $r_rev   revision timestamp, or empty string
267*2db397b2SSatoshi Sahara     * @param array  $l_size  array with width and height
268*2db397b2SSatoshi Sahara     * @param array  $r_size  array with width and height
269*2db397b2SSatoshi Sahara     * @param string $type
270*2db397b2SSatoshi Sahara     */
271*2db397b2SSatoshi Sahara    protected function media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type)
272*2db397b2SSatoshi Sahara    {
273*2db397b2SSatoshi Sahara        if ($l_size != $r_size) {
274*2db397b2SSatoshi Sahara            if ($r_size[0] > $l_size[0]) {
275*2db397b2SSatoshi Sahara                $l_size = $r_size;
276*2db397b2SSatoshi Sahara            }
277*2db397b2SSatoshi Sahara        }
278*2db397b2SSatoshi Sahara
279*2db397b2SSatoshi Sahara        $l_more = array('rev' => $l_rev, 'h' => $l_size[1], 'w' => $l_size[0]);
280*2db397b2SSatoshi Sahara        $r_more = array('rev' => $r_rev, 'h' => $l_size[1], 'w' => $l_size[0]);
281*2db397b2SSatoshi Sahara
282*2db397b2SSatoshi Sahara        $l_src = ml($image, $l_more);
283*2db397b2SSatoshi Sahara        $r_src = ml($image, $r_more);
284*2db397b2SSatoshi Sahara
285*2db397b2SSatoshi Sahara        // slider
286*2db397b2SSatoshi Sahara        echo '<div class="slider" style="max-width: '.($l_size[0]-20).'px;" ></div>'.NL;
287*2db397b2SSatoshi Sahara
288*2db397b2SSatoshi Sahara        // two images in divs
289*2db397b2SSatoshi Sahara        echo '<div class="imageDiff '.$type.'">'.NL;
290*2db397b2SSatoshi Sahara        echo '<div class="image1" style="max-width: '.$l_size[0].'px;">';
291*2db397b2SSatoshi Sahara        echo '<img src="'.$l_src.'" alt="" />';
292*2db397b2SSatoshi Sahara        echo '</div>'.NL;
293*2db397b2SSatoshi Sahara        echo '<div class="image2" style="max-width: '.$l_size[0].'px;">';
294*2db397b2SSatoshi Sahara        echo '<img src="'.$r_src.'" alt="" />';
295*2db397b2SSatoshi Sahara        echo '</div>'.NL;
296*2db397b2SSatoshi Sahara        echo '</div>'.NL;
29763ab9afeSSatoshi Sahara    }
29863ab9afeSSatoshi Sahara
29963ab9afeSSatoshi Sahara}
300