1<?php
2/**
3 * MyBB 1.8
4 * Copyright 2014 MyBB Group, All Rights Reserved
5 *
6 * Website: http://www.mybb.com
7 * License: http://www.mybb.com/about/license
8 *
9 */
10
11// Disallow direct access to this file for security reasons
12if(!defined("IN_MYBB"))
13{
14	die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
15}
16
17$page->add_breadcrumb_item($lang->mycode, "index.php?module=config-mycode");
18
19$plugins->run_hooks("admin_config_mycode_begin");
20
21if($mybb->input['action'] == "toggle_status")
22{
23	if(!verify_post_check($mybb->get_input('my_post_key')))
24	{
25		flash_message($lang->invalid_post_verify_key2, 'error');
26		admin_redirect("index.php?module=config-mycode");
27	}
28
29	$query = $db->simple_select("mycode", "*", "cid='".$mybb->get_input('cid', MyBB::INPUT_INT)."'");
30	$mycode = $db->fetch_array($query);
31
32	if(!$mycode['cid'])
33	{
34		flash_message($lang->error_invalid_mycode, 'error');
35		admin_redirect("index.php?module=config-mycode");
36	}
37
38	$plugins->run_hooks("admin_config_mycode_toggle_status");
39
40	if($mycode['active'] == 1)
41	{
42		$new_status = 0;
43		$phrase = $lang->success_deactivated_mycode;
44	}
45	else
46	{
47		$new_status = 1;
48		$phrase = $lang->success_activated_mycode;
49	}
50	$mycode_update = array(
51		'active' => $new_status,
52	);
53
54	$plugins->run_hooks("admin_config_mycode_toggle_status_commit");
55
56	$db->update_query("mycode", $mycode_update, "cid='{$mycode['cid']}'");
57
58	$cache->update_mycode();
59
60	// Log admin action
61	log_admin_action($mycode['cid'], $mycode['title'], $new_status);
62
63	flash_message($phrase, 'success');
64	admin_redirect('index.php?module=config-mycode');
65}
66
67if($mybb->input['action'] == "xmlhttp_test_mycode" && $mybb->request_method == "post")
68{
69	$plugins->run_hooks("admin_config_mycode_xmlhttp_test_mycode_start");
70
71	// Send no cache headers
72	header("Expires: Sat, 1 Jan 2000 01:00:00 GMT");
73	header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
74	header("Cache-Control: no-cache, must-revalidate");
75	header("Pragma: no-cache");
76	header("Content-type: text/html");
77
78	$sandbox = test_regex($mybb->input['regex'], $mybb->input['replacement'], $mybb->input['test_value']);
79
80	$plugins->run_hooks("admin_config_mycode_xmlhttp_test_mycode_end");
81
82	echo $sandbox['actual'];
83	exit;
84}
85
86if($mybb->input['action'] == "add")
87{
88	$sandbox = array();
89
90	$plugins->run_hooks("admin_config_mycode_add");
91
92	if($mybb->request_method == "post")
93	{
94		if(!trim($mybb->input['title']))
95		{
96			$errors[] = $lang->error_missing_title;
97		}
98
99		if(!trim($mybb->input['regex']))
100		{
101			$errors[] = $lang->error_missing_regex;
102		}
103
104		$regex = str_replace("\x0", "", $mybb->input['regex']);
105
106		if(check_existing_regex($regex))
107		{
108			$errors[] = $lang->error_regex_already_available;
109		}
110
111		if(!trim($mybb->input['replacement']))
112		{
113			$errors[] = $lang->error_missing_replacement;
114		}
115
116		if($mybb->get_input('test'))
117		{
118			$errors[] = $lang->changes_not_saved;
119			$sandbox = test_regex($mybb->input['regex'], $mybb->input['replacement'], $mybb->input['test_value']);
120		}
121
122		if(!$errors)
123		{
124			$new_mycode = array(
125				'title'	=> $db->escape_string($mybb->input['title']),
126				'description' => $db->escape_string($mybb->input['description']),
127				'regex' => $db->escape_string($regex),
128				'replacement' => $db->escape_string($mybb->input['replacement']),
129				'active' => $mybb->get_input('active', MyBB::INPUT_INT),
130				'parseorder' => $mybb->get_input('parseorder', MyBB::INPUT_INT)
131			);
132
133			$cid = $db->insert_query("mycode", $new_mycode);
134
135			$plugins->run_hooks("admin_config_mycode_add_commit");
136
137			$cache->update_mycode();
138
139			// Log admin action
140			log_admin_action($cid, $mybb->input['title']);
141
142			flash_message($lang->success_added_mycode, 'success');
143			admin_redirect('index.php?module=config-mycode');
144		}
145	}
146
147	$sub_tabs['mycode'] = array(
148		'title'	=> $lang->mycode,
149		'link' => "index.php?module=config-mycode",
150		'description' => $lang->mycode_desc
151	);
152
153	$sub_tabs['add_new_mycode'] = array(
154		'title'	=> $lang->add_new_mycode,
155		'link' => "index.php?module=config-mycode&amp;action=add",
156		'description' => $lang->add_new_mycode_desc
157	);
158
159	$page->extra_header .= "
160	<script type=\"text/javascript\">
161	var my_post_key = '".$mybb->post_code."';
162	lang.mycode_sandbox_test_error = \"{$lang->mycode_sandbox_test_error}\";
163	</script>";
164
165	$page->add_breadcrumb_item($lang->add_new_mycode);
166	$page->output_header($lang->custom_mycode." - ".$lang->add_new_mycode);
167	$page->output_nav_tabs($sub_tabs, 'add_new_mycode');
168
169	if($errors)
170	{
171		$page->output_inline_error($errors);
172	}
173	else
174	{
175		$mybb->input['active'] = 1;
176	}
177
178	$form = new Form("index.php?module=config-mycode&amp;action=add", "post", "add");
179	$form_container = new FormContainer($lang->add_mycode);
180	$form_container->output_row($lang->title." <em>*</em>", '', $form->generate_text_box('title', $mybb->get_input('title'), array('id' => 'title')), 'title');
181	$form_container->output_row($lang->short_description, '', $form->generate_text_box('description', $mybb->get_input('description'), array('id' => 'description')), 'description');
182	$form_container->output_row($lang->regular_expression." <em>*</em>", $lang->regular_expression_desc.'<br /><strong>'.$lang->example.'</strong> \[b\](.*?)\[/b\]', $form->generate_text_area('regex', $mybb->get_input('regex'), array('id' => 'regex')), 'regex');
183	$form_container->output_row($lang->replacement." <em>*</em>", $lang->replacement_desc.'<br /><strong>'.$lang->example.'</strong> &lt;strong&gt;$1&lt;/strong&gt;', $form->generate_text_area('replacement', $mybb->get_input('replacement'), array('id' => 'replacement')), 'replacement');
184	$form_container->output_row($lang->enabled." <em>*</em>", '', $form->generate_yes_no_radio('active', $mybb->get_input('active')));
185	$form_container->output_row($lang->parse_order, $lang->parse_order_desc, $form->generate_numeric_field('parseorder', $mybb->get_input('parseorder'), array('id' => 'parseorder', 'min' => 0)), 'parseorder');
186	$form_container->end();
187
188	$buttons[] = $form->generate_submit_button($lang->save_mycode);
189	$form->output_submit_wrapper($buttons);
190
191	// Sandbox
192	$sandbox_actual = isset($sandbox['actual']) ? $sandbox['actual'] : null;
193
194	echo "<br />\n";
195	$form_container = new FormContainer($lang->sandbox);
196	$form_container->output_row($lang->sandbox_desc);
197	$form_container->output_row($lang->test_value, $lang->test_value_desc, $form->generate_text_area('test_value', $mybb->get_input('test_value'), array('id' => 'test_value'))."<br />".$form->generate_submit_button($lang->test, array('id' => 'test', 'name' => 'test')), 'test_value');
198	$form_container->output_row($lang->result_html, $lang->result_html_desc, $form->generate_text_area('result_html', isset($sandbox['html']) ? $sandbox['html'] : null, array('id' => 'result_html', 'disabled' => 1)), 'result_html');
199	$form_container->output_row($lang->result_actual, $lang->result_actual_desc, "<div id=\"result_actual\">{$sandbox_actual}</div>");
200	$form_container->end();
201	echo '<script type="text/javascript" src="./jscripts/mycode_sandbox.js"></script>';
202	echo '<script type="text/javascript">
203//<![CDATA[
204$(function(){
205    new MyCodeSandbox("./index.php?module=config-mycode&action=xmlhttp_test_mycode", $("#test"), $("#regex"), $("#replacement"), $("#test_value"), $("#result_html"), $("#result_actual"));
206});
207//]]>
208</script>';
209
210	$form->end();
211
212	$page->output_footer();
213}
214
215if($mybb->input['action'] == "edit")
216{
217	$query = $db->simple_select("mycode", "*", "cid='".$mybb->get_input('cid', MyBB::INPUT_INT)."'");
218	$mycode = $db->fetch_array($query);
219
220	if(!$mycode['cid'])
221	{
222		flash_message($lang->error_invalid_mycode, 'error');
223		admin_redirect("index.php?module=config-mycode");
224	}
225
226	$sandbox = array();
227
228	$plugins->run_hooks("admin_config_mycode_edit");
229
230	if($mybb->request_method == "post")
231	{
232		if(!trim($mybb->input['title']))
233		{
234			$errors[] = $lang->error_missing_title;
235		}
236
237		if(!trim($mybb->input['regex']))
238		{
239			$errors[] = $lang->error_missing_regex;
240		}
241
242		$regex = str_replace("\x0", "", $mybb->input['regex']);
243
244		if(check_existing_regex($regex, $mycode))
245		{
246			$errors[] = $lang->error_regex_already_available;
247		}
248
249		if(!trim($mybb->input['replacement']))
250		{
251			$errors[] = $lang->error_missing_replacement;
252		}
253
254		if($mybb->get_input('test'))
255		{
256			$errors[] = $lang->changes_not_saved;
257			$sandbox = test_regex($mybb->input['regex'], $mybb->input['replacement'], $mybb->input['test_value']);
258		}
259
260		if(!$errors)
261		{
262			$updated_mycode = array(
263				'title'	=> $db->escape_string($mybb->input['title']),
264				'description' => $db->escape_string($mybb->input['description']),
265				'regex' => $db->escape_string($regex),
266				'replacement' => $db->escape_string($mybb->input['replacement']),
267				'active' => $mybb->get_input('active', MyBB::INPUT_INT),
268				'parseorder' => $mybb->get_input('parseorder', MyBB::INPUT_INT)
269			);
270
271			$plugins->run_hooks("admin_config_mycode_edit_commit");
272
273			$db->update_query("mycode", $updated_mycode, "cid='{$mycode['cid']}'");
274
275			$cache->update_mycode();
276
277			// Log admin action
278			log_admin_action($mycode['cid'], $mybb->input['title']);
279
280			flash_message($lang->success_updated_mycode, 'success');
281			admin_redirect('index.php?module=config-mycode');
282		}
283	}
284
285	$sub_tabs['edit_mycode'] = array(
286		'title'	=> $lang->edit_mycode,
287		'link' => "index.php?module=config-mycode&amp;action=edit",
288		'description' => $lang->edit_mycode_desc
289	);
290
291	$page->extra_header .= "
292	<script type=\"text/javascript\">
293	var my_post_key = '".$mybb->post_code."';
294	lang.mycode_sandbox_test_error = \"{$lang->mycode_sandbox_test_error}\";
295	</script>";
296
297	$page->add_breadcrumb_item($lang->edit_mycode);
298	$page->output_header($lang->custom_mycode." - ".$lang->edit_mycode);
299	$page->output_nav_tabs($sub_tabs, 'edit_mycode');
300
301	$form = new Form("index.php?module=config-mycode&amp;action=edit", "post", "edit");
302	echo $form->generate_hidden_field('cid', $mycode['cid']);
303
304	if($errors)
305	{
306		$page->output_inline_error($errors);
307	}
308	else
309	{
310		$mybb->input = array_merge($mybb->input, $mycode);
311	}
312
313	$form_container = new FormContainer($lang->edit_mycode);
314	$form_container->output_row($lang->title." <em>*</em>", '', $form->generate_text_box('title', $mybb->input['title'], array('id' => 'title')), 'title');
315	$form_container->output_row($lang->short_description, '', $form->generate_text_box('description', $mybb->input['description'], array('id' => 'description')), 'description');
316	$form_container->output_row($lang->regular_expression." <em>*</em>", $lang->regular_expression_desc.'<br /><strong>'.$lang->example.'</strong> \[b\](.*?)\[/b\]', $form->generate_text_area('regex', $mybb->input['regex'], array('id' => 'regex')), 'regex');
317	$form_container->output_row($lang->replacement." <em>*</em>", $lang->replacement_desc.'<br /><strong>'.$lang->example.'</strong> &lt;strong&gt;$1&lt;/strong&gt;', $form->generate_text_area('replacement', $mybb->input['replacement'], array('id' => 'replacement')), 'replacement');
318	$form_container->output_row($lang->enabled." <em>*</em>", '', $form->generate_yes_no_radio('active', $mybb->input['active']));
319	$form_container->output_row($lang->parse_order, $lang->parse_order_desc, $form->generate_numeric_field('parseorder', $mybb->input['parseorder'], array('id' => 'parseorder', 'min' => 0)), 'parseorder');
320	$form_container->end();
321
322	$buttons[] = $form->generate_submit_button($lang->save_mycode);
323
324	$form->output_submit_wrapper($buttons);
325
326	// Sandbox
327	$sandbox_actual = isset($sandbox['actual']) ? $sandbox['actual'] : null;
328
329	echo "<br />\n";
330	$form_container = new FormContainer($lang->sandbox);
331	$form_container->output_row($lang->sandbox_desc);
332	$form_container->output_row($lang->test_value, $lang->test_value_desc, $form->generate_text_area('test_value', $mybb->get_input('test_value'), array('id' => 'test_value'))."<br />".$form->generate_submit_button($lang->test, array('id' => 'test', 'name' => 'test')), 'test_value');
333	$form_container->output_row($lang->result_html, $lang->result_html_desc, $form->generate_text_area('result_html', isset($sandbox['html']) ? $sandbox['html'] : null, array('id' => 'result_html', 'disabled' => 1)), 'result_html');
334	$form_container->output_row($lang->result_actual, $lang->result_actual_desc, "<div id=\"result_actual\">{$sandbox_actual}</div>");
335	$form_container->end();
336	echo '<script type="text/javascript" src="./jscripts/mycode_sandbox.js"></script>';
337	echo '<script type="text/javascript">
338
339$(function(){
340//<![CDATA[
341    new MyCodeSandbox("./index.php?module=config-mycode&action=xmlhttp_test_mycode", $("#test"), $("#regex"), $("#replacement"), $("#test_value"), $("#result_html"), $("#result_actual"));
342});
343//]]>
344</script>';
345
346	$form->end();
347
348	$page->output_footer();
349}
350
351if($mybb->input['action'] == "delete")
352{
353	$query = $db->simple_select("mycode", "*", "cid='".$mybb->get_input('cid', MyBB::INPUT_INT)."'");
354	$mycode = $db->fetch_array($query);
355
356	if(!$mycode['cid'])
357	{
358		flash_message($lang->error_invalid_mycode, 'error');
359		admin_redirect("index.php?module=config-mycode");
360	}
361
362	$plugins->run_hooks("admin_config_mycode_delete");
363
364	// User clicked no
365	if($mybb->get_input('no'))
366	{
367		admin_redirect("index.php?module=config-mycode");
368	}
369
370	if($mybb->request_method == "post")
371	{
372		$db->delete_query("mycode", "cid='{$mycode['cid']}'");
373
374		$plugins->run_hooks("admin_config_mycode_delete_commit");
375
376		$cache->update_mycode();
377
378		// Log admin action
379		log_admin_action($mycode['cid'], $mycode['title']);
380
381		flash_message($lang->success_deleted_mycode, 'success');
382		admin_redirect("index.php?module=config-mycode");
383	}
384	else
385	{
386		$page->output_confirm_action("index.php?module=config-mycode&amp;action=delete&amp;cid={$mycode['cid']}", $lang->confirm_mycode_deletion);
387	}
388}
389
390if(!$mybb->input['action'])
391{
392	$plugins->run_hooks("admin_config_mycode_start");
393
394	$page->output_header($lang->custom_mycode);
395
396	$sub_tabs['mycode'] = array(
397		'title'	=> $lang->mycode,
398		'link' => "index.php?module=config-mycode",
399		'description' => $lang->mycode_desc
400	);
401
402	$sub_tabs['add_new_mycode'] = array(
403		'title'	=> $lang->add_new_mycode,
404		'link' => "index.php?module=config-mycode&amp;action=add"
405	);
406
407	$page->output_nav_tabs($sub_tabs, 'mycode');
408
409	$query = $db->simple_select("mycode", "COUNT(cid) AS mycode");
410	$total_rows = $db->fetch_field($query, "mycode");
411
412	$pagenum = $mybb->get_input('page', MyBB::INPUT_INT);
413	if($pagenum)
414	{
415		$start = ($pagenum - 1) * 20;
416		$pages = ceil($total_rows / 20);
417		if($pagenum > $pages)
418		{
419			$start = 0;
420			$pagenum = 1;
421		}
422	}
423	else
424	{
425		$start = 0;
426		$pagenum = 1;
427	}
428
429	$table = new Table;
430	$table->construct_header($lang->title);
431	$table->construct_header($lang->controls, array('class' => 'align_center', 'width' => 150));
432
433	$query = $db->simple_select("mycode", "*", "", array('limit_start' => $start, 'limit' => 20, 'order_by' => 'parseorder'));
434	while($mycode = $db->fetch_array($query))
435	{
436		if($mycode['active'] == 1)
437		{
438			$phrase = $lang->deactivate_mycode;
439			$icon = "<img src=\"styles/{$page->style}/images/icons/bullet_on.png\" alt=\"({$lang->alt_enabled})\" title=\"{$lang->alt_enabled}\"  style=\"vertical-align: middle;\" /> ";
440		}
441		else
442		{
443			$phrase = $lang->activate_mycode;
444			$icon = "<img src=\"styles/{$page->style}/images/icons/bullet_off.png\" alt=\"({$lang->alt_disabled})\" title=\"{$lang->alt_disabled}\"  style=\"vertical-align: middle;\" /> ";
445		}
446
447		if($mycode['description'])
448		{
449			$mycode['description'] = "<small>".htmlspecialchars_uni($mycode['description'])."</small>";
450		}
451
452		$table->construct_cell("<div>{$icon}<strong><a href=\"index.php?module=config-mycode&amp;action=edit&amp;cid={$mycode['cid']}\">".htmlspecialchars_uni($mycode['title'])."</a></strong><br />{$mycode['description']}</div>");
453
454		$popup = new PopupMenu("mycode_{$mycode['cid']}", $lang->options);
455		$popup->add_item($lang->edit_mycode, "index.php?module=config-mycode&amp;action=edit&amp;cid={$mycode['cid']}");
456		$popup->add_item($phrase, "index.php?module=config-mycode&amp;action=toggle_status&amp;cid={$mycode['cid']}&amp;my_post_key={$mybb->post_code}");
457		$popup->add_item($lang->delete_mycode, "index.php?module=config-mycode&amp;action=delete&amp;cid={$mycode['cid']}&amp;my_post_key={$mybb->post_code}", "return AdminCP.deleteConfirmation(this, '{$lang->confirm_mycode_deletion}')");
458		$table->construct_cell($popup->fetch(), array('class' => 'align_center'));
459		$table->construct_row();
460	}
461
462	if($table->num_rows() == 0)
463	{
464		$table->construct_cell($lang->no_mycode, array('colspan' => 2));
465		$table->construct_row();
466	}
467
468	$table->output($lang->custom_mycode);
469
470	echo "<br />".draw_admin_pagination($pagenum, "20", $total_rows, "index.php?module=config-mycode&amp;page={page}");
471
472	$page->output_footer();
473}
474
475/**
476 * @param string $regex
477 * @param string $replacement
478 * @param string $test
479 *
480 * @return array
481 */
482function test_regex($regex, $replacement, $test)
483{
484	$array = array();
485	$array['actual'] = @preg_replace("#".str_replace("\x0", "", $regex)."#si", $replacement, $test);
486	$array['html'] = htmlspecialchars_uni($array['actual']);
487	return $array;
488}
489
490/**
491 * Checks if a regex is already available
492 *
493 * @param string $regex The regex to check
494 * @param array $current The currently edited MyCode
495 *
496 * @return bool True if already available, false otherwise
497 */
498function check_existing_regex($regex='', $current=array())
499{
500	global $cache;
501
502	if(!empty($current) && $current['regex'] == $regex)
503	{
504		return false;
505	}
506
507	$mycodes = $cache->read('mycode');
508
509	foreach($mycodes as $mycode)
510	{
511		if($mycode['regex'] == $regex)
512		{
513			return true;
514		}
515	}
516
517	return false;
518}