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