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 158b0ba635SAndreas Gohr /** @inheritDoc */ 1687106851SAnna Dabrowska public function register(Doku_Event_Handler $controller) 1787106851SAnna Dabrowska { 18e394901aSAnna Dabrowska $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'renderBanner'); 1987106851SAnna Dabrowska } 2087106851SAnna Dabrowska 2187106851SAnna Dabrowska /** 22e394901aSAnna Dabrowska * Add banner to pages under structpublish control 2387106851SAnna Dabrowska */ 2487106851SAnna Dabrowska public function renderBanner(Doku_Event $event) 2587106851SAnna Dabrowska { 26c2f8a3c4SAnna Dabrowska global $ID; 278d2065f7SAnna Dabrowska global $INFO; 2840f4519bSAnna Dabrowska global $REV; 2987106851SAnna Dabrowska 305c2215e8SAndreas Gohr if ($event->data !== 'show') { 315c2215e8SAndreas Gohr return; 325c2215e8SAndreas Gohr } 333449f9ceSAnna Dabrowska 348d2065f7SAnna Dabrowska $this->dbHelper = plugin_load('helper', 'structpublish_db'); 35939e6e3cSAnna Dabrowska 365c2215e8SAndreas Gohr if (!$this->dbHelper->isPublishable()) { 375c2215e8SAndreas Gohr return; 385c2215e8SAndreas Gohr } 39939e6e3cSAnna Dabrowska 405c2215e8SAndreas Gohr // get the possible revisions needed in the banner 415c2215e8SAndreas Gohr $newestRevision = new Revision($this->dbHelper->getDB(), $ID, $INFO['currentrev']); 425c2215e8SAndreas Gohr if ($REV) { 435c2215e8SAndreas Gohr $shownRevision = new Revision($this->dbHelper->getDB(), $ID, $REV); 445c2215e8SAndreas Gohr } else { 455c2215e8SAndreas Gohr $shownRevision = $newestRevision; 465c2215e8SAndreas Gohr } 475c2215e8SAndreas Gohr $latestpubRevision = $newestRevision->getLatestPublishedRevision(); 485c2215e8SAndreas Gohr $prevpubRevision = $shownRevision->getLatestPublishedRevision(); 49c2f8a3c4SAnna Dabrowska 505c2215e8SAndreas Gohr $banner = '<div class="plugin-structpublish-banner ' . $shownRevision->getStatus() . '">'; 515c2215e8SAndreas Gohr 525c2215e8SAndreas Gohr // status of the shown revision 53*dd0cceddSAndreas Gohr $banner .= '<span class="icon">' . 54*dd0cceddSAndreas Gohr inlineSVG(__DIR__ . '/../ico/' . $shownRevision->getStatus() . '.svg') . 55*dd0cceddSAndreas Gohr '</span>'; 565c2215e8SAndreas Gohr $banner .= $this->getBannerText('status_' . $shownRevision->getStatus(), $shownRevision); 575c2215e8SAndreas Gohr 585c2215e8SAndreas Gohr // link to previous or newest published version 595c2215e8SAndreas Gohr if ($latestpubRevision !== null && $shownRevision->getRev() < $latestpubRevision->getRev()) { 60*dd0cceddSAndreas Gohr $banner .= $this->getBannerText('latest_publish', $latestpubRevision, $shownRevision->getRev()); 615c2215e8SAndreas Gohr } else { 62*dd0cceddSAndreas Gohr $banner .= $this->getBannerText('previous_publish', $prevpubRevision, $shownRevision->getRev()); 635c2215e8SAndreas Gohr } 645c2215e8SAndreas Gohr 655c2215e8SAndreas Gohr // link to newest draft, if exists, is not shown already and user has a role 665c2215e8SAndreas Gohr if ( 675c2215e8SAndreas Gohr $newestRevision->getRev() != $shownRevision->getRev() && 685c2215e8SAndreas Gohr $newestRevision->getStatus() != Constants::STATUS_PUBLISHED && 695c2215e8SAndreas Gohr $this->dbHelper->checkAccess($ID) 705c2215e8SAndreas Gohr ) { 71*dd0cceddSAndreas Gohr $banner .= $this->getBannerText('latest_draft', $newestRevision, $shownRevision->getRev()); 725c2215e8SAndreas Gohr } 735c2215e8SAndreas Gohr 745c2215e8SAndreas Gohr // action buttons 755c2215e8SAndreas Gohr if ($shownRevision->getRev() == $newestRevision->getRev()) { 765c2215e8SAndreas Gohr $banner .= $this->actionButtons( 775c2215e8SAndreas Gohr $shownRevision->getStatus(), 789dc573e7SAndreas Gohr $latestpubRevision ? $this->increaseVersion($latestpubRevision->getVersion()) : '1' 795c2215e8SAndreas Gohr ); 805c2215e8SAndreas Gohr } 815c2215e8SAndreas Gohr 825c2215e8SAndreas Gohr $banner .= '</div>'; 835c2215e8SAndreas Gohr echo $banner; 8487106851SAnna Dabrowska } 8587106851SAnna Dabrowska 8687106851SAnna Dabrowska /** 875c2215e8SAndreas Gohr * Fills place holder texts with data from the given Revision 885c2215e8SAndreas Gohr * 89*dd0cceddSAndreas Gohr * @param string $name 905c2215e8SAndreas Gohr * @param Revision $rev 9187106851SAnna Dabrowska * @return string 9287106851SAnna Dabrowska */ 93*dd0cceddSAndreas Gohr protected function getBannerText($name, $rev, $diff = '') 945c2215e8SAndreas Gohr { 955c2215e8SAndreas Gohr if ($rev === null) { 965c2215e8SAndreas Gohr return ''; 975c2215e8SAndreas Gohr } 985c2215e8SAndreas Gohr 995c2215e8SAndreas Gohr $replace = [ 1005c2215e8SAndreas Gohr '{user}' => userlink($rev->getUser()), 1015c2215e8SAndreas Gohr '{revision}' => $this->makeLink($rev->getId(), $rev->getRev(), dformat($rev->getRev())), 1025c2215e8SAndreas Gohr '{datetime}' => $this->makeLink($rev->getId(), $rev->getRev(), dformat($rev->getTimestamp())), 103*dd0cceddSAndreas Gohr '{version}' => '<span class="plugin-structpublish-version">' . hsc($rev->getVersion()) . '</span>', 1045c2215e8SAndreas Gohr ]; 1055c2215e8SAndreas Gohr 106*dd0cceddSAndreas Gohr $text = $this->getLang("banner_$name"); 1075c2215e8SAndreas Gohr $text = strtr($text, $replace); 1085c2215e8SAndreas Gohr 109*dd0cceddSAndreas Gohr // add link to diff view 110*dd0cceddSAndreas Gohr if ($diff && $diff !== $rev->getRev()) { 111*dd0cceddSAndreas Gohr $link = wl($rev->getId(), ['do' => 'diff', 'rev1' => $rev->getRev(), 'rev2' => $diff]); 112*dd0cceddSAndreas Gohr $icon = inlineSVG(__DIR__ . '/../ico/diff.svg'); 113*dd0cceddSAndreas Gohr $text .= ' <a href="' . $link . '" title="' . $this->getLang('diff') . '">' . $icon . '</a>'; 114*dd0cceddSAndreas Gohr } 115*dd0cceddSAndreas Gohr 116*dd0cceddSAndreas Gohr return "<p class='$name'>$text</p>"; 1175c2215e8SAndreas Gohr } 1185c2215e8SAndreas Gohr 1195c2215e8SAndreas Gohr /** 1205c2215e8SAndreas Gohr * Create a HTML link to a specific revision 1215c2215e8SAndreas Gohr * 1225c2215e8SAndreas Gohr * @param string $id page id 1235c2215e8SAndreas Gohr * @param int $rev revision to link to 1245c2215e8SAndreas Gohr * @param int $text the link text to use 1255c2215e8SAndreas Gohr * @return string 1265c2215e8SAndreas Gohr */ 1275c2215e8SAndreas Gohr protected function makeLink($id, $rev, $text) 1285c2215e8SAndreas Gohr { 1295c2215e8SAndreas Gohr $url = wl($id, ['rev' => $rev]); 1305c2215e8SAndreas Gohr return '<a href="' . $url . '">' . hsc($text) . '</a>'; 1315c2215e8SAndreas Gohr } 1325c2215e8SAndreas Gohr 1335c2215e8SAndreas Gohr /** 1345c2215e8SAndreas Gohr * Create the form for approval and publishing 1355c2215e8SAndreas Gohr * 1365c2215e8SAndreas Gohr * @param string $status current status 1375c2215e8SAndreas Gohr * @param string $newVersion suggested new Version 1385c2215e8SAndreas Gohr * @return string 1395c2215e8SAndreas Gohr */ 1405c2215e8SAndreas Gohr protected function actionButtons($status, $newVersion) 14187106851SAnna Dabrowska { 14287106851SAnna Dabrowska global $ID; 143e31c94d7SAndreas Gohr if ($status === Constants::STATUS_PUBLISHED) { 1445c2215e8SAndreas Gohr return ''; 1458d2065f7SAnna Dabrowska } 146e7259784SAnna Dabrowska 147e394901aSAnna Dabrowska $form = new dokuwiki\Form\Form(); 1481b063be2SAnna Dabrowska 1495c2215e8SAndreas Gohr if ( 1505c2215e8SAndreas Gohr $status !== Constants::STATUS_APPROVED && 1515c2215e8SAndreas Gohr $this->dbHelper->checkAccess($ID, [Constants::ACTION_APPROVE]) 1525c2215e8SAndreas Gohr ) { 1535c2215e8SAndreas Gohr $form->addButton( 1545c2215e8SAndreas Gohr 'structpublish[approve]', 1555c2215e8SAndreas Gohr $this->getLang('action_' . Constants::ACTION_APPROVE) 1565c2215e8SAndreas Gohr )->attr('type', 'submit'); 1571b063be2SAnna Dabrowska } 158e31c94d7SAndreas Gohr 1595c2215e8SAndreas Gohr if ($this->dbHelper->checkAccess($ID, [Constants::ACTION_PUBLISH])) { 1605c2215e8SAndreas Gohr $form->addTextInput('version', $this->getLang('newversion'))->val($newVersion); 1615c2215e8SAndreas Gohr $form->addButton( 1625c2215e8SAndreas Gohr 'structpublish[publish]', 1635c2215e8SAndreas Gohr $this->getLang('action_' . Constants::ACTION_PUBLISH) 1645c2215e8SAndreas Gohr )->attr('type', 'submit'); 1655c2215e8SAndreas Gohr } 166e394901aSAnna Dabrowska 167e394901aSAnna Dabrowska return $form->toHTML(); 168c2f8a3c4SAnna Dabrowska } 1699dc573e7SAndreas Gohr 1709dc573e7SAndreas Gohr /** 1719dc573e7SAndreas Gohr * Tries to increase a given version 1729dc573e7SAndreas Gohr * 1739dc573e7SAndreas Gohr * @param string $version 1749dc573e7SAndreas Gohr * @return string 1759dc573e7SAndreas Gohr */ 1769dc573e7SAndreas Gohr protected function increaseVersion($version) 1779dc573e7SAndreas Gohr { 1789dc573e7SAndreas Gohr $parts = explode('.', $version); 1799dc573e7SAndreas Gohr $last = array_pop($parts); 1809dc573e7SAndreas Gohr 1819dc573e7SAndreas Gohr if (is_numeric($last)) { 1829dc573e7SAndreas Gohr $last++; 1839dc573e7SAndreas Gohr } 1849dc573e7SAndreas Gohr $parts[] = $last; 1859dc573e7SAndreas Gohr 1869dc573e7SAndreas Gohr return join('.', $parts); 1879dc573e7SAndreas Gohr } 18887106851SAnna Dabrowska} 189