xref: /plugin/struct/admin/schemas.php (revision a0b3799e3857209811ed06eddf7c60cec2980a26)
1<?php
2/**
3 * DokuWiki Plugin struct (Admin Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
7 */
8
9use dokuwiki\Form\Form;
10use dokuwiki\plugin\struct\meta\CSVImporter;
11use dokuwiki\plugin\struct\meta\Schema;
12use dokuwiki\plugin\struct\meta\SchemaBuilder;
13use dokuwiki\plugin\struct\meta\SchemaEditor;
14use dokuwiki\plugin\struct\meta\SchemaImporter;
15use dokuwiki\plugin\struct\meta\StructException;
16
17// must be run within Dokuwiki
18if(!defined('DOKU_INC')) die();
19
20class admin_plugin_struct_schemas extends DokuWiki_Admin_Plugin {
21
22    /**
23     * @return int sort number in admin menu
24     */
25    public function getMenuSort() {
26        return 500;
27    }
28
29    /**
30     * @return bool true if only access for superuser, false is for superusers and moderators
31     */
32    public function forAdminOnly() {
33        return false;
34    }
35
36    /**
37     * Should carry out any processing required by the plugin.
38     */
39    public function handle() {
40        global $INPUT;
41        global $ID;
42        global $config_cascade;
43        $config_file_path = end($config_cascade['main']['local']);
44
45        // form submit
46        $table = Schema::cleanTableName($INPUT->str('table'));
47        if($table && $INPUT->bool('save') && checkSecurityToken()) {
48            $builder = new SchemaBuilder($table, $INPUT->arr('schema'));
49            if(!$builder->build()) {
50                msg('something went wrong while saving', -1);
51            }
52            touch(action_plugin_struct_cache::getSchemaRefreshFile());
53        }
54        // export
55        if($table && $INPUT->bool('export')) {
56            $builder = new Schema($table);
57            header('Content-Type: application/json');
58            header("Content-Disposition: attachment; filename=$table.struct.json");
59            echo $builder->toJSON();
60            exit;
61        }
62        // import
63        if($table && $INPUT->bool('import')) {
64            if(isset($_FILES['schemafile']['tmp_name'])) {
65                $json = io_readFile($_FILES['schemafile']['tmp_name'], false);
66                if(!$json) {
67                    msg('Something went wrong with the upload', -1);
68                } else {
69                    $builder = new SchemaImporter($table, $json, $INPUT->bool('lookup'));
70                    if(!$builder->build()) {
71                        msg('something went wrong while saving', -1);
72                    }
73                    touch(action_plugin_struct_cache::getSchemaRefreshFile());
74                }
75            }
76        }
77
78        // import CSV
79        if($table && $INPUT->bool('importcsv')) {
80            if(isset($_FILES['csvfile']['tmp_name'])) {
81                try {
82                    new CSVImporter($table, $_FILES['csvfile']['tmp_name']);
83                    msg('CSV imported', 1);
84                } catch(StructException $e) {
85                    msg(hsc($e->getMessage()), -1);
86                }
87            }
88        }
89
90        // delete
91        if($table && $INPUT->bool('delete')) {
92            if($table != $INPUT->str('confirm')) {
93                msg($this->getLang('del_fail'), -1);
94            } else {
95                try {
96                    $schema = new Schema($table);
97                    $schema->delete();
98                    msg($this->getLang('del_ok'), 1);
99                    touch(action_plugin_struct_cache::getSchemaRefreshFile());
100                    send_redirect(wl($ID, array('do' => 'admin', 'page' => 'struct_schemas'), true, '&'));
101                } catch(StructException $e) {
102                    msg(hsc($e->getMessage()), -1);
103                }
104            }
105        }
106
107    }
108
109    /**
110     * Render HTML output, e.g. helpful text and a form
111     */
112    public function html() {
113        global $INPUT;
114
115        $table = Schema::cleanTableName($INPUT->str('table'));
116        if($table) {
117            $schema = new Schema($table, 0, $INPUT->bool('lookup'));
118            if($schema->isLookup()) {
119                $hl = 'edithl lookup';
120            } else {
121                $hl = 'edithl page';
122            }
123
124            echo $this->locale_xhtml('editor_edit');
125            echo '<h2>' . sprintf($this->getLang($hl), hsc($table)) . '</h2>';
126
127            echo '<ul class="tabs" id="plugin__struct_tabs">';
128            /** @noinspection HtmlUnknownAnchorTarget */
129            echo '<li class="active"><a href="#plugin__struct_editor">' . $this->getLang('tab_edit') . '</a></li>';
130            /** @noinspection HtmlUnknownAnchorTarget */
131            echo '<li><a href="#plugin__struct_json">' . $this->getLang('tab_export') . '</a></li>';
132            /** @noinspection HtmlUnknownAnchorTarget */
133            echo '<li><a href="#plugin__struct_delete">' . $this->getLang('tab_delete') . '</a></li>';
134            echo '</ul>';
135            echo '<div class="panelHeader"></div>';
136
137            $editor = new SchemaEditor($schema);
138            echo $editor->getEditor();
139            echo $this->html_json($schema);
140            echo $this->html_delete($schema);
141
142        } else {
143            echo $this->locale_xhtml('editor_intro');
144            echo $this->html_newschema();
145        }
146    }
147
148    /**
149     * Form for handling import/export from/to JSON
150     *
151     * @param Schema $schema
152     * @return string
153     */
154    protected function html_json(Schema $schema) {
155        $form = new Form(array('enctype' => 'multipart/form-data', 'id' => 'plugin__struct_json'));
156        $form->setHiddenField('do', 'admin');
157        $form->setHiddenField('page', 'struct_schemas');
158        $form->setHiddenField('table', $schema->getTable());
159        $form->setHiddenField('lookup', $schema->isLookup());
160
161        $form->addFieldsetOpen($this->getLang('export'));
162        $form->addButton('export', $this->getLang('btn_export'));
163        $form->addFieldsetClose();
164
165        $form->addFieldsetOpen($this->getLang('import'));
166        $form->addElement(new \dokuwiki\Form\InputElement('file', 'schemafile'));
167        $form->addButton('import', $this->getLang('btn_import'));
168        $form->addHTML('<p>' . $this->getLang('import_warning') . '</p>');
169        $form->addFieldsetClose();
170
171        if($schema->isLookup()) {
172            $form->addFieldsetOpen($this->getLang('csvimport'));
173            $form->addElement(new \dokuwiki\Form\InputElement('file', 'csvfile'));
174            $form->addButton('importcsv', $this->getLang('btn_import'));
175            $form->addHTML('<p><a href="https://www.dokuwiki.org/plugin:struct:csvimport">' . $this->getLang('csv_help_link') . '</a></p>');
176            $form->addFieldsetClose();
177        }
178
179        return $form->toHTML();
180    }
181
182    /**
183     * Form for deleting schemas
184     *
185     * @param Schema $schema
186     * @return string
187     */
188    protected function html_delete(Schema $schema) {
189        $form = new Form(array('id' => 'plugin__struct_delete'));
190        $form->setHiddenField('do', 'admin');
191        $form->setHiddenField('page', 'struct_schemas');
192        $form->setHiddenField('table', $schema->getTable());
193
194        $form->addHTML($this->locale_xhtml('delete_intro'));
195
196        $form->addFieldsetOpen($this->getLang('tab_delete'));
197        $form->addTextInput('confirm', $this->getLang('del_confirm'));
198        $form->addButton('delete', $this->getLang('btn_delete'));
199        $form->addFieldsetClose();
200        return $form->toHTML();
201    }
202
203    /**
204     * Form to add a new schema
205     *
206     * @return string
207     */
208    protected function html_newschema() {
209        $form = new Form();
210        $form->addClass('struct_newschema');
211        $form->addFieldsetOpen($this->getLang('create'));
212        $form->setHiddenField('do', 'admin');
213        $form->setHiddenField('page', 'struct_schemas');
214        $form->addTextInput('table', $this->getLang('schemaname'));
215        $form->addRadioButton('lookup', $this->getLang('page schema'))->val('0')->attr('checked', 'checked');
216        $form->addRadioButton('lookup', $this->getLang('lookup schema'))->val('1');
217        $form->addButton('', $this->getLang('save'));
218        $form->addHTML('<p>' . $this->getLang('createhint') . '</p>'); // FIXME is that true? we probably could
219        $form->addFieldsetClose();
220        return $form->toHTML();
221    }
222
223    /**
224     * Adds all available schemas to the Table of Contents
225     *
226     * @return array
227     */
228    public function getTOC() {
229        global $ID;
230
231        $toc = array();
232        $link = wl(
233            $ID, array(
234                   'do' => 'admin',
235                   'page' => 'struct_assignments'
236               )
237        );
238        $toc[] = html_mktocitem($link, $this->getLang('menu_assignments'), 0, '');
239        $slink = wl(
240            $ID, array(
241                   'do' => 'admin',
242                   'page' => 'struct_schemas'
243               )
244        );
245        $toc[] = html_mktocitem($slink, $this->getLang('menu'), 0, '');
246
247        $tables = Schema::getAll('page');
248        if($tables) {
249            $toc[] = html_mktocitem($slink, $this->getLang('page schema'), 1, '');
250            foreach($tables as $table) {
251                $link = wl(
252                    $ID, array(
253                           'do' => 'admin',
254                           'page' => 'struct_schemas',
255                           'table' => $table
256                       )
257                );
258
259                $toc[] = html_mktocitem($link, hsc($table), 2, '');
260            }
261        }
262
263        $tables = Schema::getAll('lookup');
264        if($tables) {
265            $toc[] = html_mktocitem($slink, $this->getLang('lookup schema'), 1, '');
266            foreach($tables as $table) {
267                $link = wl(
268                    $ID, array(
269                           'do' => 'admin',
270                           'page' => 'struct_schemas',
271                           'table' => $table
272                       )
273                );
274
275                $toc[] = html_mktocitem($link, hsc($table), 2, '');
276            }
277        }
278
279        return $toc;
280    }
281
282
283
284}
285
286// vim:ts=4:sw=4:et:
287