1<?php 2 3use dokuwiki\plugin\structpublish\meta\Constants; 4use dokuwiki\plugin\structpublish\meta\Revision; 5 6/** 7 * Action component responsible for the publish banner 8 * attached to struct data of a page 9 */ 10class action_plugin_structpublish_banner extends DokuWiki_Action_Plugin 11{ 12 /** @var \helper_plugin_structpublish_db */ 13 protected $dbHelper; 14 15 /** @inheritDoc */ 16 public function register(Doku_Event_Handler $controller) 17 { 18 $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'renderBanner'); 19 } 20 21 /** 22 * Add banner to pages under structpublish control 23 */ 24 public function renderBanner(Doku_Event $event) 25 { 26 global $ID; 27 global $INFO; 28 global $REV; 29 30 if ($event->data !== 'show') { 31 return; 32 } 33 34 $this->dbHelper = plugin_load('helper', 'structpublish_db'); 35 36 if (!$this->dbHelper->isPublishable()) { 37 return; 38 } 39 40 // get the possible revisions needed in the banner 41 $newestRevision = new Revision($this->dbHelper->getDB(), $ID, $INFO['currentrev']); 42 if ($REV) { 43 $shownRevision = new Revision($this->dbHelper->getDB(), $ID, $REV); 44 } else { 45 $shownRevision = $newestRevision; 46 } 47 $latestpubRevision = $newestRevision->getLatestPublishedRevision(); 48 $prevpubRevision = $shownRevision->getLatestPublishedRevision(); 49 50 $banner = '<div class="plugin-structpublish-banner ' . $shownRevision->getStatus() . '">'; 51 52 // status of the shown revision 53 $banner .= '<span class="icon">' . 54 inlineSVG(__DIR__ . '/../ico/' . $shownRevision->getStatus() . '.svg') . 55 '</span>'; 56 $banner .= $this->getBannerText('status_' . $shownRevision->getStatus(), $shownRevision); 57 58 // link to previous or newest published version 59 if ($latestpubRevision !== null && $shownRevision->getRev() < $latestpubRevision->getRev()) { 60 $banner .= $this->getBannerText('latest_publish', $latestpubRevision, $shownRevision->getRev()); 61 } else { 62 $banner .= $this->getBannerText('previous_publish', $prevpubRevision, $shownRevision->getRev()); 63 } 64 65 // link to newest draft, if exists, is not shown already and user has a role 66 if ( 67 $newestRevision->getRev() != $shownRevision->getRev() && 68 $newestRevision->getStatus() != Constants::STATUS_PUBLISHED && 69 $this->dbHelper->checkAccess($ID) 70 ) { 71 $banner .= $this->getBannerText('latest_draft', $newestRevision, $shownRevision->getRev()); 72 } 73 74 // action buttons 75 if ($shownRevision->getRev() == $newestRevision->getRev()) { 76 $banner .= $this->actionButtons( 77 $shownRevision->getStatus(), 78 $latestpubRevision ? $this->increaseVersion($latestpubRevision->getVersion()) : '1' 79 ); 80 } 81 82 $banner .= '</div>'; 83 echo $banner; 84 } 85 86 /** 87 * Fills place holder texts with data from the given Revision 88 * 89 * @param string $name 90 * @param Revision $rev 91 * @return string 92 */ 93 protected function getBannerText($name, $rev, $diff = '') 94 { 95 if ($rev === null) { 96 return ''; 97 } 98 99 $replace = [ 100 '{user}' => userlink($rev->getUser()), 101 '{revision}' => $this->makeLink($rev->getId(), $rev->getRev(), dformat($rev->getRev())), 102 '{datetime}' => $this->makeLink($rev->getId(), $rev->getRev(), dformat($rev->getTimestamp())), 103 '{version}' => hsc($rev->getVersion()), 104 ]; 105 106 $text = $this->getLang("banner_$name"); 107 $text = strtr($text, $replace); 108 109 // add link to diff view 110 if ($diff && $diff !== $rev->getRev()) { 111 $link = wl($rev->getId(), ['do' => 'diff', 'rev1' => $rev->getRev(), 'rev2' => $diff]); 112 $icon = inlineSVG(__DIR__ . '/../ico/diff.svg'); 113 $text .= ' <a href="' . $link . '" title="' . $this->getLang('diff') . '">' . $icon . '</a>'; 114 } 115 116 return "<p class='$name'>$text</p>"; 117 } 118 119 /** 120 * Create a HTML link to a specific revision 121 * 122 * @param string $id page id 123 * @param int $rev revision to link to 124 * @param int $text the link text to use 125 * @return string 126 */ 127 protected function makeLink($id, $rev, $text) 128 { 129 $url = wl($id, ['rev' => $rev]); 130 return '<a href="' . $url . '">' . hsc($text) . '</a>'; 131 } 132 133 /** 134 * Create the form for approval and publishing 135 * 136 * @param string $status current status 137 * @param string $newVersion suggested new Version 138 * @return string 139 */ 140 protected function actionButtons($status, $newVersion) 141 { 142 global $ID; 143 if ($status === Constants::STATUS_PUBLISHED) { 144 return ''; 145 } 146 147 $form = new dokuwiki\Form\Form(); 148 149 if ( 150 $status !== Constants::STATUS_APPROVED && 151 $this->dbHelper->checkAccess($ID, [Constants::ACTION_APPROVE]) 152 ) { 153 $form->addButton( 154 'structpublish[' . Constants::ACTION_APPROVE . ']', 155 $this->getLang('action_' . Constants::ACTION_APPROVE) 156 )->attr('type', 'submit'); 157 } 158 159 if ($this->dbHelper->checkAccess($ID, [Constants::ACTION_PUBLISH])) { 160 $form->addTextInput('version', $this->getLang('newversion'))->val($newVersion); 161 $form->addButton( 162 'structpublish[' . Constants::ACTION_PUBLISH . ']', 163 $this->getLang('action_' . Constants::ACTION_PUBLISH) 164 )->attr('type', 'submit'); 165 } 166 167 return $form->toHTML(); 168 } 169 170 /** 171 * Tries to increase a given version 172 * 173 * @param string $version 174 * @return string 175 */ 176 protected function increaseVersion($version) 177 { 178 $parts = explode('.', $version); 179 $last = array_pop($parts); 180 181 if (is_numeric($last)) { 182 $last++; 183 } 184 $parts[] = $last; 185 186 return join('.', $parts); 187 } 188} 189