1<?php 2/** 3 * DokuWiki Plugin publish (Helper Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Jarrod Lowe <dokuwiki@rrod.net> 7 * @author Andreas Gohr <gohr@cosmocode.de> 8 */ 9 10// must be run within Dokuwiki 11if (!defined('DOKU_INC')) die(); 12 13class helper_plugin_publish extends DokuWiki_Plugin { 14 15 private $sortedApprovedRevisions = null; 16 17 // FIXME find out what this is supposed to do and how it can be done better 18 function in_namespace($valid, $check) { 19 // PHP apparantly does not have closures - 20 // so we will parse $valid ourselves. Wasteful. 21 $valid = preg_split('/\s+/', $valid); 22 //if(count($valid) == 0) { return true; }//whole wiki matches 23 if((count($valid)==1) and ($valid[0]=="")) { return true; }//whole wiki matches 24 $check = trim($check, ':'); 25 $check = explode(':', $check); 26 27 // Check against all possible namespaces 28 foreach($valid as $v) { 29 $v = explode(':', $v); 30 $n = 0; 31 $c = count($v); 32 $matching = 1; 33 34 // Check each element, untill all elements of $v satisfied 35 while($n < $c) { 36 if($v[$n] != $check[$n]) { 37 // not a match 38 $matching = 0; 39 break; 40 } 41 $n += 1; 42 } 43 if($matching == 1) { return true; } // a match 44 } 45 return false; 46 } 47 48 // FIXME find out what this is supposed to do and how it can be done better 49 function in_sub_namespace($valid, $check) { 50 // is check a dir which contains any valid? 51 // PHP apparantly does not have closures - 52 // so we will parse $valid ourselves. Wasteful. 53 $valid = preg_split('/\s+/', $valid); 54 //if(count($valid) == 0) { return true; }//whole wiki matches 55 if((count($valid)==1) and ($valid[0]=="")) { return true; }//whole wiki matches 56 $check = trim($check, ':'); 57 $check = explode(':', $check); 58 59 // Check against all possible namespaces 60 foreach($valid as $v) { 61 $v = explode(':', $v); 62 $n = 0; 63 $c = count($check); //this is what is different from above! 64 $matching = 1; 65 66 // Check each element, untill all elements of $v satisfied 67 while($n < $c) { 68 if($v[$n] != $check[$n]) { 69 // not a match 70 $matching = 0; 71 break; 72 } 73 $n += 1; 74 } 75 if($matching == 1) { return true; } // a match 76 } 77 return false; 78 } 79 80 function canApprove() { 81 global $INFO; 82 global $ID; 83 84 if (!$this->in_namespace($this->getConf('apr_namespaces'), $ID)) { 85 return false; 86 } 87 88 return ($INFO['perm'] >= AUTH_DELETE); 89 } 90 91 function getRevision() { 92 global $INFO; 93 if (!$INFO['rev']) { 94 return $INFO['lastmod']; 95 } 96 return $INFO['rev']; 97 } 98 99 function getApprovals($id = null) { 100 $meta = $this->getMeta($id); 101 if (!isset($meta['meta']['approval'])) { 102 return array(); 103 } 104 $approvals = $meta['meta']['approval']; 105 return $approvals; 106 } 107 108 function getMeta($id = null) { 109 global $ID; 110 if ($id === null || $ID === $id) { 111 global $INFO; 112 return $INFO; 113 } else { 114 return p_get_metadata($id); 115 } 116 } 117 118 function getApprovalsOnRevision($revision) { 119 $approvals = $this->getApprovals(); 120 121 if (isset($approvals[$revision])) { 122 return $approvals[$revision]; 123 } 124 return array(); 125 } 126 127 function getSortedApprovedRevisions() { 128 if ($this->sortedApprovedRevisions === null) { 129 $approvals = $this->getApprovals(); 130 krsort($approvals); 131 $this->sortedApprovedRevisions = $approvals; 132 } 133 return $this->sortedApprovedRevisions; 134 } 135 136 function isRevisionApproved($revision, $id = null) { 137 $approvals = $this->getApprovals($id); 138 if (!isset($approvals[$revision])) { 139 return false; 140 } 141 return (count($approvals[$revision]) >= $this->getConf('number_of_approved')); 142 } 143 144 function isCurrentRevisionApproved() { 145 return $this->isRevisionApproved($this->getRevision()); 146 } 147 148 function getLatestApprovedRevision() { 149 $approvals = $this->getSortedApprovedRevisions(); 150 foreach ($approvals as $revision => $ignored) { 151 if ($this->isRevisionApproved($revision)) { 152 return $revision; 153 } 154 } 155 return 0; 156 } 157 158 function getLastestRevision() { 159 global $INFO; 160 return $INFO['meta']['date']['modified']; 161 } 162 163 function getApprovalDate() { 164 if (!$this->isCurrentRevisionApproved()) { 165 return -1; 166 } 167 168 $approvals = $this->getApprovalsOnRevision($this->getRevision()); 169 uasort($approvals, array(&$this, 'cmpApprovals')); 170 $keys = array_keys($approvals); 171 return $approvals[$keys[$this->getConf('number_of_approved') -1]][3]; 172 173 } 174 175 function cmpApprovals($left, $right) { 176 if ($left[3] == $right[3]) { 177 return 0; 178 } 179 return ($left[3] < $right[3]) ? -1 : 1; 180 } 181 182 function getApprovers() { 183 $approvers = $this->getApprovalsOnRevision($this->getRevision()); 184 $result = array(); 185 foreach ($approvers as $approver) { 186 $result[] = editorinfo($this->getApproverName($approver)); 187 } 188 return $result; 189 } 190 191 function getApproverName($approver) { 192 if ($approver[1]) { 193 return $approver[1]; 194 } 195 if ($approver[2]) { 196 return $approver[2]; 197 } 198 return $approver[0]; 199 } 200 201 function getPreviousApprovedRevision() { 202 $currentRevision = $this->getRevision(); 203 $approvals = $this->getSortedApprovedRevisions(); 204 foreach ($approvals as $revision => $ignored) { 205 if ($revision >= $currentRevision) { 206 continue; 207 } 208 if ($this->isRevisionApproved($revision)) { 209 return $revision; 210 } 211 } 212 return 0; 213 } 214 215} 216