ask.php 10.1 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
<?php
/*
	Question2Answer by Gideon Greenspan and contributors
	http://www.question2answer.org/

	Description: Controller for ask a question page


	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
22
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
23
	header('Location: ../../');
Scott committed
24 25
	exit;
}
Scott committed
26 27


Scott committed
28 29 30 31
require_once QA_INCLUDE_DIR.'app/format.php';
require_once QA_INCLUDE_DIR.'app/limits.php';
require_once QA_INCLUDE_DIR.'db/selects.php';
require_once QA_INCLUDE_DIR.'util/sort.php';
Scott committed
32 33


Scott committed
34
// Check whether this is a follow-on question and get some info we need from the database
Scott committed
35

Scott committed
36
$in = array();
Scott committed
37

Scott committed
38 39 40
$followpostid = qa_get('follow');
$in['categoryid'] = qa_clicked('doask') ? qa_get_category_field_value('category') : qa_get('cat');
$userid = qa_get_logged_in_userid();
Scott committed
41

Scott committed
42 43 44 45 46
list($categories, $followanswer, $completetags) = qa_db_select_with_pending(
	qa_db_category_nav_selectspec($in['categoryid'], true),
	isset($followpostid) ? qa_db_full_post_selectspec($userid, $followpostid) : null,
	qa_db_popular_tags_selectspec(0, QA_DB_RETRIEVE_COMPLETE_TAGS)
);
Scott committed
47

Scott committed
48 49 50
if (!isset($categories[$in['categoryid']])) {
	$in['categoryid'] = null;
}
Scott committed
51

Scott committed
52 53 54
if (@$followanswer['basetype'] != 'A') {
	$followanswer = null;
}
Scott committed
55 56


Scott committed
57
// Check for permission error
Scott committed
58

Scott committed
59
$permiterror = qa_user_maximum_permit_error('permit_post_q', QA_LIMIT_QUESTIONS);
Scott committed
60

Scott committed
61 62
if ($permiterror) {
	$qa_content = qa_content_prepare();
Scott committed
63

Scott committed
64 65
	// The 'approve', 'login', 'confirm', 'limit', 'userblock', 'ipblock' permission errors are reported to the user here
	// The other option ('level') prevents the menu option being shown, in qa_content_prepare(...)
Scott committed
66

Scott committed
67 68 69 70
	switch ($permiterror) {
		case 'login':
			$qa_content['error'] = qa_insert_login_links(qa_lang_html('question/ask_must_login'), qa_request(), isset($followpostid) ? array('follow' => $followpostid) : null);
			break;
Scott committed
71

Scott committed
72 73 74
		case 'confirm':
			$qa_content['error'] = qa_insert_login_links(qa_lang_html('question/ask_must_confirm'), qa_request(), isset($followpostid) ? array('follow' => $followpostid) : null);
			break;
Scott committed
75

Scott committed
76 77 78
		case 'limit':
			$qa_content['error'] = qa_lang_html('question/ask_limit');
			break;
Scott committed
79

Scott committed
80
		case 'approve':
81 82 83 84
			$qa_content['error'] = strtr(qa_lang_html('question/ask_must_be_approved'), array(
				'^1' => '<a href="' . qa_path_html('account') . '">',
				'^2' => '</a>',
			));
Scott committed
85
			break;
Scott committed
86

Scott committed
87 88 89
		default:
			$qa_content['error'] = qa_lang_html('users/no_permission');
			break;
Scott committed
90 91
	}

Scott committed
92 93
	return $qa_content;
}
Scott committed
94 95


Scott committed
96
// Process input
Scott committed
97

Scott committed
98
$captchareason = qa_user_captcha_reason();
Scott committed
99

100
$in['title'] = qa_get_post_title('title'); // allow title and tags to be posted by an external form
Scott committed
101
$in['extra'] = qa_opt('extra_field_active') ? qa_post_text('extra') : null;
Scott committed
102

Scott committed
103 104 105
if (qa_using_tags()) {
	$in['tags'] = qa_get_tags_field_value('tags');
}
Scott committed
106

Scott committed
107 108 109
if (qa_clicked('doask')) {
	require_once QA_INCLUDE_DIR.'app/post-create.php';
	require_once QA_INCLUDE_DIR.'util/string.php';
Scott committed
110

Scott committed
111 112
	$categoryids = array_keys(qa_category_path($categories, @$in['categoryid']));
	$userlevel = qa_user_level_for_categories($categoryids);
Scott committed
113

114
	$in['name'] = qa_opt('allow_anonymous_naming') ? qa_post_text('name') : null;
Scott committed
115 116 117
	$in['notify'] = strlen(qa_post_text('notify')) > 0;
	$in['email'] = qa_post_text('email');
	$in['queued'] = qa_user_moderation_reason($userlevel) !== false;
Scott committed
118

Scott committed
119
	qa_get_post_content('editor', 'content', $in['editor'], $in['content'], $in['format'], $in['text']);
Scott committed
120

Scott committed
121
	$errors = array();
Scott committed
122

Scott committed
123 124 125 126 127 128 129 130 131 132
	if (!qa_check_form_security_code('ask', qa_post_text('code'))) {
		$errors['page'] = qa_lang_html('misc/form_security_again');
	}
	else {
		$filtermodules = qa_load_modules_with('filter', 'filter_question');
		foreach ($filtermodules as $filtermodule) {
			$oldin = $in;
			$filtermodule->filter_question($in, $errors, null);
			qa_update_post_text($in, $oldin);
		}
133

Scott committed
134 135 136 137 138 139 140
		if (qa_using_categories() && count($categories) && (!qa_opt('allow_no_category')) && !isset($in['categoryid'])) {
			// check this here because we need to know count($categories)
			$errors['categoryid'] = qa_lang_html('question/category_required');
		}
		elseif (qa_user_permit_error('permit_post_q', null, $userlevel)) {
			$errors['categoryid'] = qa_lang_html('question/category_ask_not_allowed');
		}
Scott committed
141

Scott committed
142 143 144 145
		if ($captchareason) {
			require_once QA_INCLUDE_DIR.'app/captcha.php';
			qa_captcha_validate_post($errors);
		}
Scott committed
146

Scott committed
147 148
		if (empty($errors)) {
			// check if the question is already posted
149 150 151
			$testTitleWords = implode(' ', qa_string_to_words($in['title']));
			$testContentWords = implode(' ', qa_string_to_words($in['content']));
			$recentQuestions = qa_db_select_with_pending(qa_db_qs_selectspec(null, 'created', 0, null, null, false, true, 5));
Scott committed
152

153
			foreach ($recentQuestions as $question) {
Scott committed
154
				if (!$question['hidden']) {
155 156 157 158
					$qTitleWords = implode(' ', qa_string_to_words($question['title']));
					$qContentWords = implode(' ', qa_string_to_words($question['content']));

					if ($qTitleWords == $testTitleWords && $qContentWords == $testContentWords) {
Scott committed
159 160 161 162
						$errors['page'] = qa_lang_html('question/duplicate_content');
						break;
					}
				}
Scott committed
163 164 165
			}
		}

Scott committed
166 167
		if (empty($errors)) {
			$cookieid = isset($userid) ? qa_cookie_get() : qa_cookie_get_create(); // create a new cookie if necessary
Scott committed
168

Scott committed
169 170 171
			$questionid = qa_question_create($followanswer, $userid, qa_get_logged_in_handle(), $cookieid,
				$in['title'], $in['content'], $in['format'], $in['text'], isset($in['tags']) ? qa_tags_to_tagstring($in['tags']) : '',
				$in['notify'], $in['email'], $in['categoryid'], $in['extra'], $in['queued'], $in['name']);
Scott committed
172

Scott committed
173 174 175 176
			qa_redirect(qa_q_request($questionid, $in['title'])); // our work is done here
		}
	}
}
Scott committed
177 178


Scott committed
179
// Prepare content for theme
Scott committed
180

Scott committed
181
$qa_content = qa_content_prepare(false, array_keys(qa_category_path($categories, @$in['categoryid'])));
Scott committed
182

Scott committed
183 184
$qa_content['title'] = qa_lang_html(isset($followanswer) ? 'question/ask_follow_title' : 'question/ask_title');
$qa_content['error'] = @$errors['page'];
Scott committed
185

Scott committed
186 187
$editorname = isset($in['editor']) ? $in['editor'] : qa_opt('editor_for_qs');
$editor = qa_load_editor(@$in['content'], @$in['format'], $editorname);
Scott committed
188

Scott committed
189 190 191
$field = qa_editor_load_field($editor, $qa_content, @$in['content'], @$in['format'], 'content', 12, false);
$field['label'] = qa_lang_html('question/q_content_label');
$field['error'] = qa_html(@$errors['content']);
Scott committed
192

Scott committed
193
$custom = qa_opt('show_custom_ask') ? trim(qa_opt('custom_ask')) : '';
Scott committed
194

Scott committed
195 196
$qa_content['form'] = array(
	'tags' => 'name="ask" method="post" action="'.qa_self_html().'"',
Scott committed
197

Scott committed
198
	'style' => 'tall',
Scott committed
199

Scott committed
200 201 202 203
	'fields' => array(
		'custom' => array(
			'type' => 'custom',
			'note' => $custom,
Scott committed
204 205
		),

Scott committed
206 207 208 209 210
		'title' => array(
			'label' => qa_lang_html('question/q_title_label'),
			'tags' => 'name="title" id="title" autocomplete="off"',
			'value' => qa_html(@$in['title']),
			'error' => qa_html(@$errors['title']),
Scott committed
211 212
		),

Scott committed
213 214 215
		'similar' => array(
			'type' => 'custom',
			'html' => '<span id="similar"></span>',
Scott committed
216 217
		),

Scott committed
218 219
		'content' => $field,
	),
Scott committed
220

Scott committed
221 222 223 224 225 226 227
	'buttons' => array(
		'ask' => array(
			'tags' => 'onclick="qa_show_waiting_after(this, false); '.
				(method_exists($editor, 'update_script') ? $editor->update_script('content') : '').'"',
			'label' => qa_lang_html('question/ask_button'),
		),
	),
Scott committed
228

Scott committed
229 230 231 232 233 234
	'hidden' => array(
		'editor' => qa_html($editorname),
		'code' => qa_get_form_security_code('ask'),
		'doask' => '1',
	),
);
Scott committed
235

Scott committed
236 237 238
if (!strlen($custom)) {
	unset($qa_content['form']['fields']['custom']);
}
Scott committed
239

Scott committed
240 241
if (qa_opt('do_ask_check_qs') || qa_opt('do_example_tags')) {
	$qa_content['form']['fields']['title']['tags'] .= ' onchange="qa_title_change(this.value);"';
Scott committed
242

Scott committed
243 244
	if (strlen(@$in['title'])) {
		$qa_content['script_onloads'][] = 'qa_title_change('.qa_js($in['title']).');';
Scott committed
245
	}
Scott committed
246
}
Scott committed
247

Scott committed
248 249
if (isset($followanswer)) {
	$viewer = qa_load_viewer($followanswer['content'], $followanswer['format']);
Scott committed
250

Scott committed
251 252 253 254 255
	$field = array(
		'type' => 'static',
		'label' => qa_lang_html('question/ask_follow_from_a'),
		'value' => $viewer->get_html($followanswer['content'], $followanswer['format'], array('blockwordspreg' => qa_get_block_words_preg())),
	);
Scott committed
256

Scott committed
257 258
	qa_array_insert($qa_content['form']['fields'], 'title', array('follows' => $field));
}
Scott committed
259

Scott committed
260 261 262 263 264
if (qa_using_categories() && count($categories)) {
	$field = array(
		'label' => qa_lang_html('question/q_category_label'),
		'error' => qa_html(@$errors['categoryid']),
	);
Scott committed
265

Scott committed
266
	qa_set_up_category_field($qa_content, $field, 'category', $categories, $in['categoryid'], true, qa_opt('allow_no_sub_category'));
Scott committed
267

Scott committed
268 269 270 271 272
	if (!qa_opt('allow_no_category')) // don't auto-select a category even though one is required
		$field['options'][''] = '';

	qa_array_insert($qa_content['form']['fields'], 'content', array('category' => $field));
}
Scott committed
273

Scott committed
274 275 276 277 278 279 280
if (qa_opt('extra_field_active')) {
	$field = array(
		'label' => qa_html(qa_opt('extra_field_prompt')),
		'tags' => 'name="extra"',
		'value' => qa_html(@$in['extra']),
		'error' => qa_html(@$errors['extra']),
	);
Scott committed
281

Scott committed
282 283
	qa_array_insert($qa_content['form']['fields'], null, array('extra' => $field));
}
Scott committed
284

Scott committed
285 286 287 288
if (qa_using_tags()) {
	$field = array(
		'error' => qa_html(@$errors['tags']),
	);
Scott committed
289

Scott committed
290 291
	qa_set_up_tag_field($qa_content, $field, 'tags', isset($in['tags']) ? $in['tags'] : array(), array(),
		qa_opt('do_complete_tags') ? array_keys($completetags) : array(), qa_opt('page_size_ask_tags'));
Scott committed
292

Scott committed
293 294
	qa_array_insert($qa_content['form']['fields'], null, array('tags' => $field));
}
Scott committed
295

296
if (!isset($userid) && qa_opt('allow_anonymous_naming')) {
Scott committed
297 298
	qa_set_up_name_field($qa_content, $qa_content['form']['fields'], @$in['name']);
}
Scott committed
299

Scott committed
300 301
qa_set_up_notify_fields($qa_content, $qa_content['form']['fields'], 'Q', qa_get_logged_in_email(),
	isset($in['notify']) ? $in['notify'] : qa_opt('notify_users_default'), @$in['email'], @$errors['email']);
Scott committed
302

Scott committed
303 304 305 306
if ($captchareason) {
	require_once QA_INCLUDE_DIR.'app/captcha.php';
	qa_set_up_captcha_field($qa_content, $qa_content['form']['fields'], @$errors, qa_captcha_reason_note($captchareason));
}
Scott committed
307

Scott committed
308
$qa_content['focusid'] = 'title';
Scott committed
309 310


Scott committed
311
return $qa_content;