1<?php 2 3/** 4 * DokuWiki Action component of DiffPreview Plugin 5 * 6 * @license GPL-2.0-or-later (http://www.gnu.org/licenses/gpl.html) 7 * @author Mikhail I. Izmestev <izmmishao5@gmail.com> 8 * @author Tilwa Qendov <tilwa.qendov@gmail.com> 9 * @version 1.3.1 10 */ 11class action_plugin_diffpreview extends DokuWiki_Action_Plugin 12{ 13 /** 14 * Register its handlers with the DokuWiki's event controller 15 */ 16 public function register(Doku_Event_Handler $controller) 17 { 18 $controller->register_hook('HTML_EDITFORM_OUTPUT', 'BEFORE', $this, '_edit_form'); // release Hogfather and below 19 $controller->register_hook('FORM_EDIT_OUTPUT', 'BEFORE', $this, '_edit_form'); // release Igor and above 20 21 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, '_action_act_preprocess'); 22 $controller->register_hook('TPL_ACT_UNKNOWN', 'BEFORE', $this, '_tpl_act_changes'); 23 } 24 25 /** 26 * Add "Changes" button to the edit form 27 */ 28 public function _edit_form(Doku_Event $event, $param) 29 { 30 $form = $event->data; 31 32 /* Check the DokuWiki release */ 33 if (is_a($form, \dokuwiki\Form\Form::class)) { 34 /* release Igor and above */ 35 36 $pos = $form->findPositionByAttribute('id', 'edbtn__preview'); 37 if ($pos !== false) { 38 $form->addButton('do[changes]', $this->getLang('changes'), $pos+1) 39 ->attr('type', 'submit') 40 ->attrs(['accesskey' => 'c', 'tabindex' => '5']) 41 ->id('edbtn__changes'); 42 } 43 44 } else { 45 /* release Hogfather and below */ 46 47 $preview = $form->findElementById('edbtn__preview'); 48 if ($preview !== false) { 49 $form->insertElement($preview+1, 50 form_makeButton('submit', 'changes', $this->getLang('changes'), 51 array('id' => 'edbtn__changes', 'accesskey' => 'c', 'tabindex' => '5'))); 52 } 53 } 54 } 55 56 /** 57 * Process the "changes" action 58 */ 59 public function _action_act_preprocess(Doku_Event $event, $param) 60 { 61 global $ACT, $INFO; 62 63 $action =& $event->data; 64 65 if (!( /* Valid cases */ 66 $action == 'changes' // Greebo 67 // Frusterick Manners and below... probably 68 || is_array($action) && array_key_exists('changes', $action) 69 )) return; 70 71 /* We check the DokuWiki release */ 72 if (class_exists('\\dokuwiki\\ActionRouter', false)) { 73 /* release Greebo and above */ 74 75 /* See ActionRouter->setupAction() and Action\Preview */ 76 // WARN: Only works because Action\Edit methods are public 77 $ae = new dokuwiki\Action\Edit(); 78 $ae->checkPreconditions(); 79 $this->savedraft(); 80 $ae->preProcess(); 81 82 $event->stopPropagation(); 83 $event->preventDefault(); 84 85 } elseif (function_exists('act_permcheck')) { 86 /* release Frusterick Manners and below */ 87 88 // Same setup as preview: permissions and environment 89 if ('preview' == act_permcheck('preview') 90 && 'preview' == act_edit('preview')) 91 { 92 act_draftsave('preview'); 93 $ACT = 'changes'; 94 95 $event->stopPropagation(); 96 $event->preventDefault(); 97 } else { 98 $ACT = 'preview'; 99 } 100 101 } else { 102 // Fallback 103 $ACT = 'preview'; 104 } 105 } 106 107 /** 108 * Display the "changes" page 109 */ 110 public function _tpl_act_changes(Doku_Event $event, $param) 111 { 112 global $TEXT; 113 global $PRE; 114 global $SUF; 115 116 if ('changes' != $event->data) return; 117 118 /* Check the DokuWiki release */ 119 try { 120 // Try to load the Ui\Editor class ourselves to avoid a fatal error in `class_exists` 121 spl_autoload('\\dokuwiki\\Ui\\Editor'); 122 } catch (Exception $e) {} 123 if (class_exists('\\dokuwiki\\Ui\\Editor', false)) { 124 /* release Igor and above */ 125 (new helper_plugin_diffpreview_changes)->tplContent(); 126 } else { 127 /* release Hogfather and below */ 128 html_edit($TEXT); 129 echo '<br id="scroll__here" />'; 130 html_diff(con($PRE,$TEXT,$SUF)); 131 } 132 133 $event->preventDefault(); 134 } 135 136 /** 137 * Saves a draft on show changes 138 * Returns if the permissions don't allow it 139 * 140 * Copied from dokuwiki\Action\Preview (inc/Action/Preview.php) 141 * so that we use the same draft. The two different versions come from 142 * different releases. 143 */ 144 protected function savedraft() 145 { 146 global $INFO, $ID, $INPUT, $conf; 147 148 if (class_exists('\\dokuwiki\\Draft', false)) { 149 /* Release Hogfather (and above) */ 150 151 $draft = new \dokuwiki\Draft($ID, $INFO['client']); 152 if (!$draft->saveDraft()) { 153 $errors = $draft->getErrors(); 154 foreach ($errors as $error) { 155 msg(hsc($error), -1); 156 } 157 } 158 159 } else { 160 /* Release Greebo and below */ 161 162 if (!$conf['usedraft']) return; 163 if (!$INPUT->post->has('wikitext')) return; 164 165 // ensure environment (safeguard when used via AJAX) 166 assert(isset($INFO['client']), 'INFO.client should have been set'); 167 assert(isset($ID), 'ID should have been set'); 168 169 $draft = array( 170 'id' => $ID, 171 'prefix' => substr($INPUT->post->str('prefix'), 0, -1), 172 'text' => $INPUT->post->str('wikitext'), 173 'suffix' => $INPUT->post->str('suffix'), 174 'date' => $INPUT->post->int('date'), 175 'client' => $INFO['client'], 176 ); 177 $cname = getCacheName($draft['client'] . $ID, '.draft'); 178 if (io_saveFile($cname, serialize($draft))) { 179 $INFO['draft'] = $cname; 180 } 181 } 182 } 183} 184