9 * |
9 * |
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied |
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied |
11 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. |
11 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. |
12 */ |
12 */ |
13 |
13 |
14 define('ENANO_INTERFACE_AJAX', ''); |
14 define('ENANO_INTERFACE_AJAX', ''); |
15 |
15 |
16 require('includes/common.php'); |
16 require('includes/common.php'); |
17 |
17 |
18 global $db, $session, $paths, $template, $plugins; // Common objects |
18 global $db, $session, $paths, $template, $plugins; // Common objects |
19 if(!isset($_GET['_mode'])) die('This script cannot be accessed directly.'); |
19 if(!isset($_GET['_mode'])) die('This script cannot be accessed directly.'); |
20 |
20 |
21 $_ob = ''; |
21 $_ob = ''; |
22 |
22 |
23 switch($_GET['_mode']) { |
23 switch($_GET['_mode']) { |
24 case "checkusername": |
24 case "checkusername": |
25 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
25 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
26 echo PageUtils::checkusername($_GET['name']); |
26 echo PageUtils::checkusername($_GET['name']); |
27 break; |
27 break; |
28 case "getsource": |
28 case "getsource": |
29 header('Content-type: text/plain'); |
29 header('Content-type: text/plain'); |
30 $password = ( isset($_GET['pagepass']) ) ? $_GET['pagepass'] : false; |
30 $password = ( isset($_GET['pagepass']) ) ? $_GET['pagepass'] : false; |
31 $revid = ( isset($_GET['revid']) ) ? intval($_GET['revid']) : 0; |
31 $revid = ( isset($_GET['revid']) ) ? intval($_GET['revid']) : 0; |
32 $page = new PageProcessor($paths->page_id, $paths->namespace, $revid); |
32 $page = new PageProcessor($paths->page_id, $paths->namespace, $revid); |
33 $page->password = $password; |
33 $page->password = $password; |
34 |
34 |
35 $have_draft = false; |
35 $have_draft = false; |
36 // Kinda hacky fix for issue 7: draft restore not offered for nonexistent pages |
36 // Kinda hacky fix for issue 7: draft restore not offered for nonexistent pages |
37 if ( ($src = $page->fetch_source()) || !$page->exists() ) |
37 if ( ($src = $page->fetch_source()) || !$page->exists() ) |
38 { |
38 { |
39 $allowed = true; |
39 $allowed = true; |
40 $q = $db->sql_query('SELECT author, time_id, page_text, edit_summary, page_format FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\' |
40 $q = $db->sql_query('SELECT author, time_id, page_text, edit_summary, page_format FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\' |
41 AND page_id = \'' . $db->escape($paths->page_id) . '\' |
41 AND page_id = \'' . $db->escape($paths->page_id) . '\' |
42 AND namespace = \'' . $db->escape($paths->namespace) . '\' |
42 AND namespace = \'' . $db->escape($paths->namespace) . '\' |
43 AND is_draft = 1;'); |
43 AND is_draft = 1;'); |
44 if ( !$q ) |
44 if ( !$q ) |
45 $db->die_json(); |
45 $db->die_json(); |
46 |
46 |
47 if ( $db->numrows() > 0 ) |
47 if ( $db->numrows() > 0 ) |
48 { |
48 { |
49 $have_draft = true; |
49 $have_draft = true; |
50 $draft_row = $db->fetchrow($q); |
50 $draft_row = $db->fetchrow($q); |
51 } |
51 } |
52 } |
52 } |
53 else if ( $src !== false ) |
53 else if ( $src !== false ) |
54 { |
54 { |
55 $allowed = true; |
55 $allowed = true; |
56 $src = ''; |
56 $src = ''; |
57 } |
57 } |
58 else |
58 else |
59 { |
59 { |
60 $allowed = false; |
60 $allowed = false; |
61 $src = ''; |
61 $src = ''; |
62 } |
62 } |
63 |
63 |
64 $auth_edit = ( $session->get_permissions('edit_page') && ( $session->get_permissions('even_when_protected') || !$page->ns->page_protected ) ); |
64 $auth_edit = ( $session->get_permissions('edit_page') && ( $session->get_permissions('even_when_protected') || !$page->ns->page_protected ) ); |
65 $auth_wysiwyg = ( $session->get_permissions('edit_wysiwyg') ); |
65 $auth_wysiwyg = ( $session->get_permissions('edit_wysiwyg') ); |
66 |
66 |
67 $return = array( |
67 $return = array( |
68 'mode' => 'editor', |
68 'mode' => 'editor', |
69 'src' => $src, |
69 'src' => $src, |
70 'auth_view_source' => $allowed, |
70 'auth_view_source' => $allowed, |
71 'auth_edit' => $auth_edit, |
71 'auth_edit' => $auth_edit, |
72 'time' => time(), |
72 'time' => time(), |
73 'require_captcha' => false, |
73 'require_captcha' => false, |
74 'allow_wysiwyg' => $auth_wysiwyg, |
74 'allow_wysiwyg' => $auth_wysiwyg, |
75 'revid' => $revid, |
75 'revid' => $revid, |
76 'have_draft' => false |
76 'have_draft' => false |
77 ); |
77 ); |
78 |
78 |
79 $return['page_format'] = $page->ns->cdata['page_format']; |
79 $return['page_format'] = $page->ns->cdata['page_format']; |
80 if ( $return['page_format'] == 'xhtml' ) |
80 if ( $return['page_format'] == 'xhtml' ) |
81 { |
81 { |
82 // gently process headings to make tinymce format them correctly |
82 // gently process headings to make tinymce format them correctly |
83 if ( preg_match_all('/^ *?(={1,6}) *(.+?) *\\1 *$/m', $return['src'], $matches) ) |
83 if ( preg_match_all('/^ *?(={1,6}) *(.+?) *\\1 *$/m', $return['src'], $matches) ) |
84 { |
84 { |
85 foreach ( $matches[0] as $i => $match ) |
85 foreach ( $matches[0] as $i => $match ) |
86 { |
86 { |
87 $hi = strlen($matches[1][$i]); |
87 $hi = strlen($matches[1][$i]); |
88 $heading = "<h{$hi}>{$matches[2][$i]}</h{$hi}>"; |
88 $heading = "<h{$hi}>{$matches[2][$i]}</h{$hi}>"; |
89 $return['src'] = str_replace_once($match, $heading, $return['src']); |
89 $return['src'] = str_replace_once($match, $heading, $return['src']); |
90 } |
90 } |
91 } |
91 } |
92 } |
92 } |
93 |
93 |
94 if ( $have_draft ) |
94 if ( $have_draft ) |
95 { |
95 { |
96 $row =& $draft_row; |
96 $row =& $draft_row; |
97 $return['have_draft'] = true; |
97 $return['have_draft'] = true; |
98 $return['draft_author'] = $row['author']; |
98 $return['draft_author'] = $row['author']; |
99 $return['draft_time'] = enano_date(ED_DATE | ED_TIME, intval($row['time_id'])); |
99 $return['draft_time'] = enano_date(ED_DATE | ED_TIME, intval($row['time_id'])); |
100 if ( isset($_GET['get_draft']) && @$_GET['get_draft'] === '1' ) |
100 if ( isset($_GET['get_draft']) && @$_GET['get_draft'] === '1' ) |
101 { |
101 { |
102 $return['src'] = $row['page_text']; |
102 $return['src'] = $row['page_text']; |
103 $return['edit_summary'] = $row['edit_summary']; |
103 $return['edit_summary'] = $row['edit_summary']; |
104 $return['page_format'] = $row['page_format']; |
104 $return['page_format'] = $row['page_format']; |
105 } |
105 } |
106 } |
106 } |
107 |
107 |
108 $return['undo_info'] = array(); |
108 $return['undo_info'] = array(); |
109 |
109 |
110 if ( $revid > 0 ) |
110 if ( $revid > 0 ) |
111 { |
111 { |
112 // Retrieve information about this revision and the current one |
112 // Retrieve information about this revision and the current one |
113 $q = $db->sql_query('SELECT l1.author AS currentrev_author, l2.author AS oldrev_author FROM ' . table_prefix . 'logs AS l1 |
113 $q = $db->sql_query('SELECT l1.author AS currentrev_author, l2.author AS oldrev_author FROM ' . table_prefix . 'logs AS l1 |
114 LEFT JOIN ' . table_prefix . 'logs AS l2 |
114 LEFT JOIN ' . table_prefix . 'logs AS l2 |
115 ON ( l2.log_id = ' . $revid . ' |
115 ON ( l2.log_id = ' . $revid . ' |
116 AND l2.log_type = \'page\' |
116 AND l2.log_type = \'page\' |
117 AND l2.action = \'edit\' |
117 AND l2.action = \'edit\' |
118 AND l2.page_id = \'' . $db->escape($paths->page_id) . '\' |
118 AND l2.page_id = \'' . $db->escape($paths->page_id) . '\' |
119 AND l2.namespace = \'' . $db->escape($paths->namespace) . '\' |
119 AND l2.namespace = \'' . $db->escape($paths->namespace) . '\' |
120 AND l2.is_draft != 1 |
120 AND l2.is_draft != 1 |
121 ) |
121 ) |
122 WHERE l1.log_type = \'page\' |
122 WHERE l1.log_type = \'page\' |
123 AND l1.action = \'edit\' |
123 AND l1.action = \'edit\' |
124 AND l1.page_id = \'' . $db->escape($paths->page_id) . '\' |
124 AND l1.page_id = \'' . $db->escape($paths->page_id) . '\' |
125 AND l1.namespace = \'' . $db->escape($paths->namespace) . '\' |
125 AND l1.namespace = \'' . $db->escape($paths->namespace) . '\' |
126 AND l1.time_id > ' . $page->revision_time . ' |
126 AND l1.time_id > ' . $page->revision_time . ' |
127 AND l1.is_draft != 1 |
127 AND l1.is_draft != 1 |
128 ORDER BY l1.time_id DESC;'); |
128 ORDER BY l1.time_id DESC;'); |
129 if ( !$q ) |
129 if ( !$q ) |
130 $db->die_json(); |
130 $db->die_json(); |
131 |
131 |
132 if ( $db->numrows() > 0 ) |
132 if ( $db->numrows() > 0 ) |
133 { |
133 { |
134 $rev_count = $db->numrows() - 1; |
134 $rev_count = $db->numrows() - 1; |
135 if ( $rev_count == -1 ) |
135 if ( $rev_count == -1 ) |
136 { |
136 { |
137 $return = array( |
137 $return = array( |
138 'mode' => 'error', |
138 'mode' => 'error', |
139 'error' => '[Internal] No rows returned by revision info query. SQL:<pre>' . $db->latest_query . '</pre>' |
139 'error' => '[Internal] No rows returned by revision info query. SQL:<pre>' . $db->latest_query . '</pre>' |
140 ); |
140 ); |
141 } |
141 } |
142 else |
142 else |
143 { |
143 { |
144 $row = $db->fetchrow(); |
144 $row = $db->fetchrow(); |
145 $return['undo_info'] = array( |
145 $return['undo_info'] = array( |
146 'old_author' => $row['oldrev_author'], |
146 'old_author' => $row['oldrev_author'], |
147 'current_author' => $row['currentrev_author'], |
147 'current_author' => $row['currentrev_author'], |
148 'undo_count' => $rev_count |
148 'undo_count' => $rev_count |
149 ); |
149 ); |
150 } |
150 } |
151 } |
151 } |
152 else |
152 else |
153 { |
153 { |
154 $return['revid'] = $revid = 0; |
154 $return['revid'] = $revid = 0; |
155 } |
155 } |
156 } |
156 } |
157 |
157 |
158 if ( $auth_edit && !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' ) |
158 if ( $auth_edit && !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' ) |
159 { |
159 { |
160 $return['require_captcha'] = true; |
160 $return['require_captcha'] = true; |
161 $return['captcha_id'] = $session->make_captcha(); |
161 $return['captcha_id'] = $session->make_captcha(); |
162 } |
162 } |
163 |
163 |
164 $template->load_theme(); |
164 $template->load_theme(); |
165 $return['toolbar_templates'] = $template->extract_vars('toolbar.tpl'); |
165 $return['toolbar_templates'] = $template->extract_vars('toolbar.tpl'); |
166 $return['edit_notice'] = $template->get_wiki_edit_notice(); |
166 $return['edit_notice'] = $template->get_wiki_edit_notice(); |
167 |
167 |
168 echo enano_json_encode($return); |
168 echo enano_json_encode($return); |
169 break; |
169 break; |
170 case "getpage": |
170 case "getpage": |
171 // echo PageUtils::getpage($paths->page, false, ( (isset($_GET['oldid'])) ? $_GET['oldid'] : false )); |
171 // echo PageUtils::getpage($paths->page, false, ( (isset($_GET['oldid'])) ? $_GET['oldid'] : false )); |
172 $output = new Output_Striptease(); |
172 $output = new Output_Striptease(); |
173 |
173 |
174 $revision_id = ( (isset($_GET['oldid'])) ? intval($_GET['oldid']) : 0 ); |
174 $revision_id = ( (isset($_GET['oldid'])) ? intval($_GET['oldid']) : 0 ); |
175 $page = new PageProcessor( $paths->page_id, $paths->namespace, $revision_id ); |
175 $page = new PageProcessor( $paths->page_id, $paths->namespace, $revision_id ); |
176 |
176 |
177 $pagepass = ( isset($_REQUEST['pagepass']) ) ? $_REQUEST['pagepass'] : ''; |
177 $pagepass = ( isset($_REQUEST['pagepass']) ) ? $_REQUEST['pagepass'] : ''; |
178 $page->password = $pagepass; |
178 $page->password = $pagepass; |
179 $page->allow_redir = ( !isset($_GET['redirect']) || (isset($_GET['redirect']) && $_GET['redirect'] !== 'no') ); |
179 $page->allow_redir = ( !isset($_GET['redirect']) || (isset($_GET['redirect']) && $_GET['redirect'] !== 'no') ); |
180 |
180 |
181 $page->send(); |
181 $page->send(); |
182 break; |
182 break; |
183 case "savepage": |
183 case "savepage": |
184 /* **** OBSOLETE **** */ |
184 /* **** OBSOLETE **** */ |
185 |
185 |
186 break; |
186 break; |
187 case "savepage_json": |
187 case "savepage_json": |
188 header('Content-type: application/json'); |
188 header('Content-type: application/json'); |
189 if ( !isset($_POST['r']) ) |
189 if ( !isset($_POST['r']) ) |
190 die('Invalid request'); |
190 die('Invalid request'); |
191 |
191 |
192 try |
192 try |
193 { |
193 { |
194 $request = enano_json_decode($_POST['r']); |
194 $request = enano_json_decode($_POST['r']); |
195 if ( !isset($request['src']) || !isset($request['summary']) || !isset($request['minor_edit']) || !isset($request['time']) || !isset($request['draft']) ) |
195 if ( !isset($request['src']) || !isset($request['summary']) || !isset($request['minor_edit']) || !isset($request['time']) || !isset($request['draft']) ) |
196 die('Invalid request'); |
196 die('Invalid request'); |
197 } |
197 } |
198 catch(Zend_Json_Exception $e) |
198 catch(Zend_Json_Exception $e) |
199 { |
199 { |
200 die("JSON parsing failed. View as HTML to see full report.\n<br /><br />\n<pre>" . htmlspecialchars(strval($e)) . "</pre><br />Request: <pre>" . htmlspecialchars($_POST['r']) . "</pre>"); |
200 die("JSON parsing failed. View as HTML to see full report.\n<br /><br />\n<pre>" . htmlspecialchars(strval($e)) . "</pre><br />Request: <pre>" . htmlspecialchars($_POST['r']) . "</pre>"); |
201 } |
201 } |
202 |
202 |
203 $time = intval($request['time']); |
203 $time = intval($request['time']); |
204 |
204 |
205 if ( $request['draft'] ) |
205 if ( $request['draft'] ) |
206 { |
206 { |
207 // |
207 // |
208 // The user wants to save a draft version of the page. |
208 // The user wants to save a draft version of the page. |
209 // |
209 // |
210 |
210 |
211 // Validate permissions |
211 // Validate permissions |
212 if ( !$session->get_permissions('edit_page') ) |
212 if ( !$session->get_permissions('edit_page') ) |
213 { |
213 { |
214 $return = array( |
214 $return = array( |
215 'mode' => 'error', |
215 'mode' => 'error', |
216 'error' => 'access_denied' |
216 'error' => 'access_denied' |
217 ); |
217 ); |
218 } |
218 } |
219 else |
219 else |
220 { |
220 { |
221 // Delete any draft copies if they exist |
221 // Delete any draft copies if they exist |
222 $q = $db->sql_query('DELETE FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\' |
222 $q = $db->sql_query('DELETE FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\' |
223 AND page_id = \'' . $db->escape($paths->page_id) . '\' |
223 AND page_id = \'' . $db->escape($paths->page_id) . '\' |
224 AND namespace = \'' . $db->escape($paths->namespace) . '\' |
224 AND namespace = \'' . $db->escape($paths->namespace) . '\' |
225 AND is_draft = 1;'); |
225 AND is_draft = 1;'); |
226 if ( !$q ) |
226 if ( !$q ) |
227 $db->die_json(); |
227 $db->die_json(); |
228 |
228 |
229 // are we just supposed to delete the draft? |
229 // are we just supposed to delete the draft? |
230 if ( $request['src'] === -1 ) |
230 if ( $request['src'] === -1 ) |
231 { |
231 { |
232 $return = array( |
232 $return = array( |
233 'mode' => 'success', |
233 'mode' => 'success', |
234 'is_draft' => 'delete' |
234 'is_draft' => 'delete' |
235 ); |
235 ); |
236 } |
236 } |
237 else |
237 else |
238 { |
238 { |
239 $src = RenderMan::preprocess_text($request['src'], false, false); |
239 $src = RenderMan::preprocess_text($request['src'], false, false); |
240 $draft_format = $request['format']; |
240 $draft_format = $request['format']; |
241 if ( !in_array($draft_format, array('xhtml', 'wikitext')) ) |
241 if ( !in_array($draft_format, array('xhtml', 'wikitext')) ) |
242 { |
242 { |
243 $return = array( |
243 $return = array( |
244 'mode' => 'error', |
244 'mode' => 'error', |
245 'error' => 'invalid_format' |
245 'error' => 'invalid_format' |
246 ); |
246 ); |
247 } |
247 } |
248 else |
248 else |
249 { |
249 { |
250 // Save the draft |
250 // Save the draft |
251 $q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs ( log_type, action, page_id, namespace, author, author_uid, edit_summary, page_text, is_draft, time_id, page_format ) |
251 $q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs ( log_type, action, page_id, namespace, author, author_uid, edit_summary, page_text, is_draft, time_id, page_format ) |
252 VALUES ( |
252 VALUES ( |
253 \'page\', |
253 \'page\', |
254 \'edit\', |
254 \'edit\', |
255 \'' . $db->escape($paths->page_id) . '\', |
255 \'' . $db->escape($paths->page_id) . '\', |
256 \'' . $db->escape($paths->namespace) . '\', |
256 \'' . $db->escape($paths->namespace) . '\', |
257 \'' . $db->escape($session->username) . '\', |
257 \'' . $db->escape($session->username) . '\', |
258 ' . $session->user_id . ', |
258 ' . $session->user_id . ', |
259 \'' . $db->escape($request['summary']) . '\', |
259 \'' . $db->escape($request['summary']) . '\', |
260 \'' . $db->escape($src) . '\', |
260 \'' . $db->escape($src) . '\', |
261 1, |
261 1, |
262 ' . time() . ', |
262 ' . time() . ', |
263 \'' . $draft_format . '\' |
263 \'' . $draft_format . '\' |
264 );'); |
264 );'); |
265 |
265 |
266 // Done! |
266 // Done! |
267 $return = array( |
267 $return = array( |
268 'mode' => 'success', |
268 'mode' => 'success', |
269 'is_draft' => true |
269 'is_draft' => true |
270 ); |
270 ); |
271 } |
271 } |
272 } |
272 } |
273 } |
273 } |
274 } |
274 } |
275 else |
275 else |
276 { |
276 { |
277 // Verify that no edits have been made since the editor was requested |
277 // Verify that no edits have been made since the editor was requested |
278 $q = $db->sql_query('SELECT time_id, author FROM ' . table_prefix . "logs WHERE log_type = 'page' AND action = 'edit' AND page_id = '{$paths->page_id}' AND namespace = '{$paths->namespace}' AND is_draft != 1 ORDER BY time_id DESC LIMIT 1;"); |
278 $q = $db->sql_query('SELECT time_id, author FROM ' . table_prefix . "logs WHERE log_type = 'page' AND action = 'edit' AND page_id = '{$paths->page_id}' AND namespace = '{$paths->namespace}' AND is_draft != 1 ORDER BY time_id DESC LIMIT 1;"); |
279 if ( !$q ) |
279 if ( !$q ) |
280 $db->die_json(); |
280 $db->die_json(); |
281 |
281 |
282 $row = $db->fetchrow(); |
282 $row = $db->fetchrow(); |
283 $db->free_result(); |
283 $db->free_result(); |
284 |
284 |
285 if ( $row['time_id'] > $time ) |
285 if ( $row['time_id'] > $time ) |
286 { |
286 { |
287 $return = array( |
287 $return = array( |
288 'mode' => 'obsolete', |
288 'mode' => 'obsolete', |
289 'author' => $row['author'], |
289 'author' => $row['author'], |
290 'date_string' => enano_date(ED_DATE | ED_TIME, $row['time_id']), |
290 'date_string' => enano_date(ED_DATE | ED_TIME, $row['time_id']), |
291 'time' => $row['time_id'] // time() ??? |
291 'time' => $row['time_id'] // time() ??? |
292 ); |
292 ); |
293 echo enano_json_encode($return); |
293 echo enano_json_encode($return); |
294 break; |
294 break; |
295 } |
295 } |
296 |
296 |
297 // Verify captcha, if needed |
297 // Verify captcha, if needed |
298 if ( false && !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' ) |
298 if ( false && !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' ) |
299 { |
299 { |
300 if ( !isset($request['captcha_id']) || !isset($request['captcha_code']) ) |
300 if ( !isset($request['captcha_id']) || !isset($request['captcha_code']) ) |
301 { |
301 { |
302 die('Invalid request, need captcha metadata'); |
302 die('Invalid request, need captcha metadata'); |
303 } |
303 } |
304 $code_correct = strtolower($session->get_captcha($request['captcha_id'])); |
304 $code_correct = strtolower($session->get_captcha($request['captcha_id'])); |
305 $code_input = strtolower($request['captcha_code']); |
305 $code_input = strtolower($request['captcha_code']); |
306 if ( $code_correct !== $code_input ) |
306 if ( $code_correct !== $code_input ) |
307 { |
307 { |
308 $return = array( |
308 $return = array( |
309 'mode' => 'errors', |
309 'mode' => 'errors', |
310 'errors' => array($lang->get('editor_err_captcha_wrong')), |
310 'errors' => array($lang->get('editor_err_captcha_wrong')), |
311 'new_captcha' => $session->make_captcha() |
311 'new_captcha' => $session->make_captcha() |
312 ); |
312 ); |
313 echo enano_json_encode($return); |
313 echo enano_json_encode($return); |
314 break; |
314 break; |
315 } |
315 } |
316 } |
316 } |
317 |
317 |
318 // Verification complete. Start the PageProcessor and let it do the dirty work for us. |
318 // Verification complete. Start the PageProcessor and let it do the dirty work for us. |
319 $page = new PageProcessor($paths->page_id, $paths->namespace); |
319 $page = new PageProcessor($paths->page_id, $paths->namespace); |
320 if ( $page->update_page($request['src'], $request['summary'], ( $request['minor_edit'] == 1 ), $request['format']) ) |
320 if ( $page->update_page($request['src'], $request['summary'], ( $request['minor_edit'] == 1 ), $request['format']) ) |
321 { |
321 { |
322 $return = array( |
322 $return = array( |
323 'mode' => 'success', |
323 'mode' => 'success', |
324 'is_draft' => false |
324 'is_draft' => false |
325 ); |
325 ); |
326 } |
326 } |
327 else |
327 else |
328 { |
328 { |
329 $errors = array(); |
329 $errors = array(); |
330 while ( $err = $page->pop_error() ) |
330 while ( $err = $page->pop_error() ) |
331 { |
331 { |
332 $errors[] = $err; |
332 $errors[] = $err; |
333 } |
333 } |
334 $return = array( |
334 $return = array( |
335 'mode' => 'errors', |
335 'mode' => 'errors', |
336 'errors' => array_values($errors) |
336 'errors' => array_values($errors) |
337 ); |
337 ); |
338 if ( !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' ) |
338 if ( !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' ) |
339 { |
339 { |
340 $return['new_captcha'] = $session->make_captcha(); |
340 $return['new_captcha'] = $session->make_captcha(); |
341 } |
341 } |
342 } |
342 } |
343 } |
343 } |
344 |
344 |
345 // If this is based on a draft version, delete the draft - we no longer need it. |
345 // If this is based on a draft version, delete the draft - we no longer need it. |
346 if ( @$request['used_draft'] && !$request['draft'] ) |
346 if ( @$request['used_draft'] && !$request['draft'] ) |
347 { |
347 { |
348 $q = $db->sql_query('DELETE FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\' |
348 $q = $db->sql_query('DELETE FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\' |
349 AND page_id = \'' . $db->escape($paths->page_id) . '\' |
349 AND page_id = \'' . $db->escape($paths->page_id) . '\' |
350 AND namespace = \'' . $db->escape($paths->namespace) . '\' |
350 AND namespace = \'' . $db->escape($paths->namespace) . '\' |
351 AND is_draft = 1;'); |
351 AND is_draft = 1;'); |
352 } |
352 } |
353 |
353 |
354 echo enano_json_encode($return); |
354 echo enano_json_encode($return); |
355 |
355 |
356 break; |
356 break; |
357 case "diff_cur": |
357 case "diff_cur": |
358 |
358 |
359 // Lie about our content type to fool ad scripts |
359 // Lie about our content type to fool ad scripts |
360 header('Content-type: application/xhtml+xml'); |
360 header('Content-type: application/xhtml+xml'); |
361 |
361 |
362 if ( !isset($_POST['text']) ) |
362 if ( !isset($_POST['text']) ) |
363 die('Invalid request'); |
363 die('Invalid request'); |
364 |
364 |
365 $page = new PageProcessor($paths->page_id, $paths->namespace); |
365 $page = new PageProcessor($paths->page_id, $paths->namespace); |
366 if ( !($src = $page->fetch_source()) ) |
366 if ( !($src = $page->fetch_source()) ) |
367 { |
367 { |
368 die('Access denied'); |
368 die('Access denied'); |
369 } |
369 } |
370 |
370 |
371 $diff = RenderMan::diff($src, $_POST['text']); |
371 $diff = RenderMan::diff($src, $_POST['text']); |
372 if ( $diff == '<table class="diff"></table>' ) |
372 if ( $diff == '<table class="diff"></table>' ) |
373 { |
373 { |
374 $diff = '<p>' . $lang->get('editor_msg_diff_empty') . '</p>'; |
374 $diff = '<p>' . $lang->get('editor_msg_diff_empty') . '</p>'; |
375 } |
375 } |
376 |
376 |
377 echo '<div class="info-box">' . $lang->get('editor_msg_diff') . '</div>'; |
377 echo '<div class="info-box">' . $lang->get('editor_msg_diff') . '</div>'; |
378 echo $diff; |
378 echo $diff; |
379 |
379 |
380 break; |
380 break; |
381 case "protect": |
381 case "protect": |
382 // echo PageUtils::protect($paths->page_id, $paths->namespace, (int)$_POST['level'], $_POST['reason']); |
382 // echo PageUtils::protect($paths->page_id, $paths->namespace, (int)$_POST['level'], $_POST['reason']); |
383 |
383 |
384 if ( @$_POST['reason'] === '__ROLLBACK__' ) |
384 if ( @$_POST['reason'] === '__ROLLBACK__' ) |
385 { |
385 { |
386 // __ROLLBACK__ is a keyword for log entries. |
386 // __ROLLBACK__ is a keyword for log entries. |
387 die('"__ROLLBACK__" ain\'t gonna do it, buddy. Try to _not_ use reserved keywords next time, ok?'); |
387 die('"__ROLLBACK__" ain\'t gonna do it, buddy. Try to _not_ use reserved keywords next time, ok?'); |
388 } |
388 } |
389 |
389 |
390 $page = new PageProcessor($paths->page_id, $paths->namespace); |
390 $page = new PageProcessor($paths->page_id, $paths->namespace); |
391 header('Content-type: application/json'); |
391 header('Content-type: application/json'); |
392 |
392 |
393 $result = $page->protect_page(intval($_POST['level']), $_POST['reason']); |
393 $result = $page->protect_page(intval($_POST['level']), $_POST['reason']); |
394 echo enano_json_encode($result); |
394 echo enano_json_encode($result); |
395 break; |
395 break; |
396 case "histlist": |
396 case "histlist": |
397 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
397 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
398 echo PageUtils::histlist($paths->page_id, $paths->namespace); |
398 echo PageUtils::histlist($paths->page_id, $paths->namespace); |
399 break; |
399 break; |
400 case "rollback": |
400 case "rollback": |
401 $id = intval(@$_GET['id']); |
401 $id = intval(@$_GET['id']); |
402 $page = new PageProcessor($paths->page_id, $paths->namespace); |
402 $page = new PageProcessor($paths->page_id, $paths->namespace); |
403 header('Content-type: application/json'); |
403 header('Content-type: application/json'); |
404 |
404 |
405 $result = $page->rollback_log_entry($id); |
405 $result = $page->rollback_log_entry($id); |
406 echo enano_json_encode($result); |
406 echo enano_json_encode($result); |
407 break; |
407 break; |
408 case "comments": |
408 case "comments": |
409 require_once(ENANO_ROOT.'/includes/comment.php'); |
409 require_once(ENANO_ROOT.'/includes/comment.php'); |
410 $comments = new Comments($paths->page_id, $paths->namespace); |
410 $comments = new Comments($paths->page_id, $paths->namespace); |
411 if ( isset($_POST['data']) ) |
411 if ( isset($_POST['data']) ) |
412 { |
412 { |
413 $comments->process_json($_POST['data']); |
413 $comments->process_json($_POST['data']); |
414 } |
414 } |
415 else |
415 else |
416 { |
416 { |
417 die('{ "mode" : "error", "error" : "No input" }'); |
417 die('{ "mode" : "error", "error" : "No input" }'); |
418 } |
418 } |
419 break; |
419 break; |
420 case "rename": |
420 case "rename": |
421 $page = new PageProcessor($paths->page_id, $paths->namespace); |
421 $page = new PageProcessor($paths->page_id, $paths->namespace); |
422 header('Content-type: application/json'); |
422 header('Content-type: application/json'); |
423 |
423 |
424 $result = $page->rename_page($_POST['newtitle']); |
424 $result = $page->rename_page($_POST['newtitle']); |
425 echo enano_json_encode($result); |
425 echo enano_json_encode($result); |
426 break; |
426 break; |
427 case "flushlogs": |
427 case "flushlogs": |
428 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
428 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
429 echo PageUtils::flushlogs($paths->page_id, $paths->namespace); |
429 echo PageUtils::flushlogs($paths->page_id, $paths->namespace); |
430 break; |
430 break; |
431 case "deletepage": |
431 case "deletepage": |
432 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
432 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
433 $reason = ( isset($_POST['reason']) ) ? $_POST['reason'] : false; |
433 $reason = ( isset($_POST['reason']) ) ? $_POST['reason'] : false; |
434 if ( empty($reason) ) |
434 if ( empty($reason) ) |
435 die($lang->get('page_err_need_reason')); |
435 die($lang->get('page_err_need_reason')); |
436 echo PageUtils::deletepage($paths->page_id, $paths->namespace, $reason); |
436 echo PageUtils::deletepage($paths->page_id, $paths->namespace, $reason); |
437 break; |
437 break; |
438 case "delvote": |
438 case "delvote": |
439 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
439 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
440 echo PageUtils::delvote($paths->page_id, $paths->namespace); |
440 echo PageUtils::delvote($paths->page_id, $paths->namespace); |
441 break; |
441 break; |
442 case "resetdelvotes": |
442 case "resetdelvotes": |
443 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
443 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
444 echo PageUtils::resetdelvotes($paths->page_id, $paths->namespace); |
444 echo PageUtils::resetdelvotes($paths->page_id, $paths->namespace); |
445 break; |
445 break; |
446 case "getstyles": |
446 case "getstyles": |
447 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
447 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
448 echo PageUtils::getstyles($_GET['id']); |
448 echo PageUtils::getstyles($_GET['id']); |
449 break; |
449 break; |
450 case "catedit": |
450 case "catedit": |
451 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
451 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
452 echo PageUtils::catedit($paths->page_id, $paths->namespace); |
452 echo PageUtils::catedit($paths->page_id, $paths->namespace); |
453 break; |
453 break; |
454 case "catsave": |
454 case "catsave": |
455 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
455 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
456 echo PageUtils::catsave($paths->page_id, $paths->namespace, $_POST); |
456 echo PageUtils::catsave($paths->page_id, $paths->namespace, $_POST); |
457 break; |
457 break; |
458 case "setwikimode": |
458 case "setwikimode": |
459 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
459 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
460 echo PageUtils::setwikimode($paths->page_id, $paths->namespace, (int)$_GET['mode']); |
460 echo PageUtils::setwikimode($paths->page_id, $paths->namespace, (int)$_GET['mode']); |
461 break; |
461 break; |
462 case "setpass": |
462 case "setpass": |
463 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
463 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
464 echo PageUtils::setpass($paths->page_id, $paths->namespace, $_POST['password']); |
464 echo PageUtils::setpass($paths->page_id, $paths->namespace, $_POST['password']); |
465 break; |
465 break; |
466 case "fillusername": |
466 case "fillusername": |
467 break; |
467 break; |
468 case "fillpagename": |
468 case "fillpagename": |
469 break; |
469 break; |
470 case "preview": |
470 case "preview": |
471 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
471 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
472 $template->init_vars(); |
472 $template->init_vars(); |
473 echo PageUtils::genPreview($_POST['text']); |
473 echo PageUtils::genPreview($_POST['text']); |
474 break; |
474 break; |
475 case "transform": |
475 case "transform": |
476 header('Content-type: text/javascript'); |
476 header('Content-type: text/javascript'); |
477 if ( !isset($_GET['to']) ) |
477 if ( !isset($_GET['to']) ) |
478 { |
478 { |
479 echo enano_json_encode(array( |
479 echo enano_json_encode(array( |
480 'mode' => 'error', |
480 'mode' => 'error', |
481 'error' => '"to" not specified' |
481 'error' => '"to" not specified' |
482 )); |
482 )); |
483 break; |
483 break; |
484 } |
484 } |
485 if ( !isset($_POST['text']) ) |
485 if ( !isset($_POST['text']) ) |
486 { |
486 { |
487 echo enano_json_encode(array( |
487 echo enano_json_encode(array( |
488 'mode' => 'error', |
488 'mode' => 'error', |
489 'error' => '"text" not specified (must be on POST)' |
489 'error' => '"text" not specified (must be on POST)' |
490 )); |
490 )); |
491 break; |
491 break; |
492 } |
492 } |
493 switch($_GET['to']) |
493 switch($_GET['to']) |
494 { |
494 { |
495 case 'xhtml': |
495 case 'xhtml': |
496 $result = RenderMan::render($_POST['text'], RENDER_BLOCK | RENDER_NOSMILIES, false); |
496 $result = RenderMan::render($_POST['text'], RENDER_BLOCK | RENDER_NOSMILIES, false); |
497 break; |
497 break; |
498 case 'wikitext': |
498 case 'wikitext': |
499 $result = RenderMan::reverse_render($_POST['text']); |
499 $result = RenderMan::reverse_render($_POST['text']); |
500 break; |
500 break; |
501 default: |
501 default: |
502 $text =& $_POST['text']; |
502 $text =& $_POST['text']; |
503 $result = false; |
503 $result = false; |
504 $code = $plugins->setHook('ajax_transform'); |
504 $code = $plugins->setHook('ajax_transform'); |
505 foreach ( $code as $cmd ) |
505 foreach ( $code as $cmd ) |
506 { |
506 { |
507 eval($cmd); |
507 eval($cmd); |
508 } |
508 } |
509 if ( !$result ) |
509 if ( !$result ) |
510 { |
510 { |
511 echo enano_json_encode(array( |
511 echo enano_json_encode(array( |
512 'mode' => 'error', |
512 'mode' => 'error', |
513 'error' => 'Invalid target format' |
513 'error' => 'Invalid target format' |
514 )); |
514 )); |
515 break; |
515 break; |
516 } |
516 } |
517 break; |
517 break; |
518 } |
518 } |
519 |
519 |
520 // mostly for debugging, but I suppose this could be useful elsewhere. |
520 // mostly for debugging, but I suppose this could be useful elsewhere. |
521 if ( isset($_POST['plaintext']) ) |
521 if ( isset($_POST['plaintext']) ) |
522 die($result); |
522 die($result); |
523 |
523 |
524 echo enano_json_encode(array( |
524 echo enano_json_encode(array( |
525 'mode' => 'transformed_text', |
525 'mode' => 'transformed_text', |
526 'text' => $result |
526 'text' => $result |
527 )); |
527 )); |
528 break; |
528 break; |
529 case "pagediff": |
529 case "pagediff": |
530 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
530 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
531 $id1 = ( isset($_GET['diff1']) ) ? (int)$_GET['diff1'] : false; |
531 $id1 = ( isset($_GET['diff1']) ) ? (int)$_GET['diff1'] : false; |
532 $id2 = ( isset($_GET['diff2']) ) ? (int)$_GET['diff2'] : false; |
532 $id2 = ( isset($_GET['diff2']) ) ? (int)$_GET['diff2'] : false; |
533 if(!$id1 || !$id2) { echo '<p>Invalid request.</p>'; $template->footer(); break; } |
533 if(!$id1 || !$id2) { echo '<p>Invalid request.</p>'; $template->footer(); break; } |
534 if(!preg_match('#^([0-9]+)$#', (string)$_GET['diff1']) || |
534 if(!preg_match('#^([0-9]+)$#', (string)$_GET['diff1']) || |
535 !preg_match('#^([0-9]+)$#', (string)$_GET['diff2'] )) { echo '<p>SQL injection attempt</p>'; $template->footer(); break; } |
535 !preg_match('#^([0-9]+)$#', (string)$_GET['diff2'] )) { echo '<p>SQL injection attempt</p>'; $template->footer(); break; } |
536 echo PageUtils::pagediff($paths->page_id, $paths->namespace, $id1, $id2); |
536 echo PageUtils::pagediff($paths->page_id, $paths->namespace, $id1, $id2); |
537 break; |
537 break; |
538 case "jsres": |
538 case "jsres": |
539 die('// ERROR: this section is deprecated and has moved to includes/clientside/static/enano-lib-basic.js.'); |
539 die('// ERROR: this section is deprecated and has moved to includes/clientside/static/enano-lib-basic.js.'); |
540 break; |
540 break; |
541 case "rdns": |
541 case "rdns": |
542 if(!$session->get_permissions('mod_misc')) die('Go somewhere else for your reverse DNS info!'); |
542 if(!$session->get_permissions('mod_misc')) die('Go somewhere else for your reverse DNS info!'); |
543 $ip = $_GET['ip']; |
543 $ip = $_GET['ip']; |
544 if ( !is_valid_ip($ip) ) |
544 if ( !is_valid_ip($ip) ) |
545 { |
545 { |
546 echo $lang->get('acpsl_err_invalid_ip'); |
546 echo $lang->get('acpsl_err_invalid_ip'); |
547 } |
547 } |
548 $rdns = gethostbyaddr($ip); |
548 $rdns = gethostbyaddr($ip); |
549 if ( $rdns == $ip ) |
549 if ( $rdns == $ip ) |
550 echo $lang->get('acpsl_err_ptr_no_resolve'); |
550 echo $lang->get('acpsl_err_ptr_no_resolve'); |
551 else echo $rdns; |
551 else echo $rdns; |
552 break; |
552 break; |
553 case 'acljson': |
553 case 'acljson': |
554 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
554 require_once(ENANO_ROOT.'/includes/pageutils.php'); |
555 $parms = ( isset($_POST['acl_params']) ) ? rawurldecode($_POST['acl_params']) : false; |
555 $parms = ( isset($_POST['acl_params']) ) ? rawurldecode($_POST['acl_params']) : false; |
556 echo PageUtils::acl_json($parms); |
556 echo PageUtils::acl_json($parms); |
557 break; |
557 break; |
558 case 'theme_list': |
558 case 'theme_list': |
559 header('Content-type: application/json'); |
559 header('Content-type: application/json'); |
560 |
560 |
561 $return = array(); |
561 $return = array(); |
562 foreach ( $template->theme_list as $theme ) |
562 foreach ( $template->theme_list as $theme ) |
563 { |
563 { |
564 if ( $theme['enabled'] != 1 ) |
564 if ( $theme['enabled'] != 1 ) |
565 continue; |
565 continue; |
566 |
566 |
567 $return[] = array( |
567 $return[] = array( |
568 'theme_name' => $theme['theme_name'], |
568 'theme_name' => $theme['theme_name'], |
569 'theme_id' => $theme['theme_id'], |
569 'theme_id' => $theme['theme_id'], |
570 'have_thumb' => file_exists(ENANO_ROOT . "/themes/{$theme['theme_id']}/preview.png") |
570 'have_thumb' => file_exists(ENANO_ROOT . "/themes/{$theme['theme_id']}/preview.png") |
571 ); |
571 ); |
572 } |
572 } |
573 |
573 |
574 echo enano_json_encode($return); |
574 echo enano_json_encode($return); |
575 |
575 |
576 break; |
576 break; |
577 case "get_styles": |
577 case "get_styles": |
578 if ( !preg_match('/^[a-z0-9_-]+$/', $_GET['theme_id']) ) |
578 if ( !preg_match('/^[a-z0-9_-]+$/', $_GET['theme_id']) ) |
579 die(enano_json_encode(array())); |
579 die(enano_json_encode(array())); |
580 |
580 |
581 $theme_id = $_GET['theme_id']; |
581 $theme_id = $_GET['theme_id']; |
582 $return = array(); |
582 $return = array(); |
583 |
583 |
584 if ( $dr = @opendir(ENANO_ROOT . "/themes/$theme_id/css/") ) |
584 if ( $dr = @opendir(ENANO_ROOT . "/themes/$theme_id/css/") ) |
585 { |
585 { |
586 while ( $dh = @readdir($dr) ) |
586 while ( $dh = @readdir($dr) ) |
587 { |
587 { |
588 if ( preg_match('/\.css$/', $dh) && $dh != '_printable.css' ) |
588 if ( preg_match('/\.css$/', $dh) && $dh != '_printable.css' ) |
589 { |
589 { |
590 $return[] = preg_replace('/\.css$/', '', $dh); |
590 $return[] = preg_replace('/\.css$/', '', $dh); |
591 } |
591 } |
592 } |
592 } |
593 } |
593 } |
594 else |
594 else |
595 { |
595 { |
596 $return = array( |
596 $return = array( |
597 'mode' => 'error', |
597 'mode' => 'error', |
598 'error' => 'Could not open directory.' |
598 'error' => 'Could not open directory.' |
599 ); |
599 ); |
600 } |
600 } |
601 echo enano_json_encode($return); |
601 echo enano_json_encode($return); |
602 break; |
602 break; |
603 case "change_theme": |
603 case "change_theme": |
604 if ( !isset($_POST['theme_id']) || !isset($_POST['style_id']) ) |
604 if ( !isset($_POST['theme_id']) || !isset($_POST['style_id']) ) |
605 { |
605 { |
606 die(enano_json_encode(array('mode' => 'error', 'error' => 'Invalid parameter'))); |
606 die(enano_json_encode(array('mode' => 'error', 'error' => 'Invalid parameter'))); |
607 } |
607 } |
608 if ( !preg_match('/^([a-z0-9_-]+)$/i', $_POST['theme_id']) || !preg_match('/^([a-z0-9_-]+)$/i', $_POST['style_id']) ) |
608 if ( !preg_match('/^([a-z0-9_-]+)$/i', $_POST['theme_id']) || !preg_match('/^([a-z0-9_-]+)$/i', $_POST['style_id']) ) |
609 { |
609 { |
610 die(enano_json_encode(array('mode' => 'error', 'error' => 'Invalid parameter'))); |
610 die(enano_json_encode(array('mode' => 'error', 'error' => 'Invalid parameter'))); |
611 } |
611 } |
612 if ( !file_exists(ENANO_ROOT . '/themes/' . $_POST['theme_id'] . '/css/' . $_POST['style_id'] . '.css') ) |
612 if ( !file_exists(ENANO_ROOT . '/themes/' . $_POST['theme_id'] . '/css/' . $_POST['style_id'] . '.css') ) |
613 { |
613 { |
614 die(enano_json_encode(array('mode' => 'error', 'error' => 'Can\'t find theme file: ' . ENANO_ROOT . '/themes/' . $_POST['theme_id'] . '/css/' . $_POST['style_id'] . '.css')));; |
614 die(enano_json_encode(array('mode' => 'error', 'error' => 'Can\'t find theme file: ' . ENANO_ROOT . '/themes/' . $_POST['theme_id'] . '/css/' . $_POST['style_id'] . '.css')));; |
615 } |
615 } |
616 if ( !$session->user_logged_in ) |
616 if ( !$session->user_logged_in ) |
617 { |
617 { |
618 die(enano_json_encode(array('mode' => 'error', 'error' => 'You must be logged in to change your theme'))); |
618 die(enano_json_encode(array('mode' => 'error', 'error' => 'You must be logged in to change your theme'))); |
619 } |
619 } |
620 // Just in case something slipped through... |
620 // Just in case something slipped through... |
621 $theme_id = $db->escape($_POST['theme_id']); |
621 $theme_id = $db->escape($_POST['theme_id']); |
622 $style_id = $db->escape($_POST['style_id']); |
622 $style_id = $db->escape($_POST['style_id']); |
623 $e = $db->sql_query('UPDATE ' . table_prefix . "users SET theme = '$theme_id', style = '$style_id' WHERE user_id = $session->user_id;"); |
623 $e = $db->sql_query('UPDATE ' . table_prefix . "users SET theme = '$theme_id', style = '$style_id' WHERE user_id = $session->user_id;"); |
624 if ( !$e ) |
624 if ( !$e ) |
625 die( $db->get_error() ); |
625 die( $db->get_error() ); |
626 |
626 |
627 echo enano_json_encode(array( |
627 echo enano_json_encode(array( |
628 'success' => true |
628 'success' => true |
629 )); |
629 )); |
630 break; |
630 break; |
631 case 'get_tags': |
631 case 'get_tags': |
632 |
632 |
633 $ret = array('tags' => array(), 'user_level' => $session->user_level, 'can_add' => $session->get_permissions('tag_create')); |
633 $ret = array('tags' => array(), 'user_level' => $session->user_level, 'can_add' => $session->get_permissions('tag_create')); |
634 $q = $db->sql_query('SELECT t.tag_id, t.tag_name, pg.pg_target IS NOT NULL AS used_in_acl, t.user_id FROM '.table_prefix.'tags AS t |
634 $q = $db->sql_query('SELECT t.tag_id, t.tag_name, pg.pg_target IS NOT NULL AS used_in_acl, t.user_id FROM '.table_prefix.'tags AS t |
635 LEFT JOIN '.table_prefix.'page_groups AS pg |
635 LEFT JOIN '.table_prefix.'page_groups AS pg |
636 ON ( ( pg.pg_type = ' . PAGE_GRP_TAGGED . ' AND pg.pg_target=t.tag_name ) OR ( pg.pg_type IS NULL AND pg.pg_target IS NULL ) ) |
636 ON ( ( pg.pg_type = ' . PAGE_GRP_TAGGED . ' AND pg.pg_target=t.tag_name ) OR ( pg.pg_type IS NULL AND pg.pg_target IS NULL ) ) |
637 WHERE t.page_id=\'' . $db->escape($paths->page_id) . '\' AND t.namespace=\'' . $db->escape($paths->namespace) . '\';'); |
637 WHERE t.page_id=\'' . $db->escape($paths->page_id) . '\' AND t.namespace=\'' . $db->escape($paths->namespace) . '\';'); |
638 if ( !$q ) |
638 if ( !$q ) |
639 $db->_die(); |
639 $db->_die(); |
640 |
640 |
641 while ( $row = $db->fetchrow() ) |
641 while ( $row = $db->fetchrow() ) |
642 { |
642 { |
643 $can_del = true; |
643 $can_del = true; |
644 |
644 |
645 $perm = ( $row['user_id'] != $session->user_id ) ? |
645 $perm = ( $row['user_id'] != $session->user_id ) ? |
646 'tag_delete_other' : |
646 'tag_delete_other' : |
647 'tag_delete_own'; |
647 'tag_delete_own'; |
648 |
648 |
649 if ( $row['user_id'] == 1 && !$session->user_logged_in ) |
649 if ( $row['user_id'] == 1 && !$session->user_logged_in ) |
650 // anonymous user trying to delete tag (hardcode blacklisted) |
650 // anonymous user trying to delete tag (hardcode blacklisted) |
651 $can_del = false; |
651 $can_del = false; |
652 |
652 |
653 if ( !$session->get_permissions($perm) ) |
653 if ( !$session->get_permissions($perm) ) |
654 $can_del = false; |
654 $can_del = false; |
655 |
655 |
656 if ( $row['used_in_acl'] == 1 && !$session->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN ) |
656 if ( $row['used_in_acl'] == 1 && !$session->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN ) |
657 $can_del = false; |
657 $can_del = false; |
658 |
658 |
659 $ret['tags'][] = array( |
659 $ret['tags'][] = array( |
660 'id' => $row['tag_id'], |
660 'id' => $row['tag_id'], |
661 'name' => $row['tag_name'], |
661 'name' => $row['tag_name'], |
662 'can_del' => $can_del, |
662 'can_del' => $can_del, |
663 'acl' => ( $row['used_in_acl'] == 1 ) |
663 'acl' => ( $row['used_in_acl'] == 1 ) |
664 ); |
664 ); |
665 } |
665 } |
666 |
666 |
667 echo enano_json_encode($ret); |
667 echo enano_json_encode($ret); |
668 |
668 |
669 break; |
669 break; |
670 case 'addtag': |
670 case 'addtag': |
671 $resp = array( |
671 $resp = array( |
672 'success' => false, |
672 'success' => false, |
673 'error' => 'No error', |
673 'error' => 'No error', |
674 'can_del' => ( $session->get_permissions('tag_delete_own') && $session->user_logged_in ), |
674 'can_del' => ( $session->get_permissions('tag_delete_own') && $session->user_logged_in ), |
675 'in_acl' => false |
675 'in_acl' => false |
676 ); |
676 ); |
677 |
677 |
678 // first of course, are we allowed to tag pages? |
678 // first of course, are we allowed to tag pages? |
679 if ( !$session->get_permissions('tag_create') ) |
679 if ( !$session->get_permissions('tag_create') ) |
680 { |
680 { |
681 $resp['error'] = 'You are not permitted to tag pages.'; |
681 $resp['error'] = 'You are not permitted to tag pages.'; |
682 die(enano_json_encode($resp)); |
682 die(enano_json_encode($resp)); |
683 } |
683 } |
684 |
684 |
685 // sanitize the tag name |
685 // sanitize the tag name |
686 $tag = sanitize_tag($_POST['tag']); |
686 $tag = sanitize_tag($_POST['tag']); |
687 $tag = $db->escape($tag); |
687 $tag = $db->escape($tag); |
688 |
688 |
689 if ( strlen($tag) < 2 ) |
689 if ( strlen($tag) < 2 ) |
690 { |
690 { |
691 $resp['error'] = 'Tags must consist of at least 2 alphanumeric characters.'; |
691 $resp['error'] = 'Tags must consist of at least 2 alphanumeric characters.'; |
692 die(enano_json_encode($resp)); |
692 die(enano_json_encode($resp)); |
693 } |
693 } |
694 |
694 |
695 // check if tag is already on page |
695 // check if tag is already on page |
696 $q = $db->sql_query('SELECT 1 FROM '.table_prefix.'tags WHERE page_id=\'' . $db->escape($paths->page_id) . '\' AND namespace=\'' . $db->escape($paths->namespace) . '\' AND tag_name=\'' . $tag . '\';'); |
696 $q = $db->sql_query('SELECT 1 FROM '.table_prefix.'tags WHERE page_id=\'' . $db->escape($paths->page_id) . '\' AND namespace=\'' . $db->escape($paths->namespace) . '\' AND tag_name=\'' . $tag . '\';'); |
697 if ( !$q ) |
697 if ( !$q ) |
698 $db->_die(); |
698 $db->_die(); |
699 if ( $db->numrows() > 0 ) |
699 if ( $db->numrows() > 0 ) |
700 { |
700 { |
701 $resp['error'] = 'This page already has this tag.'; |
701 $resp['error'] = 'This page already has this tag.'; |
702 die(enano_json_encode($resp)); |
702 die(enano_json_encode($resp)); |
703 } |
703 } |
704 $db->free_result(); |
704 $db->free_result(); |
705 |
705 |
706 // tricky: make sure this tag isn't being used in some page group, and thus adding it could affect page access |
706 // tricky: make sure this tag isn't being used in some page group, and thus adding it could affect page access |
707 $can_edit_acl = ( $session->get_permissions('edit_acl') || $session->user_level >= USER_LEVEL_ADMIN ); |
707 $can_edit_acl = ( $session->get_permissions('edit_acl') || $session->user_level >= USER_LEVEL_ADMIN ); |
708 $q = $db->sql_query('SELECT 1 FROM '.table_prefix.'page_groups WHERE pg_type=' . PAGE_GRP_TAGGED . ' AND pg_target=\'' . $tag . '\';'); |
708 $q = $db->sql_query('SELECT 1 FROM '.table_prefix.'page_groups WHERE pg_type=' . PAGE_GRP_TAGGED . ' AND pg_target=\'' . $tag . '\';'); |
709 if ( !$q ) |
709 if ( !$q ) |
710 $db->_die(); |
710 $db->_die(); |
711 if ( $db->numrows() > 0 && !$can_edit_acl ) |
711 if ( $db->numrows() > 0 && !$can_edit_acl ) |
712 { |
712 { |
713 $resp['error'] = 'This tag is used in an ACL page group, and thus can\'t be added to a page by people without administrator privileges.'; |
713 $resp['error'] = 'This tag is used in an ACL page group, and thus can\'t be added to a page by people without administrator privileges.'; |
714 die(enano_json_encode($resp)); |
714 die(enano_json_encode($resp)); |
715 } |
715 } |
716 $resp['in_acl'] = ( $db->numrows() > 0 ); |
716 $resp['in_acl'] = ( $db->numrows() > 0 ); |
717 $db->free_result(); |
717 $db->free_result(); |
718 |
718 |
719 // we're good |
719 // we're good |
720 $q = $db->sql_query('INSERT INTO '.table_prefix.'tags(tag_name,page_id,namespace,user_id) VALUES(\'' . $tag . '\', \'' . $db->escape($paths->page_id) . '\', \'' . $db->escape($paths->namespace) . '\', ' . $session->user_id . ');'); |
720 $q = $db->sql_query('INSERT INTO '.table_prefix.'tags(tag_name,page_id,namespace,user_id) VALUES(\'' . $tag . '\', \'' . $db->escape($paths->page_id) . '\', \'' . $db->escape($paths->namespace) . '\', ' . $session->user_id . ');'); |
721 if ( !$q ) |
721 if ( !$q ) |
722 $db->_die(); |
722 $db->_die(); |
723 |
723 |
724 $resp['success'] = true; |
724 $resp['success'] = true; |
725 $resp['tag'] = $tag; |
725 $resp['tag'] = $tag; |
726 $resp['tag_id'] = $db->insert_id(); |
726 $resp['tag_id'] = $db->insert_id(); |
727 |
727 |
728 echo enano_json_encode($resp); |
728 echo enano_json_encode($resp); |
729 break; |
729 break; |
730 case 'deltag': |
730 case 'deltag': |
731 |
731 |
732 $tag_id = intval($_POST['tag_id']); |
732 $tag_id = intval($_POST['tag_id']); |
733 if ( empty($tag_id) ) |
733 if ( empty($tag_id) ) |
734 die('Invalid tag ID'); |
734 die('Invalid tag ID'); |
735 |
735 |
736 $q = $db->sql_query('SELECT t.tag_id, t.user_id, t.page_id, t.namespace, pg.pg_target IS NOT NULL AS used_in_acl FROM '.table_prefix.'tags AS t |
736 $q = $db->sql_query('SELECT t.tag_id, t.user_id, t.page_id, t.namespace, pg.pg_target IS NOT NULL AS used_in_acl FROM '.table_prefix.'tags AS t |
737 LEFT JOIN '.table_prefix.'page_groups AS pg |
737 LEFT JOIN '.table_prefix.'page_groups AS pg |
738 ON ( pg.pg_id IS NULL OR ( pg.pg_target = t.tag_name AND pg.pg_type = ' . PAGE_GRP_TAGGED . ' ) ) |
738 ON ( pg.pg_id IS NULL OR ( pg.pg_target = t.tag_name AND pg.pg_type = ' . PAGE_GRP_TAGGED . ' ) ) |
739 WHERE t.tag_id=' . $tag_id . ';'); |
739 WHERE t.tag_id=' . $tag_id . ';'); |
740 |
740 |
741 if ( !$q ) |
741 if ( !$q ) |
742 $db->_die(); |
742 $db->_die(); |
743 |
743 |
744 if ( $db->numrows() < 1 ) |
744 if ( $db->numrows() < 1 ) |
745 die('Could not find a tag with that ID'); |
745 die('Could not find a tag with that ID'); |
746 |
746 |
747 $row = $db->fetchrow(); |
747 $row = $db->fetchrow(); |
748 $db->free_result(); |
748 $db->free_result(); |
749 |
749 |
750 if ( $row['page_id'] == $paths->page_id && $row['namespace'] == $paths->namespace ) |
750 if ( $row['page_id'] == $paths->page_id && $row['namespace'] == $paths->namespace ) |
751 $perms =& $session; |
751 $perms =& $session; |
752 else |
752 else |
753 $perms = $session->fetch_page_acl($row['page_id'], $row['namespace']); |
753 $perms = $session->fetch_page_acl($row['page_id'], $row['namespace']); |
754 |
754 |
755 $perm = ( $row['user_id'] != $session->user_id ) ? |
755 $perm = ( $row['user_id'] != $session->user_id ) ? |
756 'tag_delete_other' : |
756 'tag_delete_other' : |
757 'tag_delete_own'; |
757 'tag_delete_own'; |
758 |
758 |
759 if ( $row['user_id'] == 1 && !$session->user_logged_in ) |
759 if ( $row['user_id'] == 1 && !$session->user_logged_in ) |
760 // anonymous user trying to delete tag (hardcode blacklisted) |
760 // anonymous user trying to delete tag (hardcode blacklisted) |
761 die('You are not authorized to delete this tag.'); |
761 die('You are not authorized to delete this tag.'); |
762 |
762 |
763 if ( !$perms->get_permissions($perm) ) |
763 if ( !$perms->get_permissions($perm) ) |
764 die('You are not authorized to delete this tag.'); |
764 die('You are not authorized to delete this tag.'); |
765 |
765 |
766 if ( $row['used_in_acl'] == 1 && !$perms->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN ) |
766 if ( $row['used_in_acl'] == 1 && !$perms->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN ) |
767 die('You are not authorized to delete this tag.'); |
767 die('You are not authorized to delete this tag.'); |
768 |
768 |
769 // We're good |
769 // We're good |
770 $q = $db->sql_query('DELETE FROM '.table_prefix.'tags WHERE tag_id = ' . $tag_id . ';'); |
770 $q = $db->sql_query('DELETE FROM '.table_prefix.'tags WHERE tag_id = ' . $tag_id . ';'); |
771 if ( !$q ) |
771 if ( !$q ) |
772 $db->_die(); |
772 $db->_die(); |
773 |
773 |
774 echo 'success'; |
774 echo 'success'; |
775 |
775 |
776 break; |
776 break; |
777 case 'ping': |
777 case 'ping': |
778 echo 'pong'; |
778 echo 'pong'; |
779 break; |
779 break; |
780 default: |
780 default: |
781 die('Hacking attempt'); |
781 die('Hacking attempt'); |
782 break; |
782 break; |
783 } |
783 } |
784 |
784 |
785 ?> |
785 ?> |