admin.php 19.3 KB
Newer Older
Scott committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
<?php
/*
	Question2Answer by Gideon Greenspan and contributors
	http://www.question2answer.org/

	File: qa-include/qa-app-admin.php
	Description: Functions used in the admin center pages


	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	More about this license: http://www.question2answer.org/license.php
*/

Scott committed
23 24 25 26
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
	header('Location: ../');
	exit;
}
Scott committed
27 28


Scott committed
29 30 31
/**
 * Return true if user is logged in with admin privileges. If not, return false
 * and set up $qa_content with the appropriate title and error message
Scott committed
32 33
 * @param $qa_content
 * @return bool
Scott committed
34 35 36 37
 */
function qa_admin_check_privileges(&$qa_content)
{
	if (!qa_is_logged_in()) {
Scott committed
38
		require_once QA_INCLUDE_DIR . 'app/format.php';
Scott committed
39

Scott committed
40
		$qa_content = qa_content_prepare();
Scott committed
41

Scott committed
42 43
		$qa_content['title'] = qa_lang_html('admin/admin_title');
		$qa_content['error'] = qa_insert_login_links(qa_lang_html('admin/not_logged_in'), qa_request());
Scott committed
44

Scott committed
45
		return false;
Scott committed
46

Scott committed
47 48
	} elseif (qa_get_logged_in_level() < QA_USER_LEVEL_ADMIN) {
		$qa_content = qa_content_prepare();
Scott committed
49

Scott committed
50 51
		$qa_content['title'] = qa_lang_html('admin/admin_title');
		$qa_content['error'] = qa_lang_html('admin/no_privileges');
Scott committed
52

Scott committed
53
		return false;
Scott committed
54 55
	}

Scott committed
56 57 58 59 60 61 62 63 64 65
	return true;
}


/**
 *	Return a sorted array of available languages, [short code] => [long name]
 */
function qa_admin_language_options()
{
	if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
Scott committed
66

67
	/**
Scott committed
68 69
	 * @deprecated The hardcoded language ids will be removed in favor of language metadata files.
	 * See qa-lang/en-GB directory for a clear example of how to use them.
70
	 */
Scott committed
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
	$codetolanguage = array( // 2-letter language codes as per ISO 639-1
		'ar' => 'Arabic - العربية',
		'az' => 'Azerbaijani - Azərbaycanca',
		'bg' => 'Bulgarian - Български',
		'bn' => 'Bengali - বাংলা',
		'ca' => 'Catalan - Català',
		'cs' => 'Czech - Čeština',
		'cy' => 'Welsh - Cymraeg',
		'da' => 'Danish - Dansk',
		'de' => 'German - Deutsch',
		'el' => 'Greek - Ελληνικά',
		'en-GB' => 'English (UK)',
		'es' => 'Spanish - Español',
		'et' => 'Estonian - Eesti',
		'fa' => 'Persian - فارسی',
		'fi' => 'Finnish - Suomi',
		'fr' => 'French - Français',
		'he' => 'Hebrew - עברית',
		'hr' => 'Croatian - Hrvatski',
		'hu' => 'Hungarian - Magyar',
		'id' => 'Indonesian - Bahasa Indonesia',
		'is' => 'Icelandic - Íslenska',
		'it' => 'Italian - Italiano',
		'ja' => 'Japanese - 日本語',
		'ka' => 'Georgian - ქართული ენა',
		'kh' => 'Khmer - ភាសាខ្មែរ',
		'ko' => 'Korean - 한국어',
		'ku-CKB' => 'Kurdish Central - کورد',
		'lt' => 'Lithuanian - Lietuvių',
		'lv' => 'Latvian - Latviešu',
		'nl' => 'Dutch - Nederlands',
		'no' => 'Norwegian - Norsk',
		'pl' => 'Polish - Polski',
		'pt' => 'Portuguese - Português',
		'ro' => 'Romanian - Română',
		'ru' => 'Russian - Русский',
		'sk' => 'Slovak - Slovenčina',
		'sl' => 'Slovenian - Slovenščina',
		'sq' => 'Albanian - Shqip',
		'sr' => 'Serbian - Српски',
		'sv' => 'Swedish - Svenska',
		'th' => 'Thai - ไทย',
		'tr' => 'Turkish - Türkçe',
		'ug' => 'Uyghur - ئۇيغۇرچە',
		'uk' => 'Ukrainian - Українська',
		'uz' => 'Uzbek - ўзбек',
		'vi' => 'Vietnamese - Tiếng Việt',
		'zh-TW' => 'Chinese Traditional - 繁體中文',
		'zh' => 'Chinese Simplified - 简体中文',
	);

	$options = array('' => 'English (US)');

	// find all language folders
	$metadataUtil = new Q2A_Util_Metadata();
	foreach (glob(QA_LANG_DIR . '*', GLOB_ONLYDIR) as $directory) {
		$code = basename($directory);
		$metadata = $metadataUtil->fetchFromAddonPath($directory);
Scott committed
129
		if (isset($metadata['name'])) {
Scott committed
130
			$options[$code] = $metadata['name'];
Scott committed
131 132
		} elseif (isset($codetolanguage[$code])) {
			// otherwise use an entry from above
Scott committed
133
			$options[$code] = $codetolanguage[$code];
Scott committed
134
		}
Scott committed
135
	}
Scott committed
136

Scott committed
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
	asort($options, SORT_STRING);
	return $options;
}


