xref: /plugin/publish/syntax.php (revision 1317c8870fb594893a622a47c1f0084841b8ea14)
1ff9bc75fSJarrod Lowe<?php
2f576111dSAndreas Gohr/**
3f576111dSAndreas Gohr * DokuWiki Plugin publish (Syntax Component)
4f576111dSAndreas Gohr *
5f576111dSAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6f576111dSAndreas Gohr * @author  Jarrod Lowe <dokuwiki@rrod.net>
7f576111dSAndreas Gohr * @author  Andreas Gohr <gohr@cosmocode.de>
8f576111dSAndreas Gohr */
9ff9bc75fSJarrod Lowe
10ff9bc75fSJarrod Lowe
11ff9bc75fSJarrod Lowe// must be run within DokuWiki
12ff9bc75fSJarrod Loweif(!defined('DOKU_INC')) die();
13ff9bc75fSJarrod Lowe
14ff9bc75fSJarrod Lowe
15ff9bc75fSJarrod Loweclass syntax_plugin_publish extends DokuWiki_Syntax_Plugin {
16*1317c887SDominik Eckelmann
17*1317c887SDominik Eckelmann    /**
18*1317c887SDominik Eckelmann     * @var helper_plugin_publish
19*1317c887SDominik Eckelmann     */
20f576111dSAndreas Gohr    private $hlp;
21ff9bc75fSJarrod Lowe
22f576111dSAndreas Gohr    function syntax_plugin_publish(){
23f576111dSAndreas Gohr        $this->hlp = plugin_load('helper','publish');
24f576111dSAndreas Gohr    }
25ff9bc75fSJarrod Lowe
2614c32fa0SDominik Eckelmann    function pattern() {
2714c32fa0SDominik Eckelmann        return '\[APPROVALS.*?\]';
2814c32fa0SDominik Eckelmann    }
2914c32fa0SDominik Eckelmann
3014c32fa0SDominik Eckelmann    function getType() {
3114c32fa0SDominik Eckelmann        return 'substition';
3214c32fa0SDominik Eckelmann    }
3314c32fa0SDominik Eckelmann
3414c32fa0SDominik Eckelmann    function getSort() {
3514c32fa0SDominik Eckelmann        return 20;
3614c32fa0SDominik Eckelmann    }
3714c32fa0SDominik Eckelmann
3814c32fa0SDominik Eckelmann    function PType() {
3914c32fa0SDominik Eckelmann        return 'block';
4014c32fa0SDominik Eckelmann    }
4114c32fa0SDominik Eckelmann
4214c32fa0SDominik Eckelmann    function connectTo($mode) {
4314c32fa0SDominik Eckelmann        $this->Lexer->addSpecialPattern($this->pattern(),$mode,'plugin_publish');
4414c32fa0SDominik Eckelmann    }
4514c32fa0SDominik Eckelmann
46ff9bc75fSJarrod Lowe    function handle($match, $state, $pos, &$handler){
47ff9bc75fSJarrod Lowe        $namespace = substr($match, 11, -1);
48ff9bc75fSJarrod Lowe        return array($match, $state, $pos, $namespace);
49ff9bc75fSJarrod Lowe    }
50ff9bc75fSJarrod Lowe
51ff9bc75fSJarrod Lowe    function render($mode, &$renderer, $data) {
52ff9bc75fSJarrod Lowe        global $conf;
53ff9bc75fSJarrod Lowe
5414c32fa0SDominik Eckelmann        if($mode != 'xhtml') {
5514c32fa0SDominik Eckelmann            return false;
5614c32fa0SDominik Eckelmann        }
5714c32fa0SDominik Eckelmann
5814c32fa0SDominik Eckelmann        list($match, $state, $pos, $namespace) = $data;
5914c32fa0SDominik Eckelmann
6014c32fa0SDominik Eckelmann        $namespace = cleanID(getNS($namespace . ":*"));
6114c32fa0SDominik Eckelmann
6214c32fa0SDominik Eckelmann        $pages = $this->getPagesFromNamespace($namespace);
6314c32fa0SDominik Eckelmann
64ff9bc75fSJarrod Lowe        if(count($pages) == 0) {
65ff9bc75fSJarrod Lowe            $renderer->doc .= '<p class="apr_none">' . $this->getLang('apr_p_none') . '</p>';
66ff9bc75fSJarrod Lowe            return true;
67ff9bc75fSJarrod Lowe        }
6814c32fa0SDominik Eckelmann
69f576111dSAndreas Gohr        usort($pages, array($this,'_pagesorter'));
70ff9bc75fSJarrod Lowe
71f576111dSAndreas Gohr        // Output Table
72ff9bc75fSJarrod Lowe        $renderer->doc .= '<table class="apr_table"><tr class="apr_head">';
73ff9bc75fSJarrod Lowe        $renderer->doc .= '<th class="apr_page">' . $this->getLang('apr_p_hdr_page') . '</th>';
74ff9bc75fSJarrod Lowe        $renderer->doc .= '<th class="apr_prev">' . $this->getLang('apr_p_hdr_previous') . '</th>';
75ff9bc75fSJarrod Lowe        $renderer->doc .= '<th class="apr_upd">' . $this->getLang('apr_p_hdr_updated') . '</th>';
76ff9bc75fSJarrod Lowe        $renderer->doc .= '</tr>';
7714c32fa0SDominik Eckelmann
7814c32fa0SDominik Eckelmann
79ff9bc75fSJarrod Lowe        $working_ns = null;
80ff9bc75fSJarrod Lowe        foreach($pages as $page) {
81f576111dSAndreas Gohr            // $page: 0 -> pagename, 1 -> approval metadata, 2 -> last changed date
82ff9bc75fSJarrod Lowe            $this_ns = getNS($page[0]);
8314c32fa0SDominik Eckelmann
84ff9bc75fSJarrod Lowe            if($this_ns != $working_ns) {
85ff9bc75fSJarrod Lowe                $name_ns = $this_ns;
86ff9bc75fSJarrod Lowe                if($this_ns == '') { $name_ns = 'root'; }
87ff9bc75fSJarrod Lowe                $renderer->doc .= '<tr class="apr_ns"><td colspan="3"><a href="';
88ff9bc75fSJarrod Lowe                $renderer->doc .= wl($this_ns . ':' . $this->getConf('start'));
89ff9bc75fSJarrod Lowe                $renderer->doc .= '">';
90ff9bc75fSJarrod Lowe                $renderer->doc .= $name_ns;
91ff9bc75fSJarrod Lowe                $renderer->doc .= '</a></td></tr>';
92ff9bc75fSJarrod Lowe                $working_ns = $this_ns;
93ff9bc75fSJarrod Lowe            }
9414c32fa0SDominik Eckelmann
9513608ae1SAndreas Gohr            $updated = '<a href="' . wl($page[0]) . '">' . dformat($page[2]) . '</a>';
96ff9bc75fSJarrod Lowe            if($page[1] == null || count($page[1]) == 0) {
97f576111dSAndreas Gohr                // Has never been approved
98ff9bc75fSJarrod Lowe                $approved = '';
99ff9bc75fSJarrod Lowe            }else{
100ff9bc75fSJarrod Lowe                $keys = array_keys($page[1]);
101ff9bc75fSJarrod Lowe                sort($keys);
102ff9bc75fSJarrod Lowe                $last = $keys[count($keys)-1];
10314c32fa0SDominik Eckelmann                $approved = sprintf($this->getLang('apr_p_approved'),
104ff9bc75fSJarrod Lowe                    $page[1][$last][1],
105ff9bc75fSJarrod Lowe                    wl($page[0], 'rev=' . $last),
10613608ae1SAndreas Gohr                    dformat($last));
107ff9bc75fSJarrod Lowe                if($last == $page[2]) { $updated = 'Unchanged'; } //shouldn't be possible:
108ff9bc75fSJarrod Lowe                //the search_helper should have
109ff9bc75fSJarrod Lowe                //excluded this
110ff9bc75fSJarrod Lowe            }
111ff9bc75fSJarrod Lowe
112ff9bc75fSJarrod Lowe            $renderer->doc .= '<tr class="apr_table';
113ff9bc75fSJarrod Lowe            if($approved == '') { $renderer->doc .= ' apr_never'; }
114ff9bc75fSJarrod Lowe            $renderer->doc .= '"><td class="apr_page"><a href="';
115ff9bc75fSJarrod Lowe            $renderer->doc .= wl($page[0]);
116ff9bc75fSJarrod Lowe            $renderer->doc .= '">';
117ff9bc75fSJarrod Lowe            $renderer->doc .= $page[0];
118ff9bc75fSJarrod Lowe            $renderer->doc .= '</a></td><td class="apr_prev">';
119ff9bc75fSJarrod Lowe            $renderer->doc .= $approved;
120ff9bc75fSJarrod Lowe            $renderer->doc .= '</td><td class="apr_upd">';
121ff9bc75fSJarrod Lowe            $renderer->doc .= $updated;
122ff9bc75fSJarrod Lowe            $renderer->doc .= '</td></tr>';
123ff9bc75fSJarrod Lowe
124f576111dSAndreas Gohr            //$renderer->doc .= '<tr><td colspan="3">' . print_r($page, true) . '</td></tr>';
125ff9bc75fSJarrod Lowe        }
126ff9bc75fSJarrod Lowe        $renderer->doc .= '</table>';
127ff9bc75fSJarrod Lowe        return true;
128ff9bc75fSJarrod Lowe    }
12914c32fa0SDominik Eckelmann
13014c32fa0SDominik Eckelmann    function getPagesFromNamespace($namespace) {
13114c32fa0SDominik Eckelmann        global $conf;
13214c32fa0SDominik Eckelmann        $dir = $conf['datadir'] . '/' . str_replace(':', '/', $namespace);
13314c32fa0SDominik Eckelmann        $pages = array();
13414c32fa0SDominik Eckelmann        search($pages, $dir, array($this,'_search_helper'), array($namespace, $this->getConf('apr_namespaces')));
13514c32fa0SDominik Eckelmann        return $pages;
136ff9bc75fSJarrod Lowe    }
137ff9bc75fSJarrod Lowe
138f576111dSAndreas Gohr    /**
139f576111dSAndreas Gohr     * search callback function
140f576111dSAndreas Gohr     *
141f576111dSAndreas Gohr     * filter out pages which can't be approved by the current user
142f576111dSAndreas Gohr     * then check if they need approving
143f576111dSAndreas Gohr     */
144f576111dSAndreas Gohr    function _search_helper(&$data, $base, $file, $type, $lvl, $opts) {
145f576111dSAndreas Gohr        $ns = $opts[0];
146f576111dSAndreas Gohr        $valid_ns = $opts[1];
14714c32fa0SDominik Eckelmann
14814c32fa0SDominik Eckelmann        if ($type == 'd') {
14914c32fa0SDominik Eckelmann            return $this->hlp->in_sub_namespace($valid_ns, $ns . ':' . str_replace('/', ':', $file));
15014c32fa0SDominik Eckelmann        }
15114c32fa0SDominik Eckelmann
15214c32fa0SDominik Eckelmann        if (!preg_match('#\.txt$#', $file)) {
15314c32fa0SDominik Eckelmann            return false;
15414c32fa0SDominik Eckelmann        }
15514c32fa0SDominik Eckelmann
156f576111dSAndreas Gohr        $id = pathID($ns . $file);
15714c32fa0SDominik Eckelmann        if (!$this->hlp->in_namespace($valid_ns, $id)) {
15814c32fa0SDominik Eckelmann            return false;
15914c32fa0SDominik Eckelmann        }
16014c32fa0SDominik Eckelmann
16114c32fa0SDominik Eckelmann        if (auth_quickaclcheck($id) < AUTH_DELETE) {
16214c32fa0SDominik Eckelmann            return false;
16314c32fa0SDominik Eckelmann        }
16414c32fa0SDominik Eckelmann
16514c32fa0SDominik Eckelmann        $meta = $this->hlp->getMeta($id);
166*1317c887SDominik Eckelmann        if ($this->hlp->isCurrentRevisionApproved($id)) {
16714c32fa0SDominik Eckelmann
168f576111dSAndreas Gohr            // Already approved
169f576111dSAndreas Gohr            return false;
170f576111dSAndreas Gohr        }
17114c32fa0SDominik Eckelmann
172f576111dSAndreas Gohr        $data[] = array($id, $meta['approval'], $meta['last_change']['date']);
173f576111dSAndreas Gohr        return false;
174f576111dSAndreas Gohr    }
175f576111dSAndreas Gohr
176f576111dSAndreas Gohr    /**
177f576111dSAndreas Gohr     * Custom sort callback
178f576111dSAndreas Gohr     */
179f576111dSAndreas Gohr    function _pagesorter($a, $b){
180f576111dSAndreas Gohr        $ac = explode(':',$a[0]);
181f576111dSAndreas Gohr        $bc = explode(':',$b[0]);
182f576111dSAndreas Gohr        $an = count($ac);
183f576111dSAndreas Gohr        $bn = count($bc);
184f576111dSAndreas Gohr
185f576111dSAndreas Gohr        // Same number of elements, can just string sort
186f576111dSAndreas Gohr        if($an == $bn) { return strcmp($a[0], $b[0]); }
187f576111dSAndreas Gohr
188f576111dSAndreas Gohr        // For each level:
189f576111dSAndreas Gohr        // If this is not the last element in either list:
190f576111dSAndreas Gohr        //   same -> continue
191f576111dSAndreas Gohr        //   otherwise strcmp
192f576111dSAndreas Gohr        // If this is the last element in either list, it wins
193f576111dSAndreas Gohr        $n = 0;
194f576111dSAndreas Gohr        while(true) {
195f576111dSAndreas Gohr            if($n + 1 == $an) { return -1; }
196f576111dSAndreas Gohr            if($n + 1 == $bn) { return 1; }
197f576111dSAndreas Gohr            $s = strcmp($ac[$n], $bc[$n]);
198f576111dSAndreas Gohr            if($s != 0) { return $s; }
199f576111dSAndreas Gohr            $n += 1;
200f576111dSAndreas Gohr        }
201f576111dSAndreas Gohr    }
202ff9bc75fSJarrod Lowe
203ff9bc75fSJarrod Lowe}
204ff9bc75fSJarrod Lowe
205