187fdbc6bSMichael Große<?php 287fdbc6bSMichael Große/** 387fdbc6bSMichael Große * DokuWiki Plugin struct (Admin Component) 487fdbc6bSMichael Große * 587fdbc6bSMichael Große * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 687fdbc6bSMichael Große * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 787fdbc6bSMichael Große */ 887fdbc6bSMichael Große 987fdbc6bSMichael Großeuse dokuwiki\Form\Form; 10f36cc634SAndreas Gohruse dokuwiki\plugin\struct\meta\CSVExporter; 111fc2361fSSzymon Olewniczakuse dokuwiki\plugin\struct\meta\CSVLookupImporter; 121fc2361fSSzymon Olewniczakuse dokuwiki\plugin\struct\meta\CSVPageImporter; 13ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Schema; 14ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\SchemaBuilder; 15ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\SchemaEditor; 16ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\SchemaImporter; 17ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\StructException; 1887fdbc6bSMichael Große 19d5a1a6dcSAndreas Gohr// must be run within Dokuwiki 2087fdbc6bSMichael Großeif(!defined('DOKU_INC')) die(); 2187fdbc6bSMichael Große 2287fdbc6bSMichael Großeclass admin_plugin_struct_schemas extends DokuWiki_Admin_Plugin { 2387fdbc6bSMichael Große 2487fdbc6bSMichael Große /** 2587fdbc6bSMichael Große * @return int sort number in admin menu 2687fdbc6bSMichael Große */ 2787fdbc6bSMichael Große public function getMenuSort() { 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 */ 3487fdbc6bSMichael Große public function forAdminOnly() { 354d220607SAndreas Gohr return false; 3687fdbc6bSMichael Große } 3787fdbc6bSMichael Große 3887fdbc6bSMichael Große /** 3987fdbc6bSMichael Große * Should carry out any processing required by the plugin. 4087fdbc6bSMichael Große */ 4187fdbc6bSMichael Große public function handle() { 4287fdbc6bSMichael Große global $INPUT; 43d5a1a6dcSAndreas Gohr global $ID; 44e33460e2SMichael Grosse global $config_cascade; 45e33460e2SMichael Grosse $config_file_path = end($config_cascade['main']['local']); 4687fdbc6bSMichael Große 478ddf87afSAndreas Gohr // form submit 4887fdbc6bSMichael Große $table = Schema::cleanTableName($INPUT->str('table')); 4987fdbc6bSMichael Große if($table && $INPUT->bool('save') && checkSecurityToken()) { 50d5a1a6dcSAndreas Gohr $builder = new SchemaBuilder($table, $INPUT->arr('schema')); 5187fdbc6bSMichael Große if(!$builder->build()) { 5287fdbc6bSMichael Große msg('something went wrong while saving', -1); 5387fdbc6bSMichael Große } 54ae5c46faSAndreas Gohr touch(action_plugin_struct_cache::getSchemaRefreshFile()); 5587fdbc6bSMichael Große } 568ddf87afSAndreas Gohr // export 57d486d6d7SAndreas Gohr if($table && $INPUT->bool('export')) { 58d5a1a6dcSAndreas Gohr $builder = new Schema($table); 59d486d6d7SAndreas Gohr header('Content-Type: application/json'); 60d486d6d7SAndreas Gohr header("Content-Disposition: attachment; filename=$table.struct.json"); 61d486d6d7SAndreas Gohr echo $builder->toJSON(); 62d486d6d7SAndreas Gohr exit; 63d486d6d7SAndreas Gohr } 648ddf87afSAndreas Gohr // import 658ddf87afSAndreas Gohr if($table && $INPUT->bool('import')) { 668ddf87afSAndreas Gohr if(isset($_FILES['schemafile']['tmp_name'])) { 678ddf87afSAndreas Gohr $json = io_readFile($_FILES['schemafile']['tmp_name'], false); 688ddf87afSAndreas Gohr if(!$json) { 698ddf87afSAndreas Gohr msg('Something went wrong with the upload', -1); 708ddf87afSAndreas Gohr } else { 710845722bSAndreas Gohr $builder = new SchemaImporter($table, $json, $INPUT->bool('lookup')); 728ddf87afSAndreas Gohr if(!$builder->build()) { 738ddf87afSAndreas Gohr msg('something went wrong while saving', -1); 748ddf87afSAndreas Gohr } 75ae5c46faSAndreas Gohr touch(action_plugin_struct_cache::getSchemaRefreshFile()); 768ddf87afSAndreas Gohr } 778ddf87afSAndreas Gohr } 788ddf87afSAndreas Gohr } 79a0b3799eSAndreas Gohr 80a0b3799eSAndreas Gohr // import CSV 81a0b3799eSAndreas Gohr if($table && $INPUT->bool('importcsv')) { 82a0b3799eSAndreas Gohr if(isset($_FILES['csvfile']['tmp_name'])) { 83a0b3799eSAndreas Gohr try { 841fc2361fSSzymon Olewniczak if ($INPUT->bool('lookup')) { 851fc2361fSSzymon Olewniczak $csvImporter = new CSVLookupImporter($table, $_FILES['csvfile']['tmp_name']); 861fc2361fSSzymon Olewniczak } else { 871fc2361fSSzymon Olewniczak $csvImporter = new CSVPageImporter($table, $_FILES['csvfile']['tmp_name']); 881fc2361fSSzymon Olewniczak } 891fc2361fSSzymon Olewniczak $csvImporter->import(); 901fc2361fSSzymon Olewniczak 916d2df532SAndreas Gohr msg($this->getLang('admin_csvdone'), 1); 92a0b3799eSAndreas Gohr } catch(StructException $e) { 93a0b3799eSAndreas Gohr msg(hsc($e->getMessage()), -1); 94a0b3799eSAndreas Gohr } 95a0b3799eSAndreas Gohr } 96a0b3799eSAndreas Gohr } 97a0b3799eSAndreas Gohr 98f36cc634SAndreas Gohr // export CSV 99f36cc634SAndreas Gohr if($table && $INPUT->bool('exportcsv')) { 100f36cc634SAndreas Gohr header('Content-Type: text/csv'); 101f36cc634SAndreas Gohr header('Content-Disposition: attachment; filename="' . $table . '.csv";'); 102f36cc634SAndreas Gohr new CSVExporter($table); 103f36cc634SAndreas Gohr exit(); 104f36cc634SAndreas Gohr } 105f36cc634SAndreas Gohr 106d5a1a6dcSAndreas Gohr // delete 107d5a1a6dcSAndreas Gohr if($table && $INPUT->bool('delete')) { 108d5a1a6dcSAndreas Gohr if($table != $INPUT->str('confirm')) { 109d5a1a6dcSAndreas Gohr msg($this->getLang('del_fail'), -1); 110d5a1a6dcSAndreas Gohr } else { 111d5a1a6dcSAndreas Gohr try { 112d5a1a6dcSAndreas Gohr $schema = new Schema($table); 113d5a1a6dcSAndreas Gohr $schema->delete(); 114d5a1a6dcSAndreas Gohr msg($this->getLang('del_ok'), 1); 115ae5c46faSAndreas Gohr touch(action_plugin_struct_cache::getSchemaRefreshFile()); 116d5a1a6dcSAndreas Gohr send_redirect(wl($ID, array('do' => 'admin', 'page' => 'struct_schemas'), true, '&')); 117d5a1a6dcSAndreas Gohr } catch(StructException $e) { 118d5a1a6dcSAndreas Gohr msg(hsc($e->getMessage()), -1); 119d5a1a6dcSAndreas Gohr } 120d5a1a6dcSAndreas Gohr } 121d5a1a6dcSAndreas Gohr } 122d5a1a6dcSAndreas Gohr 12379c83e06SMichael Große // clear 12479c83e06SMichael Große if($table && $INPUT->bool('clear')) { 12579c83e06SMichael Große if($table != $INPUT->str('confirm_clear')) { 12679c83e06SMichael Große msg($this->getLang('clear_fail'), -1); 12779c83e06SMichael Große } else { 12879c83e06SMichael Große try { 12979c83e06SMichael Große $schema = new Schema($table); 13079c83e06SMichael Große $schema->clear(); 13179c83e06SMichael Große msg($this->getLang('clear_ok'), 1); 13279c83e06SMichael Große touch(action_plugin_struct_cache::getSchemaRefreshFile()); 13379c83e06SMichael Große send_redirect(wl($ID, array('do' => 'admin', 'page' => 'struct_schemas'), true, '&')); 13479c83e06SMichael Große } catch(StructException $e) { 13579c83e06SMichael Große msg(hsc($e->getMessage()), -1); 13679c83e06SMichael Große } 13779c83e06SMichael Große } 13879c83e06SMichael Große } 13979c83e06SMichael Große 14087fdbc6bSMichael Große } 14187fdbc6bSMichael Große 14287fdbc6bSMichael Große /** 14387fdbc6bSMichael Große * Render HTML output, e.g. helpful text and a form 14487fdbc6bSMichael Große */ 14587fdbc6bSMichael Große public function html() { 14687fdbc6bSMichael Große global $INPUT; 14787fdbc6bSMichael Große 14887fdbc6bSMichael Große $table = Schema::cleanTableName($INPUT->str('table')); 14987fdbc6bSMichael Große if($table) { 1507c080d69SAndreas Gohr $schema = new Schema($table, 0, $INPUT->bool('lookup')); 1517c080d69SAndreas Gohr if($schema->isLookup()) { 1527c080d69SAndreas Gohr $hl = 'edithl lookup'; 1537c080d69SAndreas Gohr } else { 1547c080d69SAndreas Gohr $hl = 'edithl page'; 1557c080d69SAndreas Gohr } 1567c080d69SAndreas Gohr 1576af24d3eSAndreas Gohr echo $this->locale_xhtml('editor_edit'); 1587c080d69SAndreas Gohr echo '<h2>' . sprintf($this->getLang($hl), hsc($table)) . '</h2>'; 1598ddf87afSAndreas Gohr 1608ddf87afSAndreas Gohr echo '<ul class="tabs" id="plugin__struct_tabs">'; 1618ddf87afSAndreas Gohr /** @noinspection HtmlUnknownAnchorTarget */ 1628ddf87afSAndreas Gohr echo '<li class="active"><a href="#plugin__struct_editor">' . $this->getLang('tab_edit') . '</a></li>'; 1638ddf87afSAndreas Gohr /** @noinspection HtmlUnknownAnchorTarget */ 1648ddf87afSAndreas Gohr echo '<li><a href="#plugin__struct_json">' . $this->getLang('tab_export') . '</a></li>'; 165d5a1a6dcSAndreas Gohr /** @noinspection HtmlUnknownAnchorTarget */ 166d5a1a6dcSAndreas Gohr echo '<li><a href="#plugin__struct_delete">' . $this->getLang('tab_delete') . '</a></li>'; 1678ddf87afSAndreas Gohr echo '</ul>'; 1688ddf87afSAndreas Gohr echo '<div class="panelHeader"></div>'; 1698ddf87afSAndreas Gohr 1707c080d69SAndreas Gohr $editor = new SchemaEditor($schema); 17187fdbc6bSMichael Große echo $editor->getEditor(); 1720845722bSAndreas Gohr echo $this->html_json($schema); 1730845722bSAndreas Gohr echo $this->html_delete($schema); 174d486d6d7SAndreas Gohr 17587fdbc6bSMichael Große } else { 1766af24d3eSAndreas Gohr echo $this->locale_xhtml('editor_intro'); 1778ddf87afSAndreas Gohr echo $this->html_newschema(); 17887fdbc6bSMichael Große } 17987fdbc6bSMichael Große } 18087fdbc6bSMichael Große 18187fdbc6bSMichael Große /** 1828ddf87afSAndreas Gohr * Form for handling import/export from/to JSON 1830845722bSAndreas Gohr * 1840845722bSAndreas Gohr * @param Schema $schema 1858ddf87afSAndreas Gohr * @return string 1868ddf87afSAndreas Gohr */ 1870845722bSAndreas Gohr protected function html_json(Schema $schema) { 1888ddf87afSAndreas Gohr $form = new Form(array('enctype' => 'multipart/form-data', 'id' => 'plugin__struct_json')); 1898ddf87afSAndreas Gohr $form->setHiddenField('do', 'admin'); 1908ddf87afSAndreas Gohr $form->setHiddenField('page', 'struct_schemas'); 1910845722bSAndreas Gohr $form->setHiddenField('table', $schema->getTable()); 1920845722bSAndreas Gohr $form->setHiddenField('lookup', $schema->isLookup()); 1938ddf87afSAndreas Gohr 1948ddf87afSAndreas Gohr $form->addFieldsetOpen($this->getLang('export')); 1958ddf87afSAndreas Gohr $form->addButton('export', $this->getLang('btn_export')); 1968ddf87afSAndreas Gohr $form->addFieldsetClose(); 1978ddf87afSAndreas Gohr 1988ddf87afSAndreas Gohr $form->addFieldsetOpen($this->getLang('import')); 199*0911f726SMichael Große $form->addElement((new \dokuwiki\Form\InputElement('file', 'schemafile'))->attr('accept', '.json')); 2008ddf87afSAndreas Gohr $form->addButton('import', $this->getLang('btn_import')); 2018ddf87afSAndreas Gohr $form->addHTML('<p>' . $this->getLang('import_warning') . '</p>'); 2028ddf87afSAndreas Gohr $form->addFieldsetClose(); 203a0b3799eSAndreas Gohr 2046d2df532SAndreas Gohr $form->addFieldsetOpen($this->getLang('admin_csvexport')); 205f36cc634SAndreas Gohr $form->addButton('exportcsv', $this->getLang('btn_export')); 206f36cc634SAndreas Gohr $form->addFieldsetClose(); 207f36cc634SAndreas Gohr 2086d2df532SAndreas Gohr $form->addFieldsetOpen($this->getLang('admin_csvimport')); 209*0911f726SMichael Große $form->addElement((new \dokuwiki\Form\InputElement('file', 'csvfile'))->attr('accept', '.csv')); 210a0b3799eSAndreas Gohr $form->addButton('importcsv', $this->getLang('btn_import')); 21117dbef8aSMichael Große $form->addCheckbox('createPage', 'Create missing pages')->addClass('block'); 2126d2df532SAndreas Gohr $form->addHTML('<p><a href="https://www.dokuwiki.org/plugin:struct:csvimport">' . $this->getLang('admin_csvhelp') . '</a></p>'); 213a0b3799eSAndreas Gohr $form->addFieldsetClose(); 214a0b3799eSAndreas Gohr 2158ddf87afSAndreas Gohr return $form->toHTML(); 2168ddf87afSAndreas Gohr } 2178ddf87afSAndreas Gohr 2188ddf87afSAndreas Gohr /** 219d5a1a6dcSAndreas Gohr * Form for deleting schemas 2200845722bSAndreas Gohr * 2210845722bSAndreas Gohr * @param Schema $schema 222d5a1a6dcSAndreas Gohr * @return string 223d5a1a6dcSAndreas Gohr */ 2240845722bSAndreas Gohr protected function html_delete(Schema $schema) { 225d5a1a6dcSAndreas Gohr $form = new Form(array('id' => 'plugin__struct_delete')); 226d5a1a6dcSAndreas Gohr $form->setHiddenField('do', 'admin'); 227d5a1a6dcSAndreas Gohr $form->setHiddenField('page', 'struct_schemas'); 2280845722bSAndreas Gohr $form->setHiddenField('table', $schema->getTable()); 229d5a1a6dcSAndreas Gohr 23079c83e06SMichael Große $form->addFieldsetOpen($this->getLang('btn_delete')); 231d5a1a6dcSAndreas Gohr $form->addHTML($this->locale_xhtml('delete_intro')); 232d5a1a6dcSAndreas Gohr $form->addTextInput('confirm', $this->getLang('del_confirm')); 233d5a1a6dcSAndreas Gohr $form->addButton('delete', $this->getLang('btn_delete')); 234d5a1a6dcSAndreas Gohr $form->addFieldsetClose(); 23579c83e06SMichael Große 23679c83e06SMichael Große $form->addFieldsetOpen($this->getLang('btn_clear')); 23779c83e06SMichael Große $form->addHTML($this->locale_xhtml('clear_intro')); 23879c83e06SMichael Große $form->addTextInput('confirm_clear', $this->getLang('clear_confirm')); 23979c83e06SMichael Große $form->addButton('clear', $this->getLang('btn_clear')); 24079c83e06SMichael Große $form->addFieldsetClose(); 24179c83e06SMichael Große 242d5a1a6dcSAndreas Gohr return $form->toHTML(); 243d5a1a6dcSAndreas Gohr } 244d5a1a6dcSAndreas Gohr 245d5a1a6dcSAndreas Gohr /** 24687fdbc6bSMichael Große * Form to add a new schema 2478ddf87afSAndreas Gohr * 2488ddf87afSAndreas Gohr * @return string 24987fdbc6bSMichael Große */ 25087fdbc6bSMichael Große protected function html_newschema() { 25187fdbc6bSMichael Große $form = new Form(); 2524e427bd5SAndreas Gohr $form->addClass('struct_newschema'); 25387fdbc6bSMichael Große $form->addFieldsetOpen($this->getLang('create')); 25487fdbc6bSMichael Große $form->setHiddenField('do', 'admin'); 255dbffe06eSAndreas Gohr $form->setHiddenField('page', 'struct_schemas'); 25687fdbc6bSMichael Große $form->addTextInput('table', $this->getLang('schemaname')); 2574e427bd5SAndreas Gohr $form->addRadioButton('lookup', $this->getLang('page schema'))->val('0')->attr('checked', 'checked'); 2584e427bd5SAndreas Gohr $form->addRadioButton('lookup', $this->getLang('lookup schema'))->val('1'); 25987fdbc6bSMichael Große $form->addButton('', $this->getLang('save')); 26087fdbc6bSMichael Große $form->addHTML('<p>' . $this->getLang('createhint') . '</p>'); // FIXME is that true? we probably could 26187fdbc6bSMichael Große $form->addFieldsetClose(); 2628ddf87afSAndreas Gohr return $form->toHTML(); 26387fdbc6bSMichael Große } 26487fdbc6bSMichael Große 26587fdbc6bSMichael Große /** 26687fdbc6bSMichael Große * Adds all available schemas to the Table of Contents 26787fdbc6bSMichael Große * 26887fdbc6bSMichael Große * @return array 26987fdbc6bSMichael Große */ 27087fdbc6bSMichael Große public function getTOC() { 27187fdbc6bSMichael Große global $ID; 27287fdbc6bSMichael Große 27387fdbc6bSMichael Große $toc = array(); 2748ddf87afSAndreas Gohr $link = wl( 2758ddf87afSAndreas Gohr $ID, array( 27687fdbc6bSMichael Große 'do' => 'admin', 277dbffe06eSAndreas Gohr 'page' => 'struct_assignments' 2788ddf87afSAndreas Gohr ) 2798ddf87afSAndreas Gohr ); 280dbffe06eSAndreas Gohr $toc[] = html_mktocitem($link, $this->getLang('menu_assignments'), 0, ''); 2817c080d69SAndreas Gohr $slink = wl( 2828ddf87afSAndreas Gohr $ID, array( 283dbffe06eSAndreas Gohr 'do' => 'admin', 284dbffe06eSAndreas Gohr 'page' => 'struct_schemas' 2858ddf87afSAndreas Gohr ) 2868ddf87afSAndreas Gohr ); 2877c080d69SAndreas Gohr $toc[] = html_mktocitem($slink, $this->getLang('menu'), 0, ''); 28887fdbc6bSMichael Große 2897c080d69SAndreas Gohr $tables = Schema::getAll('page'); 2907c080d69SAndreas Gohr if($tables) { 2917c080d69SAndreas Gohr $toc[] = html_mktocitem($slink, $this->getLang('page schema'), 1, ''); 292097f4a53SAndreas Gohr foreach($tables as $table) { 2938ddf87afSAndreas Gohr $link = wl( 2948ddf87afSAndreas Gohr $ID, array( 29587fdbc6bSMichael Große 'do' => 'admin', 296dbffe06eSAndreas Gohr 'page' => 'struct_schemas', 297097f4a53SAndreas Gohr 'table' => $table 2988ddf87afSAndreas Gohr ) 2998ddf87afSAndreas Gohr ); 30087fdbc6bSMichael Große 3017c080d69SAndreas Gohr $toc[] = html_mktocitem($link, hsc($table), 2, ''); 30287fdbc6bSMichael Große } 3037c080d69SAndreas Gohr } 3047c080d69SAndreas Gohr 3057c080d69SAndreas Gohr $tables = Schema::getAll('lookup'); 3067c080d69SAndreas Gohr if($tables) { 3077c080d69SAndreas Gohr $toc[] = html_mktocitem($slink, $this->getLang('lookup schema'), 1, ''); 3087c080d69SAndreas Gohr foreach($tables as $table) { 3097c080d69SAndreas Gohr $link = wl( 3107c080d69SAndreas Gohr $ID, array( 3117c080d69SAndreas Gohr 'do' => 'admin', 3127c080d69SAndreas Gohr 'page' => 'struct_schemas', 3137c080d69SAndreas Gohr 'table' => $table 3147c080d69SAndreas Gohr ) 3157c080d69SAndreas Gohr ); 3167c080d69SAndreas Gohr 3177c080d69SAndreas Gohr $toc[] = html_mktocitem($link, hsc($table), 2, ''); 3187c080d69SAndreas Gohr } 3197c080d69SAndreas Gohr } 3207c080d69SAndreas Gohr 32187fdbc6bSMichael Große return $toc; 32287fdbc6bSMichael Große } 32387fdbc6bSMichael Große 324a0b3799eSAndreas Gohr 325a0b3799eSAndreas Gohr 32687fdbc6bSMichael Große} 32787fdbc6bSMichael Große 32887fdbc6bSMichael Große// vim:ts=4:sw=4:et: 329