xref: /plugin/structpublish/action/banner.php (revision 9ab8cbae39a6ffa37705f745bc76916ea212a92b)
187106851SAnna Dabrowska<?php
287106851SAnna Dabrowska
3*9ab8cbaeSanndause dokuwiki\Extension\ActionPlugin;
4*9ab8cbaeSanndause dokuwiki\Extension\EventHandler;
5*9ab8cbaeSanndause dokuwiki\Extension\Event;
6*9ab8cbaeSanndause dokuwiki\Form\Form;
7e31c94d7SAndreas Gohruse dokuwiki\plugin\structpublish\meta\Constants;
8c2f8a3c4SAnna Dabrowskause dokuwiki\plugin\structpublish\meta\Revision;
9c2f8a3c4SAnna Dabrowska
1087106851SAnna Dabrowska/**
1187106851SAnna Dabrowska * Action component responsible for the publish banner
1287106851SAnna Dabrowska * attached to struct data of a page
1387106851SAnna Dabrowska */
14*9ab8cbaeSanndaclass action_plugin_structpublish_banner extends ActionPlugin
1587106851SAnna Dabrowska{
16e394901aSAnna Dabrowska    /** @var \helper_plugin_structpublish_db */
17e394901aSAnna Dabrowska    protected $dbHelper;
18c2f8a3c4SAnna Dabrowska
196c35120aSAnna Dabrowska    /** @var bool */
206c35120aSAnna Dabrowska    protected $compactView;
216c35120aSAnna Dabrowska
228b0ba635SAndreas Gohr    /** @inheritDoc */
23*9ab8cbaeSannda    public function register(EventHandler $controller)
2487106851SAnna Dabrowska    {
25e394901aSAnna Dabrowska        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'renderBanner');
2687106851SAnna Dabrowska    }
2787106851SAnna Dabrowska
2887106851SAnna Dabrowska    /**
29e394901aSAnna Dabrowska     * Add banner to pages under structpublish control
3087106851SAnna Dabrowska     */
31*9ab8cbaeSannda    public function renderBanner(Event $event)
3287106851SAnna Dabrowska    {
33c2f8a3c4SAnna Dabrowska        global $ID;
348d2065f7SAnna Dabrowska        global $INFO;
3540f4519bSAnna Dabrowska        global $REV;
3687106851SAnna Dabrowska
375c2215e8SAndreas Gohr        if ($event->data !== 'show') {
385c2215e8SAndreas Gohr            return;
395c2215e8SAndreas Gohr        }
403449f9ceSAnna Dabrowska
418d2065f7SAnna Dabrowska        $this->dbHelper = plugin_load('helper', 'structpublish_db');
42939e6e3cSAnna Dabrowska
435c2215e8SAndreas Gohr        if (!$this->dbHelper->isPublishable()) {
445c2215e8SAndreas Gohr            return;
455c2215e8SAndreas Gohr        }
46939e6e3cSAnna Dabrowska
476c35120aSAnna Dabrowska        $this->compactView = (bool)$this->getConf('compact_view');
486c35120aSAnna Dabrowska
495c2215e8SAndreas Gohr        // get the possible revisions needed in the banner
50b476f81dSAnna Dabrowska        $newestRevision = new Revision($ID, $INFO['currentrev']);
515c2215e8SAndreas Gohr        if ($REV) {
52b476f81dSAnna Dabrowska            $shownRevision = new Revision($ID, $REV);
535c2215e8SAndreas Gohr        } else {
545c2215e8SAndreas Gohr            $shownRevision = $newestRevision;
555c2215e8SAndreas Gohr        }
565c2215e8SAndreas Gohr        $latestpubRevision = $newestRevision->getLatestPublishedRevision();
57fd06d74cSAnna Dabrowska        $prevpubRevision = $shownRevision->getLatestPublishedRevision($REV ?:  $INFO['currentrev']);
58c2f8a3c4SAnna Dabrowska
596c35120aSAnna Dabrowska        $compactClass = $this->compactView ? ' compact' : '';
606c35120aSAnna Dabrowska        $banner = '<div class="plugin-structpublish-banner ' . $shownRevision->getStatus() . $compactClass . '">';
615c2215e8SAndreas Gohr
625c2215e8SAndreas Gohr        // status of the shown revision
63dd0cceddSAndreas Gohr        $banner .= '<span class="icon">' .
64dd0cceddSAndreas Gohr            inlineSVG(__DIR__ . '/../ico/' . $shownRevision->getStatus() . '.svg') .
65dd0cceddSAndreas Gohr            '</span>';
665c2215e8SAndreas Gohr        $banner .= $this->getBannerText('status_' . $shownRevision->getStatus(), $shownRevision);
675c2215e8SAndreas Gohr
685c2215e8SAndreas Gohr        // link to previous or newest published version
695c2215e8SAndreas Gohr        if ($latestpubRevision !== null && $shownRevision->getRev() < $latestpubRevision->getRev()) {
70dd0cceddSAndreas Gohr            $banner .= $this->getBannerText('latest_publish', $latestpubRevision, $shownRevision->getRev());
715c2215e8SAndreas Gohr        } else {
72dd0cceddSAndreas Gohr            $banner .= $this->getBannerText('previous_publish', $prevpubRevision, $shownRevision->getRev());
735c2215e8SAndreas Gohr        }
745c2215e8SAndreas Gohr
755c2215e8SAndreas Gohr        // link to newest draft, if exists, is not shown already and user has a role
765c2215e8SAndreas Gohr        if (
775c2215e8SAndreas Gohr            $newestRevision->getRev() != $shownRevision->getRev() &&
785c2215e8SAndreas Gohr            $newestRevision->getStatus() != Constants::STATUS_PUBLISHED &&
795c2215e8SAndreas Gohr            $this->dbHelper->checkAccess($ID)
805c2215e8SAndreas Gohr        ) {
81dd0cceddSAndreas Gohr            $banner .= $this->getBannerText('latest_draft', $newestRevision, $shownRevision->getRev());
825c2215e8SAndreas Gohr        }
835c2215e8SAndreas Gohr
845c2215e8SAndreas Gohr        // action buttons
855c2215e8SAndreas Gohr        if ($shownRevision->getRev() == $newestRevision->getRev()) {
865c2215e8SAndreas Gohr            $banner .= $this->actionButtons(
875c2215e8SAndreas Gohr                $shownRevision->getStatus(),
889dc573e7SAndreas Gohr                $latestpubRevision ? $this->increaseVersion($latestpubRevision->getVersion()) : '1'
895c2215e8SAndreas Gohr            );
905c2215e8SAndreas Gohr        }
915c2215e8SAndreas Gohr
925c2215e8SAndreas Gohr        $banner .= '</div>';
935c2215e8SAndreas Gohr        echo $banner;
9487106851SAnna Dabrowska    }
9587106851SAnna Dabrowska
9687106851SAnna Dabrowska    /**
975c2215e8SAndreas Gohr     * Fills place holder texts with data from the given Revision
985c2215e8SAndreas Gohr     *
99dd0cceddSAndreas Gohr     * @param string $name
1005c2215e8SAndreas Gohr     * @param Revision $rev
10187106851SAnna Dabrowska     * @return string
10287106851SAnna Dabrowska     */
103dd0cceddSAndreas Gohr    protected function getBannerText($name, $rev, $diff = '')
1045c2215e8SAndreas Gohr    {
1055c2215e8SAndreas Gohr        if ($rev === null) {
1065c2215e8SAndreas Gohr            return '';
1075c2215e8SAndreas Gohr        }
1085c2215e8SAndreas Gohr
1095c2215e8SAndreas Gohr        $replace = [
1105c2215e8SAndreas Gohr            '{user}' => userlink($rev->getUser()),
1115c2215e8SAndreas Gohr            '{revision}' => $this->makeLink($rev->getId(), $rev->getRev(), dformat($rev->getRev())),
1125c2215e8SAndreas Gohr            '{datetime}' => $this->makeLink($rev->getId(), $rev->getRev(), dformat($rev->getTimestamp())),
113fab8ee0dSAnna Dabrowska            '{version}' => hsc($rev->getVersion()),
1145c2215e8SAndreas Gohr        ];
1155c2215e8SAndreas Gohr
1166c35120aSAnna Dabrowska        $text = $this->getLang($this->compactView ? "compact_banner_$name" : "banner_$name");
1176c35120aSAnna Dabrowska
1185c2215e8SAndreas Gohr        $text = strtr($text, $replace);
1195c2215e8SAndreas Gohr
120dd0cceddSAndreas Gohr        // add link to diff view
121dd0cceddSAndreas Gohr        if ($diff && $diff !== $rev->getRev()) {
1225b591414SAnna Dabrowska            $link = wl($rev->getId(), ['do' => 'diff', 'rev2[0]' => $rev->getRev(), 'rev2[1]' => $diff]);
123dd0cceddSAndreas Gohr            $icon = inlineSVG(__DIR__ . '/../ico/diff.svg');
124dd0cceddSAndreas Gohr            $text .= ' <a href="' . $link . '" title="' . $this->getLang('diff') . '">' . $icon . '</a>';
125dd0cceddSAndreas Gohr        }
126dd0cceddSAndreas Gohr
1276c35120aSAnna Dabrowska        $tag = $this->compactView ? 'span' : 'p';
1286c35120aSAnna Dabrowska
1296c35120aSAnna Dabrowska        return "<$tag class='$name'>$text</$tag>";
1305c2215e8SAndreas Gohr    }
1315c2215e8SAndreas Gohr
1325c2215e8SAndreas Gohr    /**
1335c2215e8SAndreas Gohr     * Create a HTML link to a specific revision
1345c2215e8SAndreas Gohr     *
1355c2215e8SAndreas Gohr     * @param string $id page id
1365c2215e8SAndreas Gohr     * @param int $rev revision to link to
1375c2215e8SAndreas Gohr     * @param int $text the link text to use
1385c2215e8SAndreas Gohr     * @return string
1395c2215e8SAndreas Gohr     */
1405c2215e8SAndreas Gohr    protected function makeLink($id, $rev, $text)
1415c2215e8SAndreas Gohr    {
1425c2215e8SAndreas Gohr        $url = wl($id, ['rev' => $rev]);
1435c2215e8SAndreas Gohr        return '<a href="' . $url . '">' . hsc($text) . '</a>';
1445c2215e8SAndreas Gohr    }
1455c2215e8SAndreas Gohr
1465c2215e8SAndreas Gohr    /**
1475c2215e8SAndreas Gohr     * Create the form for approval and publishing
1485c2215e8SAndreas Gohr     *
1495c2215e8SAndreas Gohr     * @param string $status current status
1505c2215e8SAndreas Gohr     * @param string $newVersion suggested new Version
1515c2215e8SAndreas Gohr     * @return string
1525c2215e8SAndreas Gohr     */
1535c2215e8SAndreas Gohr    protected function actionButtons($status, $newVersion)
15487106851SAnna Dabrowska    {
15587106851SAnna Dabrowska        global $ID;
156e31c94d7SAndreas Gohr        if ($status === Constants::STATUS_PUBLISHED) {
1575c2215e8SAndreas Gohr            return '';
1588d2065f7SAnna Dabrowska        }
159e7259784SAnna Dabrowska
160*9ab8cbaeSannda        $form = new Form();
1611b063be2SAnna Dabrowska
1625c2215e8SAndreas Gohr        if (
1635c2215e8SAndreas Gohr            $status !== Constants::STATUS_APPROVED &&
1645c2215e8SAndreas Gohr            $this->dbHelper->checkAccess($ID, [Constants::ACTION_APPROVE])
1655c2215e8SAndreas Gohr        ) {
1665c2215e8SAndreas Gohr            $form->addButton(
1673b7236c0SAnna Dabrowska                'structpublish[' . Constants::ACTION_APPROVE . ']',
1685c2215e8SAndreas Gohr                $this->getLang('action_' . Constants::ACTION_APPROVE)
1695c2215e8SAndreas Gohr            )->attr('type', 'submit');
1701b063be2SAnna Dabrowska        }
171e31c94d7SAndreas Gohr
1725c2215e8SAndreas Gohr        if ($this->dbHelper->checkAccess($ID, [Constants::ACTION_PUBLISH])) {
1735c2215e8SAndreas Gohr            $form->addTextInput('version', $this->getLang('newversion'))->val($newVersion);
1745c2215e8SAndreas Gohr            $form->addButton(
1753b7236c0SAnna Dabrowska                'structpublish[' . Constants::ACTION_PUBLISH . ']',
1765c2215e8SAndreas Gohr                $this->getLang('action_' . Constants::ACTION_PUBLISH)
1775c2215e8SAndreas Gohr            )->attr('type', 'submit');
1785c2215e8SAndreas Gohr        }
179e394901aSAnna Dabrowska
180e394901aSAnna Dabrowska        return $form->toHTML();
181c2f8a3c4SAnna Dabrowska    }
1829dc573e7SAndreas Gohr
1839dc573e7SAndreas Gohr    /**
1849dc573e7SAndreas Gohr     * Tries to increase a given version
1859dc573e7SAndreas Gohr     *
1869dc573e7SAndreas Gohr     * @param string $version
1879dc573e7SAndreas Gohr     * @return string
1889dc573e7SAndreas Gohr     */
1899dc573e7SAndreas Gohr    protected function increaseVersion($version)
1909dc573e7SAndreas Gohr    {
1919dc573e7SAndreas Gohr        $parts = explode('.', $version);
1929dc573e7SAndreas Gohr        $last = array_pop($parts);
1939dc573e7SAndreas Gohr
1949dc573e7SAndreas Gohr        if (is_numeric($last)) {
1959dc573e7SAndreas Gohr            $last++;
1969dc573e7SAndreas Gohr        }
1979dc573e7SAndreas Gohr        $parts[] = $last;
1989dc573e7SAndreas Gohr
199*9ab8cbaeSannda        return implode('.', $parts);
2009dc573e7SAndreas Gohr    }
20187106851SAnna Dabrowska}
202