post-create.php 10.6 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: Creating questions, answers and comments (application level)


	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 26 27 28 29 30 31 32 33 34 35
	exit;
}

require_once QA_INCLUDE_DIR . 'db/maxima.php';
require_once QA_INCLUDE_DIR . 'db/post-create.php';
require_once QA_INCLUDE_DIR . 'db/points.php';
require_once QA_INCLUDE_DIR . 'db/hotness.php';
require_once QA_INCLUDE_DIR . 'util/string.php';


/**
 * Return value to store in database combining $notify and $email values entered by user $userid (or null for anonymous)
36 37 38 39
 * @param mixed $userid
 * @param bool $notify
 * @param string $email
 * @return string|null
Scott committed
40 41 42 43 44 45 46 47 48 49
 */
function qa_combine_notify_email($userid, $notify, $email)
{
	return $notify ? (empty($email) ? (isset($userid) ? '@' : null) : $email) : null;
}


/**
 * Add a question (application level) - create record, update appropriate counts, index it, send notifications.
 * If question is follow-on from an answer, $followanswer should contain answer database record, otherwise null.
50
 * See /qa-include/app/posts.php for a higher-level function which is easier to use.
51 52 53 54 55 56 57 58 59 60 61 62 63
 * @param array $followanswer
 * @param mixed $userid
 * @param string $handle
 * @param string $cookieid
 * @param string $title
 * @param string $content
 * @param string $format
 * @param string $text
 * @param string $tagstring
 * @param bool $notify
 * @param string $email
 * @param int|null $categoryid
 * @param string|null $extravalue
Scott committed
64
 * @param bool $queued
65 66
 * @param string|null $name
 * @return int
Scott committed
67 68 69 70 71 72 73 74 75 76 77 78 79
 */
function qa_question_create($followanswer, $userid, $handle, $cookieid, $title, $content, $format, $text, $tagstring, $notify, $email,
	$categoryid = null, $extravalue = null, $queued = false, $name = null)
{
	require_once QA_INCLUDE_DIR . 'db/selects.php';

	$postid = qa_db_post_create($queued ? 'Q_QUEUED' : 'Q', @$followanswer['postid'], $userid, isset($userid) ? null : $cookieid,
		qa_remote_ip_address(), $title, $content, $format, $tagstring, qa_combine_notify_email($userid, $notify, $email),
		$categoryid, isset($userid) ? null : $name);

	if (isset($extravalue)) {
		require_once QA_INCLUDE_DIR . 'db/metas.php';
		qa_db_postmeta_set($postid, 'qa_q_extra', $extravalue);
Scott committed
80 81
	}

Scott committed
82 83
	qa_db_posts_calc_category_path($postid);
	qa_db_hotness_update($postid);
Scott committed
84

Scott committed
85 86
	if ($queued) {
		qa_db_queuedcount_update();
Scott committed
87

Scott committed
88 89 90 91
	} else {
		qa_post_index($postid, 'Q', $postid, @$followanswer['postid'], $title, $content, $format, $text, $tagstring, $categoryid);
		qa_update_counts_for_q($postid);
		qa_db_points_update_ifuser($userid, 'qposts');
Scott committed
92 93
	}

Scott committed
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
	qa_report_event($queued ? 'q_queue' : 'q_post', $userid, $handle, $cookieid, array(
		'postid' => $postid,
		'parentid' => @$followanswer['postid'],
		'parent' => $followanswer,
		'title' => $title,
		'content' => $content,
		'format' => $format,
		'text' => $text,
		'tags' => $tagstring,
		'categoryid' => $categoryid,
		'extra' => $extravalue,
		'name' => $name,
		'notify' => $notify,
		'email' => $email,
	));

	return $postid;
}


/**
 * Perform various common cached count updating operations to reflect changes in the question whose id is $postid
116
 * @param int|null $postid
Scott committed
117 118 119 120 121 122 123 124 125 126
 */
