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