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