1*ff9bc75fSJarrod Lowe<?php 2*ff9bc75fSJarrod Lowe// see action.php for details 3*ff9bc75fSJarrod Lowe 4*ff9bc75fSJarrod Lowe 5*ff9bc75fSJarrod Lowe// must be run within DokuWiki 6*ff9bc75fSJarrod Loweif(!defined('DOKU_INC')) die(); 7*ff9bc75fSJarrod Lowe 8*ff9bc75fSJarrod Loweif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 9*ff9bc75fSJarrod Lowerequire_once(DOKU_PLUGIN.'syntax.php'); 10*ff9bc75fSJarrod Lowerequire_once(DOKU_PLUGIN.'publish/shared.php'); 11*ff9bc75fSJarrod Lowerequire_once(DOKU_INC.'inc/search.php'); 12*ff9bc75fSJarrod Lowe 13*ff9bc75fSJarrod Lowe 14*ff9bc75fSJarrod Lowe// filter out pages which can't be approved by the current user 15*ff9bc75fSJarrod Lowe// then check if they need approving 16*ff9bc75fSJarrod Lowefunction search_helper(&$data, $base, $file, $type, $lvl, $opts) { 17*ff9bc75fSJarrod Lowe $ns = $opts[0]; 18*ff9bc75fSJarrod Lowe $valid_ns = $opts[1]; 19*ff9bc75fSJarrod Lowe if($type == 'd') { return in_sub_namespace($valid_ns, $ns . ':' . str_replace('/', ':', $file)); } 20*ff9bc75fSJarrod Lowe if(!preg_match('#\.txt$#', $file)) { return false; } 21*ff9bc75fSJarrod Lowe $id = pathID($ns . $file); 22*ff9bc75fSJarrod Lowe if(!in_namespace($valid_ns, $id)) { return false; } 23*ff9bc75fSJarrod Lowe if(auth_quickaclcheck($id) < AUTH_DELETE) { return false; } //insufficent permissions 24*ff9bc75fSJarrod Lowe $meta = p_get_metadata($id); 25*ff9bc75fSJarrod Lowe if($meta['approval'][$meta['last_change']['date']]) { 26*ff9bc75fSJarrod Lowe # Already approved 27*ff9bc75fSJarrod Lowe return false; 28*ff9bc75fSJarrod Lowe } 29*ff9bc75fSJarrod Lowe $data[] = array($id, $meta['approval'], $meta['last_change']['date']); 30*ff9bc75fSJarrod Lowe return false; 31*ff9bc75fSJarrod Lowe} 32*ff9bc75fSJarrod Lowe 33*ff9bc75fSJarrod Lowefunction pagesorter($a, $b){ 34*ff9bc75fSJarrod Lowe $ac = explode(':',$a[0]); 35*ff9bc75fSJarrod Lowe $bc = explode(':',$b[0]); 36*ff9bc75fSJarrod Lowe $an = count($ac); 37*ff9bc75fSJarrod Lowe $bn = count($bc); 38*ff9bc75fSJarrod Lowe 39*ff9bc75fSJarrod Lowe # Same number of elements, can just string sort 40*ff9bc75fSJarrod Lowe if($an == $bn) { return strcmp($a[0], $b[0]); } 41*ff9bc75fSJarrod Lowe 42*ff9bc75fSJarrod Lowe # For each level: 43*ff9bc75fSJarrod Lowe # If this is not the last element in either list: 44*ff9bc75fSJarrod Lowe # same -> continue 45*ff9bc75fSJarrod Lowe # otherwise strcmp 46*ff9bc75fSJarrod Lowe # If this is the last element in either list, it wins 47*ff9bc75fSJarrod Lowe $n = 0; 48*ff9bc75fSJarrod Lowe while(true) { 49*ff9bc75fSJarrod Lowe if($n + 1 == $an) { return -1; } 50*ff9bc75fSJarrod Lowe if($n + 1 == $bn) { return 1; } 51*ff9bc75fSJarrod Lowe $s = strcmp($ac[$n], $bc[$n]); 52*ff9bc75fSJarrod Lowe if($s != 0) { return $s; } 53*ff9bc75fSJarrod Lowe $n += 1; 54*ff9bc75fSJarrod Lowe } 55*ff9bc75fSJarrod Lowe} 56*ff9bc75fSJarrod Lowe 57*ff9bc75fSJarrod Loweclass syntax_plugin_publish extends DokuWiki_Syntax_Plugin { 58*ff9bc75fSJarrod Lowe 59*ff9bc75fSJarrod Lowe function getInfo(){ return publish_getInfo(); } 60*ff9bc75fSJarrod Lowe 61*ff9bc75fSJarrod Lowe function pattern() { return '\[APPROVALS.*?\]'; } 62*ff9bc75fSJarrod Lowe function getType() { return 'substition'; } 63*ff9bc75fSJarrod Lowe function getSort() { return 20; } 64*ff9bc75fSJarrod Lowe function PType() { return 'block'; } 65*ff9bc75fSJarrod Lowe function connectTo($mode) { $this->Lexer->addSpecialPattern($this->pattern(),$mode,'plugin_publish'); } 66*ff9bc75fSJarrod Lowe function handle($match, $state, $pos, &$handler){ 67*ff9bc75fSJarrod Lowe $namespace = substr($match, 11, -1); 68*ff9bc75fSJarrod Lowe return array($match, $state, $pos, $namespace); 69*ff9bc75fSJarrod Lowe } 70*ff9bc75fSJarrod Lowe 71*ff9bc75fSJarrod Lowe function render($mode, &$renderer, $data) { 72*ff9bc75fSJarrod Lowe global $conf; 73*ff9bc75fSJarrod Lowe 74*ff9bc75fSJarrod Lowe if($mode == 'xhtml'){ 75*ff9bc75fSJarrod Lowe $ns = cleanID(getNS($data[3] . ":dummy")); 76*ff9bc75fSJarrod Lowe $dir = $conf['datadir'] . '/' . str_replace(':', '/', $ns); 77*ff9bc75fSJarrod Lowe $pages = array(); 78*ff9bc75fSJarrod Lowe search($pages, $dir, 'search_helper', array($ns, $this->getConf('apr_namespaces'))); 79*ff9bc75fSJarrod Lowe if(count($pages) == 0) { 80*ff9bc75fSJarrod Lowe $renderer->doc .= '<p class="apr_none">' . $this->getLang('apr_p_none') . '</p>'; 81*ff9bc75fSJarrod Lowe return true; 82*ff9bc75fSJarrod Lowe } 83*ff9bc75fSJarrod Lowe usort($pages, pagesorter); 84*ff9bc75fSJarrod Lowe 85*ff9bc75fSJarrod Lowe # Output Table 86*ff9bc75fSJarrod Lowe $renderer->doc .= '<table class="apr_table"><tr class="apr_head">'; 87*ff9bc75fSJarrod Lowe $renderer->doc .= '<th class="apr_page">' . $this->getLang('apr_p_hdr_page') . '</th>'; 88*ff9bc75fSJarrod Lowe $renderer->doc .= '<th class="apr_prev">' . $this->getLang('apr_p_hdr_previous') . '</th>'; 89*ff9bc75fSJarrod Lowe $renderer->doc .= '<th class="apr_upd">' . $this->getLang('apr_p_hdr_updated') . '</th>'; 90*ff9bc75fSJarrod Lowe $renderer->doc .= '</tr>'; 91*ff9bc75fSJarrod Lowe $working_ns = null; 92*ff9bc75fSJarrod Lowe foreach($pages as $page) { 93*ff9bc75fSJarrod Lowe # $page: 0 -> pagename, 1 -> approval metadata, 2 -> last changed date 94*ff9bc75fSJarrod Lowe $this_ns = getNS($page[0]); 95*ff9bc75fSJarrod Lowe if($this_ns != $working_ns) { 96*ff9bc75fSJarrod Lowe $name_ns = $this_ns; 97*ff9bc75fSJarrod Lowe if($this_ns == '') { $name_ns = 'root'; } 98*ff9bc75fSJarrod Lowe $renderer->doc .= '<tr class="apr_ns"><td colspan="3"><a href="'; 99*ff9bc75fSJarrod Lowe $renderer->doc .= wl($this_ns . ':' . $this->getConf('start')); 100*ff9bc75fSJarrod Lowe $renderer->doc .= '">'; 101*ff9bc75fSJarrod Lowe $renderer->doc .= $name_ns; 102*ff9bc75fSJarrod Lowe $renderer->doc .= '</a></td></tr>'; 103*ff9bc75fSJarrod Lowe $working_ns = $this_ns; 104*ff9bc75fSJarrod Lowe } 105*ff9bc75fSJarrod Lowe $updated = '<a href="' . wl($page[0]) . '">' . date('d/m/Y H:i', $page[2]) . '</a>'; 106*ff9bc75fSJarrod Lowe if($page[1] == null || count($page[1]) == 0) { 107*ff9bc75fSJarrod Lowe # Has never been approved 108*ff9bc75fSJarrod Lowe $approved = ''; 109*ff9bc75fSJarrod Lowe }else{ 110*ff9bc75fSJarrod Lowe $keys = array_keys($page[1]); 111*ff9bc75fSJarrod Lowe sort($keys); 112*ff9bc75fSJarrod Lowe $last = $keys[count($keys)-1]; 113*ff9bc75fSJarrod Lowe $approved .= sprintf($this->getLang('apr_p_approved'), 114*ff9bc75fSJarrod Lowe $page[1][$last][1], 115*ff9bc75fSJarrod Lowe wl($page[0], 'rev=' . $last), 116*ff9bc75fSJarrod Lowe date('d/m/Y H:i', $last)); 117*ff9bc75fSJarrod Lowe if($last == $page[2]) { $updated = 'Unchanged'; } //shouldn't be possible: 118*ff9bc75fSJarrod Lowe //the search_helper should have 119*ff9bc75fSJarrod Lowe //excluded this 120*ff9bc75fSJarrod Lowe } 121*ff9bc75fSJarrod Lowe 122*ff9bc75fSJarrod Lowe $renderer->doc .= '<tr class="apr_table'; 123*ff9bc75fSJarrod Lowe if($approved == '') { $renderer->doc .= ' apr_never'; } 124*ff9bc75fSJarrod Lowe $renderer->doc .= '"><td class="apr_page"><a href="'; 125*ff9bc75fSJarrod Lowe $renderer->doc .= wl($page[0]); 126*ff9bc75fSJarrod Lowe $renderer->doc .= '">'; 127*ff9bc75fSJarrod Lowe $renderer->doc .= $page[0]; 128*ff9bc75fSJarrod Lowe $renderer->doc .= '</a></td><td class="apr_prev">'; 129*ff9bc75fSJarrod Lowe $renderer->doc .= $approved; 130*ff9bc75fSJarrod Lowe $renderer->doc .= '</td><td class="apr_upd">'; 131*ff9bc75fSJarrod Lowe $renderer->doc .= $updated; 132*ff9bc75fSJarrod Lowe $renderer->doc .= '</td></tr>'; 133*ff9bc75fSJarrod Lowe 134*ff9bc75fSJarrod Lowe #$renderer->doc .= '<tr><td colspan="3">' . print_r($page, true) . '</td></tr>'; 135*ff9bc75fSJarrod Lowe } 136*ff9bc75fSJarrod Lowe $renderer->doc .= '</table>'; 137*ff9bc75fSJarrod Lowe return true; 138*ff9bc75fSJarrod Lowe } 139*ff9bc75fSJarrod Lowe return false; 140*ff9bc75fSJarrod Lowe } 141*ff9bc75fSJarrod Lowe 142*ff9bc75fSJarrod Lowe 143*ff9bc75fSJarrod Lowe 144*ff9bc75fSJarrod Lowe} 145*ff9bc75fSJarrod Lowe 146*ff9bc75fSJarrod Lowe?> 147