xref: /plugin/structpublish/action/banner.php (revision b476f81d46066c318f7a5153cbfadaf4262a2998)
187106851SAnna Dabrowska<?php
287106851SAnna Dabrowska
3e31c94d7SAndreas Gohruse dokuwiki\plugin\structpublish\meta\Constants;
4c2f8a3c4SAnna Dabrowskause dokuwiki\plugin\structpublish\meta\Revision;
5c2f8a3c4SAnna Dabrowska
687106851SAnna Dabrowska/**
787106851SAnna Dabrowska * Action component responsible for the publish banner
887106851SAnna Dabrowska * attached to struct data of a page
987106851SAnna Dabrowska */
1087106851SAnna Dabrowskaclass action_plugin_structpublish_banner extends DokuWiki_Action_Plugin
1187106851SAnna Dabrowska{
12e394901aSAnna Dabrowska    /** @var \helper_plugin_structpublish_db */
13e394901aSAnna Dabrowska    protected $dbHelper;
14c2f8a3c4SAnna Dabrowska
156c35120aSAnna Dabrowska    /** @var bool */
166c35120aSAnna Dabrowska    protected $compactView;
176c35120aSAnna Dabrowska
188b0ba635SAndreas Gohr    /** @inheritDoc */
1987106851SAnna Dabrowska    public function register(Doku_Event_Handler $controller)
2087106851SAnna Dabrowska    {
21e394901aSAnna Dabrowska        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'renderBanner');
2287106851SAnna Dabrowska    }
2387106851SAnna Dabrowska
2487106851SAnna Dabrowska    /**
25e394901aSAnna Dabrowska     * Add banner to pages under structpublish control
2687106851SAnna Dabrowska     */
2787106851SAnna Dabrowska    public function renderBanner(Doku_Event $event)
2887106851SAnna Dabrowska    {
29c2f8a3c4SAnna Dabrowska        global $ID;
308d2065f7SAnna Dabrowska        global $INFO;
3140f4519bSAnna Dabrowska        global $REV;
3287106851SAnna Dabrowska
335c2215e8SAndreas Gohr        if ($event->data !== 'show') {
345c2215e8SAndreas Gohr            return;
355c2215e8SAndreas Gohr        }
363449f9ceSAnna Dabrowska
378d2065f7SAnna Dabrowska        $this->dbHelper = plugin_load('helper', 'structpublish_db');
38939e6e3cSAnna Dabrowska
395c2215e8SAndreas Gohr        if (!$this->dbHelper->isPublishable()) {
405c2215e8SAndreas Gohr            return;
415c2215e8SAndreas Gohr        }
42939e6e3cSAnna Dabrowska
436c35120aSAnna Dabrowska        $this->compactView = (bool)$this->getConf('compact_view');
446c35120aSAnna Dabrowska
455c2215e8SAndreas Gohr        // get the possible revisions needed in the banner
46*b476f81dSAnna Dabrowska        $newestRevision = new Revision($ID, $INFO['currentrev']);
475c2215e8SAndreas Gohr        if ($REV) {
48*b476f81dSAnna Dabrowska            $shownRevision = new Revision($ID, $REV);
495c2215e8SAndreas Gohr        } else {
505c2215e8SAndreas Gohr            $shownRevision = $newestRevision;
515c2215e8SAndreas Gohr        }
525c2215e8SAndreas Gohr        $latestpubRevision = $newestRevision->getLatestPublishedRevision();
53fd06d74cSAnna Dabrowska        $prevpubRevision = $shownRevision->getLatestPublishedRevision($REV ?:  $INFO['currentrev']);
54c2f8a3c4SAnna Dabrowska
556c35120aSAnna Dabrowska        $compactClass = $this->compactView ? ' compact' : '';
566c35120aSAnna Dabrowska        $banner = '<div class="plugin-structpublish-banner ' . $shownRevision->getStatus() . $compactClass . '">';
575c2215e8SAndreas Gohr
585c2215e8SAndreas Gohr        // status of the shown revision
59dd0cceddSAndreas Gohr        $banner .= '<span class="icon">' .
60dd0cceddSAndreas Gohr            inlineSVG(__DIR__ . '/../ico/' . $shownRevision->getStatus() . '.svg') .
61dd0cceddSAndreas Gohr            '</span>';
625c2215e8SAndreas Gohr        $banner .= $this->getBannerText('status_' . $shownRevision->getStatus(), $shownRevision);
635c2215e8SAndreas Gohr
645c2215e8SAndreas Gohr        // link to previous or newest published version
655c2215e8SAndreas Gohr        if ($latestpubRevision !== null && $shownRevision->getRev() < $latestpubRevision->getRev()) {
66dd0cceddSAndreas Gohr            $banner .= $this->getBannerText('latest_publish', $latestpubRevision, $shownRevision->getRev());
675c2215e8SAndreas Gohr        } else {
68dd0cceddSAndreas Gohr            $banner .= $this->getBannerText('previous_publish', $prevpubRevision, $shownRevision->getRev());
695c2215e8SAndreas Gohr        }
705c2215e8SAndreas Gohr
715c2215e8SAndreas Gohr        // link to newest draft, if exists, is not shown already and user has a role
725c2215e8SAndreas Gohr        if (
735c2215e8SAndreas Gohr            $newestRevision->getRev() != $shownRevision->getRev() &&
745c2215e8SAndreas Gohr            $newestRevision->getStatus() != Constants::STATUS_PUBLISHED &&
755c2215e8SAndreas Gohr            $this->dbHelper->checkAccess($ID)
765c2215e8SAndreas Gohr        ) {
77dd0cceddSAndreas Gohr            $banner .= $this->getBannerText('latest_draft', $newestRevision, $shownRevision->getRev());
785c2215e8SAndreas Gohr        }
795c2215e8SAndreas Gohr
805c2215e8SAndreas Gohr        // action buttons
815c2215e8SAndreas Gohr        if ($shownRevision->getRev() == $newestRevision->getRev()) {
825c2215e8SAndreas Gohr            $banner .= $this->actionButtons(
835c2215e8SAndreas Gohr                $shownRevision->getStatus(),
849dc573e7SAndreas Gohr                $latestpubRevision ? $this->increaseVersion($latestpubRevision->getVersion()) : '1'
855c2215e8SAndreas Gohr            );
865c2215e8SAndreas Gohr        }
875c2215e8SAndreas Gohr
885c2215e8SAndreas Gohr        $banner .= '</div>';
895c2215e8SAndreas Gohr        echo $banner;
9087106851SAnna Dabrowska    }
9187106851SAnna Dabrowska
9287106851SAnna Dabrowska    /**
935c2215e8SAndreas Gohr     * Fills place holder texts with data from the given Revision
945c2215e8SAndreas Gohr     *
95dd0cceddSAndreas Gohr     * @param string $name
965c2215e8SAndreas Gohr     * @param Revision $rev
9787106851SAnna Dabrowska     * @return string
9887106851SAnna Dabrowska     */
99dd0cceddSAndreas Gohr    protected function getBannerText($name, $rev, $diff = '')
1005c2215e8SAndreas Gohr    {
1015c2215e8SAndreas Gohr        if ($rev === null) {
1025c2215e8SAndreas Gohr            return '';
1035c2215e8SAndreas Gohr        }
1045c2215e8SAndreas Gohr
1055c2215e8SAndreas Gohr        $replace = [
1065c2215e8SAndreas Gohr            '{user}' => userlink($rev->getUser()),
1075c2215e8SAndreas Gohr            '{revision}' => $this->makeLink($rev->getId(), $rev->getRev(), dformat($rev->getRev())),
1085c2215e8SAndreas Gohr            '{datetime}' => $this->makeLink($rev->getId(), $rev->getRev(), dformat($rev->getTimestamp())),
109fab8ee0dSAnna Dabrowska            '{version}' => hsc($rev->getVersion()),
1105c2215e8SAndreas Gohr        ];
1115c2215e8SAndreas Gohr
1126c35120aSAnna Dabrowska        $text = $this->getLang($this->compactView ? "compact_banner_$name" : "banner_$name");
1136c35120aSAnna Dabrowska
1145c2215e8SAndreas Gohr        $text = strtr($text, $replace);
1155c2215e8SAndreas Gohr
116dd0cceddSAndreas Gohr        // add link to diff view
117dd0cceddSAndreas Gohr        if ($diff && $diff !== $rev->getRev()) {
118dd0cceddSAndreas Gohr            $link = wl($rev->getId(), ['do' => 'diff', 'rev1' => $rev->getRev(), 'rev2' => $diff]);
119dd0cceddSAndreas Gohr            $icon = inlineSVG(__DIR__ . '/../ico/diff.svg');
120dd0cceddSAndreas Gohr            $text .= ' <a href="' . $link . '" title="' . $this->getLang('diff') . '">' . $icon . '</a>';
121dd0cceddSAndreas Gohr        }
122dd0cceddSAndreas Gohr
1236c35120aSAnna Dabrowska        $tag = $this->compactView ? 'span' : 'p';
1246c35120aSAnna Dabrowska
1256c35120aSAnna Dabrowska        return "<$tag class='$name'>$text</$tag>";
1265c2215e8SAndreas Gohr    }
1275c2215e8SAndreas Gohr
1285c2215e8SAndreas Gohr    /**
1295c2215e8SAndreas Gohr     * Create a HTML link to a specific revision
1305c2215e8SAndreas Gohr     *
1315c2215e8SAndreas Gohr     * @param string $id page id
1325c2215e8SAndreas Gohr     * @param int $rev revision to link to
1335c2215e8SAndreas Gohr     * @param int $text the link text to use
1345c2215e8SAndreas Gohr     * @return string
1355c2215e8SAndreas Gohr     */
1365c2215e8SAndreas Gohr    protected function makeLink($id, $rev, $text)
1375c2215e8SAndreas Gohr    {
1385c2215e8SAndreas Gohr        $url = wl($id, ['rev' => $rev]);
1395c2215e8SAndreas Gohr        return '<a href="' . $url . '">' . hsc($text) . '</a>';
1405c2215e8SAndreas Gohr    }
1415c2215e8SAndreas Gohr
1425c2215e8SAndreas Gohr    /**
1435c2215e8SAndreas Gohr     * Create the form for approval and publishing
1445c2215e8SAndreas Gohr     *
1455c2215e8SAndreas Gohr     * @param string $status current status
1465c2215e8SAndreas Gohr     * @param string $newVersion suggested new Version
1475c2215e8SAndreas Gohr     * @return string
1485c2215e8SAndreas Gohr     */
1495c2215e8SAndreas Gohr    protected function actionButtons($status, $newVersion)
15087106851SAnna Dabrowska    {
15187106851SAnna Dabrowska        global $ID;
152e31c94d7SAndreas Gohr        if ($status === Constants::STATUS_PUBLISHED) {
1535c2215e8SAndreas Gohr            return '';
1548d2065f7SAnna Dabrowska        }
155e7259784SAnna Dabrowska
156e394901aSAnna Dabrowska        $form = new dokuwiki\Form\Form();
1571b063be2SAnna Dabrowska
1585c2215e8SAndreas Gohr        if (
1595c2215e8SAndreas Gohr            $status !== Constants::STATUS_APPROVED &&
1605c2215e8SAndreas Gohr            $this->dbHelper->checkAccess($ID, [Constants::ACTION_APPROVE])
1615c2215e8SAndreas Gohr        ) {
1625c2215e8SAndreas Gohr            $form->addButton(
1633b7236c0SAnna Dabrowska                'structpublish[' . Constants::ACTION_APPROVE . ']',
1645c2215e8SAndreas Gohr                $this->getLang('action_' . Constants::ACTION_APPROVE)
1655c2215e8SAndreas Gohr            )->attr('type', 'submit');
1661b063be2SAnna Dabrowska        }
167e31c94d7SAndreas Gohr
1685c2215e8SAndreas Gohr        if ($this->dbHelper->checkAccess($ID, [Constants::ACTION_PUBLISH])) {
1695c2215e8SAndreas Gohr            $form->addTextInput('version', $this->getLang('newversion'))->val($newVersion);
1705c2215e8SAndreas Gohr            $form->addButton(
1713b7236c0SAnna Dabrowska                'structpublish[' . Constants::ACTION_PUBLISH . ']',
1725c2215e8SAndreas Gohr                $this->getLang('action_' . Constants::ACTION_PUBLISH)
1735c2215e8SAndreas Gohr            )->attr('type', 'submit');
1745c2215e8SAndreas Gohr        }
175e394901aSAnna Dabrowska
176e394901aSAnna Dabrowska        return $form->toHTML();
177c2f8a3c4SAnna Dabrowska    }
1789dc573e7SAndreas Gohr
1799dc573e7SAndreas Gohr    /**
1809dc573e7SAndreas Gohr     * Tries to increase a given version
1819dc573e7SAndreas Gohr     *
1829dc573e7SAndreas Gohr     * @param string $version
1839dc573e7SAndreas Gohr     * @return string
1849dc573e7SAndreas Gohr     */
1859dc573e7SAndreas Gohr    protected function increaseVersion($version)
1869dc573e7SAndreas Gohr    {
1879dc573e7SAndreas Gohr        $parts = explode('.', $version);
1889dc573e7SAndreas Gohr        $last = array_pop($parts);
1899dc573e7SAndreas Gohr
1909dc573e7SAndreas Gohr        if (is_numeric($last)) {
1919dc573e7SAndreas Gohr            $last++;
1929dc573e7SAndreas Gohr        }
1939dc573e7SAndreas Gohr        $parts[] = $last;
1949dc573e7SAndreas Gohr
1959dc573e7SAndreas Gohr        return join('.', $parts);
1969dc573e7SAndreas Gohr    }
19787106851SAnna Dabrowska}
198