xref: /dokuwiki/inc/Ui/Recent.php (revision 26dfc2323f8f70cb69aac4c8c51bf7997809f2ca)
13d7df1dcSSatoshi Sahara<?php
23d7df1dcSSatoshi Sahara
33d7df1dcSSatoshi Saharanamespace dokuwiki\Ui;
43d7df1dcSSatoshi Sahara
53d7df1dcSSatoshi Saharause dokuwiki\ChangeLog\MediaChangeLog;
6e2d055f5SAndreas Gohruse dokuwiki\ChangeLog\PageChangeLog;
7bf3fa5e9SSatoshi Saharause dokuwiki\ChangeLog\RevisionInfo;
83d7df1dcSSatoshi Saharause dokuwiki\Form\Form;
93d7df1dcSSatoshi Sahara
103d7df1dcSSatoshi Sahara/**
119e316641SSatoshi Sahara * DokuWiki Recent Interface
123d7df1dcSSatoshi Sahara *
133d7df1dcSSatoshi Sahara * @package dokuwiki\Ui
143d7df1dcSSatoshi Sahara */
153d7df1dcSSatoshi Saharaclass Recent extends Ui
163d7df1dcSSatoshi Sahara{
179e316641SSatoshi Sahara    protected $first;
189e316641SSatoshi Sahara    protected $show_changes;
199e316641SSatoshi Sahara
209e316641SSatoshi Sahara    /**
219e316641SSatoshi Sahara     * Recent Ui constructor
229e316641SSatoshi Sahara     *
239e316641SSatoshi Sahara     * @param int $first skip the first n changelog lines
24eeda7adaSGerrit Uitslag     * @param string $show_changes type of changes to show; 'pages', 'mediafiles', or 'both'
259e316641SSatoshi Sahara     */
269e316641SSatoshi Sahara    public function __construct($first = 0, $show_changes = 'both')
279e316641SSatoshi Sahara    {
289e316641SSatoshi Sahara        $this->first = $first;
299e316641SSatoshi Sahara        $this->show_changes = $show_changes;
309e316641SSatoshi Sahara    }
319e316641SSatoshi Sahara
323d7df1dcSSatoshi Sahara    /**
333d7df1dcSSatoshi Sahara     * Display recent changes
343d7df1dcSSatoshi Sahara     *
35e2d055f5SAndreas Gohr     * @return void
363d7df1dcSSatoshi Sahara     * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
373d7df1dcSSatoshi Sahara     * @author Ben Coburn <btcoburn@silicodon.net>
383d7df1dcSSatoshi Sahara     * @author Kate Arzamastseva <pshns@ukr.net>
3921b96b63SSatoshi Sahara     * @author Satoshi Sahara <sahara.satoshi@gmail.com>
403d7df1dcSSatoshi Sahara     *
41e2d055f5SAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
423d7df1dcSSatoshi Sahara     */
439e316641SSatoshi Sahara    public function show()
443d7df1dcSSatoshi Sahara    {
45bde2a644SSatoshi Sahara        global $conf, $lang;
463d7df1dcSSatoshi Sahara        global $ID;
473d7df1dcSSatoshi Sahara
48eeda7adaSGerrit Uitslag        // get recent items, and set correct pagination parameters (first, hasNext)
499e316641SSatoshi Sahara        $first = $this->first;
50e6adf5b7SSatoshi Sahara        $hasNext = false;
5121b96b63SSatoshi Sahara        $recents = $this->getRecents($first, $hasNext);
523d7df1dcSSatoshi Sahara
533d7df1dcSSatoshi Sahara        // print intro
54*26dfc232SAndreas Gohr        echo p_locale_xhtml('recent');
553d7df1dcSSatoshi Sahara
563d7df1dcSSatoshi Sahara        if (getNS($ID) != '') {
57*26dfc232SAndreas Gohr            echo '<div class="level1"><p>'
583d7df1dcSSatoshi Sahara                . sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent'))
593d7df1dcSSatoshi Sahara                . '</p></div>';
603d7df1dcSSatoshi Sahara        }
613d7df1dcSSatoshi Sahara
623d7df1dcSSatoshi Sahara        // create the form
6321b96b63SSatoshi Sahara        $form = new Form(['id' => 'dw__recent', 'method' => 'GET', 'action' => wl($ID), 'class' => 'changes']);
643d7df1dcSSatoshi Sahara        $form->addTagOpen('div')->addClass('no');
653d7df1dcSSatoshi Sahara        $form->setHiddenField('sectok', null);
663d7df1dcSSatoshi Sahara        $form->setHiddenField('do', 'recent');
673d7df1dcSSatoshi Sahara        $form->setHiddenField('id', $ID);
683d7df1dcSSatoshi Sahara
693d7df1dcSSatoshi Sahara        // show dropdown selector, whether include not only recent pages but also recent media files?
703d7df1dcSSatoshi Sahara        if ($conf['mediarevisions']) {
7121b96b63SSatoshi Sahara            $this->addRecentItemSelector($form);
7221b96b63SSatoshi Sahara        }
7321b96b63SSatoshi Sahara
7421b96b63SSatoshi Sahara        // start listing of recent items
7521b96b63SSatoshi Sahara        $form->addTagOpen('ul');
7621b96b63SSatoshi Sahara        foreach ($recents as $recent) {
770c92baf0SSatoshi Sahara            // check possible external edition for current page or media
780c92baf0SSatoshi Sahara            $this->checkCurrentRevision($recent);
790c92baf0SSatoshi Sahara
80bf3fa5e9SSatoshi Sahara            $RevInfo = new RevisionInfo($recent);
81b428a50aSSatoshi Sahara            $RevInfo->isCurrent(true);
82b428a50aSSatoshi Sahara            $class = ($RevInfo->val('type') === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor' : '';
8321b96b63SSatoshi Sahara            $form->addTagOpen('li')->addClass($class);
8421b96b63SSatoshi Sahara            $form->addTagOpen('div')->addClass('li');
8521b96b63SSatoshi Sahara            $html = implode(' ', [
86b428a50aSSatoshi Sahara                $RevInfo->showFileIcon(),          // filetype icon
87b428a50aSSatoshi Sahara                $RevInfo->showEditDate(),          // edit date and time
88b428a50aSSatoshi Sahara                $RevInfo->showIconCompareWithPrevious(),    // link to diff view icon
89b428a50aSSatoshi Sahara                $RevInfo->showIconRevisions(),     // link to revisions icon
90b428a50aSSatoshi Sahara                $RevInfo->showFileName(),          // name of page or media
91b428a50aSSatoshi Sahara                $RevInfo->showEditSummary(),       // edit summary
92b428a50aSSatoshi Sahara                $RevInfo->showEditor(),            // editor info
93b428a50aSSatoshi Sahara                $RevInfo->showSizechange(),        // size change indicator
9421b96b63SSatoshi Sahara            ]);
9521b96b63SSatoshi Sahara            $form->addHTML($html);
9621b96b63SSatoshi Sahara            $form->addTagClose('div');
9721b96b63SSatoshi Sahara            $form->addTagClose('li');
9821b96b63SSatoshi Sahara        }
9921b96b63SSatoshi Sahara        $form->addTagClose('ul');
10021b96b63SSatoshi Sahara
10121b96b63SSatoshi Sahara        $form->addTagClose('div'); // close div class=no
10221b96b63SSatoshi Sahara
103eeda7adaSGerrit Uitslag        // provide navigation for paginated recent list (of pages and/or media files)
10421b96b63SSatoshi Sahara        $form->addHTML($this->htmlNavigation($first, $hasNext));
10521b96b63SSatoshi Sahara
106*26dfc232SAndreas Gohr        echo $form->toHTML('Recent');
10721b96b63SSatoshi Sahara    }
10821b96b63SSatoshi Sahara
10921b96b63SSatoshi Sahara    /**
110eeda7adaSGerrit Uitslag     * Get recent items, and set correct pagination parameters (first, hasNext)
11121b96b63SSatoshi Sahara     *
11221b96b63SSatoshi Sahara     * @param int $first
11321b96b63SSatoshi Sahara     * @param bool $hasNext
114eeda7adaSGerrit Uitslag     * @return array  recent items to be shown in a paginated list
11521b96b63SSatoshi Sahara     *
11621b96b63SSatoshi Sahara     * @see also dokuwiki\Changelog::getRevisionInfo()
11721b96b63SSatoshi Sahara     */
11821b96b63SSatoshi Sahara    protected function getRecents(&$first, &$hasNext)
11921b96b63SSatoshi Sahara    {
12021b96b63SSatoshi Sahara        global $ID, $conf;
12121b96b63SSatoshi Sahara
12221b96b63SSatoshi Sahara        $flags = 0;
12321b96b63SSatoshi Sahara        if ($this->show_changes == 'mediafiles' && $conf['mediarevisions']) {
12421b96b63SSatoshi Sahara            $flags = RECENTS_MEDIA_CHANGES;
12521b96b63SSatoshi Sahara        } elseif ($this->show_changes == 'pages') {
12621b96b63SSatoshi Sahara            $flags = 0;
12721b96b63SSatoshi Sahara        } elseif ($conf['mediarevisions']) {
12821b96b63SSatoshi Sahara            $flags = RECENTS_MEDIA_PAGES_MIXED;
12921b96b63SSatoshi Sahara        }
13021b96b63SSatoshi Sahara
13121b96b63SSatoshi Sahara        /* we need to get one additionally log entry to be able to
13221b96b63SSatoshi Sahara         * decide if this is the last page or is there another one.
13321b96b63SSatoshi Sahara         * This is the cheapest solution to get this information.
13421b96b63SSatoshi Sahara         */
13521b96b63SSatoshi Sahara        $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
13621b96b63SSatoshi Sahara        if (count($recents) == 0 && $first != 0) {
13721b96b63SSatoshi Sahara            $first = 0;
13821b96b63SSatoshi Sahara            $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
13921b96b63SSatoshi Sahara        }
14021b96b63SSatoshi Sahara
14121b96b63SSatoshi Sahara        $hasNext = false;
14221b96b63SSatoshi Sahara        if (count($recents) > $conf['recent']) {
14321b96b63SSatoshi Sahara            $hasNext = true;
14421b96b63SSatoshi Sahara            array_pop($recents); // remove extra log entry
14521b96b63SSatoshi Sahara        }
14621b96b63SSatoshi Sahara        return $recents;
14721b96b63SSatoshi Sahara    }
14821b96b63SSatoshi Sahara
14921b96b63SSatoshi Sahara    /**
1500c92baf0SSatoshi Sahara     * Check possible external deletion for current page or media
1510c92baf0SSatoshi Sahara     *
1520c92baf0SSatoshi Sahara     * To keep sort order in the recent list, we ignore externally modification.
1530c92baf0SSatoshi Sahara     * It is not possible to know when external deletion had happened,
1540c92baf0SSatoshi Sahara     * $info['date'] is to be incremented 1 second when such deletion detected.
1550c92baf0SSatoshi Sahara     */
1560c92baf0SSatoshi Sahara    protected function checkCurrentRevision(array &$info)
1570c92baf0SSatoshi Sahara    {
1583f168574STherealperO        $itemType = $info['media'] ? 'media' : 'page';
1590c92baf0SSatoshi Sahara        if ($itemType == 'page') {
1600c92baf0SSatoshi Sahara            $changelog = new PageChangelog($info['id']);
1610c92baf0SSatoshi Sahara        } else {
1620c92baf0SSatoshi Sahara            $changelog = new MediaChangelog($info['id']);
1630c92baf0SSatoshi Sahara        }
164df7627d6SSatoshi Sahara        if (!$changelog->isCurrentRevision($info['date'])) {
1650c92baf0SSatoshi Sahara            $currentRevInfo = $changelog->getCurrentRevisionInfo();
166b622cd79SGerrit Uitslag            if ($currentRevInfo['type'] == DOKU_CHANGE_TYPE_DELETE) {
167b622cd79SGerrit Uitslag                // the page or media file was externally deleted, updated info because the link is already red
168b622cd79SGerrit Uitslag                // externally created and edited not updated because sorting by date is not worth so much changes
1690c92baf0SSatoshi Sahara                $info = array_merge($info, $currentRevInfo);
1700c92baf0SSatoshi Sahara            }
171b622cd79SGerrit Uitslag        }
1720c92baf0SSatoshi Sahara        unset($changelog);
1730c92baf0SSatoshi Sahara    }
1740c92baf0SSatoshi Sahara
1750c92baf0SSatoshi Sahara    /**
176eeda7adaSGerrit Uitslag     * Navigation buttons for Pagination (prev/next)
17721b96b63SSatoshi Sahara     *
17821b96b63SSatoshi Sahara     * @param int $first
17921b96b63SSatoshi Sahara     * @param bool $hasNext
18079a2d784SGerrit Uitslag     * @return string html
18121b96b63SSatoshi Sahara     */
18221b96b63SSatoshi Sahara    protected function htmlNavigation($first, $hasNext)
18321b96b63SSatoshi Sahara    {
18421b96b63SSatoshi Sahara        global $conf, $lang;
18521b96b63SSatoshi Sahara
18621b96b63SSatoshi Sahara        $last = $first + $conf['recent'];
18721b96b63SSatoshi Sahara        $html = '<div class="pagenav">';
18821b96b63SSatoshi Sahara        if ($first > 0) {
18921b96b63SSatoshi Sahara            $first = max($first - $conf['recent'], 0);
19021b96b63SSatoshi Sahara            $html .= '<div class="pagenav-prev">';
19121b96b63SSatoshi Sahara            $html .= '<button type="submit" name="first[' . $first . ']" accesskey="n"'
19221b96b63SSatoshi Sahara                . ' title="' . $lang['btn_newer'] . ' [N]" class="button show">'
19321b96b63SSatoshi Sahara                . $lang['btn_newer']
19421b96b63SSatoshi Sahara                . '</button>';
19521b96b63SSatoshi Sahara            $html .= '</div>';
19621b96b63SSatoshi Sahara        }
19721b96b63SSatoshi Sahara        if ($hasNext) {
19821b96b63SSatoshi Sahara            $html .= '<div class="pagenav-next">';
19921b96b63SSatoshi Sahara            $html .= '<button type="submit" name="first[' . $last . ']" accesskey="p"'
20021b96b63SSatoshi Sahara                . ' title="' . $lang['btn_older'] . ' [P]" class="button show">'
20121b96b63SSatoshi Sahara                . $lang['btn_older']
20221b96b63SSatoshi Sahara                . '</button>';
20321b96b63SSatoshi Sahara            $html .= '</div>';
20421b96b63SSatoshi Sahara        }
20521b96b63SSatoshi Sahara        $html .= '</div>';
20621b96b63SSatoshi Sahara        return $html;
20721b96b63SSatoshi Sahara    }
20821b96b63SSatoshi Sahara
20921b96b63SSatoshi Sahara    /**
21021b96b63SSatoshi Sahara     * Add dropdown selector of item types to the form instance
21121b96b63SSatoshi Sahara     *
21221b96b63SSatoshi Sahara     * @param Form $form
21321b96b63SSatoshi Sahara     * @return void
21421b96b63SSatoshi Sahara     */
21521b96b63SSatoshi Sahara    protected function addRecentItemSelector(Form $form)
21621b96b63SSatoshi Sahara    {
21721b96b63SSatoshi Sahara        global $lang;
21821b96b63SSatoshi Sahara
2193d7df1dcSSatoshi Sahara        $form->addTagOpen('div')->addClass('changeType');
220e2d055f5SAndreas Gohr        $options = [
2213d7df1dcSSatoshi Sahara            'pages' => $lang['pages_changes'],
2223d7df1dcSSatoshi Sahara            'mediafiles' => $lang['media_changes'],
223e2d055f5SAndreas Gohr            'both' => $lang['both_changes']
224e2d055f5SAndreas Gohr        ];
2253d7df1dcSSatoshi Sahara        $form->addDropdown('show_changes', $options, $lang['changes_type'])
22621b96b63SSatoshi Sahara            ->val($this->show_changes)->addClass('quickselect');
2273d7df1dcSSatoshi Sahara        $form->addButton('do[recent]', $lang['btn_apply'])->attr('type', 'submit');
2283d7df1dcSSatoshi Sahara        $form->addTagClose('div');
2293d7df1dcSSatoshi Sahara    }
2303d7df1dcSSatoshi Sahara}
231