/**
 * Return a sorted array of available themes, [theme name] => [theme name]
 */
function qa_admin_theme_options()
{
	if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }

	$metadataUtil = new Q2A_Util_Metadata();
	foreach (glob(QA_THEME_DIR . '*', GLOB_ONLYDIR) as $directory) {
		$theme = basename($directory);
		$metadata = $metadataUtil->fetchFromAddonPath($directory);
		if (empty($metadata)) {
			// limit theme parsing to first 8kB
155
			$contents = file_get_contents($directory . '/qa-styles.css', false, null, 0, 8192);
Scott committed
156
			$metadata = qa_addon_metadata($contents, 'Theme');
Scott committed
157
		}
Scott committed
158
		$options[$theme] = isset($metadata['name']) ? $metadata['name'] : $theme;
Scott committed
159 160
	}

Scott committed
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
	asort($options, SORT_STRING);
	return $options;
}


/**
 * Return an array of widget placement options, with keys matching the database value
 */
function qa_admin_place_options()
{
	return array(
		'FT' => qa_lang_html('options/place_full_top'),
		'FH' => qa_lang_html('options/place_full_below_nav'),
		'FL' => qa_lang_html('options/place_full_below_content'),
		'FB' => qa_lang_html('options/place_full_below_footer'),
		'MT' => qa_lang_html('options/place_main_top'),
		'MH' => qa_lang_html('options/place_main_below_title'),
		'ML' => qa_lang_html('options/place_main_below_lists'),
		'MB' => qa_lang_html('options/place_main_bottom'),
		'ST' => qa_lang_html('options/place_side_top'),
		'SH' => qa_lang_html('options/place_side_below_sidebar'),
		'SL' => qa_lang_html('options/place_side_low'),
		'SB' => qa_lang_html('options/place_side_last'),
	);
}


/**
 * Return an array of page size options up to $maximum, [page size] => [page size]
Scott committed
190 191
 * @param $maximum
 * @return array
Scott committed
192 193 194
 */
function qa_admin_page_size_options($maximum)
{
Scott committed
195
	$rawoptions = array(5, 10, 15, 20, 25, 30, 40, 50, 60, 80, 100, 120, 150, 200, 250, 300, 400, 500, 600, 800, 1000);
Scott committed
196

Scott committed
197
	$options = array();
Scott committed
198
	foreach ($rawoptions as $rawoption) {
Scott committed
199
		if ($rawoption > $maximum)
Scott committed
200 201
			break;

Scott committed
202
		$options[$rawoption] = $rawoption;
Scott committed
203
	}
Scott committed
204

Scott committed
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
	return $options;
}


/**
 * Return an array of options representing matching precision, [value] => [label]
 */
