1<?php
2/**
3 * DokuWiki Plugin jsongendoc (Helper Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Janez Paternoster <janez.paternoster@siol.net>
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) {
11    die();
12}
13
14//Resolve to absolute page ID
15use dokuwiki\File\PageResolver;
16
17class helper_plugin_jsongendoc extends helper_plugin_json {
18
19    /**
20     * Handle extension to syntax_plugin_json_define
21     *
22     * @param array $data Reference to $data, which can be further manipulated
23     */
24    public function handle(&$data) {
25        $json_o = $this->loadHelper('json');
26
27        $mime = isset($data['keys']['mime']) ? $data['keys']['mime'] : '';
28        $template = isset($data['keys']['template']) ? $data['keys']['template'] : '';
29        $namespace = isset($data['keys']['namespace']) ? $data['keys']['namespace'] : '';
30        $select = isset($data['keys']['select']) ? $data['keys']['select'] : '';
31        $docname = isset($data['keys']['docname']) ? strval($data['keys']['docname']) : '';
32
33        if($select) {
34            $select = $json_o->parse_links($select);
35        }
36
37        if(!$namespace) {
38            $namespace = getNS(getID());
39        }
40
41        //mime type for download or undefined for new Dokuwiki page
42        $data['mime'] = $mime;
43        //dokuwiki page ID for template (optional)
44        $data['template'] = $template;
45        //namespace for the new page
46        $data['namespace'] = $namespace;
47        //options for select dropdown (optional)
48        //[name1=>[path,to,name1], name2=>[path,to,name2], ..., template=>[path,to,template]]
49        $data['select'] = $select;
50        //ID for the new page
51        $data['docname'] = $docname;
52
53        //If display is overriden, then show json tabs menu, othervise not.
54        if(!isset($data['keys']['display'])) {
55            $data['display'] = 'error';
56        }
57    }
58
59
60    /**
61     * Render extension to syntax_plugin_json_define
62     *
63     * For parameters see render::syntax_plugin_json_define
64     *
65     * @param array $data from handler
66     * @param array $class definitions for parent div
67     * @param array $data_attr html data attributes
68     * @param array $tabs definitions for jQuery UI tabs widget
69     * @param array $body definitions for jQuery UI tabs widget
70     * @param array $log for reporting errors
71     * @param array $tab_no must incerment for each tab
72     * @param array $tab_number for id attribute
73     */
74    public function render(Doku_Renderer $renderer, &$data, &$class, &$data_attr, &$tabs, &$body, &$log, &$tab_no, $tab_number) {
75        global $ID;
76
77        $data_attr['active'] = $tab_no++;   //make this tab active
78
79        //get (autoincrementing) filename and send it also to the javascript
80        $docname = strval($data['docname']);
81        $data_attr['docname'] = $docname;
82        if(preg_match('/^(\S+?)(#+)$/', $docname, $matches)) {
83            list(, $base, $hash) = $matches;
84            $docname_meta = $base.str_replace('#', '0', $hash);
85            // make absolute path
86            $resolver = new PageResolver($data['namespace'].':page'); // ':page' will be stripped
87            $docname_meta = $resolver->resolveId($docname_meta);
88            //increment is stored in metadata
89            $increment = p_get_metadata($ID, 'jsongendoc_'.$docname_meta);
90            if(is_null($increment)) {
91                $increment = 0;
92            }
93            //replace #### with zero padded $increment
94            $docname = $base.str_pad(strval($increment), strlen($hash), "0", STR_PAD_LEFT);
95        }
96        else {
97            $docname_meta = '';
98        }
99
100        //build select list with data integrated
101        if(is_array($data['select']) && is_array($data['json_combined'])) {
102            $options = array();
103            foreach($data['json_combined'] as $select_data) {
104                //get values from each select parameter
105                $template = $data['template'];
106                $names = array();
107                foreach($data['select'] as $key => $path) {
108                    $v = $select_data;
109                    foreach($path as $tok) {
110                        if(is_array($v) && isset($v[$tok])) {
111                            $v = $v[$tok];
112                        }
113                        else {
114                            $v = null;
115                            break;
116                        }
117                    }
118                    if(is_scalar($v)) {
119                        if($key === 'template') {
120                            $template = strval($v);
121                        }
122                        else {
123                            $names[] = strval($v);
124                        }
125                    }
126                }
127                $name = htmlspecialchars(implode(' - ', $names));
128                $v = htmlspecialchars(json_encode(array('parent_id'=>$ID, 'mime'=> $data['mime'], 'docname_meta'=> $docname_meta,
129                    'template'=>$template, 'namespace'=>$data['namespace'], 'json'=>$select_data)));
130                $options[] = "<option value=\"$v\">$name</option>";
131            }
132            $form = '<select>'.implode($options).'</select>';
133        }
134        else {
135            $v = htmlspecialchars(json_encode(array('parent_id'=>$ID, 'mime'=> $data['mime'], 'docname_meta'=> $docname_meta,
136                'template'=>$data['template'], 'namespace'=>$data['namespace'], 'json'=>$data['json_combined'])));
137            $form = '<select hidden=""><option value="'.$v.'">-</option></select>';
138        }
139
140        //add name field and button to form
141        $form .= '<input type="text" size="20" maxlength="255" value="'.htmlspecialchars($docname).'">';
142        $form .= '<button>'.$this->getLang('add_button').'</button>';
143
144        //jQuery-UI tabs
145        $class[] = 'jsongendoc-plugin';
146        $tabs[] = '<li><a href="#json-tab-'.$tab_number.'-table">Generate Document</a></li>';
147        $body[] =      '<div id="json-tab-'.$tab_number.'-table"><div class="json-gendoc">'.$form.'</div><p class="json-gendoc-msg"></p></div>';
148    }
149}
150