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 15*6c35120aSAnna Dabrowska /** @var bool */ 16*6c35120aSAnna Dabrowska protected $compactView; 17*6c35120aSAnna 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 43*6c35120aSAnna Dabrowska $this->compactView = (bool)$this->getConf('compact_view'); 44*6c35120aSAnna Dabrowska 455c2215e8SAndreas Gohr // get the possible revisions needed in the banner 465c2215e8SAndreas Gohr $newestRevision = new Revision($this->dbHelper->getDB(), $ID, $INFO['currentrev']); 475c2215e8SAndreas Gohr if ($REV) { 485c2215e8SAndreas Gohr $shownRevision = new Revision($this->dbHelper->getDB(), $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 55*6c35120aSAnna Dabrowska $compactClass = $this->compactView ? ' compact' : ''; 56*6c35120aSAnna 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 112*6c35120aSAnna Dabrowska $text = $this->getLang($this->compactView ? "compact_banner_$name" : "banner_$name"); 113*6c35120aSAnna 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 123*6c35120aSAnna Dabrowska $tag = $this->compactView ? 'span' : 'p'; 124*6c35120aSAnna Dabrowska 125*6c35120aSAnna 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