function qa_admin_match_options()
{
	return array(
		5 => qa_lang_html('options/match_5'),
		4 => qa_lang_html('options/match_4'),
		3 => qa_lang_html('options/match_3'),
		2 => qa_lang_html('options/match_2'),
		1 => qa_lang_html('options/match_1'),
	);
}


/**
 * Return an array of options representing permission restrictions, [value] => [label]
 * ranging from $widest to $narrowest. Set $doconfirms to whether email confirmations are on
Scott committed
227 228 229 230 231
 * @param $widest
 * @param $narrowest
 * @param bool $doconfirms
 * @param bool $dopoints
 * @return array
Scott committed
232
 */
Scott committed
233
function qa_admin_permit_options($widest, $narrowest, $doconfirms = true, $dopoints = true)
Scott committed
234
{
Scott committed
235
	require_once QA_INCLUDE_DIR . 'app/options.php';
Scott committed
236

Scott committed
237
	$options = array(
Scott committed
238 239 240 241 242 243 244 245 246 247 248 249 250 251
		QA_PERMIT_ALL => qa_lang_html('options/permit_all'),
		QA_PERMIT_USERS => qa_lang_html('options/permit_users'),
		QA_PERMIT_CONFIRMED => qa_lang_html('options/permit_confirmed'),
		QA_PERMIT_POINTS => qa_lang_html('options/permit_points'),
		QA_PERMIT_POINTS_CONFIRMED => qa_lang_html('options/permit_points_confirmed'),
		QA_PERMIT_APPROVED => qa_lang_html('options/permit_approved'),
		QA_PERMIT_APPROVED_POINTS => qa_lang_html('options/permit_approved_points'),
		QA_PERMIT_EXPERTS => qa_lang_html('options/permit_experts'),
		QA_PERMIT_EDITORS => qa_lang_html('options/permit_editors'),
		QA_PERMIT_MODERATORS => qa_lang_html('options/permit_moderators'),
		QA_PERMIT_ADMINS => qa_lang_html('options/permit_admins'),
		QA_PERMIT_SUPERS => qa_lang_html('options/permit_supers'),
	);

Scott committed
252 253
	foreach ($options as $key => $label) {
		if ($key < $narrowest || $key > $widest)
Scott committed
254
			unset($options[$key]);
Scott committed
255
	}
Scott committed
256 257 258 259

	if (!$doconfirms) {
		unset($options[QA_PERMIT_CONFIRMED]);
		unset($options[QA_PERMIT_POINTS_CONFIRMED]);
Scott committed
260 261
	}

Scott committed
262 263 264 265 266
	if (!$dopoints) {
		unset($options[QA_PERMIT_POINTS]);
		unset($options[QA_PERMIT_POINTS_CONFIRMED]);
		unset($options[QA_PERMIT_APPROVED_POINTS]);
	}
Scott committed
267

Scott committed
268 269 270
	if (QA_FINAL_EXTERNAL_USERS || !qa_opt('moderate_users')) {
		unset($options[QA_PERMIT_APPROVED]);
		unset($options[QA_PERMIT_APPROVED_POINTS]);
Scott committed
271 272
	}

Scott committed
273 274
	return $options;
}
Scott committed
275 276


Scott committed
277 278 279 280 281 282
/**
 * Return the sub navigation structure common to admin pages
 */
