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