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

Scott committed
355
		if (defined('QA_CACHE_DIRECTORY')) {
Scott committed
356
			$navigation['admin/caching'] = array(
Scott committed
357 358
				'label' => qa_lang_html('admin/caching_title'),
				'url' => qa_path_html('admin/caching'),
Scott committed
359
			);
Scott committed
360
		}
Scott committed
361

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

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

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

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

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

Scott committed
388
	if (qa_opt('flagging_of_posts') && !qa_user_maximum_permit_error('permit_hide_show')) {
Scott committed
389
		$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
390

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

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

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

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

Scott committed
413 414
	return $navigation;
}
Scott committed
415 416


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

Scott committed
425
	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
426 427 428 429
		return strtr(
			qa_lang_html('admin/upgrade_db'),

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

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

Scott committed
439
	return null;
Scott committed
440
}
Scott committed
441 442


Scott committed
443 444 445 446 447 448 449
/**
 * 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
450 451


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

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

Scott committed
465
	$pathmap = qa_get_request_map();
Scott committed
466

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

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

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

Scott committed
489 490
	return false;
}
Scott committed
491 492


Scott committed
493 494 495
/**
 * 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
496 497 498
 * @param $entityid
 * @param $action
 * @return bool
Scott committed
499 500 501
 */
function qa_admin_single_click($entityid, $action)
{
Scott committed
502
	$userid = qa_get_logged_in_userid();
Scott committed
503

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

Scott committed
507
		$useraccount = qa_db_select_with_pending(qa_db_user_account_selectspec($entityid, true));
Scott committed
508

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

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

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

Scott committed
530
		$post = qa_post_get_full($entityid);
Scott committed
531

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

Scott committed
535 536 537 538 539 540 541
			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
542

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

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

Scott committed
557 558 559 560 561 562
				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
563

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

Scott committed
571
				case 'clearflags':
Scott committed
572
					require_once QA_INCLUDE_DIR . 'app/votes.php';
Scott committed
573

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

Scott committed
583 584 585 586 587 588 589 590 591
	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
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
	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
610

Scott committed
611 612
	return null;
}
Scott committed
613 614


Scott committed
615 616 617 618
/**
 * 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
619 620 621
 * @param $contents
 * @param $fields
 * @return array
Scott committed
622 623 624
 */
function qa_admin_addon_metadata($contents, $fields)
{
Scott committed
625
	$metadata = array();
Scott committed
626

Scott committed
627 628 629 630
	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
631

Scott committed
632 633
	return $metadata;
}
634

Scott committed
635

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

Scott committed
646 647
	return reset($hashes);
}
Scott committed
648 649


Scott committed
650 651
/**
 * Return the URL (relative to the current page) to navigate to the options panel for the plugin in $directory (without trailing slash)
Scott committed
652 653
 * @param $directory
 * @return mixed|string
Scott committed
654 655 656 657 658 659
 */
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
660

Scott committed
661

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

Scott committed
673 674
	return qa_admin_plugin_options_path($dir);
}