function qa_admin_sub_navigation()
{
	if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
Scott committed
283

Scott committed
284 285
	$navigation = array();
	$level = qa_get_logged_in_level();
Scott committed
286

Scott committed
287 288
	if ($level >= QA_USER_LEVEL_ADMIN) {
		$navigation['admin/general'] = array(
Scott committed
289 290 291
			'label' => qa_lang_html('admin/general_title'),
			'url' => qa_path_html('admin/general'),
		);
Scott committed
292

Scott committed
293
		$navigation['admin/emails'] = array(
Scott committed
294 295 296
			'label' => qa_lang_html('admin/emails_title'),
			'url' => qa_path_html('admin/emails'),
		);
Scott committed
297

Scott committed
298
		$navigation['admin/users'] = array(
Scott committed
299 300 301
			'label' => qa_lang_html('admin/users_title'),
			'url' => qa_path_html('admin/users'),
			'selected_on' => array('admin/users$', 'admin/userfields$', 'admin/usertitles$'),
Scott committed
302 303
		);

Scott committed
304
		$navigation['admin/layout'] = array(
Scott committed
305 306 307
			'label' => qa_lang_html('admin/layout_title'),
			'url' => qa_path_html('admin/layout'),
		);
Scott committed
308

Scott committed
309
		$navigation['admin/posting'] = array(
Scott committed
310 311
			'label' => qa_lang_html('admin/posting_title'),
			'url' => qa_path_html('admin/posting'),
Scott committed
312 313
		);

Scott committed
314
		$navigation['admin/viewing'] = array(
Scott committed
315 316 317
			'label' => qa_lang_html('admin/viewing_title'),
			'url' => qa_path_html('admin/viewing'),
		);
Scott committed
318

Scott committed
319
		$navigation['admin/lists'] = array(
Scott committed
320 321 322
			'label' => qa_lang_html('admin/lists_title'),
			'url' => qa_path_html('admin/lists'),
		);
Scott committed
323

Scott committed
324
		if (qa_using_categories())
Scott committed
325
			$navigation['admin/categories'] = array(
Scott committed
326 327 328
				'label' => qa_lang_html('admin/categories_title'),
				'url' => qa_path_html('admin/categories'),
			);
Scott committed
329

Scott committed
330
		$navigation['admin/permissions'] = array(
Scott committed
331 332 333
			'label' => qa_lang_html('admin/permissions_title'),
			'url' => qa_path_html('admin/permissions'),
		);
Scott committed
334

Scott committed
335
		$navigation['admin/pages'] = array(
Scott committed
336 337 338
			'label' => qa_lang_html('admin/pages_title'),
			'url' => qa_path_html('admin/pages'),
		);
Scott committed
339

Scott committed
340
		$navigation['admin/feeds'] = array(
Scott committed
341 342 343
			'label' => qa_lang_html('admin/feeds_title'),
			'url' => qa_path_html('admin/feeds'),
		);
Scott committed
344

Scott committed
345
		$navigation['admin/points'] = array(
Scott committed
346 347 348
			'label' => qa_lang_html('admin/points_title'),
			'url' => qa_path_html('admin/points'),
		);
Scott committed
349

Scott committed
350
		$navigation['admin/spam'] = array(
Scott committed
351 352 353
			'label' => qa_lang_html('admin/spam_title'),
			'url' => qa_path_html('admin/spam'),
		);
Scott committed
354

355 356 357 358
		$navigation['admin/caching'] = array(
			'label' => qa_lang_html('admin/caching_title'),
			'url' => qa_path_html('admin/caching'),
		);
Scott committed
359

Scott committed
360
		$navigation['admin/stats'] = array(
Scott committed
361 362 363
			'label' => qa_lang_html('admin/stats_title'),
			'url' => qa_path_html('admin/stats'),
		);
Scott committed
364

Scott committed
365
		if (!QA_FINAL_EXTERNAL_USERS)
Scott committed
366
			$navigation['admin/mailing'] = array(
Scott committed
367 368
				'label' => qa_lang_html('admin/mailing_title'),
				'url' => qa_path_html('admin/mailing'),
Scott committed
369 370
			);

Scott committed
371
		$navigation['admin/plugins'] = array(
Scott committed
372 373 374 375
			'label' => qa_lang_html('admin/plugins_title'),
			'url' => qa_path_html('admin/plugins'),
		);
	}
Scott committed
376

Scott committed
377
	if (!qa_user_maximum_permit_error('permit_moderate')) {
Scott committed
378
		$count = qa_user_permit_error('permit_moderate') ? null : qa_opt('cache_queuedcount'); // if only in some categories don't show cached count
Scott committed
379

Scott committed
380 381
		$navigation['admin/moderate'] = array(
			'label' => qa_lang_html('admin/moderate_title') . ($count ? (' (' . $count . ')') : ''),
Scott committed
382 383 384
			'url' => qa_path_html('admin/moderate'),
		);
	}
Scott committed
385

Scott committed
386
	if (qa_opt('flagging_of_posts') && !qa_user_maximum_permit_error('permit_hide_show')) {
Scott committed
387
		$count = qa_user_permit_error('permit_hide_show') ? null : qa_opt('cache_flaggedcount'); // if only in some categories don't show cached count
Scott committed
388

Scott committed
389 390
		$navigation['admin/flagged'] = array(
			'label' => qa_lang_html('admin/flagged_title') . ($count ? (' (' . $count . ')') : ''),
Scott committed
391 392 393
			'url' => qa_path_html('admin/flagged'),
		);
	}
Scott committed
394

Scott committed
395 396
	if (!qa_user_maximum_permit_error('permit_hide_show') || !qa_user_maximum_permit_error('permit_delete_hidden')) {
		$navigation['admin/hidden'] = array(
Scott committed
397 398 399
			'label' => qa_lang_html('admin/hidden_title'),
			'url' => qa_path_html('admin/hidden'),
		);
Scott committed
400
	}
Scott committed
401

Scott committed
402 403
	if (!QA_FINAL_EXTERNAL_USERS && qa_opt('moderate_users') && $level >= QA_USER_LEVEL_MODERATOR) {
		$count = qa_opt('cache_uapprovecount');
Scott committed
404

Scott committed
405 406
		$navigation['admin/approve'] = array(
			'label' => qa_lang_html('admin/approve_users_title') . ($count ? (' (' . $count . ')') : ''),
Scott committed
407 408 409
			'url' => qa_path_html('admin/approve'),
		);
	}
Scott committed
410

Scott committed
411 412
	return $navigation;
}
Scott committed
413 414


