<?php
/*
	Question2Answer by Gideon Greenspan and contributors
	http://www.question2answer.org/

	File: qa-include/qa-app-post-create.php
	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
*/

	if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
		header('Location: ../');
		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';


	function qa_combine_notify_email($userid, $notify, $email)
/*
	Return value to store in database combining $notify and $email values entered by user $userid (or null for anonymous)
*/
	{
		return $notify ? (empty($email) ? (isset($userid) ? '@' : null) : $email) : null;
	}


	function qa_question_create($followanswer, $userid, $handle, $cookieid, $title, $content, $format, $text, $tagstring, $notify, $email,
		$categoryid=null, $extravalue=null, $queued=false, $name=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.
	See qa-app-posts.php for a higher-level function which is easier to use.
*/
	{
		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);
		}

		qa_db_posts_calc_category_path($postid);
		qa_db_hotness_update($postid);

		if ($queued) {
			qa_db_queuedcount_update();

		} 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');
		}

		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;
	}


	function qa_update_counts_for_q($postid)
/*
	Perform various common cached count updating operations to reflect changes in the question whose id is $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();
	}


	function qa_array_filter_by_keys($inarray, $keys)
/*
	Return an array containing the elements of $inarray whose key is in $keys
*/
	{
		$outarray=array();

		foreach ($keys as $key)
			if (isset($inarray[$key]))
				$outarray[$key]=$inarray[$key];

		return $outarray;
	}


	function qa_suspend_post_indexing($suspend=true)
/*
	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.
*/
	{
		global $qa_post_indexing_suspended;

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


	function qa_post_index($postid, $type, $questionid, $parentid, $title, $content, $format, $text, $tagstring, $categoryid)
/*
	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.
*/
	{
		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);
	}


	function qa_answer_create($userid, $handle, $cookieid, $content, $format, $text, $notify, $email, $question, $queued=false, $name=null)
/*
	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.
	See qa-app-posts.php for a higher-level function which is easier to use.
*/
	{
		$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');
		}

		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;
	}


	function qa_update_q_counts_for_a($questionid)
/*
	Perform various common cached count updating operations to reflect changes in an answer of question $questionid
*/
	{
		qa_db_post_acount_update($questionid);
		qa_db_hotness_update($questionid);
		qa_db_acount_update();
		qa_db_unaqcount_update();
		qa_db_unupaqcount_update();
	}


	function qa_comment_create($userid, $handle, $cookieid, $content, $format, $text, $notify, $email, $question, $parent, $commentsfollows, $queued=false, $name=null)
/*
	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.
	See qa-app-posts.php for a higher-level function which is easier to use.
*/
	{
		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 {
			if ( ($question['type']=='Q') && (($parent['type']=='Q') || ($parent['type']=='A')) ) // only index if antecedents fully visible
				qa_post_index($postid, 'C', $question['postid'], $parent['postid'], null, $content, $format, $text, null, $question['categoryid']);

			qa_db_points_update_ifuser($userid, 'cposts');
			qa_db_ccount_update();
		}

		$thread=array();

		foreach ($commentsfollows as $comment)
			if (($comment['type']=='C') && ($comment['parentid']==$parent['postid'])) // find just those for this parent, fully visible
				$thread[]=$comment;

		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;
	}


/*
	Omit PHP closing tag to help avoid accidental output
*/