xref: /plugin/structpublish/action/banner.php (revision 9413dce69dd07ebac0d2b1c19f70eabc6b84c3d0)
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($REV ?:  $INFO['currentrev']);
49
50        $banner = '<div class="plugin-structpublish-banner ' . $shownRevision->getStatus() . '">';
51
52        // status of the shown revision
53        $banner .= '<span class="icon">' .
54            inlineSVG(__DIR__ . '/../ico/' . $shownRevision->getStatus() . '.svg') .
55            '</span>';
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, $shownRevision->getRev());
61        } else {
62            $banner .= $this->getBannerText('previous_publish', $prevpubRevision, $shownRevision->getRev());
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, $shownRevision->getRev());
72        }
73
74        // action buttons
75        if ($shownRevision->getRev() == $newestRevision->getRev()) {
76            $banner .= $this->actionButtons(
77                $shownRevision->getStatus(),
78                $latestpubRevision ? $this->increaseVersion($latestpubRevision->getVersion()) : '1'
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 $name
90     * @param Revision $rev
91     * @return string
92     */
93    protected function getBannerText($name, $rev, $diff = '')
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_$name");
107        $text = strtr($text, $replace);
108
109        // add link to diff view
110        if ($diff && $diff !== $rev->getRev()) {
111            $link = wl($rev->getId(), ['do' => 'diff', 'rev1' => $rev->getRev(), 'rev2' => $diff]);
112            $icon = inlineSVG(__DIR__ . '/../ico/diff.svg');
113            $text .= ' <a href="' . $link . '" title="' . $this->getLang('diff') . '">' . $icon . '</a>';
114        }
115
116        return "<p class='$name'>$text</p>";
117    }
118
119    /**
120     * Create a HTML link to a specific revision
121     *
122     * @param string $id page id
123     * @param int $rev revision to link to
124     * @param int $text the link text to use
125     * @return string
126     */
127    protected function makeLink($id, $rev, $text)
128    {
129        $url = wl($id, ['rev' => $rev]);
130        return '<a href="' . $url . '">' . hsc($text) . '</a>';
131    }
132
133    /**
134     * Create the form for approval and publishing
135     *
136     * @param string $status current status
137     * @param string $newVersion suggested new Version
138     * @return string
139     */
140    protected function actionButtons($status, $newVersion)
141    {
142        global $ID;
143        if ($status === Constants::STATUS_PUBLISHED) {
144            return '';
145        }
146
147        $form = new dokuwiki\Form\Form();
148
149        if (
150            $status !== Constants::STATUS_APPROVED &&
151            $this->dbHelper->checkAccess($ID, [Constants::ACTION_APPROVE])
152        ) {
153            $form->addButton(
154                'structpublish[' . Constants::ACTION_APPROVE . ']',
155                $this->getLang('action_' . Constants::ACTION_APPROVE)
156            )->attr('type', 'submit');
157        }
158
159        if ($this->dbHelper->checkAccess($ID, [Constants::ACTION_PUBLISH])) {
160            $form->addTextInput('version', $this->getLang('newversion'))->val($newVersion);
161            $form->addButton(
162                'structpublish[' . Constants::ACTION_PUBLISH . ']',
163                $this->getLang('action_' . Constants::ACTION_PUBLISH)
164            )->attr('type', 'submit');
165        }
166
167        return $form->toHTML();
168    }
169
170    /**
171     * Tries to increase a given version
172     *
173     * @param string $version
174     * @return string
175     */
176    protected function increaseVersion($version)
177    {
178        $parts = explode('.', $version);
179        $last = array_pop($parts);
180
181        if (is_numeric($last)) {
182            $last++;
183        }
184        $parts[] = $last;
185
186        return join('.', $parts);
187    }
188}
189