Scott committed
415 416 417 418 419
/**
 * Return the error that needs to displayed on all admin pages, or null if none
 */
function qa_admin_page_error()
{
Scott committed
420 421
	if (file_exists(QA_INCLUDE_DIR . 'db/install.php')) // file can be removed for extra security
		include_once QA_INCLUDE_DIR . 'db/install.php';
422

Scott committed
423
	if (defined('QA_DB_VERSION_CURRENT') && qa_opt('db_version') < QA_DB_VERSION_CURRENT && qa_get_logged_in_level() >= QA_USER_LEVEL_ADMIN) {
Scott committed
424 425 426 427
		return strtr(
			qa_lang_html('admin/upgrade_db'),

			array(
Scott committed
428
				'^1' => '<a href="' . qa_path_html('install') . '">',
Scott committed
429 430 431
				'^2' => '</a>',
			)
		);
Scott committed
432

Scott committed
433
	} elseif (defined('QA_BLOBS_DIRECTORY') && !is_writable(QA_BLOBS_DIRECTORY)) {
Scott committed
434
		return qa_lang_html_sub('admin/blobs_directory_error', qa_html(QA_BLOBS_DIRECTORY));
Scott committed
435
	}
Scott committed
436

Scott committed
437
	return null;
Scott committed
438
}
Scott committed
439 440


Scott committed
441 442 443 444 445 446 447
/**
 * Return an HTML fragment to display for a URL test which has passed
 */
function qa_admin_url_test_html()
{
	return '; font-size:9px; color:#060; font-weight:bold; font-family:arial,sans-serif; border-color:#060;">OK<';
}
Scott committed
448 449


Scott committed
450 451
/**
 * Returns whether a URL path beginning with $requestpart is reserved by the engine or a plugin page module
Scott committed
452 453
 * @param $requestpart
 * @return bool
Scott committed
454 455 456
 */
