xref: /plugin/addnewpage/syntax.php (revision d36b62c63952c124e76297294fabc51938236ffb)
1<?php
2
3// must be run within Dokuwiki
4if (!defined('DOKU_INC')) die();
5
6if (!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../../') . '/');
7if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
8require_once(DOKU_PLUGIN . 'syntax.php');
9
10/**
11 * Add-New-Page Plugin: a simple form for adding new pages.
12 *
13 * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
14 * @author   iDO <ido@idotech.info>
15 * @author   Sam Wilson <sam@samwilson.id.au>
16 */
17class syntax_plugin_addnewpage extends DokuWiki_Syntax_Plugin {
18
19    /**
20     * Get some information about this plugin.
21     *
22     * @return array The info array.
23     */
24    function getInfo() {
25        return array(
26            'author' => 'iDo, Sam Wilson, Michael Braun',
27            'email' => '',
28            'date' => '2013-05-17',
29            'name' => 'addnewpage',
30            'desc' => 'Adds a "new page form" to any wiki page.',
31            'url' => 'https://wiki.dokuwiki.org/plugin:addnewpage',
32        );
33    }
34
35    function getType() { return 'substition'; }
36
37    function getPType() { return 'block'; }
38
39    function getSort() { return 199; }
40
41    function connectTo($mode) {
42        $this->Lexer->addSpecialPattern('\{\{NEWPAGE[^\}]*\}\}', $mode, 'plugin_addnewpage');
43    }
44
45    function handle($match, $state, $pos, &$handler) {
46        $ns = substr($match, 10, -2);  // strip markup
47        return array($ns); // use an array here
48    }
49
50    /**
51     * Create the new-page form.
52     *
53     * @return boolean
54     */
55    function render($mode, &$renderer, $data) {
56        global $lang;
57        $renderer->info['cache'] = false;
58        $data = $data[0]; // get data back from the array
59
60        if ($mode == 'xhtml') {
61            $ns_select = $this->_makecombo($data);
62            if ($ns_select == $this->getLang('nooption')) {
63                $renderer->doc .= (!$this->getConf('addpage_hideACL')) ? $ns_select : '';
64                return true;
65            }
66
67            $button_val = ((@$this->getLang('okbutton')) ? $this->getLang('okbutton') : 'ok');
68            $form = '<div class="addnewpage">'.DOKU_LF
69                .DOKU_TAB.'<form name="addnewpage" method="get" action="'.DOKU_BASE.DOKU_SCRIPT.'" accept-charset="'.$lang['encoding'].'">'.DOKU_LF
70                .DOKU_TAB.DOKU_TAB.$ns_select.DOKU_LF
71                .DOKU_TAB.DOKU_TAB.'<input class="edit" type="text" name="title" size="20" maxlength="255" tabindex="2" />'.DOKU_LF
72                .DOKU_TAB.DOKU_TAB.'<input type="hidden" name="do" value="edit" />'.DOKU_LF
73                .DOKU_TAB.DOKU_TAB.'<input type="hidden" name="id" />'.DOKU_LF
74                .DOKU_TAB.DOKU_TAB.'<input class="button" type="submit" value="'.$button_val.'" tabindex="3" />'.DOKU_LF
75                .DOKU_TAB.'</form>'.DOKU_LF
76                .'</div>';
77            $renderer->doc .= $form;
78
79            return true;
80        }
81        return false;
82    }
83
84    /**
85     * Parse namespace request
86     *
87     * @author Samuele Tognini <samuele@cli.di.unipi.it>
88     * @author Michael Braun <michael-dev@fami-braun.de>
89     */
90    function _parse_ns($ns) {
91        global $ID;
92        if ($ns == "@PAGE@") return $ID;
93        if ($ns == "@NS@") return getNS($ID);
94        $ns = preg_replace("/^\.(:|$)/", dirname(str_replace(':', '/', $ID)) . "$1", $ns);
95        $ns = str_replace("/", ":", $ns);
96        $ns = cleanID($ns);
97        return $ns;
98    }
99
100    /**
101     * Create the HTML Select element for namespace selection.
102     *
103     * @global string $ID The page ID
104     * @param string|false $dest_ns The destination namespace, or false if none provided.
105     * @return string Select element with appropriate NS selected.
106     */
107    function _makecombo($dest_ns) {
108        global $ID;
109
110        // If a NS has been provided:
111        // Whether to hide the NS selection (otherwise, show only subnamespaces).
112        $hide = $this->getConf('addpage_hide');
113
114        // Whether the user can create pages in the provided NS (or root, if no
115        // destination NS has been set.
116        $can_create = (auth_quickaclcheck($dest_ns.":") >= AUTH_CREATE);
117
118        if (!empty($dest_ns) && $hide) {
119            if ($can_create) {
120                return '<input type="hidden" name="np_cat" id="np_cat" value="'.$this->_parse_ns($dest_ns).'"/>';
121            } else {
122                return $this->getLang('nooption');
123            }
124        }
125
126        $ns = explode(':', $ID);
127        array_pop($ns);
128        $ns = implode(':', $ns);
129
130        $r = $this->_getnslist("");
131        $ret = '<select class="edit" id="np_cat" name="np_cat" tabindex="1">';
132
133        // Whether the NS select element has any options
134        $someopt=false;
135
136        // Show root namespace if requested and allowed
137        if ($this->getConf('addpage_showroot') && $can_create) {
138            if (empty($dest_ns)) {
139                // If no namespace has been provided, add an option for the root NS.
140                $option_text = ((@$this->getLang('namespaceRoot'))?$this->getLang('namespaceRoot'):'top');
141                $ret.='<option '.(($ns=='')?'selected ':'').'value="">'.$option_text.'</option>';
142                $someopt=true;
143            } else {
144                // If a namespace has been provided, add an option for it.
145                $ret.='<option '.(($ns==$dest_ns)?'selected ':'').'value="'.$dest_ns.'">'.$dest_ns.'</option>';
146                $someopt=true;
147            }
148        }
149
150        foreach ($r as $k => $v) {
151            if ($data != '') {
152                if (strpos(":" . $v, ":" . $data . ":") === false) {
153                    continue;
154                }
155            }
156            if (auth_quickaclcheck($v . ":") < AUTH_CREATE) continue;
157            $vv = explode(':', $v);
158            $vv = str_repeat('&nbsp;&nbsp;', substr_count($v, ':')) . $vv[count($vv) - 1];
159            $ret.='<option '.(($ns == $v) ? 'selected ' : '').'value="'.$v.'">'.$vv.'</option>';
160            $someopt = true;
161        }
162        $ret.='</select>';
163        if (!$someopt) $ret = $this->getLang('nooption');
164
165        return $ret;
166    }
167
168    function _getnslist($tns = '') {
169        require_once(DOKU_INC . 'inc/search.php');
170        global $conf;
171        if ($tns == '') $tns = $conf['datadir'];
172        if (!is_dir($tns)) $tns = str_replace(':', '/', $tns);
173        $data = array();
174        $exclude = $this->getConf('addpage_exclude');
175
176        if ($exclude == "") $exclude = array();
177        else $exclude = @explode(';', strtolower($exclude));
178
179        search($data, $tns, 'search_index', array('ns' => ''));
180
181        $data2 = array();
182        foreach ($data as $k => $v) {
183            if ($v['type'] == 'd') {
184                if (!in_array(strtolower($v['id']), $exclude)) {
185                    array_push($data2, $v['id']);
186                    $r = $this->_getnslist($tns . '/' . $v['id']);
187                    foreach ($r as $vv) {
188                        if (!in_array(strtolower($vv), $exclude)) {
189                            array_push($data2, $v['id'] . ':' . $vv);
190                        }
191                    }
192                }
193            }
194        }
195        return $data2;
196    }
197
198}
199