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