1<?php 2 3namespace dokuwiki\Ui; 4 5use dokuwiki\Draft; 6use dokuwiki\Extension\Event; 7use dokuwiki\Form\Form; 8 9/** 10 * DokuWiki Page Editor 11 * 12 * @package dokuwiki\Ui 13 */ 14class Editor extends Ui 15{ 16 /** 17 * Display the Edit Window 18 * preprocess edit form data 19 * 20 * @return void 21 * @author Andreas Gohr <andi@splitbrain.org> 22 * 23 * @triggers EDIT_FORM_ADDTEXTAREA 24 */ 25 public function show() 26 { 27 global $INPUT; 28 global $ID; 29 global $REV; 30 global $DATE; 31 global $PRE; 32 global $SUF; 33 global $INFO; 34 global $SUM; 35 global $lang; 36 global $conf; 37 global $TEXT; 38 39 global $license; 40 41 if ($INPUT->has('changecheck')) { 42 $check = $INPUT->str('changecheck'); 43 } elseif (!$INFO['exists']) { 44 // $TEXT has been loaded from page template 45 $check = md5(''); 46 } else { 47 $check = md5($TEXT); 48 } 49 $mod = (md5($TEXT) !== $check); 50 51 $wr = $INFO['writable'] && !$INFO['locked']; 52 53 // intro locale text (edit, rditrev, or read) 54 if ($wr) { 55 $intro = ($REV) ? 'editrev' : 'edit'; 56 } else { 57 // check pseudo action 'source' 58 if (!actionOK('source')) { 59 msg('Command disabled: source', -1); 60 return; 61 } 62 $intro = 'read'; 63 } 64 65 // create the Editor form 66 $form = new Form(['id' => 'dw__editform']); 67 $form->setHiddenField('id', $ID); 68 $form->setHiddenField('rev', $REV); 69 $form->setHiddenField('date', $DATE); 70 $form->setHiddenField('prefix', $PRE . '.'); 71 $form->setHiddenField('suffix', $SUF); 72 $form->setHiddenField('changecheck', $check); 73 74 // prepare data for EDIT_FORM_ALTERNATE event 75 $data = [ 76 'form' => $form, 77 'wr' => $wr, 78 'media_manager' => true, 79 'target' => ($INPUT->has('target') && $wr) ? $INPUT->str('target') : 'section', 80 'intro_locale' => $intro 81 ]; 82 83 if ($data['target'] !== 'section') { 84 // Only emit event if page is writable, section edit data is valid and 85 // edit target is not section. 86 Event::createAndTrigger('EDIT_FORM_ADDTEXTAREA', $data, [$this, 'addTextarea'], true); 87 } else { 88 $this->addTextarea($data); 89 } 90 91 $form->setHiddenField('target', $data['target']); 92 93 if ($INPUT->has('hid')) { 94 $form->setHiddenField('hid', $INPUT->str('hid')); 95 } 96 if ($INPUT->has('codeblockOffset')) { 97 $form->setHiddenField('codeblockOffset', $INPUT->str('codeblockOffset')); 98 } 99 100 $form->addTagOpen('div')->id('wiki__editbar')->addClass('editBar'); 101 102 $form->addTagOpen('div')->id('size__ctl'); 103 $form->addTagClose('div'); 104 105 if ($wr) { 106 // add edit buttons: save, preview, cancel 107 $form->addTagOpen('div')->addClass('editButtons'); 108 $form->addButton('do[save]', $lang['btn_save'])->attr('type', 'submit') 109 ->attrs(['accesskey' => 's', 'tabindex' => '4']) 110 ->id('edbtn__save'); 111 $form->addButton('do[preview]', $lang['btn_preview'])->attr('type', 'submit') 112 ->attrs(['accesskey' => 'p', 'tabindex' => '5']) 113 ->id('edbtn__preview'); 114 $form->addButton('do[cancel]', $lang['btn_cancel'])->attr('type', 'submit') 115 ->attrs(['tabindex' => '6']); 116 $form->addTagClose('div'); // close div editButtons class 117 118 // add a textbox for edit summary 119 $form->addTagOpen('div')->addClass('summary'); 120 $input = $form->addTextInput('summary', $lang['summary']) 121 ->attrs(['size' => '50', 'tabindex' => '2']) 122 ->id('edit__summary')->addClass('edit') 123 ->val($SUM); 124 $input->getLabel()->attr('class', 'nowrap'); 125 126 // adds a checkbox for minor edits for logged in users 127 if ($conf['useacl'] && $INPUT->server->str('REMOTE_USER')) { 128 $form->addHTML(' '); 129 $form->addCheckbox('minor', $lang['minoredit'])->id('edit__minoredit')->addClass('nowrap')->val('1'); 130 } 131 $form->addTagClose('div'); // close div summary class 132 } 133 134 $form->addTagClose('div'); // close div editBar class 135 136 // license note 137 if ($wr && $conf['license']) { 138 $attr = [ 139 'href' => $license[$conf['license']]['url'], 140 'rel' => 'license', 141 'class' => 'urlextern', 142 'target' => $conf['target']['extern'] ?: '' 143 ]; 144 $form->addTagOpen('div')->addClass('license'); 145 $form->addHTML($lang['licenseok'] 146 . ' <a ' . buildAttributes($attr, true) . '>' . $license[$conf['license']]['name'] . '</a>'); 147 $form->addTagClose('div'); 148 } 149 150 // start editor html output 151 if ($wr) { 152 // sets changed to true when previewed 153 tpl_inlineScript('textChanged = ' . ($mod ? 'true' : 'false') . ';'); 154 } 155 156 // print intro locale text (edit, rditrev, or read.txt) 157 if (isset($data['intro_locale'])) { 158 echo p_locale_xhtml($data['intro_locale']); 159 } 160 161 echo '<div class="editBox" role="application">'; 162 163 echo '<div class="toolbar group">'; 164 echo '<div id="tool__bar" class="tool__bar">'; 165 if ($wr && $data['media_manager']) { 166 echo '<a href="' . DOKU_BASE . 'lib/exe/mediamanager.php?ns=' . $INFO['namespace'] . '" target="_blank">'; 167 echo $lang['mediaselect']; 168 echo '</a>'; 169 } 170 echo '</div>'; 171 echo '</div>'; 172 173 echo '<div id="draft__status" class="draft__status">'; 174 $draft = new Draft($ID, $INFO['client']); 175 if ($draft->isDraftAvailable()) { 176 echo $draft->getDraftMessage(); 177 } 178 echo '</div>'; 179 180 echo $form->toHTML('Edit'); 181 182 echo '</div>'; // close div editBox class 183 } 184 185 /** 186 * Display the default edit form (textarea) 187 * 188 * the default action for EDIT_FORM_ADDTEXTAREA 189 * 190 * @param array{wr: bool, media_manager: bool, target: string, intro_locale: string, form: Form} $data 191 */ 192 public function addTextarea(&$data) 193 { 194 global $TEXT; 195 196 if ($data['target'] !== 'section') { 197 msg('No editor for edit target ' . hsc($data['target']) . ' found.', -1); 198 } 199 200 // set textarea attributes 201 $attr = ['tabindex' => '1']; 202 if (!$data['wr']) $attr['readonly'] = 'readonly'; 203 $attr['dir'] = 'auto'; 204 $attr['cols'] = '80'; 205 $attr['rows'] = '10'; 206 207 $data['form']->addTextarea('wikitext', '')->attrs($attr)->val($TEXT) 208 ->id('wiki__text')->addClass('edit'); 209 } 210} 211