xref: /plugin/structpublish/action/banner.php (revision 5c2215e890cc9516db9bc28cfa976283c0e72b1e)
1<?php
2
3use dokuwiki\plugin\structpublish\meta\Constants;
4use dokuwiki\plugin\structpublish\meta\Revision;
5
6/**
7 * Action component responsible for the publish banner
8 * attached to struct data of a page
9 */
10class action_plugin_structpublish_banner extends DokuWiki_Action_Plugin
11{
12    /** @var \helper_plugin_structpublish_db */
13    protected $dbHelper;
14
15    /**
16     * @inheritDoc
17     */
18    public function register(Doku_Event_Handler $controller)
19    {
20        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'renderBanner');
21    }
22
23    /**
24     * Add banner to pages under structpublish control
25     */
26    public function renderBanner(Doku_Event $event)
27    {
28        global $ID;
29        global $INFO;
30        global $REV;
31
32        if ($event->data !== 'show') {
33            return;
34        }
35
36        $this->dbHelper = plugin_load('helper', 'structpublish_db');
37
38        if (!$this->dbHelper->isPublishable()) {
39            return;
40        }
41
42        // get the possible revisions needed in the banner
43        $newestRevision = new Revision($this->dbHelper->getDB(), $ID, $INFO['currentrev']);
44        if ($REV) {
45            $shownRevision = new Revision($this->dbHelper->getDB(), $ID, $REV);
46        } else {
47            $shownRevision = $newestRevision;
48        }
49        $latestpubRevision = $newestRevision->getLatestPublishedRevision();
50        $prevpubRevision = $shownRevision->getLatestPublishedRevision();
51
52        $banner = '<div class="plugin-structpublish-banner ' . $shownRevision->getStatus() . '">';
53
54        // status of the shown revision
55        $banner .= inlineSVG(__DIR__ . '/../ico/' . $shownRevision->getStatus() . '.svg');
56        $banner .= $this->getBannerText('status_' . $shownRevision->getStatus(), $shownRevision);
57
58        // link to previous or newest published version
59        if ($latestpubRevision !== null && $shownRevision->getRev() < $latestpubRevision->getRev()) {
60            $banner .= $this->getBannerText('latest_publish', $latestpubRevision);
61        } else {
62            $banner .= $this->getBannerText('previous_publish', $prevpubRevision);
63        }
64
65        // link to newest draft, if exists, is not shown already and user has a role
66        if (
67            $newestRevision->getRev() != $shownRevision->getRev() &&
68            $newestRevision->getStatus() != Constants::STATUS_PUBLISHED &&
69            $this->dbHelper->checkAccess($ID)
70        ) {
71            $banner .= $this->getBannerText('latest_draft', $newestRevision);
72        }
73
74        // action buttons
75        if ($shownRevision->getRev() == $newestRevision->getRev()) {
76            $banner .= $this->actionButtons(
77                $shownRevision->getStatus(),
78                $latestpubRevision ? $latestpubRevision->getVersion() : ''
79            );
80        }
81
82        $banner .= '</div>';
83        echo $banner;
84    }
85
86    /**
87     * Fills place holder texts with data from the given Revision
88     *
89     * @param string $text
90     * @param Revision $rev
91     * @return string
92     */
93    protected function getBannerText($text, $rev)
94    {
95        if ($rev === null) {
96            return '';
97        }
98
99        $replace = [
100            '{user}' => userlink($rev->getUser()),
101            '{revision}' => $this->makeLink($rev->getId(), $rev->getRev(), dformat($rev->getRev())),
102            '{datetime}' => $this->makeLink($rev->getId(), $rev->getRev(), dformat($rev->getTimestamp())),
103            '{version}' => hsc($rev->getVersion()),
104        ];
105
106        $text = $this->getLang("banner_$text");
107        $text = strtr($text, $replace);
108
109        return "<p>$text</p>";
110    }
111
112    /**
113     * Create a HTML link to a specific revision
114     *
115     * @param string $id page id
116     * @param int $rev revision to link to
117     * @param int $text the link text to use
118     * @return string
119     */
120    protected function makeLink($id, $rev, $text)
121    {
122        $url = wl($id, ['rev' => $rev]);
123        return '<a href="' . $url . '">' . hsc($text) . '</a>';
124    }
125
126    /**
127     * Create the form for approval and publishing
128     *
129     * @param string $status current status
130     * @param string $newVersion suggested new Version
131     * @return string
132     */
133    protected function actionButtons($status, $newVersion)
134    {
135        global $ID;
136        if ($status === Constants::STATUS_PUBLISHED) {
137            return '';
138        }
139
140        $form = new dokuwiki\Form\Form();
141
142        if (
143            $status !== Constants::STATUS_APPROVED &&
144            $this->dbHelper->checkAccess($ID, [Constants::ACTION_APPROVE])
145        ) {
146            $form->addButton(
147                'structpublish[approve]',
148                $this->getLang('action_' . Constants::ACTION_APPROVE)
149            )->attr('type', 'submit');
150        }
151
152        if ($this->dbHelper->checkAccess($ID, [Constants::ACTION_PUBLISH])) {
153            $form->addTextInput('version', $this->getLang('newversion'))->val($newVersion);
154            $form->addButton(
155                'structpublish[publish]',
156                $this->getLang('action_' . Constants::ACTION_PUBLISH)
157            )->attr('type', 'submit');
158        }
159
160        return $form->toHTML();
161    }
162}
163