source: www/forum/includes/acp/acp_bbcodes.php@ 54

Last change on this file since 54 was 54, checked in by george, 17 years ago

Přidáno: Forum phpBB 3.

  • Property svn:executable set to *
File size: 13.2 KB
Line 
1<?php
2/**
3*
4* @package acp
5* @version $Id: acp_bbcodes.php,v 1.48 2007/10/07 10:34:45 naderman Exp $
6* @copyright (c) 2005 phpBB Group
7* @license http://opensource.org/licenses/gpl-license.php GNU Public License
8*
9*/
10
11/**
12* @ignore
13*/
14if (!defined('IN_PHPBB'))
15{
16 exit;
17}
18
19/**
20* @package acp
21*/
22class acp_bbcodes
23{
24 var $u_action;
25
26 function main($id, $mode)
27 {
28 global $db, $user, $auth, $template, $cache;
29 global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
30
31 $user->add_lang('acp/posting');
32
33 // Set up general vars
34 $action = request_var('action', '');
35 $bbcode_id = request_var('bbcode', 0);
36
37 $this->tpl_name = 'acp_bbcodes';
38 $this->page_title = 'ACP_BBCODES';
39 $form_key = 'acp_bbcodes';
40
41 add_form_key($form_key);
42
43 // Set up mode-specific vars
44 switch ($action)
45 {
46 case 'add':
47 $bbcode_match = $bbcode_tpl = $bbcode_helpline = '';
48 $display_on_posting = 0;
49 break;
50
51 case 'edit':
52 $sql = 'SELECT bbcode_match, bbcode_tpl, display_on_posting, bbcode_helpline
53 FROM ' . BBCODES_TABLE . '
54 WHERE bbcode_id = ' . $bbcode_id;
55 $result = $db->sql_query($sql);
56 $row = $db->sql_fetchrow($result);
57 $db->sql_freeresult($result);
58
59 if (!$row)
60 {
61 trigger_error($user->lang['BBCODE_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING);
62 }
63
64 $bbcode_match = $row['bbcode_match'];
65 $bbcode_tpl = htmlspecialchars($row['bbcode_tpl']);
66 $display_on_posting = $row['display_on_posting'];
67 $bbcode_helpline = $row['bbcode_helpline'];
68 break;
69
70 case 'modify':
71 $sql = 'SELECT bbcode_id, bbcode_tag
72 FROM ' . BBCODES_TABLE . '
73 WHERE bbcode_id = ' . $bbcode_id;
74 $result = $db->sql_query($sql);
75 $row = $db->sql_fetchrow($result);
76 $db->sql_freeresult($result);
77
78 if (!$row)
79 {
80 trigger_error($user->lang['BBCODE_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING);
81 }
82
83 // No break here
84
85 case 'create':
86 $display_on_posting = request_var('display_on_posting', 0);
87
88 $bbcode_match = request_var('bbcode_match', '');
89 $bbcode_tpl = htmlspecialchars_decode(utf8_normalize_nfc(request_var('bbcode_tpl', '', true)));
90 $bbcode_helpline = utf8_normalize_nfc(request_var('bbcode_helpline', '', true));
91 break;
92 }
93
94 // Do major work
95 switch ($action)
96 {
97 case 'edit':
98 case 'add':
99
100 $template->assign_vars(array(
101 'S_EDIT_BBCODE' => true,
102 'U_BACK' => $this->u_action,
103 'U_ACTION' => $this->u_action . '&amp;action=' . (($action == 'add') ? 'create' : 'modify') . (($bbcode_id) ? "&amp;bbcode=$bbcode_id" : ''),
104
105 'L_BBCODE_USAGE_EXPLAIN'=> sprintf($user->lang['BBCODE_USAGE_EXPLAIN'], '<a href="#down">', '</a>'),
106 'BBCODE_MATCH' => $bbcode_match,
107 'BBCODE_TPL' => $bbcode_tpl,
108 'BBCODE_HELPLINE' => $bbcode_helpline,
109 'DISPLAY_ON_POSTING' => $display_on_posting)
110 );
111
112 foreach ($user->lang['tokens'] as $token => $token_explain)
113 {
114 $template->assign_block_vars('token', array(
115 'TOKEN' => '{' . $token . '}',
116 'EXPLAIN' => $token_explain)
117 );
118 }
119
120 return;
121
122 break;
123
124 case 'modify':
125 case 'create':
126
127 $data = $this->build_regexp($bbcode_match, $bbcode_tpl);
128
129 // Make sure the user didn't pick a "bad" name for the BBCode tag.
130 $hard_coded = array('code', 'quote', 'quote=', 'attachment', 'attachment=', 'b', 'i', 'url', 'url=', 'img', 'size', 'size=', 'color', 'color=', 'u', 'list', 'list=', 'email', 'email=', 'flash', 'flash=');
131
132 if (($action == 'modify' && strtolower($data['bbcode_tag']) !== strtolower($row['bbcode_tag'])) || ($action == 'create'))
133 {
134 $sql = 'SELECT 1 as test
135 FROM ' . BBCODES_TABLE . "
136 WHERE LOWER(bbcode_tag) = '" . $db->sql_escape(strtolower($data['bbcode_tag'])) . "'";
137 $result = $db->sql_query($sql);
138 $info = $db->sql_fetchrow($result);
139 $db->sql_freeresult($result);
140
141 // Grab the end, interrogate the last closing tag
142 if ($info['test'] === '1' || in_array(strtolower($data['bbcode_tag']), $hard_coded) || (preg_match('#\[/([^[]*)]$#', $bbcode_match, $regs) && in_array(strtolower($regs[1]), $hard_coded)))
143 {
144 trigger_error($user->lang['BBCODE_INVALID_TAG_NAME'] . adm_back_link($this->u_action), E_USER_WARNING);
145 }
146 }
147
148 if (substr($data['bbcode_tag'], -1) === '=')
149 {
150 $test = substr($data['bbcode_tag'], 0, -1);
151 }
152 else
153 {
154 $test = $data['bbcode_tag'];
155 }
156
157 if (!preg_match('%\\[' . $test . '[^]]*].*?\\[/' . $test . ']%s', $bbcode_match))
158 {
159 trigger_error($user->lang['BBCODE_OPEN_ENDED_TAG'] . adm_back_link($this->u_action), E_USER_WARNING);
160 }
161
162 if (strlen($data['bbcode_tag']) > 16)
163 {
164 trigger_error($user->lang['BBCODE_TAG_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING);
165 }
166
167 if (strlen($bbcode_match) > 4000)
168 {
169 trigger_error($user->lang['BBCODE_TAG_DEF_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING);
170 }
171
172 $sql_ary = array(
173 'bbcode_tag' => $data['bbcode_tag'],
174 'bbcode_match' => $bbcode_match,
175 'bbcode_tpl' => $bbcode_tpl,
176 'display_on_posting' => $display_on_posting,
177 'bbcode_helpline' => $bbcode_helpline,
178 'first_pass_match' => $data['first_pass_match'],
179 'first_pass_replace' => $data['first_pass_replace'],
180 'second_pass_match' => $data['second_pass_match'],
181 'second_pass_replace' => $data['second_pass_replace']
182 );
183
184 if ($action == 'create')
185 {
186 $sql = 'SELECT MAX(bbcode_id) as max_bbcode_id
187 FROM ' . BBCODES_TABLE;
188 $result = $db->sql_query($sql);
189 $row = $db->sql_fetchrow($result);
190 $db->sql_freeresult($result);
191
192 if ($row)
193 {
194 $bbcode_id = $row['max_bbcode_id'] + 1;
195
196 // Make sure it is greater than the core bbcode ids...
197 if ($bbcode_id <= NUM_CORE_BBCODES)
198 {
199 $bbcode_id = NUM_CORE_BBCODES + 1;
200 }
201 }
202 else
203 {
204 $bbcode_id = NUM_CORE_BBCODES + 1;
205 }
206
207 if ($bbcode_id > 1511)
208 {
209 trigger_error($user->lang['TOO_MANY_BBCODES'] . adm_back_link($this->u_action), E_USER_WARNING);
210 }
211
212 $sql_ary['bbcode_id'] = (int) $bbcode_id;
213
214 $db->sql_query('INSERT INTO ' . BBCODES_TABLE . $db->sql_build_array('INSERT', $sql_ary));
215 $cache->destroy('sql', BBCODES_TABLE);
216
217 $lang = 'BBCODE_ADDED';
218 $log_action = 'LOG_BBCODE_ADD';
219 }
220 else
221 {
222 $sql = 'UPDATE ' . BBCODES_TABLE . '
223 SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
224 WHERE bbcode_id = ' . $bbcode_id;
225 $db->sql_query($sql);
226 $cache->destroy('sql', BBCODES_TABLE);
227
228 $lang = 'BBCODE_EDITED';
229 $log_action = 'LOG_BBCODE_EDIT';
230 }
231
232 add_log('admin', $log_action, $data['bbcode_tag']);
233
234 trigger_error($user->lang[$lang] . adm_back_link($this->u_action));
235
236 break;
237
238 case 'delete':
239
240 $sql = 'SELECT bbcode_tag
241 FROM ' . BBCODES_TABLE . "
242 WHERE bbcode_id = $bbcode_id";
243 $result = $db->sql_query($sql);
244 $row = $db->sql_fetchrow($result);
245 $db->sql_freeresult($result);
246
247 if ($row)
248 {
249 if (confirm_box(true))
250 {
251 $db->sql_query('DELETE FROM ' . BBCODES_TABLE . " WHERE bbcode_id = $bbcode_id");
252 $cache->destroy('sql', BBCODES_TABLE);
253 add_log('admin', 'LOG_BBCODE_DELETE', $row['bbcode_tag']);
254 }
255 else
256 {
257 confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
258 'bbcode' => $bbcode_id,
259 'i' => $id,
260 'mode' => $mode,
261 'action' => $action))
262 );
263 }
264 }
265
266 break;
267 }
268
269 $template->assign_vars(array(
270 'U_ACTION' => $this->u_action . '&amp;action=add')
271 );
272
273 $sql = 'SELECT *
274 FROM ' . BBCODES_TABLE . '
275 ORDER BY bbcode_tag';
276 $result = $db->sql_query($sql);
277
278 while ($row = $db->sql_fetchrow($result))
279 {
280 $template->assign_block_vars('bbcodes', array(
281 'BBCODE_TAG' => $row['bbcode_tag'],
282 'U_EDIT' => $this->u_action . '&amp;action=edit&amp;bbcode=' . $row['bbcode_id'],
283 'U_DELETE' => $this->u_action . '&amp;action=delete&amp;bbcode=' . $row['bbcode_id'])
284 );
285 }
286 $db->sql_freeresult($result);
287 }
288
289 /*
290 * Build regular expression for custom bbcode
291 */
292 function build_regexp(&$bbcode_match, &$bbcode_tpl)
293 {
294 $bbcode_match = trim($bbcode_match);
295 $bbcode_tpl = trim($bbcode_tpl);
296
297 $fp_match = preg_quote($bbcode_match, '!');
298 $fp_replace = preg_replace('#^\[(.*?)\]#', '[$1:$uid]', $bbcode_match);
299 $fp_replace = preg_replace('#\[/(.*?)\]$#', '[/$1:$uid]', $fp_replace);
300
301 $sp_match = preg_quote($bbcode_match, '!');
302 $sp_match = preg_replace('#^\\\\\[(.*?)\\\\\]#', '\[$1:$uid\]', $sp_match);
303 $sp_match = preg_replace('#\\\\\[/(.*?)\\\\\]$#', '\[/$1:$uid\]', $sp_match);
304 $sp_replace = $bbcode_tpl;
305
306 // @todo Make sure to change this too if something changed in message parsing
307 $tokens = array(
308 'URL' => array(
309 '!(?:(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('url')) . ')|(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('www_url')) . '))!ie' => "\$this->bbcode_specialchars(('\$1') ? '\$1' : 'http://\$2')"
310 ),
311 'LOCAL_URL' => array(
312 '!(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')!e' => "\$this->bbcode_specialchars('$1')"
313 ),
314 'EMAIL' => array(
315 '!([a-z0-9]+[a-z0-9\-\._]*@(?:(?:[0-9]{1,3}\.){3,5}[0-9]{1,3}|[a-z0-9]+[a-z0-9\-\._]*\.[a-z]+))!i' => "\$this->bbcode_specialchars('$1')"
316 ),
317 'TEXT' => array(
318 '!(.*?)!es' => "str_replace(array(\"\\r\\n\", '\\\"', '\\'', '(', ')'), array(\"\\n\", '\"', '&#39;', '&#40;', '&#41;'), trim('\$1'))"
319 ),
320 'SIMPLETEXT' => array(
321 '!([a-zA-Z0-9-+.,_ ]+)!' => "$1"
322 ),
323 'IDENTIFIER' => array(
324 '!([a-zA-Z0-9-_]+)!' => "$1"
325 ),
326 'COLOR' => array(
327 '!([a-z]+|#[0-9abcdef]+)!i' => '$1'
328 ),
329 'NUMBER' => array(
330 '!([0-9]+)!' => '$1'
331 )
332 );
333
334 $sp_tokens = array(
335 'URL' => '(?i)((?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('url')) . ')|(?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('www_url')) . '))(?-i)',
336 'LOCAL_URL' => '(?i)(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')(?-i)',
337 'EMAIL' => '([a-zA-Z0-9]+[a-zA-Z0-9\-\._]*@(?:(?:[0-9]{1,3}\.){3,5}[0-9]{1,3}|[a-zA-Z0-9]+[a-zA-Z0-9\-\._]*\.[a-zA-Z]+))',
338 'TEXT' => '(.*?)',
339 'SIMPLETEXT' => '([a-zA-Z0-9-+.,_ ]+)',
340 'IDENTIFIER' => '([a-zA-Z0-9-_]+)',
341 'COLOR' => '([a-zA-Z]+|#[0-9abcdefABCDEF]+)',
342 'NUMBER' => '([0-9]+)',
343 );
344
345 $pad = 0;
346 $modifiers = 'i';
347
348 if (preg_match_all('/\{(' . implode('|', array_keys($tokens)) . ')[0-9]*\}/i', $bbcode_match, $m))
349 {
350 foreach ($m[0] as $n => $token)
351 {
352 $token_type = $m[1][$n];
353
354 reset($tokens[strtoupper($token_type)]);
355 list($match, $replace) = each($tokens[strtoupper($token_type)]);
356
357 // Pad backreference numbers from tokens
358 if (preg_match_all('/(?<!\\\\)\$([0-9]+)/', $replace, $repad))
359 {
360 $repad = $pad + sizeof(array_unique($repad[0]));
361 $replace = preg_replace('/(?<!\\\\)\$([0-9]+)/e', "'\${' . (\$1 + \$pad) . '}'", $replace);
362 $pad = $repad;
363 }
364
365 // Obtain pattern modifiers to use and alter the regex accordingly
366 $regex = preg_replace('/!(.*)!([a-z]*)/', '$1', $match);
367 $regex_modifiers = preg_replace('/!(.*)!([a-z]*)/', '$2', $match);
368
369 for ($i = 0, $size = strlen($regex_modifiers); $i < $size; ++$i)
370 {
371 if (strpos($modifiers, $regex_modifiers[$i]) === false)
372 {
373 $modifiers .= $regex_modifiers[$i];
374
375 if ($regex_modifiers[$i] == 'e')
376 {
377 $fp_replace = "'" . str_replace("'", "\\'", $fp_replace) . "'";
378 }
379 }
380
381 if ($regex_modifiers[$i] == 'e')
382 {
383 $replace = "'.$replace.'";
384 }
385 }
386
387 $fp_match = str_replace(preg_quote($token, '!'), $regex, $fp_match);
388 $fp_replace = str_replace($token, $replace, $fp_replace);
389
390 $sp_match = str_replace(preg_quote($token, '!'), $sp_tokens[$token_type], $sp_match);
391 $sp_replace = str_replace($token, '${' . ($n + 1) . '}', $sp_replace);
392 }
393
394 $fp_match = '!' . $fp_match . '!' . $modifiers;
395 $sp_match = '!' . $sp_match . '!s';
396
397 if (strpos($fp_match, 'e') !== false)
398 {
399 $fp_replace = str_replace("'.'", '', $fp_replace);
400 $fp_replace = str_replace(".''.", '.', $fp_replace);
401 }
402 }
403 else
404 {
405 // No replacement is present, no need for a second-pass pattern replacement
406 // A simple str_replace will suffice
407 $fp_match = '!' . $fp_match . '!' . $modifiers;
408 $sp_match = $fp_replace;
409 $sp_replace = '';
410 }
411
412 // Lowercase tags
413 $bbcode_tag = preg_replace('/.*?\[([a-z0-9_-]+=?).*/i', '$1', $bbcode_match);
414 $bbcode_search = preg_replace('/.*?\[([a-z0-9_-]+)=?.*/i', '$1', $bbcode_match);
415
416 if (!preg_match('/^[a-zA-Z0-9_-]+=?$/', $bbcode_tag))
417 {
418 global $user;
419 trigger_error($user->lang['BBCODE_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
420 }
421
422 $fp_match = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $fp_match);
423 $fp_replace = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $fp_replace);
424 $sp_match = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $sp_match);
425 $sp_replace = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $sp_replace);
426
427 return array(
428 'bbcode_tag' => $bbcode_tag,
429 'first_pass_match' => $fp_match,
430 'first_pass_replace' => $fp_replace,
431 'second_pass_match' => $sp_match,
432 'second_pass_replace' => $sp_replace
433 );
434 }
435}
436
437?>
Note: See TracBrowser for help on using the repository browser.