Commit 0794e784 by Scott

Coding style (db posts/users)

parent f5aaabc6
......@@ -20,394 +20,437 @@
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;
}
function qa_db_post_create($type, $parentid, $userid, $cookieid, $ip, $title, $content, $format, $tagstring, $notify, $categoryid=null, $name=null)
/*
Create a new post in the database and return its ID (based on auto-incrementing)
*/
{
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../');
exit;
}
/**
* Create a new post in the database and return its ID (based on auto-incrementing)
* @param $type
* @param $parentid
* @param $userid
* @param $cookieid
* @param $ip
* @param $title
* @param $content
* @param $format
* @param $tagstring
* @param $notify
* @param $categoryid
* @param $name
* @return mixed
*/
function qa_db_post_create($type, $parentid, $userid, $cookieid, $ip, $title, $content, $format, $tagstring, $notify, $categoryid = null, $name = null)
{
qa_db_query_sub(
'INSERT INTO ^posts (categoryid, type, parentid, userid, cookieid, createip, title, content, format, tags, notify, name, created) ' .
'VALUES (#, $, #, $, #, $, $, $, $, $, $, $, NOW())',
$categoryid, $type, $parentid, $userid, $cookieid, @inet_pton($ip), $title, $content, $format, $tagstring, $notify, $name
);
return qa_db_last_insert_id();
}
/**
* Recalculate the full category path (i.e. columns catidpath1/2/3) for posts from $firstpostid to $lastpostid (if specified)
* @param $firstpostid
* @param $lastpostid
*/
function qa_db_posts_calc_category_path($firstpostid, $lastpostid = null)
{
if (!isset($lastpostid))
$lastpostid = $firstpostid;
qa_db_query_sub(
"UPDATE ^posts AS x, (SELECT ^posts.postid, " .
"COALESCE(parent2.parentid, parent1.parentid, parent0.parentid, parent0.categoryid) AS catidpath1, " .
"IF (parent2.parentid IS NOT NULL, parent1.parentid, IF (parent1.parentid IS NOT NULL, parent0.parentid, IF (parent0.parentid IS NOT NULL, parent0.categoryid, NULL))) AS catidpath2, " .
"IF (parent2.parentid IS NOT NULL, parent0.parentid, IF (parent1.parentid IS NOT NULL, parent0.categoryid, NULL)) AS catidpath3 " .
"FROM ^posts LEFT JOIN ^categories AS parent0 ON ^posts.categoryid=parent0.categoryid LEFT JOIN ^categories AS parent1 ON parent0.parentid=parent1.categoryid LEFT JOIN ^categories AS parent2 ON parent1.parentid=parent2.categoryid WHERE ^posts.postid BETWEEN # AND #) AS a SET x.catidpath1=a.catidpath1, x.catidpath2=a.catidpath2, x.catidpath3=a.catidpath3 WHERE x.postid=a.postid",
$firstpostid, $lastpostid
); // requires QA_CATEGORY_DEPTH=4
}
/**
* Get the full category path (including categoryid) for $postid
* @param $postid
* @return array|null
*/
function qa_db_post_get_category_path($postid)
{
return qa_db_read_one_assoc(qa_db_query_sub(
'SELECT categoryid, catidpath1, catidpath2, catidpath3 FROM ^posts WHERE postid=#',
$postid
)); // requires QA_CATEGORY_DEPTH=4
}
/**
* Update the cached number of answers for $questionid in the database, along with the highest netvotes of any of its answers
* @param $questionid
*/
function qa_db_post_acount_update($questionid)
{
if (qa_should_update_counts()) {
qa_db_query_sub(
'INSERT INTO ^posts (categoryid, type, parentid, userid, cookieid, createip, title, content, format, tags, notify, name, created) '.
'VALUES (#, $, #, $, #, $, $, $, $, $, $, $, NOW())',
$categoryid, $type, $parentid, $userid, $cookieid, @inet_pton($ip), $title, $content, $format, $tagstring, $notify, $name
"UPDATE ^posts AS x, (SELECT COUNT(*) AS acount, COALESCE(GREATEST(MAX(netvotes), 0), 0) AS amaxvote FROM ^posts WHERE parentid=# AND type='A') AS a SET x.acount=a.acount, x.amaxvote=a.amaxvote WHERE x.postid=#",
$questionid, $questionid
);
return qa_db_last_insert_id();
}
function qa_db_posts_calc_category_path($firstpostid, $lastpostid=null)
/*
Recalculate the full category path (i.e. columns catidpath1/2/3) for posts from $firstpostid to $lastpostid (if specified)
*/
{
if (!isset($lastpostid))
$lastpostid=$firstpostid;
}
/**
* Recalculate the number of questions for each category in $path retrieved via qa_db_post_get_category_path()
* @param $path
*/
function qa_db_category_path_qcount_update($path)
{
qa_db_ifcategory_qcount_update($path['categoryid']); // requires QA_CATEGORY_DEPTH=4
qa_db_ifcategory_qcount_update($path['catidpath1']);
qa_db_ifcategory_qcount_update($path['catidpath2']);
qa_db_ifcategory_qcount_update($path['catidpath3']);
}
/**
* Update the cached number of questions for category $categoryid in the database, including its subcategories
* @param $categoryid
*/
function qa_db_ifcategory_qcount_update($categoryid)
{
if (qa_should_update_counts() && isset($categoryid)) {
// This seemed like the most sensible approach which avoids explicitly calculating the category's depth in the hierarchy
qa_db_query_sub(
"UPDATE ^posts AS x, (SELECT ^posts.postid, ".
"COALESCE(parent2.parentid, parent1.parentid, parent0.parentid, parent0.categoryid) AS catidpath1, ".
"IF (parent2.parentid IS NOT NULL, parent1.parentid, IF (parent1.parentid IS NOT NULL, parent0.parentid, IF (parent0.parentid IS NOT NULL, parent0.categoryid, NULL))) AS catidpath2, ".
"IF (parent2.parentid IS NOT NULL, parent0.parentid, IF (parent1.parentid IS NOT NULL, parent0.categoryid, NULL)) AS catidpath3 ".
"FROM ^posts LEFT JOIN ^categories AS parent0 ON ^posts.categoryid=parent0.categoryid LEFT JOIN ^categories AS parent1 ON parent0.parentid=parent1.categoryid LEFT JOIN ^categories AS parent2 ON parent1.parentid=parent2.categoryid WHERE ^posts.postid BETWEEN # AND #) AS a SET x.catidpath1=a.catidpath1, x.catidpath2=a.catidpath2, x.catidpath3=a.catidpath3 WHERE x.postid=a.postid",
$firstpostid, $lastpostid
"UPDATE ^categories SET qcount=GREATEST( (SELECT COUNT(*) FROM ^posts WHERE categoryid=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath1=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath2=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath3=# AND type='Q') ) WHERE categoryid=#",
$categoryid, $categoryid, $categoryid, $categoryid, $categoryid
); // requires QA_CATEGORY_DEPTH=4
}
}
/**
* Add rows into the database title index, where $postid contains the words $wordids - this does the same sort
* of thing as qa_db_posttags_add_post_wordids() in a different way, for no particularly good reason.
* @param $postid
* @param $wordids
*/
function qa_db_titlewords_add_post_wordids($postid, $wordids)
{
if (count($wordids)) {
$rowstoadd = array();
foreach ($wordids as $wordid)
$rowstoadd[] = array($postid, $wordid);
function qa_db_post_get_category_path($postid)
/*
Get the full category path (including categoryid) for $postid
*/
{
return qa_db_read_one_assoc(qa_db_query_sub(
'SELECT categoryid, catidpath1, catidpath2, catidpath3 FROM ^posts WHERE postid=#',
$postid
)); // requires QA_CATEGORY_DEPTH=4
}
function qa_db_post_acount_update($questionid)
/*
Update the cached number of answers for $questionid in the database, along with the highest netvotes of any of its answers
*/
{
if (qa_should_update_counts())
qa_db_query_sub(
"UPDATE ^posts AS x, (SELECT COUNT(*) AS acount, COALESCE(GREATEST(MAX(netvotes), 0), 0) AS amaxvote FROM ^posts WHERE parentid=# AND type='A') AS a SET x.acount=a.acount, x.amaxvote=a.amaxvote WHERE x.postid=#",
$questionid, $questionid
);
qa_db_query_sub(
'INSERT INTO ^titlewords (postid, wordid) VALUES #',
$rowstoadd
);
}
}
/**
* Add rows into the database content index, where $postid (of $type, with the antecedent $questionid)
* has words as per the keys of $wordidcounts, and the corresponding number of those words in the values.
* @param $postid
* @param $type
* @param $questionid
* @param $wordidcounts
*/
function qa_db_contentwords_add_post_wordidcounts($postid, $type, $questionid, $wordidcounts)
{
if (count($wordidcounts)) {
$rowstoadd = array();
foreach ($wordidcounts as $wordid => $count)
$rowstoadd[] = array($postid, $wordid, $count, $type, $questionid);
function qa_db_category_path_qcount_update($path)
/*
Recalculate the number of questions for each category in $path retrieved via qa_db_post_get_category_path()
*/
{
qa_db_ifcategory_qcount_update($path['categoryid']); // requires QA_CATEGORY_DEPTH=4
qa_db_ifcategory_qcount_update($path['catidpath1']);
qa_db_ifcategory_qcount_update($path['catidpath2']);
qa_db_ifcategory_qcount_update($path['catidpath3']);
qa_db_query_sub(
'INSERT INTO ^contentwords (postid, wordid, count, type, questionid) VALUES #',
$rowstoadd
);
}
}
function qa_db_ifcategory_qcount_update($categoryid)
/*
Update the cached number of questions for category $categoryid in the database, including its subcategories
*/
{
if (qa_should_update_counts() && isset($categoryid)) {
// This seemed like the most sensible approach which avoids explicitly calculating the category's depth in the hierarchy
qa_db_query_sub(
"UPDATE ^categories SET qcount=GREATEST( (SELECT COUNT(*) FROM ^posts WHERE categoryid=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath1=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath2=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath3=# AND type='Q') ) WHERE categoryid=#",
$categoryid, $categoryid, $categoryid, $categoryid, $categoryid
); // requires QA_CATEGORY_DEPTH=4
}
}
/**
* Add rows into the database index of individual tag words, where $postid contains the words $wordids
* @param $postid
* @param $wordids
*/
function qa_db_tagwords_add_post_wordids($postid, $wordids)
{
if (count($wordids)) {
$rowstoadd = array();
foreach ($wordids as $wordid)
$rowstoadd[] = array($postid, $wordid);
function qa_db_titlewords_add_post_wordids($postid, $wordids)
/*
Add rows into the database title index, where $postid contains the words $wordids - this does the same sort
of thing as qa_db_posttags_add_post_wordids() in a different way, for no particularly good reason.
*/
{
if (count($wordids)) {
$rowstoadd=array();
foreach ($wordids as $wordid)
$rowstoadd[]=array($postid, $wordid);
qa_db_query_sub(
'INSERT INTO ^titlewords (postid, wordid) VALUES #',
$rowstoadd
);
}
qa_db_query_sub(
'INSERT INTO ^tagwords (postid, wordid) VALUES #',
$rowstoadd
);
}
}
function qa_db_contentwords_add_post_wordidcounts($postid, $type, $questionid, $wordidcounts)
/*
Add rows into the database content index, where $postid (of $type, with the antecedent $questionid)
has words as per the keys of $wordidcounts, and the corresponding number of those words in the values.
*/
{
if (count($wordidcounts)) {
$rowstoadd=array();
foreach ($wordidcounts as $wordid => $count)
$rowstoadd[]=array($postid, $wordid, $count, $type, $questionid);
qa_db_query_sub(
'INSERT INTO ^contentwords (postid, wordid, count, type, questionid) VALUES #',
$rowstoadd
);
}
/**
* Add rows into the database index of whole tags, where $postid contains the tags $wordids
* @param $postid
* @param $wordids
*/
function qa_db_posttags_add_post_wordids($postid, $wordids)
{
if (count($wordids)) {
qa_db_query_sub(
'INSERT INTO ^posttags (postid, wordid, postcreated) SELECT postid, wordid, created FROM ^words, ^posts WHERE postid=# AND wordid IN ($)',
$postid, $wordids
);
}
function qa_db_tagwords_add_post_wordids($postid, $wordids)
/*
Add rows into the database index of individual tag words, where $postid contains the words $wordids
*/
{
if (count($wordids)) {
$rowstoadd=array();
foreach ($wordids as $wordid)
$rowstoadd[]=array($postid, $wordid);
qa_db_query_sub(
'INSERT INTO ^tagwords (postid, wordid) VALUES #',
$rowstoadd
);
}
}
/**
* Return an array mapping each word in $words to its corresponding wordid in the database
* @param $words
* @return array
*/
function qa_db_word_mapto_ids($words)
{
if (count($words)) {
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT wordid, word FROM ^words WHERE word IN ($)', $words
), 'word', 'wordid');
}
return array();
}
function qa_db_posttags_add_post_wordids($postid, $wordids)
/*
Add rows into the database index of whole tags, where $postid contains the tags $wordids
*/
{
if (count($wordids))
qa_db_query_sub(
'INSERT INTO ^posttags (postid, wordid, postcreated) SELECT postid, wordid, created FROM ^words, ^posts WHERE postid=# AND wordid IN ($)',
$postid, $wordids
);
}
/**
* Return an array mapping each word in $words to its corresponding wordid in the database, adding any that are missing
* @param $words
* @return array
*/
function qa_db_word_mapto_ids_add($words)
{
$wordtoid = qa_db_word_mapto_ids($words);
function qa_db_word_mapto_ids($words)
/*
Return an array mapping each word in $words to its corresponding wordid in the database
*/
{
if (count($words))
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT wordid, word FROM ^words WHERE word IN ($)', $words
), 'word', 'wordid');
else
return array();
$wordstoadd = array();
foreach ($words as $word) {
if (!isset($wordtoid[$word]))
$wordstoadd[] = $word;
}
if (count($wordstoadd)) {
qa_db_query_sub('LOCK TABLES ^words WRITE'); // to prevent two requests adding the same word
function qa_db_word_mapto_ids_add($words)
/*
Return an array mapping each word in $words to its corresponding wordid in the database, adding any that are missing
*/
{
$wordtoid=qa_db_word_mapto_ids($words);
$wordtoid = qa_db_word_mapto_ids($words); // map it again in case table content changed before it was locked
$wordstoadd=array();
foreach ($words as $word)
$rowstoadd = array();
foreach ($words as $word) {
if (!isset($wordtoid[$word]))
$wordstoadd[]=$word;
if (count($wordstoadd)) {
qa_db_query_sub('LOCK TABLES ^words WRITE'); // to prevent two requests adding the same word
$wordtoid=qa_db_word_mapto_ids($words); // map it again in case table content changed before it was locked
$rowstoadd=array();
foreach ($words as $word)
if (!isset($wordtoid[$word]))
$rowstoadd[]=array($word);
qa_db_query_sub('INSERT IGNORE INTO ^words (word) VALUES $', $rowstoadd);
$rowstoadd[] = array($word);
}
qa_db_query_sub('UNLOCK TABLES');
qa_db_query_sub('INSERT IGNORE INTO ^words (word) VALUES $', $rowstoadd);
$wordtoid=qa_db_word_mapto_ids($words); // do it one last time
}
qa_db_query_sub('UNLOCK TABLES');
return $wordtoid;
$wordtoid = qa_db_word_mapto_ids($words); // do it one last time
}
return $wordtoid;
}
function qa_db_word_titlecount_update($wordids)
/*
Update the titlecount column in the database for the words in $wordids, based on how many posts they appear in the title of
*/
{
if (qa_should_update_counts() && count($wordids))
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^titlewords.wordid) AS titlecount FROM ^words LEFT JOIN ^titlewords ON ^titlewords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.titlecount=a.titlecount WHERE x.wordid=a.wordid',
$wordids
);
/**
* Update the titlecount column in the database for the words in $wordids, based on how many posts they appear in the title of
* @param $wordids
*/
function qa_db_word_titlecount_update($wordids)
{
if (qa_should_update_counts() && count($wordids)) {
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^titlewords.wordid) AS titlecount FROM ^words LEFT JOIN ^titlewords ON ^titlewords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.titlecount=a.titlecount WHERE x.wordid=a.wordid',
$wordids
);
}
}
function qa_db_word_contentcount_update($wordids)
/*
Update the contentcount column in the database for the words in $wordids, based on how many posts they appear in the content of
*/
{
if (qa_should_update_counts() && count($wordids))
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^contentwords.wordid) AS contentcount FROM ^words LEFT JOIN ^contentwords ON ^contentwords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.contentcount=a.contentcount WHERE x.wordid=a.wordid',
$wordids
);
/**
* Update the contentcount column in the database for the words in $wordids, based on how many posts they appear in the content of
* @param $wordids
*/
function qa_db_word_contentcount_update($wordids)
{
if (qa_should_update_counts() && count($wordids)) {
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^contentwords.wordid) AS contentcount FROM ^words LEFT JOIN ^contentwords ON ^contentwords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.contentcount=a.contentcount WHERE x.wordid=a.wordid',
$wordids
);
}
}
function qa_db_word_tagwordcount_update($wordids)
/*
Update the tagwordcount column in the database for the individual tag words in $wordids, based on how many posts they appear in the tags of
*/
{
if (qa_should_update_counts() && count($wordids))
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^tagwords.wordid) AS tagwordcount FROM ^words LEFT JOIN ^tagwords ON ^tagwords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.tagwordcount=a.tagwordcount WHERE x.wordid=a.wordid',
$wordids
);
/**
* Update the tagwordcount column in the database for the individual tag words in $wordids, based on how many posts they appear in the tags of
* @param $wordids
*/
function qa_db_word_tagwordcount_update($wordids)
{
if (qa_should_update_counts() && count($wordids)) {
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^tagwords.wordid) AS tagwordcount FROM ^words LEFT JOIN ^tagwords ON ^tagwords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.tagwordcount=a.tagwordcount WHERE x.wordid=a.wordid',
$wordids
);
}
}
function qa_db_word_tagcount_update($wordids)
/*
Update the tagcount column in the database for the whole tags in $wordids, based on how many posts they appear as tags of
*/
{
if (qa_should_update_counts() && count($wordids))
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^posttags.wordid) AS tagcount FROM ^words LEFT JOIN ^posttags ON ^posttags.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.tagcount=a.tagcount WHERE x.wordid=a.wordid',
$wordids
);
/**
* Update the tagcount column in the database for the whole tags in $wordids, based on how many posts they appear as tags of
* @param $wordids
*/
function qa_db_word_tagcount_update($wordids)
{
if (qa_should_update_counts() && count($wordids)) {
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^posttags.wordid) AS tagcount FROM ^words LEFT JOIN ^posttags ON ^posttags.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.tagcount=a.tagcount WHERE x.wordid=a.wordid',
$wordids
);
}
}
function qa_db_qcount_update()
/*
Update the cached count in the database of the number of questions (excluding hidden/queued)
*/
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_qcount', COUNT(*) FROM ^posts " .
"WHERE type = 'Q' " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
/**
* Update the cached count in the database of the number of questions (excluding hidden/queued)
*/
function qa_db_qcount_update()
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_qcount', COUNT(*) FROM ^posts " .
"WHERE type = 'Q' " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
}
function qa_db_acount_update()
/*
Update the cached count in the database of the number of answers (excluding hidden/queued)
*/
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_acount', COUNT(*) FROM ^posts " .
"WHERE type = 'A' " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
/**
* Update the cached count in the database of the number of answers (excluding hidden/queued)
*/
function qa_db_acount_update()
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_acount', COUNT(*) FROM ^posts " .
"WHERE type = 'A' " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
}
function qa_db_ccount_update()
/*
Update the cached count in the database of the number of comments (excluding hidden/queued)
*/
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_ccount', COUNT(*) FROM ^posts " .
"WHERE type = 'C' " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
/**
* Update the cached count in the database of the number of comments (excluding hidden/queued)
*/
function qa_db_ccount_update()
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_ccount', COUNT(*) FROM ^posts " .
"WHERE type = 'C' " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
}
function qa_db_tagcount_update()
/*
Update the cached count in the database of the number of different tags used
*/
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_tagcount', COUNT(*) FROM ^words " .
"WHERE tagcount > 0 " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
/**
* Update the cached count in the database of the number of different tags used
*/
function qa_db_tagcount_update()
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_tagcount', COUNT(*) FROM ^words " .
"WHERE tagcount > 0 " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
}
function qa_db_unaqcount_update()
/*
Update the cached count in the database of the number of unanswered questions (excluding hidden/queued)
*/
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_unaqcount', COUNT(*) FROM ^posts " .
"WHERE type = 'Q' AND acount = 0 AND closedbyid IS NULL " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
/**
* Update the cached count in the database of the number of unanswered questions (excluding hidden/queued)
*/
function qa_db_unaqcount_update()
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_unaqcount', COUNT(*) FROM ^posts " .
"WHERE type = 'Q' AND acount = 0 AND closedbyid IS NULL " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
}
function qa_db_unselqcount_update()
/*
Update the cached count in the database of the number of questions with no answer selected (excluding hidden/queued)
*/
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_unselqcount', COUNT(*) FROM ^posts " .
"WHERE type = 'Q' AND selchildid IS NULL AND closedbyid IS NULL " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
/**
* Update the cached count in the database of the number of questions with no answer selected (excluding hidden/queued)
*/
function qa_db_unselqcount_update()
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_unselqcount', COUNT(*) FROM ^posts " .
"WHERE type = 'Q' AND selchildid IS NULL AND closedbyid IS NULL " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
}
function qa_db_unupaqcount_update()
/*
Update the cached count in the database of the number of questions with no upvoted answers (excluding hidden/queued)
*/
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_unupaqcount', COUNT(*) FROM ^posts " .
"WHERE type = 'Q' AND amaxvote = 0 AND closedbyid IS NULL " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
/**
* Update the cached count in the database of the number of questions with no upvoted answers (excluding hidden/queued)
*/
function qa_db_unupaqcount_update()
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_unupaqcount', COUNT(*) FROM ^posts " .
"WHERE type = 'Q' AND amaxvote = 0 AND closedbyid IS NULL " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
}
function qa_db_queuedcount_update()
/*
Update the cached count in the database of the number of posts which are queued for moderation
*/
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_queuedcount', COUNT(*) FROM ^posts " .
"WHERE type IN ('Q_QUEUED', 'A_QUEUED', 'C_QUEUED') " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
/**
* Update the cached count in the database of the number of posts which are queued for moderation
*/
function qa_db_queuedcount_update()
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_queuedcount', COUNT(*) FROM ^posts " .
"WHERE type IN ('Q_QUEUED', 'A_QUEUED', 'C_QUEUED') " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
/*
Omit PHP closing tag to help avoid accidental output
*/
}
......@@ -20,349 +20,414 @@
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;
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../');
exit;
}
require_once QA_INCLUDE_DIR . 'app/updates.php';
/**
* Update the selected answer in the database for $questionid to $selchildid, and optionally record that $lastuserid did it from $lastip
* @param $questionid
* @param $selchildid
* @param $lastuserid
* @param $lastip
*/
function qa_db_post_set_selchildid($questionid, $selchildid, $lastuserid = null, $lastip = null)
{
qa_db_query_sub(
"UPDATE ^posts AS x, (SELECT selchildid FROM ^posts WHERE postid=#) AS a " .
"SET x.updated=NULL, x.updatetype=NULL, x.lastuserid=NULL, x.lastip=NULL WHERE " . // if previous answer's last edit was to be selected, remove that
"x.postid=a.selchildid AND x.updatetype=$",
$questionid, QA_UPDATE_SELECTED
);
qa_db_query_sub(
'UPDATE ^posts SET selchildid=# WHERE postid=#',
$selchildid, $questionid
);
if (isset($selchildid) && isset($lastuserid) && isset($lastip)) {
qa_db_query_sub(
"UPDATE ^posts SET updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#",
QA_UPDATE_SELECTED, $lastuserid, @inet_pton($lastip), $selchildid
);
}
require_once QA_INCLUDE_DIR.'app/updates.php';
function qa_db_post_set_selchildid($questionid, $selchildid, $lastuserid=null, $lastip=null)
/*
Update the selected answer in the database for $questionid to $selchildid, and optionally record that $lastuserid did it from $lastip
*/
{
}
/**
* Set $questionid to be closed by post $closedbyid (null if not closed) in the database, and optionally record that
* $lastuserid did it from $lastip
* @param $questionid
* @param $closedbyid
* @param $lastuserid
* @param $lastip
*/
function qa_db_post_set_closed($questionid, $closedbyid, $lastuserid = null, $lastip = null)
{
if (isset($lastuserid) || isset($lastip)) {
qa_db_query_sub(
"UPDATE ^posts AS x, (SELECT selchildid FROM ^posts WHERE postid=#) AS a ".
"SET x.updated=NULL, x.updatetype=NULL, x.lastuserid=NULL, x.lastip=NULL WHERE ". // if previous answer's last edit was to be selected, remove that
"x.postid=a.selchildid AND x.updatetype=$",
$questionid, QA_UPDATE_SELECTED
"UPDATE ^posts SET closedbyid=#, updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#",
$closedbyid, QA_UPDATE_CLOSED, $lastuserid, @inet_pton($lastip), $questionid
);
} else {
qa_db_query_sub(
'UPDATE ^posts SET selchildid=# WHERE postid=#',
$selchildid, $questionid
'UPDATE ^posts SET closedbyid=# WHERE postid=#',
$closedbyid, $questionid
);
if (isset($selchildid) && isset($lastuserid) && isset($lastip))
qa_db_query_sub(
"UPDATE ^posts SET updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#",
QA_UPDATE_SELECTED, $lastuserid, @inet_pton($lastip), $selchildid
);
}
function qa_db_post_set_closed($questionid, $closedbyid, $lastuserid=null, $lastip=null)
/*
Set $questionid to be closed by post $closedbyid (null if not closed) in the database, and optionally record that
$lastuserid did it from $lastip
*/
{
if (isset($lastuserid) || isset($lastip)) {
qa_db_query_sub(
"UPDATE ^posts SET closedbyid=#, updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#",
$closedbyid, QA_UPDATE_CLOSED, $lastuserid, @inet_pton($lastip), $questionid
);
} else
qa_db_query_sub(
'UPDATE ^posts SET closedbyid=# WHERE postid=#',
$closedbyid, $questionid
);
}
function qa_db_post_set_type($postid, $type, $lastuserid=null, $lastip=null, $updatetype=QA_UPDATE_TYPE)
/*
Set the type in the database of $postid to $type, and optionally record that $lastuserid did it from $lastip
*/
{
if (isset($lastuserid) || isset($lastip)) {
qa_db_query_sub(
'UPDATE ^posts SET type=$, updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#',
$type, $updatetype, $lastuserid, @inet_pton($lastip), $postid
);
} else
qa_db_query_sub(
'UPDATE ^posts SET type=$ WHERE postid=#',
$type, $postid
);
}
function qa_db_post_set_parent($postid, $parentid, $lastuserid=null, $lastip=null)
/*
Set the parent in the database of $postid to $parentid, and optionally record that $lastuserid did it from $lastip
(if at least one is specified)
*/
{
if (isset($lastuserid) || isset($lastip))
qa_db_query_sub(
"UPDATE ^posts SET parentid=#, updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#",
$parentid, QA_UPDATE_PARENT, $lastuserid, @inet_pton($lastip), $postid
);
else
qa_db_query_sub(
'UPDATE ^posts SET parentid=# WHERE postid=#',
$parentid, $postid
);
}
function qa_db_post_set_content($postid, $title, $content, $format, $tagstring, $notify, $lastuserid=null, $lastip=null, $updatetype=QA_UPDATE_CONTENT, $name=null)
/*
Set the text fields in the database of $postid to $title, $content, $tagstring, $notify and $name, and record that
$lastuserid did it from $lastip (if at least one is specified) with $updatetype. For backwards compatibility if $name
is null then the name will not be changed.
*/
{
if (isset($lastuserid) || isset($lastip)) // use COALESCE() for name since $name=null means it should not be modified (for backwards compatibility)
qa_db_query_sub(
'UPDATE ^posts SET title=$, content=$, format=$, tags=$, name=COALESCE($, name), notify=$, updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#',
$title, $content, $format, $tagstring, $name, $notify, $updatetype, $lastuserid, @inet_pton($lastip), $postid
);
else
qa_db_query_sub(
'UPDATE ^posts SET title=$, content=$, format=$, tags=$, name=COALESCE($, name), notify=$ WHERE postid=#',
$title, $content, $format, $tagstring, $name, $notify, $postid
);
}
function qa_db_post_set_userid($postid, $userid)
/*
Set the author in the database of $postid to $userid, and set the lastuserid to $userid as well if appropriate
*/
{
}
/**
* Set the type in the database of $postid to $type, and optionally record that $lastuserid did it from $lastip
* @param $postid
* @param $type
* @param $lastuserid
* @param $lastip
* @param string $updatetype
*/
function qa_db_post_set_type($postid, $type, $lastuserid = null, $lastip = null, $updatetype = QA_UPDATE_TYPE)
{
if (isset($lastuserid) || isset($lastip)) {
qa_db_query_sub(
'UPDATE ^posts SET userid=$, lastuserid=IF(updated IS NULL, lastuserid, COALESCE(lastuserid,$)) WHERE postid=#',
$userid, $userid, $postid
'UPDATE ^posts SET type=$, updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#',
$type, $updatetype, $lastuserid, @inet_pton($lastip), $postid
);
} else {
qa_db_query_sub(
'UPDATE ^posts SET type=$ WHERE postid=#',
$type, $postid
);
}
function qa_db_post_set_category($postid, $categoryid, $lastuserid=null, $lastip=null)
/*
Set the (exact) category in the database of $postid to $categoryid, and optionally record that $lastuserid did it from
$lastip (if at least one is specified)
*/
{
if (isset($lastuserid) || isset($lastip))
qa_db_query_sub(
"UPDATE ^posts SET categoryid=#, updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#",
$categoryid, QA_UPDATE_CATEGORY, $lastuserid, @inet_pton($lastip), $postid
);
else
qa_db_query_sub(
'UPDATE ^posts SET categoryid=# WHERE postid=#',
$categoryid, $postid
);
}
function qa_db_posts_set_category_path($postids, $path)
/*
Set the category path in the database of each of $postids to $path retrieved via qa_db_post_get_category_path()
*/
{
if (count($postids))
qa_db_query_sub(
'UPDATE ^posts SET categoryid=#, catidpath1=#, catidpath2=#, catidpath3=# WHERE postid IN (#)',
$path['categoryid'], $path['catidpath1'], $path['catidpath2'], $path['catidpath3'], $postids
); // requires QA_CATEGORY_DEPTH=4
}
function qa_db_post_set_created($postid, $created)
/*
Set the created date of $postid to $created, which is a unix timestamp. If created is null, set to now.
*/
{
if (isset($created))
qa_db_query_sub(
'UPDATE ^posts SET created=FROM_UNIXTIME(#) WHERE postid=#',
$created, $postid
);
else
qa_db_query_sub(
'UPDATE ^posts SET created=NOW() WHERE postid=#',
$postid
);
}
function qa_db_post_set_updated($postid, $updated)
/*
Set the last updated date of $postid to $updated, which is a unix timestamp. If updated is null, set to now.
*/
{
if (isset($updated))
qa_db_query_sub(
'UPDATE ^posts SET updated=FROM_UNIXTIME(#) WHERE postid=#',
$updated, $postid
);
else
qa_db_query_sub(
'UPDATE ^posts SET updated=NOW() WHERE postid=#',
$postid
);
}
/**
* Set the parent in the database of $postid to $parentid, and optionally record that $lastuserid did it from $lastip
* (if at least one is specified)
* @param $postid
* @param $parentid
* @param $lastuserid
* @param $lastip
*/
function qa_db_post_set_parent($postid, $parentid, $lastuserid = null, $lastip = null)
{
if (isset($lastuserid) || isset($lastip)) {
qa_db_query_sub(
"UPDATE ^posts SET parentid=#, updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#",
$parentid, QA_UPDATE_PARENT, $lastuserid, @inet_pton($lastip), $postid
);
} else {
qa_db_query_sub(
'UPDATE ^posts SET parentid=# WHERE postid=#',
$parentid, $postid
);
}
function qa_db_post_delete($postid)
/*
Deletes post $postid from the database (will also delete any votes on the post due to foreign key cascading)
*/
{
}
/**
* Set the text fields in the database of $postid to $title, $content, $tagstring, $notify and $name, and record that
* $lastuserid did it from $lastip (if at least one is specified) with $updatetype. For backwards compatibility if $name
* is null then the name will not be changed.
* @param $postid
* @param $title
* @param $content
* @param $format
* @param $tagstring
* @param $notify
* @param $lastuserid
* @param $lastip
* @param string $updatetype
* @param $name
*/
function qa_db_post_set_content($postid, $title, $content, $format, $tagstring, $notify, $lastuserid = null, $lastip = null, $updatetype = QA_UPDATE_CONTENT, $name = null)
{
if (isset($lastuserid) || isset($lastip)) {
// use COALESCE() for name since $name=null means it should not be modified (for backwards compatibility)
qa_db_query_sub(
'DELETE FROM ^posts WHERE postid=#',
$postid
'UPDATE ^posts SET title=$, content=$, format=$, tags=$, name=COALESCE($, name), notify=$, updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#',
$title, $content, $format, $tagstring, $name, $notify, $updatetype, $lastuserid, @inet_pton($lastip), $postid
);
} else {
qa_db_query_sub(
'UPDATE ^posts SET title=$, content=$, format=$, tags=$, name=COALESCE($, name), notify=$ WHERE postid=#',
$title, $content, $format, $tagstring, $name, $notify, $postid
);
}
function qa_db_titlewords_get_post_wordids($postid)
/*
Return an array of wordids that were indexed in the database for the title of $postid
*/
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT wordid FROM ^titlewords WHERE postid=#',
$postid
));
}
/**
* Set the author in the database of $postid to $userid, and set the lastuserid to $userid as well if appropriate
* @param $postid
* @param $userid
*/
function qa_db_post_set_userid($postid, $userid)
{
qa_db_query_sub(
'UPDATE ^posts SET userid=$, lastuserid=IF(updated IS NULL, lastuserid, COALESCE(lastuserid,$)) WHERE postid=#',
$userid, $userid, $postid
);
}
/**
* Set the (exact) category in the database of $postid to $categoryid, and optionally record that $lastuserid did it from
* $lastip (if at least one is specified)
* @param $postid
* @param $categoryid
* @param $lastuserid
* @param $lastip
*/
function qa_db_post_set_category($postid, $categoryid, $lastuserid = null, $lastip = null)
{
if (isset($lastuserid) || isset($lastip)) {
qa_db_query_sub(
"UPDATE ^posts SET categoryid=#, updated=NOW(), updatetype=$, lastuserid=$, lastip=$ WHERE postid=#",
$categoryid, QA_UPDATE_CATEGORY, $lastuserid, @inet_pton($lastip), $postid
);
} else {
qa_db_query_sub(
'UPDATE ^posts SET categoryid=# WHERE postid=#',
$categoryid, $postid
);
}
function qa_db_titlewords_delete_post($postid)
/*
Remove all entries in the database index of title words for $postid
*/
{
}
/**
* Set the category path in the database of each of $postids to $path retrieved via qa_db_post_get_category_path()
* @param $postids
* @param $path
*/
function qa_db_posts_set_category_path($postids, $path)
{
if (count($postids)) {
// requires QA_CATEGORY_DEPTH=4
qa_db_query_sub(
'DELETE FROM ^titlewords WHERE postid=#',
$postid
'UPDATE ^posts SET categoryid=#, catidpath1=#, catidpath2=#, catidpath3=# WHERE postid IN (#)',
$path['categoryid'], $path['catidpath1'], $path['catidpath2'], $path['catidpath3'], $postids
);
}
}
function qa_db_contentwords_get_post_wordids($postid)
/*
Return an array of wordids that were indexed in the database for the content of $postid
*/
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT wordid FROM ^contentwords WHERE postid=#',
/**
* Set the created date of $postid to $created, which is a unix timestamp. If created is null, set to now.
* @param $postid
* @param $created
*/
function qa_db_post_set_created($postid, $created)
{
if (isset($created)) {
qa_db_query_sub(
'UPDATE ^posts SET created=FROM_UNIXTIME(#) WHERE postid=#',
$created, $postid
);
} else {
qa_db_query_sub(
'UPDATE ^posts SET created=NOW() WHERE postid=#',
$postid
));
);
}
}
function qa_db_contentwords_delete_post($postid)
/*
Remove all entries in the database index of content words for $postid
*/
{
/**
* Set the last updated date of $postid to $updated, which is a unix timestamp. If updated is null, set to now.
* @param $postid
* @param $updated
*/
function qa_db_post_set_updated($postid, $updated)
{
if (isset($updated)) {
qa_db_query_sub(
'UPDATE ^posts SET updated=FROM_UNIXTIME(#) WHERE postid=#',
$updated, $postid
);
} else {
qa_db_query_sub(
'DELETE FROM ^contentwords WHERE postid=#',
'UPDATE ^posts SET updated=NOW() WHERE postid=#',
$postid
);
}
function qa_db_tagwords_get_post_wordids($postid)
/*
Return an array of wordids that were indexed in the database for the individual words in tags of $postid
*/
{
}
/**
* Deletes post $postid from the database (will also delete any votes on the post due to foreign key cascading)
* @param $postid
*/
function qa_db_post_delete($postid)
{
qa_db_query_sub(
'DELETE FROM ^posts WHERE postid=#',
$postid
);
}
/**
* Return an array of wordids that were indexed in the database for the title of $postid
* @param $postid
* @return array
*/
function qa_db_titlewords_get_post_wordids($postid)
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT wordid FROM ^titlewords WHERE postid=#',
$postid
));
}
/**
* Remove all entries in the database index of title words for $postid
* @param $postid
*/
function qa_db_titlewords_delete_post($postid)
{
qa_db_query_sub(
'DELETE FROM ^titlewords WHERE postid=#',
$postid
);
}
/**
* Return an array of wordids that were indexed in the database for the content of $postid
* @param $postid
* @return array
*/
function qa_db_contentwords_get_post_wordids($postid)
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT wordid FROM ^contentwords WHERE postid=#',
$postid
));
}
/**
* Remove all entries in the database index of content words for $postid
* @param $postid
*/
function qa_db_contentwords_delete_post($postid)
{
qa_db_query_sub(
'DELETE FROM ^contentwords WHERE postid=#',
$postid
);
}
/**
* Return an array of wordids that were indexed in the database for the individual words in tags of $postid
* @param $postid
* @return array
*/
function qa_db_tagwords_get_post_wordids($postid)
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT wordid FROM ^tagwords WHERE postid=#',
$postid
));
}
/**
* Remove all entries in the database index of individual words in tags of $postid
* @param $postid
*/
function qa_db_tagwords_delete_post($postid)
{
qa_db_query_sub(
'DELETE FROM ^tagwords WHERE postid=#',
$postid
);
}
/**
* Return an array of wordids that were indexed in the database for the whole tags of $postid
* @param $postid
* @return array
*/
function qa_db_posttags_get_post_wordids($postid)
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT wordid FROM ^posttags WHERE postid=#',
$postid
));
}
/**
* Remove all entries in the database index of whole tags for $postid
* @param $postid
*/
function qa_db_posttags_delete_post($postid)
{
qa_db_query_sub(
'DELETE FROM ^posttags WHERE postid=#',
$postid
);
}
/**
* Return the array $postids containing only those elements which are the postid of a question in the database
* @param $postids
* @return array
*/
function qa_db_posts_filter_q_postids($postids)
{
if (count($postids)) {
return qa_db_read_all_values(qa_db_query_sub(
'SELECT wordid FROM ^tagwords WHERE postid=#',
$postid
"SELECT postid FROM ^posts WHERE type='Q' AND postid IN (#)",
$postids
));
}
return array();
}
function qa_db_tagwords_delete_post($postid)
/*
Remove all entries in the database index of individual words in tags of $postid
*/
{
qa_db_query_sub(
'DELETE FROM ^tagwords WHERE postid=#',
$postid
);
}
function qa_db_posttags_get_post_wordids($postid)
/*
Return an array of wordids that were indexed in the database for the whole tags of $postid
*/
{
/**
* Return an array of all the userids of authors of posts in the array $postids
* @param $postids
* @return array
*/
function qa_db_posts_get_userids($postids)
{
if (count($postids)) {
return qa_db_read_all_values(qa_db_query_sub(
'SELECT wordid FROM ^posttags WHERE postid=#',
$postid
"SELECT DISTINCT userid FROM ^posts WHERE postid IN (#) AND userid IS NOT NULL",
$postids
));
}
return array();
}
function qa_db_posttags_delete_post($postid)
/*
Remove all entries in the database index of whole tags for $postid
*/
{
/**
* Update the cached count of the number of flagged posts in the database
*/
function qa_db_flaggedcount_update()
{
if (qa_should_update_counts()) {
qa_db_query_sub(
'DELETE FROM ^posttags WHERE postid=#',
$postid
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_flaggedcount', COUNT(*) FROM ^posts " .
"WHERE flagcount > 0 AND type IN ('Q', 'A', 'C') " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
function qa_db_posts_filter_q_postids($postids)
/*
Return the array $postids containing only those elements which are the postid of a question in the database
*/
{
if (count($postids))
return qa_db_read_all_values(qa_db_query_sub(
"SELECT postid FROM ^posts WHERE type='Q' AND postid IN (#)",
$postids
));
else
return array();
}
function qa_db_posts_get_userids($postids)
/*
Return an array of all the userids of authors of posts in the array $postids
*/
{
if (count($postids))
return qa_db_read_all_values(qa_db_query_sub(
"SELECT DISTINCT userid FROM ^posts WHERE postid IN (#) AND userid IS NOT NULL",
$postids
));
else
return array();
}
function qa_db_flaggedcount_update()
/*
Update the cached count of the number of flagged posts in the database
*/
{
if (qa_should_update_counts()) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_flaggedcount', COUNT(*) FROM ^posts " .
"WHERE flagcount > 0 AND type IN ('Q', 'A', 'C') " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)"
);
}
}
/*
Omit PHP closing tag to help avoid accidental output
*/
}
......@@ -20,337 +20,381 @@
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;
}
function qa_db_calc_passcheck($password, $salt)
/*
Return the expected value for the passcheck column given the $password and password $salt
*/
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
return sha1(substr($salt, 0, 8).$password.substr($salt, 8));
}
function qa_db_user_create($email, $password, $handle, $level, $ip)
/*
Create a new user in the database with $email, $password, $handle, privilege $level, and $ip address
*/
{
require_once QA_INCLUDE_DIR.'util/string.php';
$ipbin = @inet_pton($ip);
if (QA_PASSWORD_HASH) {
qa_db_query_sub(
'INSERT INTO ^users (created, createip, email, passhash, level, handle, loggedin, loginip) '.
'VALUES (NOW(), $, $, $, #, $, NOW(), $)',
$ipbin, $email, isset($password) ? password_hash($password, PASSWORD_BCRYPT) : null, (int)$level, $handle, $ipbin
);
} else {
$salt = isset($password) ? qa_random_alphanum(16) : null;
qa_db_query_sub(
'INSERT INTO ^users (created, createip, email, passsalt, passcheck, level, handle, loggedin, loginip) '.
'VALUES (NOW(), $, $, $, UNHEX($), #, $, NOW(), $)',
$ipbin, $email, $salt, isset($password) ? qa_db_calc_passcheck($password, $salt) : null, (int)$level, $handle, $ipbin
);
}
return qa_db_last_insert_id();
}
function qa_db_user_delete($userid)
/*
Delete user $userid from the database, along with everything they have ever done (to the extent that it's possible)
*/
{
qa_db_query_sub('UPDATE ^posts SET lastuserid=NULL WHERE lastuserid=$', $userid);
qa_db_query_sub('DELETE FROM ^userpoints WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^blobs WHERE blobid=(SELECT avatarblobid FROM ^users WHERE userid=$)', $userid);
qa_db_query_sub('DELETE FROM ^users WHERE userid=$', $userid);
// All the queries below should be superfluous due to foreign key constraints, but just in case the user switched to MyISAM.
// Note also that private messages to/from that user are kept since we don't have all the keys we need to delete efficiently.
qa_db_query_sub('UPDATE ^posts SET userid=NULL WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^userlogins WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^userprofile WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^userfavorites WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^userevents WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^uservotes WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^userlimits WHERE userid=$', $userid);
}
function qa_db_user_find_by_email($email)
/*
Return the ids of all users in the database which match $email (should be one or none)
*/
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT userid FROM ^users WHERE email=$',
$email
));
}
function qa_db_user_find_by_handle($handle)
/*
Return the ids of all users in the database which match $handle (=username), should be one or none
*/
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT userid FROM ^users WHERE handle=$',
$handle
));
}
function qa_db_user_get_userid_handles($userids)
/*
Return an array mapping each userid in $userids that can be found to that user's handle
*/
{
if (count($userids))
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT userid, handle FROM ^users WHERE userid IN (#)',
$userids
), 'userid', 'handle');
else
return array();
}
function qa_db_user_get_handle_userids($handles)
/*
Return an array mapping mapping each handle in $handle that can be found to that user's userid
*/
{
if (count($handles))
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT handle, userid FROM ^users WHERE handle IN ($)',
$handles
), 'handle', 'userid');
else
return array();
}
function qa_db_user_set($userid, $field, $value)
/*
Set $field of $userid to $value in the database users table
*/
{
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../');
exit;
}
/**
* Return the expected value for the passcheck column given the $password and password $salt
* @param $password
* @param $salt
* @return mixed|string
*/
function qa_db_calc_passcheck($password, $salt)
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
return sha1(substr($salt, 0, 8) . $password . substr($salt, 8));
}
/**
* Create a new user in the database with $email, $password, $handle, privilege $level, and $ip address
* @param $email
* @param $password
* @param $handle
* @param $level
* @param $ip
* @return mixed
*/
function qa_db_user_create($email, $password, $handle, $level, $ip)
{
require_once QA_INCLUDE_DIR . 'util/string.php';
$ipbin = @inet_pton($ip);
if (QA_PASSWORD_HASH) {
qa_db_query_sub(
'UPDATE ^users SET '.qa_db_escape_string($field).'=$ WHERE userid=$',
$value, $userid
'INSERT INTO ^users (created, createip, email, passhash, level, handle, loggedin, loginip) ' .
'VALUES (NOW(), $, $, $, #, $, NOW(), $)',
$ipbin, $email, isset($password) ? password_hash($password, PASSWORD_BCRYPT) : null, (int)$level, $handle, $ipbin
);
}
function qa_db_user_set_password($userid, $password)
/*
Set the password of $userid to $password, and reset their salt at the same time
*/
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
require_once QA_INCLUDE_DIR.'util/string.php';
if (QA_PASSWORD_HASH) {
qa_db_query_sub(
'UPDATE ^users SET passhash=$, passsalt=NULL, passcheck=NULL WHERE userid=$',
password_hash($password, PASSWORD_BCRYPT), $userid
);
} else {
$salt = qa_random_alphanum(16);
qa_db_query_sub(
'UPDATE ^users SET passsalt=$, passcheck=UNHEX($) WHERE userid=$',
$salt, qa_db_calc_passcheck($password, $salt), $userid
);
}
}
} else {
$salt = isset($password) ? qa_random_alphanum(16) : null;
function qa_db_user_set_flag($userid, $flag, $set)
/*
Switch on the $flag bit of the flags column for $userid if $set is true, or switch off otherwise
*/
{
qa_db_query_sub(
'UPDATE ^users SET flags=flags'.($set ? '|' : '&~').'# WHERE userid=$',
$flag, $userid
'INSERT INTO ^users (created, createip, email, passsalt, passcheck, level, handle, loggedin, loginip) ' .
'VALUES (NOW(), $, $, $, UNHEX($), #, $, NOW(), $)',
$ipbin, $email, $salt, isset($password) ? qa_db_calc_passcheck($password, $salt) : null, (int)$level, $handle, $ipbin
);
}
function qa_db_user_rand_emailcode()
/*
Return a random string to be used for a user's emailcode column
*/
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
require_once QA_INCLUDE_DIR.'util/string.php';
return qa_random_alphanum(8);
return qa_db_last_insert_id();
}
/**
* Delete user $userid from the database, along with everything they have ever done (to the extent that it's possible)
* @param $userid
*/
function qa_db_user_delete($userid)
{
qa_db_query_sub('UPDATE ^posts SET lastuserid=NULL WHERE lastuserid=$', $userid);
qa_db_query_sub('DELETE FROM ^userpoints WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^blobs WHERE blobid=(SELECT avatarblobid FROM ^users WHERE userid=$)', $userid);
qa_db_query_sub('DELETE FROM ^users WHERE userid=$', $userid);
// All the queries below should be superfluous due to foreign key constraints, but just in case the user switched to MyISAM.
// Note also that private messages to/from that user are kept since we don't have all the keys we need to delete efficiently.
qa_db_query_sub('UPDATE ^posts SET userid=NULL WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^userlogins WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^userprofile WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^userfavorites WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^userevents WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^uservotes WHERE userid=$', $userid);
qa_db_query_sub('DELETE FROM ^userlimits WHERE userid=$', $userid);
}
/**
* Return the ids of all users in the database which match $email (should be one or none)
* @param $email
* @return array
*/
function qa_db_user_find_by_email($email)
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT userid FROM ^users WHERE email=$',
$email
));
}
/**
* Return the ids of all users in the database which match $handle (=username), should be one or none
* @param $handle
* @return array
*/
function qa_db_user_find_by_handle($handle)
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT userid FROM ^users WHERE handle=$',
$handle
));
}
/**
* Return an array mapping each userid in $userids that can be found to that user's handle
* @param $userids
* @return array
*/
function qa_db_user_get_userid_handles($userids)
{
if (count($userids)) {
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT userid, handle FROM ^users WHERE userid IN (#)',
$userids
), 'userid', 'handle');
}
return array();
}
function qa_db_user_rand_sessioncode()
/*
Return a random string to be used for a user's sessioncode column (for browser session cookies)
*/
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
require_once QA_INCLUDE_DIR.'util/string.php';
return qa_random_alphanum(8);
/**
* Return an array mapping mapping each handle in $handle that can be found to that user's userid
* @param $handles
* @return array
*/
function qa_db_user_get_handle_userids($handles)
{
if (count($handles)) {
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT handle, userid FROM ^users WHERE handle IN ($)',
$handles
), 'handle', 'userid');
}
function qa_db_user_profile_set($userid, $field, $value)
/*
Set a row in the database user profile table to store $value for $field for $userid
*/
{
return array();
}
/**
* Set $field of $userid to $value in the database users table
* @param $userid
* @param $field
* @param $value
*/
function qa_db_user_set($userid, $field, $value)
{
qa_db_query_sub(
'UPDATE ^users SET ' . qa_db_escape_string($field) . '=$ WHERE userid=$',
$value, $userid
);
}
/**
* Set the password of $userid to $password, and reset their salt at the same time
* @param $userid
* @param $password
* @return mixed
*/
function qa_db_user_set_password($userid, $password)
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
require_once QA_INCLUDE_DIR . 'util/string.php';
if (QA_PASSWORD_HASH) {
qa_db_query_sub(
'INSERT INTO ^userprofile (userid, title, content) VALUES ($, $, $) ' .
'ON DUPLICATE KEY UPDATE content = VALUES(content)',
$userid, $field, $value
'UPDATE ^users SET passhash=$, passsalt=NULL, passcheck=NULL WHERE userid=$',
password_hash($password, PASSWORD_BCRYPT), $userid
);
}
} else {
$salt = qa_random_alphanum(16);
function qa_db_user_logged_in($userid, $ip)
/*
Note in the database that $userid just logged in from $ip address
*/
{
qa_db_query_sub(
'UPDATE ^users SET loggedin=NOW(), loginip=$ WHERE userid=$',
@inet_pton($ip), $userid
'UPDATE ^users SET passsalt=$, passcheck=UNHEX($) WHERE userid=$',
$salt, qa_db_calc_passcheck($password, $salt), $userid
);
}
function qa_db_user_written($userid, $ip)
/*
Note in the database that $userid just performed a write operation from $ip address
*/
{
qa_db_query_sub(
'UPDATE ^users SET written=NOW(), writeip=$ WHERE userid=$',
@inet_pton($ip), $userid
);
}
/**
* Switch on the $flag bit of the flags column for $userid if $set is true, or switch off otherwise
* @param $userid
* @param $flag
* @param $set
*/
function qa_db_user_set_flag($userid, $flag, $set)
{
qa_db_query_sub(
'UPDATE ^users SET flags=flags' . ($set ? '|' : '&~') . '# WHERE userid=$',
$flag, $userid
);
}
/**
* Return a random string to be used for a user's emailcode column
*/
function qa_db_user_rand_emailcode()
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
require_once QA_INCLUDE_DIR . 'util/string.php';
return qa_random_alphanum(8);
}
/**
* Return a random string to be used for a user's sessioncode column (for browser session cookies)
*/
function qa_db_user_rand_sessioncode()
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
require_once QA_INCLUDE_DIR . 'util/string.php';
return qa_random_alphanum(8);
}
/**
* Set a row in the database user profile table to store $value for $field for $userid
* @param $userid
* @param $field
* @param $value
*/
function qa_db_user_profile_set($userid, $field, $value)
{
qa_db_query_sub(
'INSERT INTO ^userprofile (userid, title, content) VALUES ($, $, $) ' .
'ON DUPLICATE KEY UPDATE content = VALUES(content)',
$userid, $field, $value
);
}
/**
* Note in the database that $userid just logged in from $ip address
* @param $userid
* @param $ip
*/
function qa_db_user_logged_in($userid, $ip)
{
qa_db_query_sub(
'UPDATE ^users SET loggedin=NOW(), loginip=$ WHERE userid=$',
@inet_pton($ip), $userid
);
}
/**
* Note in the database that $userid just performed a write operation from $ip address
* @param $userid
* @param $ip
*/
function qa_db_user_written($userid, $ip)
{
qa_db_query_sub(
'UPDATE ^users SET written=NOW(), writeip=$ WHERE userid=$',
@inet_pton($ip), $userid
);
}
/**
* Add an external login in the database for $source and $identifier for user $userid
* @param $userid
* @param $source
* @param $identifier
*/
function qa_db_user_login_add($userid, $source, $identifier)
{
qa_db_query_sub(
'INSERT INTO ^userlogins (userid, source, identifier, identifiermd5) ' .
'VALUES ($, $, $, UNHEX($))',
$userid, $source, $identifier, md5($identifier)
);
}
/**
* Return some information about the user with external login $source and $identifier in the database, if a match is found
* @param $source
* @param $identifier
* @return array
*/
function qa_db_user_login_find($source, $identifier)
{
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT ^userlogins.userid, handle, email FROM ^userlogins LEFT JOIN ^users ON ^userlogins.userid=^users.userid ' .
'WHERE source=$ AND identifiermd5=UNHEX($) AND identifier=$',
$source, md5($identifier), $identifier
));
}
/**
* Lock all tables if $sync is true, otherwise unlock them. Used to synchronize creation of external login mappings.
* @param $sync
*/
function qa_db_user_login_sync($sync)
{
if ($sync) { // need to lock all tables since any could be used by a plugin's event module
$tables = qa_db_list_tables();
$locks = array();
foreach ($tables as $table)
$locks[] = $table . ' WRITE';
qa_db_query_sub('LOCK TABLES ' . implode(', ', $locks));
} else {
qa_db_query_sub('UNLOCK TABLES');
}
function qa_db_user_login_add($userid, $source, $identifier)
/*
Add an external login in the database for $source and $identifier for user $userid
*/
{
}
/**
* Reset the full set of context-specific (currently, per category) user levels for user $userid to $userlevels, where
* $userlevels is an array of arrays, the inner arrays containing items 'entitytype', 'entityid' and 'level'.
* @param $userid
* @param $userlevels
*/
function qa_db_user_levels_set($userid, $userlevels)
{
qa_db_query_sub(
'DELETE FROM ^userlevels WHERE userid=$',
$userid
);
foreach ($userlevels as $userlevel) {
qa_db_query_sub(
'INSERT INTO ^userlogins (userid, source, identifier, identifiermd5) '.
'VALUES ($, $, $, UNHEX($))',
$userid, $source, $identifier, md5($identifier)
'INSERT INTO ^userlevels (userid, entitytype, entityid, level) VALUES ($, $, #, #) ' .
'ON DUPLICATE KEY UPDATE level = VALUES(level)',
$userid, $userlevel['entitytype'], $userlevel['entityid'], $userlevel['level']
);
}
function qa_db_user_login_find($source, $identifier)
/*
Return some information about the user with external login $source and $identifier in the database, if a match is found
*/
{
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT ^userlogins.userid, handle, email FROM ^userlogins LEFT JOIN ^users ON ^userlogins.userid=^users.userid '.
'WHERE source=$ AND identifiermd5=UNHEX($) AND identifier=$',
$source, md5($identifier), $identifier
));
}
function qa_db_user_login_sync($sync)
/*
Lock all tables if $sync is true, otherwise unlock them. Used to synchronize creation of external login mappings.
*/
{
if ($sync) { // need to lock all tables since any could be used by a plugin's event module
$tables=qa_db_list_tables();
$locks=array();
foreach ($tables as $table)
$locks[]=$table.' WRITE';
qa_db_query_sub('LOCK TABLES '.implode(', ', $locks));
} else
qa_db_query_sub('UNLOCK TABLES');
}
function qa_db_user_levels_set($userid, $userlevels)
/*
Reset the full set of context-specific (currently, per category) user levels for user $userid to $userlevels, where
$userlevels is an array of arrays, the inner arrays containing items 'entitytype', 'entityid' and 'level'.
*/
{
}
/**
* Get the information required for sending a mailing to the next $count users with userids greater than $lastuserid
* @param $lastuserid
* @param $count
* @return array
*/
function qa_db_users_get_mailing_next($lastuserid, $count)
{
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT userid, email, handle, emailcode, flags FROM ^users WHERE userid># ORDER BY userid LIMIT #',
$lastuserid, $count
));
}
/**
* Update the cached count of the number of users who are awaiting approval after registration
*/
function qa_db_uapprovecount_update()
{
if (qa_should_update_counts() && !QA_FINAL_EXTERNAL_USERS) {
qa_db_query_sub(
'DELETE FROM ^userlevels WHERE userid=$',
$userid
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_uapprovecount', COUNT(*) FROM ^users " .
"WHERE level < # AND NOT (flags & #) " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)",
QA_USER_LEVEL_APPROVED, QA_USER_FLAGS_USER_BLOCKED
);
foreach ($userlevels as $userlevel) {
qa_db_query_sub(
'INSERT INTO ^userlevels (userid, entitytype, entityid, level) VALUES ($, $, #, #) ' .
'ON DUPLICATE KEY UPDATE level = VALUES(level)',
$userid, $userlevel['entitytype'], $userlevel['entityid'], $userlevel['level']
);
}
}
function qa_db_users_get_mailing_next($lastuserid, $count)
/*
Get the information required for sending a mailing to the next $count users with userids greater than $lastuserid
*/
{
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT userid, email, handle, emailcode, flags FROM ^users WHERE userid># ORDER BY userid LIMIT #',
$lastuserid, $count
));
}
function qa_db_uapprovecount_update()
/*
Update the cached count of the number of users who are awaiting approval after registration
*/
{
if ( qa_should_update_counts() && !QA_FINAL_EXTERNAL_USERS ) {
qa_db_query_sub(
"INSERT INTO ^options (title, content) " .
"SELECT 'cache_uapprovecount', COUNT(*) FROM ^users " .
"WHERE level < # AND NOT (flags & #) " .
"ON DUPLICATE KEY UPDATE content = VALUES(content)",
QA_USER_LEVEL_APPROVED, QA_USER_FLAGS_USER_BLOCKED
);
}
}
/*
Omit PHP closing tag to help avoid accidental output
*/
}
......@@ -20,145 +20,159 @@
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;
}
function qa_db_uservote_set($postid, $userid, $vote)
/*
Set the vote for $userid on $postid to $vote in the database
*/
{
$vote=max(min(($vote), 1), -1);
qa_db_query_sub(
'INSERT INTO ^uservotes (postid, userid, vote, flag) VALUES (#, #, #, 0) ON DUPLICATE KEY UPDATE vote=#',
$postid, $userid, $vote, $vote
);
}
function qa_db_uservote_get($postid, $userid)
/*
Get the vote for $userid on $postid from the database (or NULL if none)
*/
{
return qa_db_read_one_value(qa_db_query_sub(
'SELECT vote FROM ^uservotes WHERE postid=# AND userid=#',
$postid, $userid
), true);
}
function qa_db_userflag_set($postid, $userid, $flag)
/*
Set the flag for $userid on $postid to $flag (true or false) in the database
*/
{
$flag=$flag ? 1 : 0;
if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../');
exit;
}
/**
* Set the vote for $userid on $postid to $vote in the database
* @param $postid
* @param $userid
* @param $vote
*/
function qa_db_uservote_set($postid, $userid, $vote)
{
$vote = max(min(($vote), 1), -1);
qa_db_query_sub(
'INSERT INTO ^uservotes (postid, userid, vote, flag) VALUES (#, #, #, 0) ON DUPLICATE KEY UPDATE vote=#',
$postid, $userid, $vote, $vote
);
}
/**
* Get the vote for $userid on $postid from the database (or NULL if none)
* @param $postid
* @param $userid
* @return mixed|null
*/
function qa_db_uservote_get($postid, $userid)
{
return qa_db_read_one_value(qa_db_query_sub(
'SELECT vote FROM ^uservotes WHERE postid=# AND userid=#',
$postid, $userid
), true);
}
/**
* Set the flag for $userid on $postid to $flag (true or false) in the database
* @param $postid
* @param $userid
* @param $flag
*/
function qa_db_userflag_set($postid, $userid, $flag)
{
$flag = $flag ? 1 : 0;
qa_db_query_sub(
'INSERT INTO ^uservotes (postid, userid, vote, flag) VALUES (#, #, 0, #) ON DUPLICATE KEY UPDATE flag=#',
$postid, $userid, $flag, $flag
);
}
/**
* Clear all flags for $postid in the database
* @param $postid
*/
function qa_db_userflags_clear_all($postid)
{
qa_db_query_sub(
'UPDATE ^uservotes SET flag=0 WHERE postid=#',
$postid
);
}
/**
* Recalculate the cached count of upvotes, downvotes and netvotes for $postid in the database
* @param $postid
*/
function qa_db_post_recount_votes($postid)
{
if (qa_should_update_counts())
qa_db_query_sub(
'INSERT INTO ^uservotes (postid, userid, vote, flag) VALUES (#, #, 0, #) ON DUPLICATE KEY UPDATE flag=#',
$postid, $userid, $flag, $flag
'UPDATE ^posts AS x, (SELECT COALESCE(SUM(GREATEST(0,vote)),0) AS upvotes, -COALESCE(SUM(LEAST(0,vote)),0) AS downvotes FROM ^uservotes WHERE postid=#) AS a SET x.upvotes=a.upvotes, x.downvotes=a.downvotes, x.netvotes=a.upvotes-a.downvotes WHERE x.postid=#',
$postid, $postid
);
}
}
function qa_db_userflags_clear_all($postid)
/*
Clear all flags for $postid in the database
*/
{
/**
* Recalculate the cached count of flags for $postid in the database
* @param $postid
*/
function qa_db_post_recount_flags($postid)
{
if (qa_should_update_counts())
qa_db_query_sub(
'UPDATE ^uservotes SET flag=0 WHERE postid=#',
$postid
'UPDATE ^posts AS x, (SELECT COALESCE(SUM(IF(flag, 1, 0)),0) AS flagcount FROM ^uservotes WHERE postid=#) AS a SET x.flagcount=a.flagcount WHERE x.postid=#',
$postid, $postid
);
}
function qa_db_post_recount_votes($postid)
/*
Recalculate the cached count of upvotes, downvotes and netvotes for $postid in the database
*/
{
if (qa_should_update_counts())
qa_db_query_sub(
'UPDATE ^posts AS x, (SELECT COALESCE(SUM(GREATEST(0,vote)),0) AS upvotes, -COALESCE(SUM(LEAST(0,vote)),0) AS downvotes FROM ^uservotes WHERE postid=#) AS a SET x.upvotes=a.upvotes, x.downvotes=a.downvotes, x.netvotes=a.upvotes-a.downvotes WHERE x.postid=#',
$postid, $postid
);
}
function qa_db_post_recount_flags($postid)
/*
Recalculate the cached count of flags for $postid in the database
*/
{
if (qa_should_update_counts())
qa_db_query_sub(
'UPDATE ^posts AS x, (SELECT COALESCE(SUM(IF(flag, 1, 0)),0) AS flagcount FROM ^uservotes WHERE postid=#) AS a SET x.flagcount=a.flagcount WHERE x.postid=#',
$postid, $postid
);
}
function qa_db_uservote_post_get($postid)
/*
Returns all non-zero votes on post $postid from the database as an array of [userid] => [vote]
*/
{
}
/**
* Returns all non-zero votes on post $postid from the database as an array of [userid] => [vote]
* @param $postid
* @return array
*/
function qa_db_uservote_post_get($postid)
{
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT userid, vote FROM ^uservotes WHERE postid=# AND vote!=0',
$postid
), 'userid', 'vote');
}
/**
* Returns all the postids from the database for posts that $userid has voted on or flagged
* @param $userid
* @return array
*/
function qa_db_uservoteflag_user_get($userid)
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT postid FROM ^uservotes WHERE userid=# AND (vote!=0) OR (flag!=0)',
$userid
));
}
/**
* Return information about all the non-zero votes and/or flags on the posts in postids, including user handles for internal user management
* @param $postids
* @return array
*/
function qa_db_uservoteflag_posts_get($postids)
{
if (QA_FINAL_EXTERNAL_USERS) {
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT userid, vote FROM ^uservotes WHERE postid=# AND vote!=0',
$postid
), 'userid', 'vote');
}
function qa_db_uservoteflag_user_get($userid)
/*
Returns all the postids from the database for posts that $userid has voted on or flagged
*/
{
return qa_db_read_all_values(qa_db_query_sub(
'SELECT postid FROM ^uservotes WHERE userid=# AND (vote!=0) OR (flag!=0)',
$userid
'SELECT postid, userid, vote, flag FROM ^uservotes WHERE postid IN (#) AND ((vote!=0) OR (flag!=0))',
$postids
));
} else {
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT postid, handle, vote, flag FROM ^uservotes LEFT JOIN ^users ON ^uservotes.userid=^users.userid WHERE postid IN (#) AND ((vote!=0) OR (flag!=0))',
$postids
));
}
function qa_db_uservoteflag_posts_get($postids)
/*
Return information about all the non-zero votes and/or flags on the posts in postids, including user handles for internal user management
*/
{
if (QA_FINAL_EXTERNAL_USERS)
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT postid, userid, vote, flag FROM ^uservotes WHERE postid IN (#) AND ((vote!=0) OR (flag!=0))',
$postids
));
else
return qa_db_read_all_assoc(qa_db_query_sub(
'SELECT postid, handle, vote, flag FROM ^uservotes LEFT JOIN ^users ON ^uservotes.userid=^users.userid WHERE postid IN (#) AND ((vote!=0) OR (flag!=0))',
$postids
));
}
/**
* Remove all votes assigned to a post that had been cast by the owner of the post.
*
* @param int $postid The post ID from which the owner's votes will be removed.
*/
function qa_db_uservote_remove_own($postid)
{
qa_db_query_sub(
'DELETE uv FROM ^uservotes uv JOIN ^posts p ON uv.postid=p.postid AND uv.userid=p.userid WHERE uv.postid=#', $postid
);
}
/*
Omit PHP closing tag to help avoid accidental output
*/
\ No newline at end of file
}
/**
* Remove all votes assigned to a post that had been cast by the owner of the post.
*
* @param int $postid The post ID from which the owner's votes will be removed.
*/
function qa_db_uservote_remove_own($postid)
{
qa_db_query_sub(
'DELETE uv FROM ^uservotes uv JOIN ^posts p ON uv.postid=p.postid AND uv.userid=p.userid WHERE uv.postid=#', $postid
);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment