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