187fdbc6bSMichael Große<?php 2d6d97f60SAnna Dabrowska 387fdbc6bSMichael Große/** 487fdbc6bSMichael Große * DokuWiki Plugin struct (Admin Component) 587fdbc6bSMichael Große * 687fdbc6bSMichael Große * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 787fdbc6bSMichael Große * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 887fdbc6bSMichael Große */ 987fdbc6bSMichael Große 1087fdbc6bSMichael Großeuse dokuwiki\Form\Form; 11f36cc634SAndreas Gohruse dokuwiki\plugin\struct\meta\CSVExporter; 1269d92b7aSAnna Dabrowskause dokuwiki\plugin\struct\meta\CSVImporter; 131fc2361fSSzymon Olewniczakuse dokuwiki\plugin\struct\meta\CSVPageImporter; 14ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Schema; 15ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\SchemaBuilder; 16ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\SchemaEditor; 17ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\SchemaImporter; 18ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\StructException; 1987fdbc6bSMichael Große 20d6d97f60SAnna Dabrowskaclass admin_plugin_struct_schemas extends DokuWiki_Admin_Plugin 21d6d97f60SAnna Dabrowska{ 2287fdbc6bSMichael Große 2387fdbc6bSMichael Große /** 2487fdbc6bSMichael Große * @return int sort number in admin menu 2587fdbc6bSMichael Große */ 26d6d97f60SAnna Dabrowska public function getMenuSort() 27d6d97f60SAnna Dabrowska { 2887fdbc6bSMichael Große return 500; 2987fdbc6bSMichael Große } 3087fdbc6bSMichael Große 3187fdbc6bSMichael Große /** 3287fdbc6bSMichael Große * @return bool true if only access for superuser, false is for superusers and moderators 3387fdbc6bSMichael Große */ 34d6d97f60SAnna Dabrowska public function forAdminOnly() 35d6d97f60SAnna Dabrowska { 364d220607SAndreas Gohr return false; 3787fdbc6bSMichael Große } 3887fdbc6bSMichael Große 3987fdbc6bSMichael Große /** 4087fdbc6bSMichael Große * Should carry out any processing required by the plugin. 4187fdbc6bSMichael Große */ 42d6d97f60SAnna Dabrowska public function handle() 43d6d97f60SAnna Dabrowska { 4487fdbc6bSMichael Große global $INPUT; 45d5a1a6dcSAndreas Gohr global $ID; 46e33460e2SMichael Grosse global $config_cascade; 47e33460e2SMichael Grosse $config_file_path = end($config_cascade['main']['local']); 4887fdbc6bSMichael Große 498ddf87afSAndreas Gohr // form submit 5087fdbc6bSMichael Große $table = Schema::cleanTableName($INPUT->str('table')); 5187fdbc6bSMichael Große if ($table && $INPUT->bool('save') && checkSecurityToken()) { 52d5a1a6dcSAndreas Gohr $builder = new SchemaBuilder($table, $INPUT->arr('schema')); 5387fdbc6bSMichael Große if (!$builder->build()) { 5487fdbc6bSMichael Große msg('something went wrong while saving', -1); 5587fdbc6bSMichael Große } 56ae5c46faSAndreas Gohr touch(action_plugin_struct_cache::getSchemaRefreshFile()); 5787fdbc6bSMichael Große } 588ddf87afSAndreas Gohr // export 59d486d6d7SAndreas Gohr if ($table && $INPUT->bool('export')) { 60d5a1a6dcSAndreas Gohr $builder = new Schema($table); 61d486d6d7SAndreas Gohr header('Content-Type: application/json'); 62d486d6d7SAndreas Gohr header("Content-Disposition: attachment; filename=$table.struct.json"); 63d486d6d7SAndreas Gohr echo $builder->toJSON(); 64d486d6d7SAndreas Gohr exit; 65d486d6d7SAndreas Gohr } 668ddf87afSAndreas Gohr // import 678ddf87afSAndreas Gohr if ($table && $INPUT->bool('import')) { 688ddf87afSAndreas Gohr if (isset($_FILES['schemafile']['tmp_name'])) { 698ddf87afSAndreas Gohr $json = io_readFile($_FILES['schemafile']['tmp_name'], false); 708ddf87afSAndreas Gohr if (!$json) { 718ddf87afSAndreas Gohr msg('Something went wrong with the upload', -1); 728ddf87afSAndreas Gohr } else { 7369d92b7aSAnna Dabrowska $builder = new SchemaImporter($table, $json); 748ddf87afSAndreas Gohr if (!$builder->build()) { 758ddf87afSAndreas Gohr msg('something went wrong while saving', -1); 768ddf87afSAndreas Gohr } 77ae5c46faSAndreas Gohr touch(action_plugin_struct_cache::getSchemaRefreshFile()); 788ddf87afSAndreas Gohr } 798ddf87afSAndreas Gohr } 808ddf87afSAndreas Gohr } 81a0b3799eSAndreas Gohr 82a0b3799eSAndreas Gohr // import CSV 83a0b3799eSAndreas Gohr if ($table && $INPUT->bool('importcsv')) { 84a0b3799eSAndreas Gohr if (isset($_FILES['csvfile']['tmp_name'])) { 85a0b3799eSAndreas Gohr try { 8669d92b7aSAnna Dabrowska // FIXME 87*28d21c10SAnna Dabrowska $datatype = $INPUT->str('importtype'); 88*28d21c10SAnna Dabrowska if ($datatype === 'page') { 89*28d21c10SAnna Dabrowska $csvImporter = new CSVPageImporter($table, $_FILES['csvfile']['tmp_name'], $datatype); 9069d92b7aSAnna Dabrowska } else { 91*28d21c10SAnna Dabrowska $csvImporter = new CSVImporter($table, $_FILES['csvfile']['tmp_name'], $datatype); 921fc2361fSSzymon Olewniczak } 931fc2361fSSzymon Olewniczak $csvImporter->import(); 946d2df532SAndreas Gohr msg($this->getLang('admin_csvdone'), 1); 95a0b3799eSAndreas Gohr } catch (StructException $e) { 96a0b3799eSAndreas Gohr msg(hsc($e->getMessage()), -1); 97a0b3799eSAndreas Gohr } 98a0b3799eSAndreas Gohr } 99a0b3799eSAndreas Gohr } 100a0b3799eSAndreas Gohr 101f36cc634SAndreas Gohr // export CSV 102f36cc634SAndreas Gohr if ($table && $INPUT->bool('exportcsv')) { 103f36cc634SAndreas Gohr header('Content-Type: text/csv'); 104f36cc634SAndreas Gohr header('Content-Disposition: attachment; filename="' . $table . '.csv";'); 10569d92b7aSAnna Dabrowska new CSVExporter($table, $INPUT->str('exporttype')); 106f36cc634SAndreas Gohr exit(); 107f36cc634SAndreas Gohr } 108f36cc634SAndreas Gohr 109d5a1a6dcSAndreas Gohr // delete 110d5a1a6dcSAndreas Gohr if ($table && $INPUT->bool('delete')) { 111d5a1a6dcSAndreas Gohr if ($table != $INPUT->str('confirm')) { 112d5a1a6dcSAndreas Gohr msg($this->getLang('del_fail'), -1); 113d5a1a6dcSAndreas Gohr } else { 114d5a1a6dcSAndreas Gohr try { 115d5a1a6dcSAndreas Gohr $schema = new Schema($table); 116d5a1a6dcSAndreas Gohr $schema->delete(); 117d5a1a6dcSAndreas Gohr msg($this->getLang('del_ok'), 1); 118ae5c46faSAndreas Gohr touch(action_plugin_struct_cache::getSchemaRefreshFile()); 119d5a1a6dcSAndreas Gohr send_redirect(wl($ID, array('do' => 'admin', 'page' => 'struct_schemas'), true, '&')); 120d5a1a6dcSAndreas Gohr } catch (StructException $e) { 121d5a1a6dcSAndreas Gohr msg(hsc($e->getMessage()), -1); 122d5a1a6dcSAndreas Gohr } 123d5a1a6dcSAndreas Gohr } 124d5a1a6dcSAndreas Gohr } 125d5a1a6dcSAndreas Gohr 12679c83e06SMichael Große // clear 12779c83e06SMichael Große if ($table && $INPUT->bool('clear')) { 12879c83e06SMichael Große if ($table != $INPUT->str('confirm_clear')) { 12979c83e06SMichael Große msg($this->getLang('clear_fail'), -1); 13079c83e06SMichael Große } else { 13179c83e06SMichael Große try { 13279c83e06SMichael Große $schema = new Schema($table); 13379c83e06SMichael Große $schema->clear(); 13479c83e06SMichael Große msg($this->getLang('clear_ok'), 1); 13579c83e06SMichael Große touch(action_plugin_struct_cache::getSchemaRefreshFile()); 13679c83e06SMichael Große send_redirect(wl($ID, array('do' => 'admin', 'page' => 'struct_schemas'), true, '&')); 13779c83e06SMichael Große } catch (StructException $e) { 13879c83e06SMichael Große msg(hsc($e->getMessage()), -1); 13979c83e06SMichael Große } 14079c83e06SMichael Große } 14179c83e06SMichael Große } 14287fdbc6bSMichael Große } 14387fdbc6bSMichael Große 14487fdbc6bSMichael Große /** 14587fdbc6bSMichael Große * Render HTML output, e.g. helpful text and a form 14687fdbc6bSMichael Große */ 147d6d97f60SAnna Dabrowska public function html() 148d6d97f60SAnna Dabrowska { 14987fdbc6bSMichael Große global $INPUT; 15087fdbc6bSMichael Große 15187fdbc6bSMichael Große $table = Schema::cleanTableName($INPUT->str('table')); 15287fdbc6bSMichael Große if ($table) { 1530ceefd5cSAnna Dabrowska $schema = new Schema($table, 0); 1547c080d69SAndreas Gohr 1556af24d3eSAndreas Gohr echo $this->locale_xhtml('editor_edit'); 1560ceefd5cSAnna Dabrowska echo '<h2>' . sprintf($this->getLang('edithl'), hsc($table)) . '</h2>'; 1578ddf87afSAndreas Gohr 1588ddf87afSAndreas Gohr echo '<ul class="tabs" id="plugin__struct_tabs">'; 1598ddf87afSAndreas Gohr /** @noinspection HtmlUnknownAnchorTarget */ 1608ddf87afSAndreas Gohr echo '<li class="active"><a href="#plugin__struct_editor">' . $this->getLang('tab_edit') . '</a></li>'; 1618ddf87afSAndreas Gohr /** @noinspection HtmlUnknownAnchorTarget */ 1628ddf87afSAndreas Gohr echo '<li><a href="#plugin__struct_json">' . $this->getLang('tab_export') . '</a></li>'; 163d5a1a6dcSAndreas Gohr /** @noinspection HtmlUnknownAnchorTarget */ 164d5a1a6dcSAndreas Gohr echo '<li><a href="#plugin__struct_delete">' . $this->getLang('tab_delete') . '</a></li>'; 1658ddf87afSAndreas Gohr echo '</ul>'; 1668ddf87afSAndreas Gohr echo '<div class="panelHeader"></div>'; 1678ddf87afSAndreas Gohr 1687c080d69SAndreas Gohr $editor = new SchemaEditor($schema); 16987fdbc6bSMichael Große echo $editor->getEditor(); 170748e747fSAnna Dabrowska echo $this->htmlJson($schema); 171748e747fSAnna Dabrowska echo $this->htmlDelete($schema); 17287fdbc6bSMichael Große } else { 1736af24d3eSAndreas Gohr echo $this->locale_xhtml('editor_intro'); 174748e747fSAnna Dabrowska echo $this->htmlNewschema(); 17587fdbc6bSMichael Große } 17687fdbc6bSMichael Große } 17787fdbc6bSMichael Große 17887fdbc6bSMichael Große /** 17969d92b7aSAnna Dabrowska * Form for handling import/export from/to JSON and CSV 1800845722bSAndreas Gohr * 1810845722bSAndreas Gohr * @param Schema $schema 1828ddf87afSAndreas Gohr * @return string 1838ddf87afSAndreas Gohr */ 184748e747fSAnna Dabrowska protected function htmlJson(Schema $schema) 185d6d97f60SAnna Dabrowska { 1868ddf87afSAndreas Gohr $form = new Form(array('enctype' => 'multipart/form-data', 'id' => 'plugin__struct_json')); 1878ddf87afSAndreas Gohr $form->setHiddenField('do', 'admin'); 1888ddf87afSAndreas Gohr $form->setHiddenField('page', 'struct_schemas'); 1890845722bSAndreas Gohr $form->setHiddenField('table', $schema->getTable()); 1908ddf87afSAndreas Gohr 19169d92b7aSAnna Dabrowska // schemas 1928ddf87afSAndreas Gohr $form->addFieldsetOpen($this->getLang('export')); 1938ddf87afSAndreas Gohr $form->addButton('export', $this->getLang('btn_export')); 1948ddf87afSAndreas Gohr $form->addFieldsetClose(); 1958ddf87afSAndreas Gohr 1968ddf87afSAndreas Gohr $form->addFieldsetOpen($this->getLang('import')); 1970bd068beSMichael Große $form->addElement(new \dokuwiki\Form\InputElement('file', 'schemafile'))->attr('accept', '.json'); 1988ddf87afSAndreas Gohr $form->addButton('import', $this->getLang('btn_import')); 1998ddf87afSAndreas Gohr $form->addHTML('<p>' . $this->getLang('import_warning') . '</p>'); 2008ddf87afSAndreas Gohr $form->addFieldsetClose(); 201a0b3799eSAndreas Gohr 20269d92b7aSAnna Dabrowska // data 2036d2df532SAndreas Gohr $form->addFieldsetOpen($this->getLang('admin_csvexport')); 20469d92b7aSAnna Dabrowska $form->addTagOpen('legend'); 20569d92b7aSAnna Dabrowska $form->addHTML($this->getLang('admin_csvexport_datatype')); 20669d92b7aSAnna Dabrowska $form->addTagClose('legend'); 20769d92b7aSAnna Dabrowska $form->addRadioButton('exporttype',$this->getLang('admin_csv_page'))->val('page')->attr('checked', 'checked'); 20869d92b7aSAnna Dabrowska $form->addRadioButton('exporttype',$this->getLang('admin_csv_lookup'))->val('lookup'); 20969d92b7aSAnna Dabrowska $form->addRadioButton('exporttype',$this->getLang('admin_csv_serial'))->val('serial'); 21069d92b7aSAnna Dabrowska $form->addHTML('<br>'); 211f36cc634SAndreas Gohr $form->addButton('exportcsv', $this->getLang('btn_export')); 212f36cc634SAndreas Gohr $form->addFieldsetClose(); 213f36cc634SAndreas Gohr 2146d2df532SAndreas Gohr $form->addFieldsetOpen($this->getLang('admin_csvimport')); 21569d92b7aSAnna Dabrowska $form->addTagOpen('legend'); 21669d92b7aSAnna Dabrowska $form->addHTML($this->getLang('admin_csvimport_datatype')); 21769d92b7aSAnna Dabrowska $form->addTagClose('legend'); 218*28d21c10SAnna Dabrowska $form->addRadioButton('importtype',$this->getLang('admin_csv_page'))->val('page')->attr('checked', 'checked'); 219*28d21c10SAnna Dabrowska $form->addRadioButton('importtype',$this->getLang('admin_csv_lookup'))->val('lookup'); 220*28d21c10SAnna Dabrowska $form->addRadioButton('importtype',$this->getLang('admin_csv_serial'))->val('serial'); 22169d92b7aSAnna Dabrowska $form->addHTML('<br>'); 2220bd068beSMichael Große $form->addElement(new \dokuwiki\Form\InputElement('file', 'csvfile'))->attr('accept', '.csv'); 223a0b3799eSAndreas Gohr $form->addButton('importcsv', $this->getLang('btn_import')); 224a22f2592SMichael Große $form->addCheckbox('createPage', 'Create missing pages')->addClass('block edit'); 2256d2df532SAndreas Gohr $form->addHTML('<p><a href="https://www.dokuwiki.org/plugin:struct:csvimport">' . $this->getLang('admin_csvhelp') . '</a></p>'); 226a0b3799eSAndreas Gohr $form->addFieldsetClose(); 227a0b3799eSAndreas Gohr 2288ddf87afSAndreas Gohr return $form->toHTML(); 2298ddf87afSAndreas Gohr } 2308ddf87afSAndreas Gohr 2318ddf87afSAndreas Gohr /** 232d5a1a6dcSAndreas Gohr * Form for deleting schemas 2330845722bSAndreas Gohr * 2340845722bSAndreas Gohr * @param Schema $schema 235d5a1a6dcSAndreas Gohr * @return string 236d5a1a6dcSAndreas Gohr */ 237748e747fSAnna Dabrowska protected function htmlDelete(Schema $schema) 238d6d97f60SAnna Dabrowska { 239d5a1a6dcSAndreas Gohr $form = new Form(array('id' => 'plugin__struct_delete')); 240d5a1a6dcSAndreas Gohr $form->setHiddenField('do', 'admin'); 241d5a1a6dcSAndreas Gohr $form->setHiddenField('page', 'struct_schemas'); 2420845722bSAndreas Gohr $form->setHiddenField('table', $schema->getTable()); 243d5a1a6dcSAndreas Gohr 24479c83e06SMichael Große $form->addFieldsetOpen($this->getLang('btn_delete')); 245d5a1a6dcSAndreas Gohr $form->addHTML($this->locale_xhtml('delete_intro')); 246d5a1a6dcSAndreas Gohr $form->addTextInput('confirm', $this->getLang('del_confirm')); 247d5a1a6dcSAndreas Gohr $form->addButton('delete', $this->getLang('btn_delete')); 248d5a1a6dcSAndreas Gohr $form->addFieldsetClose(); 24979c83e06SMichael Große 25079c83e06SMichael Große $form->addFieldsetOpen($this->getLang('btn_clear')); 25179c83e06SMichael Große $form->addHTML($this->locale_xhtml('clear_intro')); 25279c83e06SMichael Große $form->addTextInput('confirm_clear', $this->getLang('clear_confirm')); 25379c83e06SMichael Große $form->addButton('clear', $this->getLang('btn_clear')); 25479c83e06SMichael Große $form->addFieldsetClose(); 25579c83e06SMichael Große 256d5a1a6dcSAndreas Gohr return $form->toHTML(); 257d5a1a6dcSAndreas Gohr } 258d5a1a6dcSAndreas Gohr 259d5a1a6dcSAndreas Gohr /** 26087fdbc6bSMichael Große * Form to add a new schema 2618ddf87afSAndreas Gohr * 2628ddf87afSAndreas Gohr * @return string 26387fdbc6bSMichael Große */ 264748e747fSAnna Dabrowska protected function htmlNewschema() 265d6d97f60SAnna Dabrowska { 26687fdbc6bSMichael Große $form = new Form(); 2674e427bd5SAndreas Gohr $form->addClass('struct_newschema'); 26887fdbc6bSMichael Große $form->addFieldsetOpen($this->getLang('create')); 26987fdbc6bSMichael Große $form->setHiddenField('do', 'admin'); 270dbffe06eSAndreas Gohr $form->setHiddenField('page', 'struct_schemas'); 27187fdbc6bSMichael Große $form->addTextInput('table', $this->getLang('schemaname')); 27287fdbc6bSMichael Große $form->addButton('', $this->getLang('save')); 27387fdbc6bSMichael Große $form->addHTML('<p>' . $this->getLang('createhint') . '</p>'); // FIXME is that true? we probably could 27487fdbc6bSMichael Große $form->addFieldsetClose(); 2758ddf87afSAndreas Gohr return $form->toHTML(); 27687fdbc6bSMichael Große } 27787fdbc6bSMichael Große 27887fdbc6bSMichael Große /** 27987fdbc6bSMichael Große * Adds all available schemas to the Table of Contents 28087fdbc6bSMichael Große * 28187fdbc6bSMichael Große * @return array 28287fdbc6bSMichael Große */ 283d6d97f60SAnna Dabrowska public function getTOC() 284d6d97f60SAnna Dabrowska { 28587fdbc6bSMichael Große global $ID; 28687fdbc6bSMichael Große 28787fdbc6bSMichael Große $toc = array(); 2888ddf87afSAndreas Gohr $link = wl( 289d6d97f60SAnna Dabrowska $ID, 290d6d97f60SAnna Dabrowska array( 29187fdbc6bSMichael Große 'do' => 'admin', 292dbffe06eSAndreas Gohr 'page' => 'struct_assignments' 2938ddf87afSAndreas Gohr ) 2948ddf87afSAndreas Gohr ); 295dbffe06eSAndreas Gohr $toc[] = html_mktocitem($link, $this->getLang('menu_assignments'), 0, ''); 2967c080d69SAndreas Gohr $slink = wl( 297d6d97f60SAnna Dabrowska $ID, 298d6d97f60SAnna Dabrowska array( 299dbffe06eSAndreas Gohr 'do' => 'admin', 300dbffe06eSAndreas Gohr 'page' => 'struct_schemas' 3018ddf87afSAndreas Gohr ) 3028ddf87afSAndreas Gohr ); 3037c080d69SAndreas Gohr $toc[] = html_mktocitem($slink, $this->getLang('menu'), 0, ''); 30487fdbc6bSMichael Große 3050ceefd5cSAnna Dabrowska $tables = Schema::getAll(); 3067c080d69SAndreas Gohr if ($tables) { 307097f4a53SAndreas Gohr foreach ($tables as $table) { 3088ddf87afSAndreas Gohr $link = wl( 309d6d97f60SAnna Dabrowska $ID, 310d6d97f60SAnna Dabrowska array( 31187fdbc6bSMichael Große 'do' => 'admin', 312dbffe06eSAndreas Gohr 'page' => 'struct_schemas', 313097f4a53SAndreas Gohr 'table' => $table 3148ddf87afSAndreas Gohr ) 3158ddf87afSAndreas Gohr ); 31687fdbc6bSMichael Große 3170ceefd5cSAnna Dabrowska $toc[] = html_mktocitem($link, hsc($table), 1, ''); 3187c080d69SAndreas Gohr } 3197c080d69SAndreas Gohr } 3207c080d69SAndreas Gohr 32187fdbc6bSMichael Große return $toc; 32287fdbc6bSMichael Große } 32387fdbc6bSMichael Große} 32487fdbc6bSMichael Große 32587fdbc6bSMichael Große// vim:ts=4:sw=4:et: 326