1<?php 2 3if(!defined('DOKU_INC')) die(); 4define(APPROVED, 'Approved'); 5define(READY_FOR_APPROVAL, 'Ready for approval'); 6 7class action_plugin_approve_approve extends DokuWiki_Action_Plugin { 8 9 private $hlp; 10 function __construct(){ 11 $this->hlp = plugin_load('helper', 'approve'); 12 } 13 14 function register(Doku_Event_Handler $controller) { 15 16 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_approve, array()); 17 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_viewer, array()); 18 $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, handle_diff_accept, array()); 19 $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, handle_display_banner, array()); 20 $controller->register_hook('HTML_SHOWREV_OUTPUT', 'BEFORE', $this, handle_showrev, array()); 21 } 22 23 function handle_diff_accept(Doku_Event $event, $param) { 24 global $ID; 25 26 if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return; 27 28 if ($event->data == 'diff' && isset($_GET['approve'])) { 29 ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&approve=approve">'.$this->getLang('approve').'</a>'); 30 } 31 32 if ($event->data == 'diff' && isset($_GET['ready_for_approval'])) { 33 ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&ready_for_approval=ready_for_approval">'.$this->getLang('approve_ready').'</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 can_edit() { 51 global $ID; 52 return auth_quickaclcheck($ID) >= AUTH_EDIT; 53 } 54 55 function handle_approve(Doku_Event $event, $param) { 56 global $ID, $REV, $INFO; 57 58 if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return; 59 60 if ($event->data == 'show' && isset($_GET['approve'])) { 61 if ( ! $this->can_approve()) return; 62 63 //change last commit comment to Approved 64 $meta = p_read_metadata($ID); 65 $meta[current][last_change][sum] = $meta[persistent][last_change][sum] = APPROVED; 66 $meta[current][last_change][user] = $meta[persistent][last_change][user] = $INFO[client]; 67 if (!array_key_exists($INFO[client], $meta[current][contributor])) { 68 $meta[current][contributor][$INFO[client]] = $INFO[userinfo][name]; 69 $meta[persistent][contributor][$INFO[client]] = $INFO[userinfo][name]; 70 } 71 p_save_metadata($ID, $meta); 72 //update changelog 73 //remove last line from file 74 $changelog_file = metaFN($ID, '.changes'); 75 $changes = file($changelog_file, FILE_SKIP_EMPTY_LINES); 76 $lastLogLine = array_pop($changes); 77 $info = parseChangelogLine($lastLogLine); 78 79 $info[user] = $INFO[client]; 80 $info[sum] = APPROVED; 81 82 $logline = implode("\t", $info)."\n"; 83 array_push($changes, $logline); 84 85 io_saveFile($changelog_file, implode('', $changes)); 86 87 header('Location: ?id='.$ID); 88 } 89 90 if ($event->data == 'show' && isset($_GET['ready_for_approval'])) { 91 if ( ! $this->can_edit()) return; 92 93 //change last commit comment to Approved 94 $meta = p_read_metadata($ID); 95 $meta[current][last_change][sum] = $meta[persistent][last_change][sum] = READY_FOR_APPROVAL; 96 $meta[current][last_change][user] = $meta[persistent][last_change][user] = $INFO[client]; 97 if (!array_key_exists($INFO[client], $meta[current][contributor])) { 98 $meta[current][contributor][$INFO[client]] = $INFO[userinfo][name]; 99 $meta[persistent][contributor][$INFO[client]] = $INFO[userinfo][name]; 100 } 101 p_save_metadata($ID, $meta); 102 //update changelog 103 //remove last line from file 104 $changelog_file = metaFN($ID, '.changes'); 105 $changes = file($changelog_file, FILE_SKIP_EMPTY_LINES); 106 $lastLogLine = array_pop($changes); 107 $info = parseChangelogLine($lastLogLine); 108 109 $info[user] = $INFO[client]; 110 $info[sum] = APPROVED; 111 112 $logline = implode("\t", $info)."\n"; 113 array_push($changes, $logline); 114 115 io_saveFile($changelog_file, implode('', $changes)); 116 117 header('Location: ?id='.$ID); 118 } 119 } 120 function handle_viewer(Doku_Event $event, $param) { 121 global $REV, $ID; 122 if ($event->data != 'show') return; 123 if (auth_quickaclcheck($ID) > AUTH_READ || ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID))) return; 124 125 $last = $this->find_lastest_approved(); 126 //no page is approved 127 if ($last == -1) return; 128 //approved page is the newest page 129 if ($last == 0) return; 130 131 //if we are viewing lastest revision, show last approved 132 if ($REV == 0) header("Location: ?id=$ID&rev=$last"); 133 } 134 function find_lastest_approved() { 135 global $ID; 136 $m = p_get_metadata($ID); 137 $sum = $m['last_change']['sum']; 138 if ($sum == APPROVED) 139 return 0; 140 141 $changelog = new PageChangeLog($ID); 142 //wyszukaj najnowszej zatwierdzonej 143 //poszukaj w dół 144 $chs = $changelog->getRevisions(0, 10000); 145 foreach ($chs as $rev) { 146 $ch = $changelog->getRevisionInfo($rev); 147 if ($ch['sum'] == APPROVED) 148 return $rev; 149 } 150 return -1; 151 } 152 153 function handle_display_banner(Doku_Event $event, $param) { 154 global $ID, $REV, $INFO; 155 156 if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return; 157 if ($event->data != 'show') return; 158 if (!$INFO['exists']) return; 159 160 $sum = $this->hlp->page_sum($ID, $REV); 161 162 ptln('<div class="approval '.($sum == APPROVED ? 'approved_yes' : ($sum == READY_FOR_APPROVAL ? 'approved_ready' :'approved_no')).'">'); 163 164 tpl_pageinfo(); 165 ptln(' | '); 166 $last_approved_rev = $this->find_lastest_approved(); 167 if ($sum == APPROVED) { 168 ptln('<span>'.$this->getLang('approved').'</span>'); 169 if ($REV != 0 && auth_quickaclcheck($ID) > AUTH_READ) { 170 ptln('<a href="'.wl($ID).'">'); 171 ptln($this->getLang($m['last_change']['sum'] == APPROVED ? 'newest_approved' : 'newest_draft')); 172 ptln('</a>'); 173 } else if ($REV != 0 && $REV != $last_approved_rev) { 174 ptln('<a href="'.wl($ID).'">'); 175 ptln($this->getLang('newest_approved')); 176 ptln('</a>'); 177 } 178 } else { 179 ptln('<span>'.$this->getLang('draft').'</span>'); 180 181 if ($sum == READY_FOR_APPROVAL) { 182 ptln('<span>| '.$this->getLang('marked_approve_ready').'</span>'); 183 } 184 185 186 if ($last_approved_rev == -1) { 187 if ($REV != 0) { 188 ptln('<a href="'.wl($ID).'">'); 189 ptln($this->getLang('newest_draft')); 190 ptln('</a>'); 191 } 192 } else { 193 if ($last_approved_rev != 0) 194 ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev)).'">'); 195 else 196 ptln('<a href="'.wl($ID).'">'); 197 198 ptln($this->getLang('newest_approved')); 199 ptln('</a>'); 200 } 201 202 if ($REV == 0 && $this->can_edit() && $sum != READY_FOR_APPROVAL) { 203 ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff', 204 'ready_for_approval' => 'ready_for_approval')).'">'); 205 ptln($this->getLang('approve_ready')); 206 ptln('</a>'); 207 } 208 209 //można zatwierdzać tylko najnowsze strony 210 if ($REV == 0 && $this->can_approve()) { 211 ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff', 212 'approve' => 'approve')).'">'); 213 ptln($this->getLang('approve')); 214 ptln('</a>'); 215 } 216 217 218 } 219 ptln('</div>'); 220 } 221 222} 223