function qa_update_counts_for_q($postid)
{
	if (isset($postid)) // post might no longer exist
		qa_db_category_path_qcount_update(qa_db_post_get_category_path($postid));

	qa_db_qcount_update();
	qa_db_unaqcount_update();
	qa_db_unselqcount_update();
	qa_db_unupaqcount_update();
127
	qa_db_tagcount_update();
Scott committed
128 129 130 131 132
}


/**
 * Return an array containing the elements of $inarray whose key is in $keys
133 134
 * @param array $inarray
 * @param array $keys
Scott committed
135 136 137 138 139 140 141 142 143
 * @return array
 */
function qa_array_filter_by_keys($inarray, $keys)
{
	$outarray = array();

	foreach ($keys as $key) {
		if (isset($inarray[$key]))
			$outarray[$key] = $inarray[$key];
Scott committed
144 145
	}

Scott committed
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
	return $outarray;
}


/**
 * Suspend the indexing (and unindexing) of posts via qa_post_index(...) and qa_post_unindex(...)
 * if $suspend is true, otherwise reinstate it. A counter is kept to allow multiple calls.
 * @param bool $suspend
 */
function qa_suspend_post_indexing($suspend = true)
{
	global $qa_post_indexing_suspended;

	$qa_post_indexing_suspended += ($suspend ? 1 : -1);
}


/**
 * Add post $postid (which comes under $questionid) of $type (Q/A/C) to the database index, with $title, $text,
 * $tagstring and $categoryid. Calls through to all installed search modules.
166 167 168 169 170 171 172 173 174 175
 * @param int $postid
 * @param string $type
 * @param int $questionid
 * @param int $parentid
 * @param string $title
 * @param string $content
 * @param string $format
 * @param string $text
 * @param string $tagstring
 * @param int $categoryid
Scott committed
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
 */
function qa_post_index($postid, $type, $questionid, $parentid, $title, $content, $format, $text, $tagstring, $categoryid)
{
	global $qa_post_indexing_suspended;

	if ($qa_post_indexing_suspended > 0)
		return;

	// Send through to any search modules for indexing

	$searches = qa_load_modules_with('search', 'index_post');
	foreach ($searches as $search)
		$search->index_post($postid, $type, $questionid, $parentid, $title, $content, $format, $text, $tagstring, $categoryid);
}


/**
 * Add an answer (application level) - create record, update appropriate counts, index it, send notifications.
 * $question should contain database record for the question this is an answer to.
195
 * See /qa-include/app/posts.php for a higher-level function which is easier to use.
196 197 198 199 200 201 202 203 204
 * @param mixed $userid
 * @param string $handle
 * @param string $cookieid
 * @param string $content
 * @param string $format
 * @param string $text
 * @param bool $notify
 * @param string $email
 * @param array $question
Scott committed
205
 * @param bool $queued
206 207
 * @param string|null $name
 * @return int
Scott committed
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
 */
function qa_answer_create($userid, $handle, $cookieid, $content, $format, $text, $notify, $email, $question, $queued = false, $name = null)
{
	$postid = qa_db_post_create($queued ? 'A_QUEUED' : 'A', $question['postid'], $userid, isset($userid) ? null : $cookieid,
		qa_remote_ip_address(), null, $content, $format, null, qa_combine_notify_email($userid, $notify, $email),
		$question['categoryid'], isset($userid) ? null : $name);

	qa_db_posts_calc_category_path($postid);

	if ($queued) {
		qa_db_queuedcount_update();

	} else {
		if ($question['type'] == 'Q') // don't index answer if parent question is hidden or queued
			qa_post_index($postid, 'A', $question['postid'], $question['postid'], null, $content, $format, $text, null, $question['categoryid']);

		qa_update_q_counts_for_a($question['postid']);
		qa_db_points_update_ifuser($userid, 'aposts');
Scott committed
226 227
	}

Scott committed
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
	qa_report_event($queued ? 'a_queue' : 'a_post', $userid, $handle, $cookieid, array(
		'postid' => $postid,
		'parentid' => $question['postid'],
		'parent' => $question,
		'content' => $content,
		'format' => $format,
		'text' => $text,
		'categoryid' => $question['categoryid'],
		'name' => $name,
		'notify' => $notify,
		'email' => $email,
	));

	return $postid;
}


