1<?php
2
3use dokuwiki\plugin\structpublish\meta\Constants;
4use dokuwiki\plugin\structpublish\meta\Revision;
5
6class action_plugin_structpublish_show extends DokuWiki_Action_Plugin
7{
8    /** @var int */
9    protected static $latestPublishedRev;
10
11    /** @inheritDoc */
12    public function register(Doku_Event_Handler $controller)
13    {
14        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleShow');
15        $controller->register_hook('HTML_SHOWREV_OUTPUT', 'BEFORE', $this, 'handleShowrev');
16    }
17
18    /**
19     * Decide which revision to show based on role assignments
20     *
21     * @param Doku_Event $event
22     * @return void
23     */
24    public function handleShow(Doku_Event $event)
25    {
26        if ($event->data != 'show') {
27            return;
28        }
29
30        global $ID;
31        global $REV;
32        global $INFO;
33
34        /** @var helper_plugin_structpublish_db $dbHelper */
35        $dbHelper = plugin_load('helper', 'structpublish_db');
36
37        if (
38            !$dbHelper->isPublishable() ||
39            (auth_isadmin() && !$this->getConf('restrict_admin'))
40        ) {
41            return;
42        }
43
44        $currentRevision = new Revision($ID, $REV ?: $INFO['currentrev']);
45        $isPublished = $currentRevision->getStatus() === Constants::STATUS_PUBLISHED;
46
47        if (!$dbHelper->isPublisher($ID)) {
48            $latestPublished = $currentRevision->getLatestPublishedRevision();
49            // there is no published revision, show nothing
50            if (!$isPublished && is_null($latestPublished)) {
51                $event->data = 'denied';
52                // FIXME we could add our own action to display a custom message instead of standard denied action
53                return;
54            }
55
56            self::$latestPublishedRev = $latestPublished->getRev();
57
58            // show either the explicitly requested or the latest published revision
59            if (!$isPublished) {
60                $REV = self::$latestPublishedRev;
61                $INFO['rev'] = self::$latestPublishedRev;
62            }
63        }
64    }
65
66    /**
67     * Suppress message about viewing an old revision if it is the latest one
68     * that the current user is allowed to see.
69     *
70     * @param Doku_Event $event
71     * @return void
72     */
73    public function handleShowrev(Doku_Event $event)
74    {
75        /** @var helper_plugin_structpublish_db $dbHelper */
76        $dbHelper = plugin_load('helper', 'structpublish_db');
77
78        if (
79            !$dbHelper->isPublishable() ||
80            (auth_isadmin() && !$this->getConf('restrict_admin'))
81        ) {
82            return;
83        }
84
85        global $INFO;
86
87        if (self::$latestPublishedRev && self::$latestPublishedRev == $INFO['rev']) {
88            $event->preventDefault();
89        }
90    }
91}
92