1<?php
2/**
3 *
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Myron Turner <turnermm02@shaw.ca>
7 */
8if(!defined('DOKU_INC')) die();
9
10define('REPLACE_DIR', DOKU_INC . 'data/meta/macros/');
11
12/**
13 * All DokuWiki plugins to extend the admin function
14 * need to inherit from this class
15 */
16class admin_plugin_textinsert extends DokuWiki_Admin_Plugin {
17
18    var $output = false;
19    var $macros_file;
20    var $macros_data; //used for html listings
21    /**
22     * handle user request
23     */
24     function __construct() {
25         if(!$this->getConf('farm')) {
26             define('MACROS_FILE', REPLACE_DIR . 'macros.ser');
27         }
28         else {
29             define('MACROS_FILE', metaFN('macros','.ser'));
30         }
31
32     }
33    function handle() {
34
35      $this->macros_file=MACROS_FILE;
36
37      if (!isset($_REQUEST['cmd'])) return;   // first time - nothing to do
38
39      $this->output = '';
40      if (!checkSecurityToken()) return;
41      if (!is_array($_REQUEST['cmd'])) return;
42      $action = "";
43
44      // verify valid values
45      switch (key($_REQUEST['cmd'])) {
46        case 'add' :
47                $action = 'add';
48                $a = $this->add();
49              break;
50
51        case 'delete' :
52                $a = $this->del();
53                break;
54        case 'edit':
55             $a = $this->edit();
56             break;
57      }
58   //    $this->output = print_r($a,true);
59   //  $this->output .= print_r($_REQUEST,true);
60    }
61
62    function add() {
63     $a = $this->get_macros();
64     $macros = $_REQUEST['macro'];
65     $words = $_REQUEST['word'];
66
67      foreach ($macros AS $key=>$value) {
68        if(isset($value) && trim($value)) {
69           if(isset($words[$key]) && trim($words[$key])) {
70             $value =  utf8_deaccent($value);
71             $a[$value] = htmlspecialchars (($words[$key]),ENT_NOQUOTES, 'UTF-8');
72         }
73        }
74     }
75
76     io_saveFile(MACROS_FILE,serialize($a));
77     return $a;
78    }
79
80    function del() {
81      $macros = $this->get_macros();
82
83      $deletions = $_REQUEST['delete'];
84      $keys = array_keys($deletions);
85      foreach ($keys AS $_key) {
86         unset($macros[$_key]);
87      }
88
89      io_saveFile(MACROS_FILE,serialize($macros));
90      return $macros;
91    }
92
93    function edit() {
94       $macros = $this->get_macros();
95
96       $encoded = $_REQUEST['encoded'];
97       $encoded = array_map('urldecode',$encoded);
98       foreach($encoded AS $k=>$val) {
99          $macros[$k] = htmlspecialchars ($val,ENT_NOQUOTES, 'UTF-8', false);
100       }
101        io_saveFile(MACROS_FILE,serialize($macros));
102        return $macros;
103    }
104
105    function get_macros() {
106       if(file_exists(MACROS_FILE)) {
107           $a = unserialize(file_get_contents(MACROS_FILE));
108          if(!is_array($a)) return array();
109           ksort($a);
110           return $a;
111       }
112       return array();
113    }
114
115   function get_delete_list() {
116      $macros = $this->macros_data;
117      ptln('<table cellspacing="4px" width="90%">');
118      foreach($macros as $macro=>$subst) {
119          ptln("<tr><td><input type='checkbox' name='delete[$macro]' value='$subst'>");
120          ptln( "<td style='padding:4px;'>$macro<td>$subst</td>");
121
122      }
123      ptln('</table>');
124   }
125
126   function get_edit_list() {
127      $macros = $this->macros_data;
128      ptln('<table cellspacing="4"><tr><th align="center">Macro</th><th align="center">' . $this->getLang('col_subst') .'</th></tr>');
129      foreach($macros as $macro=>$subst) {
130          ptln("<tr><td align='center'>$macro&nbsp;</td><td>");
131          $encoded = urlencode($subst);
132          if($subst != $encoded) {
133             ptln("<input type = 'hidden' name='encoded[$macro]' value='$encoded'>");
134          }
135          if(strlen($subst) > 80) {
136            ptln ("<textarea cols='55' rows='3' name='edit[$macro]' onchange='replace_encode(this)'>$subst</textarea></td></tr>");
137
138          }
139          else {
140            ptln ("<input type='text' size='80' name='edit[$macro]' onchange='replace_encode(this)' value='$subst'></td></tr>");
141          }
142
143      }
144      ptln('</table>');
145   }
146
147   function view_entries() {
148      $macros = $this->macros_data;
149      ptln('<table cellpadding="8px"  width="90%">');
150      foreach($macros as $macro=>$subst) {
151          ptln( "<tr><td align='center'>$macro<td style='padding: 4px; border-bottom: 1px solid black;'>$subst</tr>");
152
153      }
154      ptln('</table>');
155   }
156
157   function js() {
158
159echo <<<JSFN
160
161 <script type="text/javascript">
162 //<![CDATA[
163    var replace_divs= new Array('macro_add','macro_del','macro_edit','ti_info','macro_list');
164   /**
165    * Edit onChange handler
166    * @param el  input element which has been changed
167    * @desc  if an encode hidden input already exists, its value
168    *        is re-encoded from the text input's value
169    *        If not, a new encoded hidden input is created with the encoded
170    *        value.  The encode input value is used to substitute the new edit values
171    *        in the php edit() function
172   */
173    function replace_encode (el) {
174      var matches = el.name.match(/\[(.*)\]/);
175      if(matches[1]) {
176        var name = 'encoded['+matches[1]+']';
177        var val = el.value;
178        val = val.replace(/>/g,"&gt;");
179        val = val.replace(/</g,"&lt;");
180        if(!el.form[name]) {
181            var encoder = document.createElement('input');
182            encoder.type = 'hidden';
183            encoder.name = name;
184            encoder.value = encodeURIComponent(val);
185            el.form.appendChild(encoder);
186        }
187        else if(el.form[name]) {
188          el.form[name].value = encodeURIComponent(val);
189        }
190      }
191    }
192
193 function ti_getEL(n) {
194      return document.getElementById(n);
195  }
196
197 function replace_show(which) {
198    for(var i in replace_divs) {
199      ti_getEL(replace_divs[i]).style.display='none';
200    }
201    ti_getEL(which).style.display='block';
202    ti_getEL('ti_info_btn').style.display='inline';
203 }
204//]]>
205 </script>
206JSFN;
207
208   }
209    /**
210     * output appropriate html
211     */
212    function html() {
213     $this->macros_data = $this->get_macros();
214     $this->js();
215      if($this->output) {
216        ptln('<pre>' . $this->output . '</pre>');
217      }
218      ptln('<div style="padding:4px" id="ti_info">');
219      ptln('<div style="text-align:right;">');
220      ptln('<button class="button" style="padding:0px;margin:0px;" onclick="replace_show(\'ti_info_btn\');">');
221      ptln($this->getLang('hide_info') .'</button>&nbsp;&nbsp;&nbsp;&nbsp;');
222      ptln('</div>');
223      ptln('<h2>Info</h2>');
224      ptln( $this->locale_xhtml('intro') . '</div>');
225
226      ptln('<div style="padding-bottom:8px;">');
227      ptln('<button class="button" onclick="replace_show(\'macro_add\'); ">');
228      ptln($this->getLang('add_macros') .'</button>&nbsp;&nbsp;');
229
230      ptln('<button class="button" onclick="replace_show(\'macro_del\'); ">');
231      ptln($this->getLang('delete_macros') .'</button>&nbsp;&nbsp;');
232
233      ptln('<button class="button" onclick="replace_show(\'macro_edit\'); ">');
234      ptln($this->getLang('edit_macros') .'</button>&nbsp;&nbsp;');
235
236      ptln('<button class="button" onclick="ti_getEL(\'macro_list\').style.display=\'block\';ti_getEL(\'macro_list\').scrollIntoView();">');
237      ptln($this->getLang('view_macros') .'</button>&nbsp;&nbsp;');
238
239      ptln('<button class="button" onclick="ti_getEL(\'macro_list\').style.display=\'none\';">');
240      ptln($this->getLang('hide_macros') .'</button>&nbsp;&nbsp;');
241
242      ptln('<button class="button" id="ti_info_btn" style="display:none" onclick="ti_getEL(\'ti_info\').style.display=\'block\';">');
243      ptln($this->getLang('show_info') .'</button>');
244
245      ptln('</div>');
246      ptln('<form action="'.wl($ID).'" method="post">');
247
248      // output hidden values to ensure dokuwiki will return back to this plugin
249      ptln('  <input type="hidden" name="do"   value="admin" />');
250      ptln('  <input type="hidden" name="page" value="'.$this->getPluginName().'" />');
251      formSecurityToken();
252
253      ptln('<div id="macro_add" style="display:none">');
254      ptln('<h2>' . $this->getLang('label_add') . '</h2>');
255      ptln( '<table cellspacing="8px"><tr><th>Macro</th><th>' . $this->getLang('col_subst') . '</th></tr>');
256      ptln('<tr><td>  <input type="text" name="macro[A]" id="m_A" value="" /></td>');
257      ptln('<td>  <input type="text" name="word[A]"  size="80" id="w_A" value="" /></td></tr>');
258      ptln('<tr><td>  <input type="text" name="macro[B]" id="m_B" value="" /></td>');
259      ptln('<td>  <input type="text" name="word[B]" size="80" id="w_B" value="" /></td></tr>');
260      ptln('<tr><td>  <input type="text" name="macro[C]" id="m_C" value="" /></td>');
261      ptln('<td>  <input type="text" name="word[C]" size="80"  id="w_C" value="" /></td></tr>');
262      ptln('<tr><td>  <input type="text" name="macro[D]" id="m_D" value="" /></td>');
263      ptln('<td>  <input type="text" name="word[D]" size="80" id="w_C" value="" /></td></tr>');
264      ptln('<tr><td>  <input type="text" name="macro[E]" id="m_E" value="" /></td>');
265      ptln('<td>  <input type="text" name="word[E]" size="80" id="w_E" value="" /></td>');
266      ptln('<tr><td>  <input type="text" name="macro[F]" id="m_F" value="" /></td>');
267      ptln('<td>  <textarea cols="45" name="word[F]" rows="4" id="w_F"></textarea></td>');
268      ptln('</table>');
269      ptln('  <input type="submit" name="cmd[add]"  value="'.$this->getLang('btn_add').'" />');
270      ptln('</div><br />');
271
272      ptln('<div id="macro_del" style="display:none">');
273      ptln('<h2>' . $this->getLang('label_del') . '</h2>');
274      $this->get_delete_list();
275      ptln('<br /><input type="submit" name="cmd[delete]"  value="'.$this->getLang('btn_del').'" />');
276      ptln('</div>');
277
278      ptln('<div id="macro_edit" style="display:none; padding: 8px;">');
279      ptln('<h2>' . $this->getLang('label_edit') . '</h2>');
280      $this->get_edit_list();
281      ptln('<br /><input type="submit" name="cmd[edit]"  value="'.$this->getLang('btn_edit').'" />');
282      ptln('</div>');
283
284      ptln('</form>');
285
286      ptln('<br /><div id="macro_list" style="overflow:auto;display:block;">');
287      ptln('<h2>' . $this->getLang('label_list') .  '</h2>');
288      $this->view_entries();
289      ptln('</div>');
290    }
291
292}
293