1<?php 2 3if(!defined('DOKU_INC')) die(); 4define(APPROVED, 'Approved'); 5 6define(METADATA_VERSION_KEY, 'plugin_approve_version'); 7 8class action_plugin_approve_approve extends DokuWiki_Action_Plugin { 9 10 private $hlp; 11 function __construct(){ 12 $this->hlp = plugin_load('helper', 'approve'); 13 } 14 15 function register(Doku_Event_Handler $controller) { 16 17 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_approve, array()); 18 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_viewer, array()); 19 $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, handle_diff_accept, array()); 20 $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, handle_display_banner, array()); 21 $controller->register_hook('HTML_SHOWREV_OUTPUT', 'BEFORE', $this, handle_showrev, array()); 22 // ensure a page revision is created when summary changes: 23 $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'BEFORE', $this, 'handle_pagesave_before'); 24 $controller->register_hook('PARSER_METADATA_RENDER', 'AFTER', $this, 'handle_parser_metadata_render'); 25 } 26 27 function handle_diff_accept(Doku_Event $event, $param) { 28 global $ID; 29 30 if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return; 31 32 if ($event->data == 'diff' && isset($_GET['approve'])) { 33 ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&approve=approve">'.$this->getLang('approve').'</a>'); 34 } 35 } 36 37 function handle_showrev(Doku_Event $event, $param) { 38 global $ID, $REV; 39 40 $last = $this->find_lastest_approved(); 41 if ($last == $REV) 42 $event->preventDefault(); 43 } 44 45 function can_approve() { 46 global $ID; 47 return auth_quickaclcheck($ID) >= AUTH_DELETE; 48 } 49 50 function handle_approve(Doku_Event $event, $param) { 51 global $ID, $REV, $INFO; 52 53 if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return; 54 55 if ($event->data == 'show' && isset($_GET['approve'])) { 56 if ( ! $this->can_approve()) return; 57 58 //create new page revison 59 saveWikiText($ID, rawWiki($ID), APPROVED); 60 61 header('Location: ?id='.$ID); 62 } 63 } 64 function handle_viewer(Doku_Event $event, $param) { 65 global $REV, $ID; 66 if ($event->data != 'show') return; 67 if (auth_quickaclcheck($ID) > AUTH_READ || ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID))) return; 68 69 $last = $this->find_lastest_approved(); 70 //no page is approved 71 if ($last == -1) return; 72 //approved page is the newest page 73 if ($last == 0) return; 74 75 //if we are viewing lastest revision, show last approved 76 if ($REV == 0) header("Location: ?id=$ID&rev=$last"); 77 } 78 function find_lastest_approved() { 79 global $ID; 80 $m = p_get_metadata($ID); 81 $sum = $m['last_change']['sum']; 82 if ($sum == APPROVED) 83 return 0; 84 85 $changelog = new PageChangeLog($ID); 86 //wyszukaj najnowszej zatwierdzonej 87 //poszukaj w dół 88 $chs = $changelog->getRevisions(0, 10000); 89 foreach ($chs as $rev) { 90 $ch = $changelog->getRevisionInfo($rev); 91 if ($ch['sum'] == APPROVED) 92 return $rev; 93 } 94 return -1; 95 } 96 97 function handle_display_banner(Doku_Event $event, $param) { 98 global $ID, $REV, $INFO; 99 100 if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return; 101 if ($event->data != 'show') return; 102 if (!$INFO['exists']) return; 103 104 $sum = $this->hlp->page_sum($ID, $REV); 105 106 ptln('<div class="approval '.($sum == APPROVED ? 'approved_yes' : 'approved_no').'">'); 107 108 tpl_pageinfo(); 109 ptln(' | '); 110 $last_approved_rev = $this->find_lastest_approved(); 111 if ($sum == APPROVED) { 112 $version = p_get_metadata($ID, METADATA_VERSION_KEY); 113 114 ptln('<span>'.$this->getLang('approved').' (' . $this->getLang('version') . ': ' . $version 115 . ')</span>'); 116 if ($REV != 0 && auth_quickaclcheck($ID) > AUTH_READ) { 117 ptln('<a href="'.wl($ID).'">'); 118 ptln($this->getLang(p_get_metadata($ID, 'last_change sum') == APPROVED ? 'newest_approved' : 'newest_draft')); 119 ptln('</a>'); 120 } else if ($REV != 0 && $REV != $last_approved_rev) { 121 ptln('<a href="'.wl($ID).'">'); 122 ptln($this->getLang('newest_approved')); 123 ptln('</a>'); 124 } 125 } else { 126 ptln('<span>'.$this->getLang('draft').'</span>'); 127 128 if ($last_approved_rev == -1) { 129 if ($REV != 0) { 130 ptln('<a href="'.wl($ID).'">'); 131 ptln($this->getLang('newest_draft')); 132 ptln('</a>'); 133 } 134 } else { 135 if ($last_approved_rev != 0) 136 ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev)).'">'); 137 else 138 ptln('<a href="'.wl($ID).'">'); 139 140 ptln($this->getLang('newest_approved')); 141 ptln('</a>'); 142 } 143 144 //można zatwierdzać tylko najnowsze strony 145 if ($REV == 0 && $this->can_approve()) { 146 ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff', 147 'approve' => 'approve')).'">'); 148 ptln($this->getLang('approve')); 149 ptln('</a>'); 150 } 151 } 152 ptln('</div>'); 153 } 154 155 /** 156 * Check if the page has to be changed 157 * 158 * @param Doku_Event $event event object by reference 159 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 160 * handler was registered] 161 * @return void 162 */ 163 public function handle_pagesave_before(Doku_Event $event, $param) { 164 $id = $event->data['id']; 165 if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $id)) return; 166 167 //save page if summary is provided 168 if($event->data['summary'] == APPROVED) { 169 $event->data['contentChanged'] = true; 170 171 $version = p_get_metadata($id, METADATA_VERSION_KEY); 172 173 //calculate current version 174 if (!$version) { 175 $version = $this->calculateVersion($id); 176 } else { 177 $version += 1; 178 } 179 180 p_set_metadata($id, array(METADATA_VERSION_KEY => $version)); 181 } 182 } 183 184 /** 185 * Check if the page has to be changed 186 * 187 * @param Doku_Event $event event object by reference 188 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 189 * handler was registered] 190 * @return void 191 */ 192 public function handle_parser_metadata_render(Doku_Event $event, $param) { 193 global $ID; 194 $id = $ID; 195 if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $id)) return; 196 197 if (!isset($event->data['persistent'][METADATA_VERSION_KEY])) { 198 $event->data['persistent'][METADATA_VERSION_KEY] = $this->calculateVersion($id); 199 } 200 201 202 } 203 204 /** 205 * Calculate current version 206 * 207 * @param $id 208 * @return int 209 */ 210 protected function calculateVersion($id) { 211 $version = 1; 212 213 $changelog = new PageChangeLog($id); 214 $first = 0; 215 $num = 100; 216 while (count($revs = $changelog->getRevisions($first, $num)) > 0) { 217 foreach ($revs as $rev) { 218 $revInfo = $changelog->getRevisionInfo($rev); 219 if ($revInfo['sum'] == APPROVED) { 220 $version += 1; 221 } 222 } 223 $first += $num; 224 } 225 226 return $version; 227 } 228 229} 230