function qa_admin_is_slug_reserved($requestpart)
{
Scott committed
457 458
	$requestpart = trim(strtolower($requestpart));
	$routing = qa_page_routing();
Scott committed
459

Scott committed
460
	if (isset($routing[$requestpart]) || isset($routing[$requestpart . '/']) || is_numeric($requestpart))
Scott committed
461
		return true;
Scott committed
462

Scott committed
463
	$pathmap = qa_get_request_map();
Scott committed
464

Scott committed
465
	foreach ($pathmap as $mappedrequest) {
Scott committed
466 467
		if (trim(strtolower($mappedrequest)) == $requestpart)
			return true;
Scott committed
468
	}
Scott committed
469

Scott committed
470 471 472 473 474 475 476 477 478
	switch ($requestpart) {
		case '':
		case 'qa':
		case 'feed':
		case 'install':
		case 'url':
		case 'image':
		case 'ajax':
			return true;
Scott committed
479 480
	}

Scott committed
481 482
	$pagemodules = qa_load_modules_with('page', 'match_request');
	foreach ($pagemodules as $pagemodule) {
Scott committed
483 484
		if ($pagemodule->match_request($requestpart))
			return true;
Scott committed
485
	}
Scott committed
486

Scott committed
487 488
	return false;
}
Scott committed
489 490


Scott committed
491 492 493
/**
 * Returns true if admin (hidden/flagged/approve/moderate) page $action performed on $entityid is permitted by the
 * logged in user and was processed successfully
Scott committed
494 495 496
 * @param $entityid
 * @param $action
 * @return bool
Scott committed
497 498 499
 */
function qa_admin_single_click($entityid, $action)
{
Scott committed
500
	$userid = qa_get_logged_in_userid();
Scott committed
501

Scott committed
502 503
	if (!QA_FINAL_EXTERNAL_USERS && ($action == 'userapprove' || $action == 'userblock')) { // approve/block moderated users
		require_once QA_INCLUDE_DIR . 'db/selects.php';
Scott committed
504

Scott committed
505
		$useraccount = qa_db_select_with_pending(qa_db_user_account_selectspec($entityid, true));
Scott committed
506

Scott committed
507
		if (isset($useraccount) && qa_get_logged_in_level() >= QA_USER_LEVEL_MODERATOR) {
Scott committed
508 509
			switch ($action) {
				case 'userapprove':
Scott committed
510 511
					if ($useraccount['level'] <= QA_USER_LEVEL_APPROVED) { // don't demote higher level users
						require_once QA_INCLUDE_DIR . 'app/users-edit.php';
Scott committed
512 513 514 515
						qa_set_user_level($useraccount['userid'], $useraccount['handle'], QA_USER_LEVEL_APPROVED, $useraccount['level']);
						return true;
					}
					break;
Scott committed
516

Scott committed
517
				case 'userblock':
Scott committed
518
					require_once QA_INCLUDE_DIR . 'app/users-edit.php';
Scott committed
519 520 521 522
					qa_set_user_blocked($useraccount['userid'], $useraccount['handle'], true);
					return true;
					break;
			}
Scott committed
523
		}
Scott committed
524

Scott committed
525
	} else { // something to do with a post
Scott committed
526
		require_once QA_INCLUDE_DIR . 'app/posts.php';
Scott committed
527

Scott committed
528
		$post = qa_post_get_full($entityid);
Scott committed
529

Scott committed
530
		if (isset($post)) {
Scott committed
531
			$queued = (substr($post['type'], 1) == '_QUEUED');
Scott committed
532

Scott committed
533 534 535 536 537 538 539
			switch ($action) {
				case 'approve':
					if ($queued && !qa_user_post_permit_error('permit_moderate', $post)) {
						qa_post_set_hidden($entityid, false, $userid);
						return true;
					}
					break;
Scott committed
540

Scott committed
541 542 543 544 545 546
				case 'reject':
					if ($queued && !qa_user_post_permit_error('permit_moderate', $post)) {
						qa_post_set_hidden($entityid, true, $userid);
						return true;
					}
					break;
Scott committed
547

Scott committed
548
				case 'hide':
Scott committed
549
					if (!$queued && !qa_user_post_permit_error('permit_hide_show', $post)) {
Scott committed
550 551 552 553
						qa_post_set_hidden($entityid, true, $userid);
						return true;
					}
					break;
Scott committed
554

Scott committed
555 556 557 558 559 560
				case 'reshow':
					if ($post['hidden'] && !qa_user_post_permit_error('permit_hide_show', $post)) {
						qa_post_set_hidden($entityid, false, $userid);
						return true;
					}
					break;
Scott committed
561

Scott committed
562 563 564 565 566 567
				case 'delete':
					if ($post['hidden'] && !qa_user_post_permit_error('permit_delete_hidden', $post)) {
						qa_post_delete($entityid);
						return true;
					}
					break;
Scott committed
568

Scott committed
569
				case 'clearflags':
Scott committed
570
					require_once QA_INCLUDE_DIR . 'app/votes.php';
Scott committed
571

Scott committed
572 573
					if (!qa_user_post_permit_error('permit_hide_show', $post)) {
						qa_flags_clear_all($post, $userid, qa_get_logged_in_handle(), null);
Scott committed
574
						return true;
Scott committed
575 576
					}
					break;
Scott committed
577 578 579 580
			}
		}
	}

Scott committed
581 582 583 584 585 586 587 588 589
	return false;
}


