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