OSDN Git Service

9a381959447bd745ce68789cd34b7ebecb549863
[pukiwiki/pukiwiki.git] / plugin / edit.inc.php
1 <?php
2 // PukiWiki - Yet another WikiWikiWeb clone.
3 // edit.inc.php
4 // Copyright 2001-2017 PukiWiki Development Team
5 // License: GPL v2 or (at your option) any later version
6 //
7 // Edit plugin (cmd=edit)
8
9 // Remove #freeze written by hand
10 define('PLUGIN_EDIT_FREEZE_REGEX', '/^(?:#freeze(?!\w)\s*)+/im');
11
12 function plugin_edit_action()
13 {
14         global $vars, $_title_edit, $load_template_func;
15
16         if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
17
18         $page = isset($vars['page']) ? $vars['page'] : '';
19
20         check_editable($page, true, true);
21         check_readable($page, true, true);
22
23         if (isset($vars['preview'])) {
24                 return plugin_edit_preview($vars['msg']);
25         } else if ($load_template_func && isset($vars['template'])) {
26                 return plugin_edit_preview_with_template();
27         } else if (isset($vars['write'])) {
28                 return plugin_edit_write();
29         } else if (isset($vars['cancel'])) {
30                 return plugin_edit_cancel();
31         }
32
33         $postdata = @join('', get_source($page));
34         if ($postdata === '') $postdata = auto_template($page);
35         $postdata = remove_author_info($postdata);
36         return array('msg'=>$_title_edit, 'body'=>edit_form($page, $postdata));
37 }
38
39 /**
40  * Preview with template
41  */
42 function plugin_edit_preview_with_template()
43 {
44         global $vars;
45         $msg = '';
46         $page = isset($vars['page']) ? $vars['page'] : '';
47         // Loading template
48         $template_page;
49         if (isset($vars['template_page']) && is_page($template_page = $vars['template_page'])) {
50                 if (is_page_readable($template_page)) {
51                         $msg = remove_author_info(get_source($vars['template_page'], TRUE, TRUE));
52                         // Cut fixed anchors
53                         $msg = preg_replace('/^(\*{1,3}.*)\[#[A-Za-z][\w-]+\](.*)$/m', '$1$2', $msg);
54                 }
55         }
56         return plugin_edit_preview($msg);
57 }
58
59 /**
60  * Preview
61  *
62  * @param msg preview target
63  */
64 function plugin_edit_preview($msg)
65 {
66         global $vars;
67         global $_title_preview, $_msg_preview, $_msg_preview_delete;
68
69         $page = isset($vars['page']) ? $vars['page'] : '';
70
71         $msg = preg_replace(PLUGIN_EDIT_FREEZE_REGEX, '', $msg);
72         $postdata = $msg;
73
74         if (isset($vars['add']) && $vars['add']) {
75                 if (isset($vars['add_top']) && $vars['add_top']) {
76                         $postdata  = $postdata . "\n\n" . @join('', get_source($page));
77                 } else {
78                         $postdata  = @join('', get_source($page)) . "\n\n" . $postdata;
79                 }
80         }
81
82         $body = $_msg_preview . '<br />' . "\n";
83         if ($postdata === '')
84                 $body .= '<strong>' . $_msg_preview_delete . '</strong>';
85         $body .= '<br />' . "\n";
86
87         if ($postdata) {
88                 $postdata = make_str_rules($postdata);
89                 $postdata = explode("\n", $postdata);
90                 $postdata = drop_submit(convert_html($postdata));
91                 $body .= '<div id="preview">' . $postdata . '</div>' . "\n";
92         }
93         $body .= edit_form($page, $msg, $vars['digest'], FALSE);
94
95         return array('msg'=>$_title_preview, 'body'=>$body);
96 }
97
98 // Inline: Show edit (or unfreeze text) link
99 function plugin_edit_inline()
100 {
101         static $usage = '&edit(pagename#anchor[[,noicon],nolabel])[{label}];';
102
103         global $vars, $fixed_heading_anchor_edit;
104
105         if (PKWK_READONLY) return ''; // Show nothing 
106
107         // Arguments
108         $args = func_get_args();
109
110         // {label}. Strip anchor tags only
111         $s_label = strip_htmltag(array_pop($args), FALSE);
112
113         $page = array_shift($args);
114         if ($page === NULL) $page = '';
115         $_noicon = $_nolabel = FALSE;
116         foreach($args as $arg){
117                 switch(strtolower($arg)){
118                 case ''       :                   break;
119                 case 'nolabel': $_nolabel = TRUE; break;
120                 case 'noicon' : $_noicon  = TRUE; break;
121                 default       : return $usage;
122                 }
123         }
124
125         // Separate a page-name and a fixed anchor
126         list($s_page, $id, $editable) = anchor_explode($page, TRUE);
127
128         // Default: This one
129         if ($s_page == '') $s_page = isset($vars['page']) ? $vars['page'] : '';
130
131         // $s_page fixed
132         $isfreeze = is_freeze($s_page);
133         $ispage   = is_page($s_page);
134
135         // Paragraph edit enabled or not
136         $short = htmlsc('Edit');
137         if ($fixed_heading_anchor_edit && $editable && $ispage && ! $isfreeze) {
138                 // Paragraph editing
139                 $id    = rawurlencode($id);
140                 $title = htmlsc(sprintf('Edit %s', $page));
141                 $icon = '<img src="' . IMAGE_DIR . 'paraedit.png' .
142                         '" width="9" height="9" alt="' .
143                         $short . '" title="' . $title . '" /> ';
144                 $class = ' class="anchor_super"';
145         } else {
146                 // Normal editing / unfreeze
147                 $id    = '';
148                 if ($isfreeze) {
149                         $title = 'Unfreeze %s';
150                         $icon  = 'unfreeze.png';
151                 } else {
152                         $title = 'Edit %s';
153                         $icon  = 'edit.png';
154                 }
155                 $title = htmlsc(sprintf($title, $s_page));
156                 $icon = '<img src="' . IMAGE_DIR . $icon .
157                         '" width="20" height="20" alt="' .
158                         $short . '" title="' . $title . '" />';
159                 $class = '';
160         }
161         if ($_noicon) $icon = ''; // No more icon
162         if ($_nolabel) {
163                 if (!$_noicon) {
164                         $s_label = '';     // No label with an icon
165                 } else {
166                         $s_label = $short; // Short label without an icon
167                 }
168         } else {
169                 if ($s_label == '') $s_label = $title; // Rich label with an icon
170         }
171
172         // URL
173         $script = get_base_uri();
174         if ($isfreeze) {
175                 $url   = $script . '?cmd=unfreeze&amp;page=' . rawurlencode($s_page);
176         } else {
177                 $s_id = ($id == '') ? '' : '&amp;id=' . $id;
178                 $url  = $script . '?cmd=edit&amp;page=' . rawurlencode($s_page) . $s_id;
179         }
180         $atag  = '<a' . $class . ' href="' . $url . '" title="' . $title . '">';
181         static $atags = '</a>';
182
183         if ($ispage) {
184                 // Normal edit link
185                 return $atag . $icon . $s_label . $atags;
186         } else {
187                 // Dangling edit link
188                 return '<span class="noexists">' . $atag . $icon . $atags .
189                         $s_label . $atag . '?' . $atags . '</span>';
190         }
191 }
192
193 // Write, add, or insert new comment
194 function plugin_edit_write()
195 {
196         global $vars;
197         global $_title_collided, $_msg_collided_auto, $_msg_collided, $_title_deleted;
198         global $notimeupdate, $_msg_invalidpass, $do_update_diff_table;
199
200         $page   = isset($vars['page'])   ? $vars['page']   : '';
201         $add    = isset($vars['add'])    ? $vars['add']    : '';
202         $digest = isset($vars['digest']) ? $vars['digest'] : '';
203
204         $vars['msg'] = preg_replace(PLUGIN_EDIT_FREEZE_REGEX, '', $vars['msg']);
205         $msg = & $vars['msg']; // Reference
206
207         $retvars = array();
208
209         // Collision Detection
210         $oldpagesrc = join('', get_source($page));
211         $oldpagemd5 = md5($oldpagesrc);
212         if ($digest !== $oldpagemd5) {
213                 $vars['digest'] = $oldpagemd5; // Reset
214
215                 $original = isset($vars['original']) ? $vars['original'] : '';
216                 $old_body = remove_author_info($oldpagesrc);
217                 list($postdata_input, $auto) = do_update_diff($old_body, $msg, $original);
218
219                 $retvars['msg' ] = $_title_collided;
220                 $retvars['body'] = ($auto ? $_msg_collided_auto : $_msg_collided) . "\n";
221                 $retvars['body'] .= $do_update_diff_table;
222                 $retvars['body'] .= edit_form($page, $postdata_input, $oldpagemd5, FALSE);
223                 return $retvars;
224         }
225
226         // Action?
227         if ($add) {
228                 // Add
229                 if (isset($vars['add_top']) && $vars['add_top']) {
230                         $postdata  = $msg . "\n\n" . @join('', get_source($page));
231                 } else {
232                         $postdata  = @join('', get_source($page)) . "\n\n" . $msg;
233                 }
234         } else {
235                 // Edit or Remove
236                 $postdata = & $msg; // Reference
237         }
238
239         // NULL POSTING, OR removing existing page
240         if ($postdata === '') {
241                 page_write($page, $postdata);
242                 $retvars['msg' ] = $_title_deleted;
243                 $retvars['body'] = str_replace('$1', htmlsc($page), $_title_deleted);
244                 return $retvars;
245         }
246
247         // $notimeupdate: Checkbox 'Do not change timestamp'
248         $notimestamp = isset($vars['notimestamp']) && $vars['notimestamp'] != '';
249         if ($notimeupdate > 1 && $notimestamp && ! pkwk_login($vars['pass'])) {
250                 // Enable only administrator & password error
251                 $retvars['body']  = '<p><strong>' . $_msg_invalidpass . '</strong></p>' . "\n";
252                 $retvars['body'] .= edit_form($page, $msg, $digest, FALSE);
253                 return $retvars;
254         }
255
256         page_write($page, $postdata, $notimeupdate != 0 && $notimestamp);
257         pkwk_headers_sent();
258         header('Location: ' . get_page_uri($page, PKWK_URI_ROOT));
259         exit;
260 }
261
262 // Cancel (Back to the page / Escape edit page)
263 function plugin_edit_cancel()
264 {
265         global $vars;
266         pkwk_headers_sent();
267         header('Location: ' . get_page_uri($vars['page'], PKWK_URI_ROOT));
268         exit;
269 }