/**
 * Checks for a POSTed click on an admin (hidden/flagged/approve/moderate) page, and refresh the page if processed successfully (non Ajax)
 */
function qa_admin_check_clicks()
{
Scott committed
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
	if (!qa_is_http_post()) {
		return null;
	}

	foreach ($_POST as $field => $value) {
		if (strpos($field, 'admin_') !== 0) {
			continue;
		}

		@list($dummy, $entityid, $action) = explode('_', $field);

		if (strlen($entityid) && strlen($action)) {
			if (!qa_check_form_security_code('admin/click', qa_post_text('code')))
				return qa_lang_html('misc/form_security_again');
			elseif (qa_admin_single_click($entityid, $action))
				qa_redirect(qa_request());
		}
	}
Scott committed
608

Scott committed
609 610
	return null;
}
Scott committed
611 612


Scott committed
613 614 615 616
/**
 * Retrieve metadata information from the $contents of a qa-theme.php or qa-plugin.php file, mapping via $fields.
 *
 * @deprecated Deprecated from 1.7; use `qa_addon_metadata($contents, $type)` instead.
Scott committed
617 618 619
 * @param $contents
 * @param $fields
 * @return array
Scott committed
620 621 622
 */
function qa_admin_addon_metadata($contents, $fields)
{
Scott committed
623
	$metadata = array();
Scott committed
624

Scott committed
625 626 627 628
	foreach ($fields as $key => $field) {
		if (preg_match('/' . str_replace(' ', '[ \t]*', preg_quote($field, '/')) . ':[ \t]*([^\n\f]*)[\n\f]/i', $contents, $matches))
			$metadata[$key] = trim($matches[1]);
	}
Scott committed
629

Scott committed
630 631
	return $metadata;
}
632

Scott committed
633

Scott committed
634 635
/**
 * Return the hash code for the plugin in $directory (without trailing slash), used for in-page navigation on admin/plugins page
Scott committed
636 637
 * @param $directory
 * @return mixed
Scott committed
638 639 640 641 642
 */
function qa_admin_plugin_directory_hash($directory)
{
	$pluginManager = new Q2A_Plugin_PluginManager();
	$hashes = $pluginManager->getHashesForPlugins(array($directory));
Scott committed
643

Scott committed
644 645
	return reset($hashes);
}
Scott committed
646 647


Scott committed
648 649
/**
 * Return the URL (relative to the current page) to navigate to the options panel for the plugin in $directory (without trailing slash)
Scott committed
650 651
 * @param $directory
 * @return mixed|string
Scott committed
652 653 654 655 656 657
 */
function qa_admin_plugin_options_path($directory)
{
	$hash = qa_admin_plugin_directory_hash($directory);
	return qa_path_html('admin/plugins', array('show' => $hash), null, null, $hash);
}
Scott committed
658

Scott committed
659

Scott committed
660 661
/**
 * Return the URL (relative to the current page) to navigate to the options panel for plugin module $name of $type
Scott committed
662 663 664
 * @param $type
 * @param $name
 * @return mixed|string
Scott committed
665 666 667 668
 */
function qa_admin_module_options_path($type, $name)
{
	$info = qa_get_module_info($type, $name);
Scott committed
669
	$dir = basename($info['directory']);
Scott committed
670

Scott committed
671 672
	return qa_admin_plugin_options_path($dir);
}