/**
 * Perform various common cached count updating operations to reflect changes in an answer of question $questionid
247
 * @param int $questionid
Scott committed
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
 */
function qa_update_q_counts_for_a($questionid)
{
	qa_db_post_acount_update($questionid);
	qa_db_hotness_update($questionid);
	qa_db_acount_update();
	qa_db_unaqcount_update();
	qa_db_unupaqcount_update();
}


/**
 * Add a comment (application level) - create record, update appropriate counts, index it, send notifications.
 * $question should contain database record for the question this is part of (as direct or comment on Q's answer).
 * If this is a comment on an answer, $answer should contain database record for the answer, otherwise null.
 * $commentsfollows should contain database records for all previous comments on the same question or answer,
 * but it can also contain other records that are ignored.
265
 * See /qa-include/app/posts.php for a higher-level function which is easier to use.
266 267 268 269 270 271 272 273 274 275 276
 * @param mixed $userid
 * @param string $handle
 * @param string $cookieid
 * @param string $content
 * @param string $format
 * @param string $text
 * @param bool $notify
 * @param string $email
 * @param array $question
 * @param array $parent
 * @param array $commentsfollows
Scott committed
277
 * @param bool $queued
278 279
 * @param string|null $name
 * @return int
Scott committed
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
 */
function qa_comment_create($userid, $handle, $cookieid, $content, $format, $text, $notify, $email, $question, $parent, $commentsfollows, $queued = false, $name = null)
{
	require_once QA_INCLUDE_DIR . 'app/emails.php';
	require_once QA_INCLUDE_DIR . 'app/options.php';
	require_once QA_INCLUDE_DIR . 'app/format.php';
	require_once QA_INCLUDE_DIR . 'util/string.php';

	if (!isset($parent))
		$parent = $question; // for backwards compatibility with old answer parameter

	$postid = qa_db_post_create($queued ? 'C_QUEUED' : 'C', $parent['postid'], $userid, isset($userid) ? null : $cookieid,
		qa_remote_ip_address(), null, $content, $format, null, qa_combine_notify_email($userid, $notify, $email),
		$question['categoryid'], isset($userid) ? null : $name);

	qa_db_posts_calc_category_path($postid);

	if ($queued) {
		qa_db_queuedcount_update();

	} else {
Scott committed
301
		if ($question['type'] == 'Q' && ($parent['type'] == 'Q' || $parent['type'] == 'A')) { // only index if antecedents fully visible
Scott committed
302
			qa_post_index($postid, 'C', $question['postid'], $parent['postid'], null, $content, $format, $text, null, $question['categoryid']);
Scott committed
303
		}
Scott committed
304 305 306

		qa_db_points_update_ifuser($userid, 'cposts');
		qa_db_ccount_update();
Scott committed
307 308
	}

Scott committed
309
	$thread = array();
Scott committed
310

Scott committed
311
	foreach ($commentsfollows as $comment) {
Scott committed
312
		if ($comment['type'] == 'C' && $comment['parentid'] == $parent['postid']) // find just those for this parent, fully visible
Scott committed
313
			$thread[] = $comment;
Scott committed
314 315
	}

Scott committed
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
	qa_report_event($queued ? 'c_queue' : 'c_post', $userid, $handle, $cookieid, array(
		'postid' => $postid,
		'parentid' => $parent['postid'],
		'parenttype' => $parent['basetype'],
		'parent' => $parent,
		'questionid' => $question['postid'],
		'question' => $question,
		'thread' => $thread,
		'content' => $content,
		'format' => $format,
		'text' => $text,
		'categoryid' => $question['categoryid'],
		'name' => $name,
		'notify' => $notify,
		'email' => $email,
	));

	return $postid;
}