Editor.php 6.8 KB

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