Commit 54ada742 by Scott

Coding style (app/)

parent f24542bb
...@@ -39,6 +39,8 @@ function qa_captcha_available() ...@@ -39,6 +39,8 @@ function qa_captcha_available()
/** /**
* Return an HTML string explaining $captchareason (from qa_user_captcha_reason()) to the user about why they are seeing a captcha * Return an HTML string explaining $captchareason (from qa_user_captcha_reason()) to the user about why they are seeing a captcha
* @param $captchareason
* @return mixed|null|string
*/ */
function qa_captcha_reason_note($captchareason) function qa_captcha_reason_note($captchareason)
{ {
...@@ -65,8 +67,13 @@ function qa_captcha_reason_note($captchareason) ...@@ -65,8 +67,13 @@ function qa_captcha_reason_note($captchareason)
/** /**
* Prepare $qa_content for showing a captcha, adding the element to $fields, given previous $errors, and a $note to display. * Prepare $qa_content for showing a captcha, adding the element to $fields, given previous $errors, and a $note to display.
* Returns JavaScript required to load CAPTCHA when field is shown by user (e.g. clicking comment button). * Returns JavaScript required to load CAPTCHA when field is shown by user (e.g. clicking comment button).
* @param $qa_content
* @param $fields
* @param $errors
* @param $note
* @return string
*/ */
function qa_set_up_captcha_field(&$qa_content, &$fields, $errors, $note=null) function qa_set_up_captcha_field(&$qa_content, &$fields, $errors, $note = null)
{ {
if (!qa_captcha_available()) if (!qa_captcha_available())
return ''; return '';
...@@ -79,8 +86,7 @@ function qa_set_up_captcha_field(&$qa_content, &$fields, $errors, $note=null) ...@@ -79,8 +86,7 @@ function qa_set_up_captcha_field(&$qa_content, &$fields, $errors, $note=null)
if ($count > 1) { if ($count > 1) {
// use blank captcha in order to load via JS // use blank captcha in order to load via JS
$html = ''; $html = '';
} } else {
else {
// first captcha is always loaded explicitly // first captcha is always loaded explicitly
$qa_content['script_var']['qa_captcha_in'] = 'qa_captcha_div_1'; $qa_content['script_var']['qa_captcha_in'] = 'qa_captcha_div_1';
$html = $captcha->form_html($qa_content, @$errors['captcha']); $html = $captcha->form_html($qa_content, @$errors['captcha']);
...@@ -89,17 +95,19 @@ function qa_set_up_captcha_field(&$qa_content, &$fields, $errors, $note=null) ...@@ -89,17 +95,19 @@ function qa_set_up_captcha_field(&$qa_content, &$fields, $errors, $note=null)
$fields['captcha'] = array( $fields['captcha'] = array(
'type' => 'custom', 'type' => 'custom',
'label' => qa_lang_html('misc/captcha_label'), 'label' => qa_lang_html('misc/captcha_label'),
'html' => '<div id="qa_captcha_div_'.$count.'">'.$html.'</div>', 'html' => '<div id="qa_captcha_div_' . $count . '">' . $html . '</div>',
'error' => @array_key_exists('captcha', $errors) ? qa_lang_html('misc/captcha_error') : null, 'error' => @array_key_exists('captcha', $errors) ? qa_lang_html('misc/captcha_error') : null,
'note' => $note, 'note' => $note,
); );
return "if (!document.getElementById('qa_captcha_div_".$count."').hasChildNodes()) { recaptcha_load('qa_captcha_div_".$count."'); }"; return "if (!document.getElementById('qa_captcha_div_" . $count . "').hasChildNodes()) { recaptcha_load('qa_captcha_div_" . $count . "'); }";
} }
/** /**
* Check if captcha is submitted correctly, and if not, set $errors['captcha'] to a descriptive string. * Check if captcha is submitted correctly, and if not, set $errors['captcha'] to a descriptive string.
* @param $errors
* @return bool
*/ */
function qa_captcha_validate_post(&$errors) function qa_captcha_validate_post(&$errors)
{ {
......
...@@ -20,59 +20,56 @@ ...@@ -20,59 +20,56 @@
More about this license: http://www.question2answer.org/license.php 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 if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../'); header('Location: ../');
exit; exit;
} }
function qa_cookie_get() /**
/* * Return the user identification cookie sent by the browser for this page request, or null if none
Return the user identification cookie sent by the browser for this page request, or null if none */
*/ function qa_cookie_get()
{ {
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); } if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
return isset($_COOKIE['qa_id']) ? qa_gpc_to_string($_COOKIE['qa_id']) : null; return isset($_COOKIE['qa_id']) ? qa_gpc_to_string($_COOKIE['qa_id']) : null;
} }
function qa_cookie_get_create() /**
/* * Return user identification cookie sent by browser if valid, or create a new one if not.
Return user identification cookie sent by browser if valid, or create a new one if not. * Either way, extend for another year (this is used when an anonymous post is created)
Either way, extend for another year (this is used when an anonymous post is created) */
*/ function qa_cookie_get_create()
{ {
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); } if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
require_once QA_INCLUDE_DIR.'db/cookies.php';
$cookieid=qa_cookie_get(); require_once QA_INCLUDE_DIR . 'db/cookies.php';
if (isset($cookieid) && qa_db_cookie_exists($cookieid)) $cookieid = qa_cookie_get();
; // cookie is valid
else
$cookieid=qa_db_cookie_create(qa_remote_ip_address());
setcookie('qa_id', $cookieid, time()+86400*365, '/', QA_COOKIE_DOMAIN, (bool)ini_get('session.cookie_secure'), true); if (!isset($cookieid) || !qa_db_cookie_exists($cookieid)) {
$_COOKIE['qa_id']=$cookieid; // cookie is invalid
$cookieid = qa_db_cookie_create(qa_remote_ip_address());
return $cookieid;
} }
setcookie('qa_id', $cookieid, time() + 86400 * 365, '/', QA_COOKIE_DOMAIN, (bool)ini_get('session.cookie_secure'), true);
$_COOKIE['qa_id'] = $cookieid;
function qa_cookie_report_action($cookieid, $action) return $cookieid;
/* }
Called after a database write $action performed by a user identified by $cookieid,
relating to $questionid, $answerid and/or $commentid
*/
{
require_once QA_INCLUDE_DIR.'db/cookies.php';
qa_db_cookie_written($cookieid, qa_remote_ip_address());
}
/**
* Called after a database write $action performed by a user identified by $cookieid,
* relating to $questionid, $answerid and/or $commentid
* @param $cookieid
* @param $action
*/
function qa_cookie_report_action($cookieid, $action)
{
require_once QA_INCLUDE_DIR . 'db/cookies.php';
/* qa_db_cookie_written($cookieid, qa_remote_ip_address());
Omit PHP closing tag to help avoid accidental output }
*/
...@@ -20,159 +20,164 @@ ...@@ -20,159 +20,164 @@
More about this license: http://www.question2answer.org/license.php 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 if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../'); header('Location: ../');
exit; exit;
} }
require_once QA_INCLUDE_DIR.'app/options.php'; require_once QA_INCLUDE_DIR . 'app/options.php';
/**
* Suspend the sending of all email notifications via qa_send_notification(...) if $suspend is true, otherwise
* reinstate it. A counter is kept to allow multiple calls.
* @param bool $suspend
*/
function qa_suspend_notifications($suspend = true)
{
global $qa_notifications_suspended;
$qa_notifications_suspended += ($suspend ? 1 : -1);
}
/**
* Send email to person with $userid and/or $email and/or $handle (null/invalid values are ignored or retrieved from
* user database as appropriate). Email uses $subject and $body, after substituting each key in $subs with its
* corresponding value, plus applying some standard substitutions such as ^site_title, ^handle and ^email.
* @param $userid
* @param $email
* @param $handle
* @param $subject
* @param $body
* @param $subs
* @param bool $html
* @return bool
*/
function qa_send_notification($userid, $email, $handle, $subject, $body, $subs, $html = false)
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
global $qa_notifications_suspended;
if ($qa_notifications_suspended > 0)
return false;
require_once QA_INCLUDE_DIR . 'db/selects.php';
require_once QA_INCLUDE_DIR . 'util/string.php';
if (isset($userid)) {
$needemail = !qa_email_validate(@$email); // take from user if invalid, e.g. @ used in practice
$needhandle = empty($handle);
if ($needemail || $needhandle) {
if (QA_FINAL_EXTERNAL_USERS) {
if ($needhandle) {
$handles = qa_get_public_from_userids(array($userid));
$handle = @$handles[$userid];
}
function qa_suspend_notifications($suspend=true) if ($needemail)
/* $email = qa_get_user_email($userid);
Suspend the sending of all email notifications via qa_send_notification(...) if $suspend is true, otherwise
reinstate it. A counter is kept to allow multiple calls.
*/
{
global $qa_notifications_suspended;
$qa_notifications_suspended+=($suspend ? 1 : -1); } else {
} $useraccount = qa_db_select_with_pending(
array(
'columns' => array('email', 'handle'),
'source' => '^users WHERE userid = #',
'arguments' => array($userid),
'single' => true,
)
);
if ($needhandle)
$handle = @$useraccount['handle'];
function qa_send_notification($userid, $email, $handle, $subject, $body, $subs, $html = false) if ($needemail)
/* $email = @$useraccount['email'];
Send email to person with $userid and/or $email and/or $handle (null/invalid values are ignored or retrieved from
user database as appropriate). Email uses $subject and $body, after substituting each key in $subs with its
corresponding value, plus applying some standard substitutions such as ^site_title, ^handle and ^email.
*/
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
global $qa_notifications_suspended;
if ($qa_notifications_suspended>0)
return false;
require_once QA_INCLUDE_DIR.'db/selects.php';
require_once QA_INCLUDE_DIR.'util/string.php';
if (isset($userid)) {
$needemail=!qa_email_validate(@$email); // take from user if invalid, e.g. @ used in practice
$needhandle=empty($handle);
if ($needemail || $needhandle) {
if (QA_FINAL_EXTERNAL_USERS) {
if ($needhandle) {
$handles=qa_get_public_from_userids(array($userid));
$handle=@$handles[$userid];
}
if ($needemail)
$email=qa_get_user_email($userid);
} else {
$useraccount=qa_db_select_with_pending(
array(
'columns' => array('email', 'handle'),
'source' => '^users WHERE userid = #',
'arguments' => array($userid),
'single' => true,
)
);
if ($needhandle)
$handle=@$useraccount['handle'];
if ($needemail)
$email=@$useraccount['email'];
}
} }
} }
if (isset($email) && qa_email_validate($email)) {
$subs['^site_title']=qa_opt('site_title');
$subs['^handle']=$handle;
$subs['^email']=$email;
$subs['^open']="\n";
$subs['^close']="\n";
return qa_send_email(array(
'fromemail' => qa_opt('from_email'),
'fromname' => qa_opt('site_title'),
'toemail' => $email,
'toname' => $handle,
'subject' => strtr($subject, $subs),
'body' => (empty($handle) ? '' : qa_lang_sub('emails/to_handle_prefix', $handle)).strtr($body, $subs),
'html' => $html,
));
} else
return false;
} }
if (isset($email) && qa_email_validate($email)) {
$subs['^site_title'] = qa_opt('site_title');
$subs['^handle'] = $handle;
$subs['^email'] = $email;
$subs['^open'] = "\n";
$subs['^close'] = "\n";
return qa_send_email(array(
'fromemail' => qa_opt('from_email'),
'fromname' => qa_opt('site_title'),
'toemail' => $email,
'toname' => $handle,
'subject' => strtr($subject, $subs),
'body' => (empty($handle) ? '' : qa_lang_sub('emails/to_handle_prefix', $handle)) . strtr($body, $subs),
'html' => $html,
));
}
function qa_send_email($params) return false;
/* }
Send the email based on the $params array - the following keys are required (some can be empty): fromemail,
fromname, toemail, toname, subject, body, html
*/
{
if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
// @error_log(print_r($params, true));
require_once QA_INCLUDE_DIR.'vendor/PHPMailer/PHPMailerAutoload.php';
$mailer=new PHPMailer();
$mailer->CharSet='utf-8';
$mailer->From=$params['fromemail']; /**
$mailer->Sender=$params['fromemail']; * Send the email based on the $params array - the following keys are required (some can be empty): fromemail,
$mailer->FromName=$params['fromname']; * fromname, toemail, toname, subject, body, html
$mailer->addAddress($params['toemail'], $params['toname']); * @param $params
if(!empty($params['replytoemail'])){ * @return bool
$mailer->addReplyTo($params['replytoemail'], $params['replytoname']); */
} function qa_send_email($params)
$mailer->Subject=$params['subject']; {
$mailer->Body=$params['body']; if (qa_to_override(__FUNCTION__)) { $args=func_get_args(); return qa_call_override(__FUNCTION__, $args); }
if ($params['html']) // @error_log(print_r($params, true));
$mailer->isHTML(true);
if (qa_opt('smtp_active')) { require_once QA_INCLUDE_DIR . 'vendor/PHPMailer/PHPMailerAutoload.php';
$mailer->isSMTP();
$mailer->Host=qa_opt('smtp_address');
$mailer->Port=qa_opt('smtp_port');
if (qa_opt('smtp_secure')){ $mailer = new PHPMailer();
$mailer->SMTPSecure=qa_opt('smtp_secure'); $mailer->CharSet = 'utf-8';
}
else {
$mailer->SMTPOptions=array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
}
if (qa_opt('smtp_authenticate')) { $mailer->From = $params['fromemail'];
$mailer->SMTPAuth=true; $mailer->Sender = $params['fromemail'];
$mailer->Username=qa_opt('smtp_username'); $mailer->FromName = $params['fromname'];
$mailer->Password=qa_opt('smtp_password'); $mailer->addAddress($params['toemail'], $params['toname']);
} if (!empty($params['replytoemail'])) {
$mailer->addReplyTo($params['replytoemail'], $params['replytoname']);
}
$mailer->Subject = $params['subject'];
$mailer->Body = $params['body'];
if ($params['html'])
$mailer->isHTML(true);
if (qa_opt('smtp_active')) {
$mailer->isSMTP();
$mailer->Host = qa_opt('smtp_address');
$mailer->Port = qa_opt('smtp_port');
if (qa_opt('smtp_secure')) {
$mailer->SMTPSecure = qa_opt('smtp_secure');
} else {
$mailer->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
),
);
} }
$send_status = $mailer->send(); if (qa_opt('smtp_authenticate')) {
if(!$send_status){ $mailer->SMTPAuth = true;
@error_log('PHP Question2Answer email send error: '.$mailer->ErrorInfo); $mailer->Username = qa_opt('smtp_username');
$mailer->Password = qa_opt('smtp_password');
} }
return $send_status;
} }
$send_status = $mailer->send();
/* if (!$send_status) {
Omit PHP closing tag to help avoid accidental output @error_log('PHP Question2Answer email send error: ' . $mailer->ErrorInfo);
*/ }
return $send_status;
}
...@@ -20,69 +20,82 @@ ...@@ -20,69 +20,82 @@
More about this license: http://www.question2answer.org/license.php 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 if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../'); header('Location: ../');
exit; exit;
}
require_once QA_INCLUDE_DIR . 'db/events.php';
require_once QA_INCLUDE_DIR . 'app/updates.php';
/**
* Add appropriate events to the database for an action performed on a question. The event of type $updatetype relates
* to $lastpostid whose antecedent question is $questionid, and was caused by $lastuserid. Pass a unix $timestamp for
* the event time or leave as null to use now. This will add an event to $questionid's and $lastuserid's streams. If
* $otheruserid is set, it will also add an notification-style event for that user, unless they are the one who did it.
* @param $questionid
* @param $lastpostid
* @param $updatetype
* @param $lastuserid
* @param $otheruserid
* @param $timestamp
*/
function qa_create_event_for_q_user($questionid, $lastpostid, $updatetype, $lastuserid, $otheruserid = null, $timestamp = null)
{
qa_db_event_create_for_entity(QA_ENTITY_QUESTION, $questionid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp); // anyone who favorited the question
if (isset($lastuserid) && !QA_FINAL_EXTERNAL_USERS)
qa_db_event_create_for_entity(QA_ENTITY_USER, $lastuserid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp); // anyone who favorited the user who did it
if (isset($otheruserid) && ($otheruserid != $lastuserid))
qa_db_event_create_not_entity($otheruserid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp); // possible other user to be informed
}
/**
* Add appropriate events to the database for an action performed on a set of tags in $tagstring (namely, a question
* being created with those tags or having one of those tags added afterwards). The event of type $updatetype relates
* to the question $questionid, and was caused by $lastuserid. Pass a unix $timestamp for the event time or leave as
* null to use now.
* @param $tagstring
* @param $questionid
* @param $updatetype
* @param $lastuserid
* @param $timestamp
*/
function qa_create_event_for_tags($tagstring, $questionid, $updatetype, $lastuserid, $timestamp = null)
{
require_once QA_INCLUDE_DIR . 'util/string.php';
require_once QA_INCLUDE_DIR . 'db/post-create.php';
$tagwordids = qa_db_word_mapto_ids(array_unique(qa_tagstring_to_tags($tagstring)));
foreach ($tagwordids as $wordid) {
qa_db_event_create_for_entity(QA_ENTITY_TAG, $wordid, $questionid, $questionid, $updatetype, $lastuserid, $timestamp);
} }
}
require_once QA_INCLUDE_DIR.'db/events.php';
require_once QA_INCLUDE_DIR.'app/updates.php';
/**
* Add appropriate events to the database for an action performed on $categoryid (namely, a question being created in
function qa_create_event_for_q_user($questionid, $lastpostid, $updatetype, $lastuserid, $otheruserid=null, $timestamp=null) * that category or being moved to it later on), along with all of its ancestor categories. The event of type
/* * $updatetype relates to the question $questionid, and was caused by $lastuserid. Pass a unix $timestamp for the event
Add appropriate events to the database for an action performed on a question. The event of type $updatetype relates * time or leave as null to use now.
to $lastpostid whose antecedent question is $questionid, and was caused by $lastuserid. Pass a unix $timestamp for * @param $categoryid
the event time or leave as null to use now. This will add an event to $questionid's and $lastuserid's streams. If * @param $questionid
$otheruserid is set, it will also add an notification-style event for that user, unless they are the one who did it. * @param $updatetype
*/ * @param $lastuserid
{ * @param $timestamp
qa_db_event_create_for_entity(QA_ENTITY_QUESTION, $questionid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp); // anyone who favorited the question */
function qa_create_event_for_category($categoryid, $questionid, $updatetype, $lastuserid, $timestamp = null)
if (isset($lastuserid) && !QA_FINAL_EXTERNAL_USERS) {
qa_db_event_create_for_entity(QA_ENTITY_USER, $lastuserid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp); // anyone who favorited the user who did it if (isset($categoryid)) {
require_once QA_INCLUDE_DIR . 'db/selects.php';
if (isset($otheruserid) && ($otheruserid!=$lastuserid)) require_once QA_INCLUDE_DIR . 'app/format.php';
qa_db_event_create_not_entity($otheruserid, $questionid, $lastpostid, $updatetype, $lastuserid, $timestamp); // possible other user to be informed
} $categories = qa_category_path(qa_db_single_select(qa_db_category_nav_selectspec($categoryid, true)), $categoryid);
foreach ($categories as $category) {
qa_db_event_create_for_entity(QA_ENTITY_CATEGORY, $category['categoryid'], $questionid, $questionid, $updatetype, $lastuserid, $timestamp);
function qa_create_event_for_tags($tagstring, $questionid, $updatetype, $lastuserid, $timestamp=null)
/*
Add appropriate events to the database for an action performed on a set of tags in $tagstring (namely, a question
being created with those tags or having one of those tags added afterwards). The event of type $updatetype relates
to the question $questionid, and was caused by $lastuserid. Pass a unix $timestamp for the event time or leave as
null to use now.
*/
{
require_once QA_INCLUDE_DIR.'util/string.php';
require_once QA_INCLUDE_DIR.'db/post-create.php';
$tagwordids=qa_db_word_mapto_ids(array_unique(qa_tagstring_to_tags($tagstring)));
foreach ($tagwordids as $wordid)
qa_db_event_create_for_entity(QA_ENTITY_TAG, $wordid, $questionid, $questionid, $updatetype, $lastuserid, $timestamp);
}
function qa_create_event_for_category($categoryid, $questionid, $updatetype, $lastuserid, $timestamp=null)
/*
Add appropriate events to the database for an action performed on $categoryid (namely, a question being created in
that category or being moved to it later on), along with all of its ancestor categories. The event of type
$updatetype relates to the question $questionid, and was caused by $lastuserid. Pass a unix $timestamp for the event
time or leave as null to use now.
*/
{
if (isset($categoryid)) {
require_once QA_INCLUDE_DIR.'db/selects.php';
require_once QA_INCLUDE_DIR.'app/format.php';
$categories=qa_category_path(qa_db_single_select(qa_db_category_nav_selectspec($categoryid, true)), $categoryid);
foreach ($categories as $category)
qa_db_event_create_for_entity(QA_ENTITY_CATEGORY, $category['categoryid'], $questionid, $questionid, $updatetype, $lastuserid, $timestamp);
} }
} }
}
/*
Omit PHP closing tag to help avoid accidental output
*/
\ No newline at end of file
...@@ -133,8 +133,8 @@ function qa_limits_calc_remaining($action, $userlimits, $iplimits) ...@@ -133,8 +133,8 @@ function qa_limits_calc_remaining($action, $userlimits, $iplimits)
$period = (int)(qa_opt('db_time') / 3600); $period = (int)(qa_opt('db_time') / 3600);
return max(0, min( return max(0, min(
$usermax - ((@$userlimits['period'] == $period) ? $userlimits['count'] : 0), $usermax - (@$userlimits['period'] == $period ? $userlimits['count'] : 0),
$ipmax - ((@$iplimits['period'] == $period) ? $iplimits['count'] : 0) $ipmax - (@$iplimits['period'] == $period ? $iplimits['count'] : 0)
)); ));
} }
...@@ -229,7 +229,7 @@ function qa_ip_between($ip, $startip, $endip) ...@@ -229,7 +229,7 @@ function qa_ip_between($ip, $startip, $endip)
if (count($uip) != count($ustartip) || count($uip) != count($uendip)) if (count($uip) != count($ustartip) || count($uip) != count($uendip))
return false; return false;
foreach ($uip as $i=>$byte) { foreach ($uip as $i => $byte) {
if ($byte < $ustartip[$i] || $byte > $uendip[$i]) { if ($byte < $ustartip[$i] || $byte > $uendip[$i]) {
return false; return false;
} }
......
...@@ -20,135 +20,138 @@ ...@@ -20,135 +20,138 @@
More about this license: http://www.question2answer.org/license.php 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 if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../'); header('Location: ../');
exit; exit;
}
/**
* Start a mailing to all users, unless one has already been started
*/
function qa_mailing_start()
{
require_once QA_INCLUDE_DIR . 'db/admin.php';
if (strlen(qa_opt('mailing_last_userid')) == 0) {
qa_opt('mailing_last_timestamp', time());
qa_opt('mailing_last_userid', '0');
qa_opt('mailing_total_users', qa_db_count_users());
qa_opt('mailing_done_users', 0);
} }
}
function qa_mailing_start() /**
/* * Stop a mailing to all users
Start a mailing to all users, unless one has already been started */
*/ function qa_mailing_stop()
{ {
require_once QA_INCLUDE_DIR.'db/admin.php'; qa_opt('mailing_last_timestamp', '');
qa_opt('mailing_last_userid', '');
if (strlen(qa_opt('mailing_last_userid'))==0) { qa_opt('mailing_done_users', '');
qa_opt('mailing_last_timestamp', time()); qa_opt('mailing_total_users', '');
qa_opt('mailing_last_userid', '0'); }
qa_opt('mailing_total_users', qa_db_count_users());
qa_opt('mailing_done_users', 0);
}
}
function qa_mailing_stop() /**
/* * Allow the mailing to proceed forwards, for the appropriate amount of time and users, based on the options
Stop a mailing to all users */
*/ function qa_mailing_perform_step()
{ {
qa_opt('mailing_last_timestamp', ''); require_once QA_INCLUDE_DIR . 'db/users.php';
qa_opt('mailing_last_userid', '');
qa_opt('mailing_done_users', '');
qa_opt('mailing_total_users', '');
}
$lastuserid = qa_opt('mailing_last_userid');
function qa_mailing_perform_step() if (strlen($lastuserid)) {
/* $thistime = time();
Allow the mailing to proceed forwards, for the appropriate amount of time and users, based on the options $lasttime = qa_opt('mailing_last_timestamp');
*/ $perminute = qa_opt('mailing_per_minute');
{
require_once QA_INCLUDE_DIR.'db/users.php';
$lastuserid=qa_opt('mailing_last_userid');
if (strlen($lastuserid)) { if (($lasttime - $thistime) > 60) // if it's been a while, we assume there hasn't been continuous mailing...
$thistime=time(); $lasttime = $thistime - 1; // ... so only do 1 second's worth
$lasttime=qa_opt('mailing_last_timestamp'); else // otherwise...
$perminute=qa_opt('mailing_per_minute'); $lasttime = max($lasttime, $thistime - 6); // ... don't do more than 6 seconds' worth
if (($lasttime-$thistime)>60) // if it's been a while, we assume there hasn't been continuous mailing... $count = min(floor(($thistime - $lasttime) * $perminute / 60), 100); // don't do more than 100 messages at a time
$lasttime=$thistime-1; // ... so only do 1 second's worth
else // otherwise...
$lasttime=max($lasttime, $thistime-6); // ... don't do more than 6 seconds' worth
$count=min(floor(($thistime-$lasttime)*$perminute/60), 100); // don't do more than 100 messages at a time if ($count > 0) {
qa_opt('mailing_last_timestamp', $thistime + 30);
// prevents a parallel call to qa_mailing_perform_step() from sending messages, unless we're very unlucky with timing (poor man's mutex)
if ($count>0) { $sentusers = 0;
qa_opt('mailing_last_timestamp', $thistime+30); $users = qa_db_users_get_mailing_next($lastuserid, $count);
// prevents a parallel call to qa_mailing_perform_step() from sending messages, unless we're very unlucky with timing (poor man's mutex)
$sentusers=0; if (count($users)) {
$users=qa_db_users_get_mailing_next($lastuserid, $count); foreach ($users as $user) {
$lastuserid = max($lastuserid, $user['userid']);
}
if (count($users)) { qa_opt('mailing_last_userid', $lastuserid);
foreach ($users as $user) qa_opt('mailing_done_users', qa_opt('mailing_done_users') + count($users));
$lastuserid=max($lastuserid, $user['userid']);
qa_opt('mailing_last_userid', $lastuserid); foreach ($users as $user) {
qa_opt('mailing_done_users', qa_opt('mailing_done_users')+count($users)); if (!($user['flags'] & QA_USER_FLAGS_NO_MAILINGS)) {
qa_mailing_send_one($user['userid'], $user['handle'], $user['email'], $user['emailcode']);
$sentusers++;
}
}
foreach ($users as $user) qa_opt('mailing_last_timestamp', $lasttime + $sentusers * 60 / $perminute); // can be floating point result, based on number of mails actually sent
if (!($user['flags'] & QA_USER_FLAGS_NO_MAILINGS)) {
qa_mailing_send_one($user['userid'], $user['handle'], $user['email'], $user['emailcode']);
$sentusers++;
}
qa_opt('mailing_last_timestamp', $lasttime+$sentusers*60/$perminute); // can be floating point result, based on number of mails actually sent } else
qa_mailing_stop();
} else
qa_mailing_stop();
}
} }
} }
}
function qa_mailing_send_one($userid, $handle, $email, $emailcode)
/* /**
Send a single message from the mailing, to $userid with $handle and $email. * Send a single message from the mailing, to $userid with $handle and $email.
Pass the user's existing $emailcode if there is one, otherwise a new one will be set up * Pass the user's existing $emailcode if there is one, otherwise a new one will be set up
*/ * @param $userid
{ * @param $handle
require_once QA_INCLUDE_DIR.'app/emails.php'; * @param $email
require_once QA_INCLUDE_DIR.'db/users.php'; * @param $emailcode
* @return bool
if (!strlen(trim($emailcode))) { */
$emailcode=qa_db_user_rand_emailcode(); function qa_mailing_send_one($userid, $handle, $email, $emailcode)
qa_db_user_set($userid, 'emailcode', $emailcode); {
} require_once QA_INCLUDE_DIR . 'app/emails.php';
require_once QA_INCLUDE_DIR . 'db/users.php';
$unsubscribeurl=qa_path_absolute('unsubscribe', array('c' => $emailcode, 'u' => $handle));
if (!strlen(trim($emailcode))) {
return qa_send_email(array( $emailcode = qa_db_user_rand_emailcode();
'fromemail' => qa_opt('mailing_from_email'), qa_db_user_set($userid, 'emailcode', $emailcode);
'fromname' => qa_opt('mailing_from_name'),
'toemail' => $email,
'toname' => $handle,
'subject' => qa_opt('mailing_subject'),
'body' => trim(qa_opt('mailing_body'))."\n\n\n".qa_lang('users/unsubscribe').' '.$unsubscribeurl,
'html' => false,
));
} }
$unsubscribeurl = qa_path_absolute('unsubscribe', array('c' => $emailcode, 'u' => $handle));
function qa_mailing_progress_message()
/* return qa_send_email(array(
Return a message describing current progress in the mailing 'fromemail' => qa_opt('mailing_from_email'),
*/ 'fromname' => qa_opt('mailing_from_name'),
{ 'toemail' => $email,
require_once QA_INCLUDE_DIR . 'app/format.php'; 'toname' => $handle,
'subject' => qa_opt('mailing_subject'),
if (strlen(qa_opt('mailing_last_userid'))) 'body' => trim(qa_opt('mailing_body')) . "\n\n\n" . qa_lang('users/unsubscribe') . ' ' . $unsubscribeurl,
return strtr(qa_lang('admin/mailing_progress'), array( 'html' => false,
'^1' => qa_format_number(qa_opt('mailing_done_users')), ));
'^2' => qa_format_number(qa_opt('mailing_total_users')), }
));
else
return null; /**
* Return a message describing current progress in the mailing
*/
function qa_mailing_progress_message()
{
require_once QA_INCLUDE_DIR . 'app/format.php';
if (strlen(qa_opt('mailing_last_userid'))) {
return strtr(qa_lang('admin/mailing_progress'), array(
'^1' => qa_format_number(qa_opt('mailing_done_users')),
'^2' => qa_format_number(qa_opt('mailing_total_users')),
));
} }
return null;
/* }
Omit PHP closing tag to help avoid accidental output
*/
\ No newline at end of file
...@@ -20,121 +20,122 @@ ...@@ -20,121 +20,122 @@
More about this license: http://www.question2answer.org/license.php 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 if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../'); header('Location: ../');
exit; exit;
}
/**
* Returns $count search results for $query performed by $userid, starting at offset $start. Set $absoluteurls to true
* to get absolute URLs for the results and $fullcontent if the results should include full post content. This calls
* through to the chosen search module, and performs all the necessary post-processing to supplement the results for
* display online or in an RSS feed.
* @param $query
* @param $start
* @param $count
* @param $userid
* @param $absoluteurls
* @param $fullcontent
* @return
*/
function qa_get_search_results($query, $start, $count, $userid, $absoluteurls, $fullcontent)
{
// Identify which search module should be used
$searchmodules = qa_load_modules_with('search', 'process_search');
if (!count($searchmodules))
qa_fatal_error('No search engine is available');
$module = reset($searchmodules); // use first one by default
if (count($searchmodules) > 1) {
$tryname = qa_opt('search_module'); // use chosen one if it's available
if (isset($searchmodules[$tryname]))
$module = $searchmodules[$tryname];
} }
// Get the results
function qa_get_search_results($query, $start, $count, $userid, $absoluteurls, $fullcontent) $results = $module->process_search($query, $start, $count, $userid, $absoluteurls, $fullcontent);
/*
Returns $count search results for $query performed by $userid, starting at offset $start. Set $absoluteurls to true
to get absolute URLs for the results and $fullcontent if the results should include full post content. This calls
through to the chosen search module, and performs all the necessary post-processing to supplement the results for
display online or in an RSS feed.
*/
{
// Identify which search module should be used // Work out what additional information (if any) we need to retrieve for the results
$searchmodules=qa_load_modules_with('search', 'process_search'); $keypostidgetfull = array();
$keypostidgettype = array();
$keypostidgetquestion = array();
$keypageidgetpage = array();
if (!count($searchmodules)) foreach ($results as $result) {
qa_fatal_error('No search engine is available'); if (isset($result['question_postid']) && !isset($result['question']))
$keypostidgetfull[$result['question_postid']] = true;
$module=reset($searchmodules); // use first one by default if (isset($result['match_postid'])) {
if (!((isset($result['question_postid'])) || (isset($result['question']))))
$keypostidgetquestion[$result['match_postid']] = true; // we can also get $result['match_type'] from this
if (count($searchmodules)>1) { elseif (!isset($result['match_type']))
$tryname=qa_opt('search_module'); // use chosen one if it's available $keypostidgettype[$result['match_postid']] = true;
if (isset($searchmodules[$tryname]))
$module=$searchmodules[$tryname];
} }
// Get the results if (isset($result['page_pageid']) && !isset($result['page']))
$keypageidgetpage[$result['page_pageid']] = true;
}
$results=$module->process_search($query, $start, $count, $userid, $absoluteurls, $fullcontent); // Perform the appropriate database queries
// Work out what additional information (if any) we need to retrieve for the results list($postidfull, $postidtype, $postidquestion, $pageidpage) = qa_db_select_with_pending(
count($keypostidgetfull) ? qa_db_posts_selectspec($userid, array_keys($keypostidgetfull), $fullcontent) : null,
count($keypostidgettype) ? qa_db_posts_basetype_selectspec(array_keys($keypostidgettype)) : null,
count($keypostidgetquestion) ? qa_db_posts_to_qs_selectspec($userid, array_keys($keypostidgetquestion), $fullcontent) : null,
count($keypageidgetpage) ? qa_db_pages_selectspec(null, array_keys($keypageidgetpage)) : null
);
$keypostidgetfull=array(); // Supplement the results as appropriate
$keypostidgettype=array();
$keypostidgetquestion=array();
$keypageidgetpage=array();
foreach ($results as $result) { foreach ($results as $key => $result) {
if (isset($result['question_postid']) && !isset($result['question'])) if (isset($result['question_postid']) && !isset($result['question']))
$keypostidgetfull[$result['question_postid']]=true; if (@$postidfull[$result['question_postid']]['basetype'] == 'Q')
$result['question'] = @$postidfull[$result['question_postid']];
if (isset($result['match_postid'])) { if (isset($result['match_postid'])) {
if (!( (isset($result['question_postid'])) || (isset($result['question'])) )) if (!(isset($result['question_postid']) || isset($result['question']))) {
$keypostidgetquestion[$result['match_postid']]=true; // we can also get $result['match_type'] from this $result['question'] = @$postidquestion[$result['match_postid']];
elseif (!isset($result['match_type'])) if (!isset($result['match_type']))
$keypostidgettype[$result['match_postid']]=true; $result['match_type'] = @$result['question']['obasetype'];
}
if (isset($result['page_pageid']) && !isset($result['page'])) } elseif (!isset($result['match_type']))
$keypageidgetpage[$result['page_pageid']]=true; $result['match_type'] = @$postidtype[$result['match_postid']];
} }
// Perform the appropriate database queries if (isset($result['question']) && !isset($result['question_postid']))
$result['question_postid'] = $result['question']['postid'];
list($postidfull, $postidtype, $postidquestion, $pageidpage)=qa_db_select_with_pending(
count($keypostidgetfull) ? qa_db_posts_selectspec($userid, array_keys($keypostidgetfull), $fullcontent) : null,
count($keypostidgettype) ? qa_db_posts_basetype_selectspec(array_keys($keypostidgettype)) : null,
count($keypostidgetquestion) ? qa_db_posts_to_qs_selectspec($userid, array_keys($keypostidgetquestion), $fullcontent) : null,
count($keypageidgetpage) ? qa_db_pages_selectspec(null, array_keys($keypageidgetpage)) : null
);
// Supplement the results as appropriate
foreach ($results as $key => $result) {
if (isset($result['question_postid']) && !isset($result['question']))
if (@$postidfull[$result['question_postid']]['basetype']=='Q')
$result['question']=@$postidfull[$result['question_postid']];
if (isset($result['match_postid'])) {
if (!( (isset($result['question_postid'])) || (isset($result['question'])) )) {
$result['question']=@$postidquestion[$result['match_postid']];
if (!isset($result['match_type'])) if (isset($result['page_pageid']) && !isset($result['page']))
$result['match_type']=@$result['question']['obasetype']; $result['page'] = @$pageidpage[$result['page_pageid']];
} elseif (!isset($result['match_type'])) if (!isset($result['title'])) {
$result['match_type']=@$postidtype[$result['match_postid']]; if (isset($result['question']))
} $result['title'] = $result['question']['title'];
elseif (isset($result['page']))
if (isset($result['question']) && !isset($result['question_postid'])) $result['title'] = $result['page']['heading'];
$result['question_postid']=$result['question']['postid'];
if (isset($result['page_pageid']) && !isset($result['page']))
$result['page']=@$pageidpage[$result['page_pageid']];
if (!isset($result['title'])) {
if (isset($result['question']))
$result['title']=$result['question']['title'];
elseif (isset($result['page']))
$result['title']=$result['page']['heading'];
}
if (!isset($result['url'])) {
if (isset($result['question']))
$result['url']=qa_q_path($result['question']['postid'], $result['question']['title'],
$absoluteurls, @$result['match_type'], @$result['match_postid']);
elseif (isset($result['page']))
$result['url']=qa_path($result['page']['tags'], null, qa_opt('site_url'));
}
$results[$key]=$result;
} }
// Return the results if (!isset($result['url'])) {
if (isset($result['question']))
$result['url'] = qa_q_path($result['question']['postid'], $result['question']['title'],
$absoluteurls, @$result['match_type'], @$result['match_postid']);
elseif (isset($result['page']))
$result['url'] = qa_path($result['page']['tags'], null, qa_opt('site_url'));
}
return $results; $results[$key] = $result;
} }
// Return the results
/* return $results;
Omit PHP closing tag to help avoid accidental output }
*/
\ No newline at end of file
...@@ -20,39 +20,35 @@ ...@@ -20,39 +20,35 @@
More about this license: http://www.question2answer.org/license.php 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 if (!defined('QA_VERSION')) { // don't allow this page to be requested directly from browser
header('Location: ../'); header('Location: ../');
exit; exit;
} }
// Character codes for the different types of entity that can be followed (entitytype columns) // Character codes for the different types of entity that can be followed (entitytype columns)
define('QA_ENTITY_QUESTION', 'Q'); define('QA_ENTITY_QUESTION', 'Q');
define('QA_ENTITY_USER', 'U'); define('QA_ENTITY_USER', 'U');
define('QA_ENTITY_TAG', 'T'); define('QA_ENTITY_TAG', 'T');
define('QA_ENTITY_CATEGORY', 'C'); define('QA_ENTITY_CATEGORY', 'C');
define('QA_ENTITY_NONE', '-'); define('QA_ENTITY_NONE', '-');
// Character codes for the different types of updates on a post (updatetype columns) // Character codes for the different types of updates on a post (updatetype columns)
define('QA_UPDATE_CATEGORY', 'A'); // questions only, category changed define('QA_UPDATE_CATEGORY', 'A'); // questions only, category changed
define('QA_UPDATE_CLOSED', 'C'); // questions only, closed or reopened define('QA_UPDATE_CLOSED', 'C'); // questions only, closed or reopened
define('QA_UPDATE_CONTENT', 'E'); // title or content edited define('QA_UPDATE_CONTENT', 'E'); // title or content edited
define('QA_UPDATE_PARENT', 'M'); // e.g. comment moved when converting its parent answer to a comment define('QA_UPDATE_PARENT', 'M'); // e.g. comment moved when converting its parent answer to a comment
define('QA_UPDATE_SELECTED', 'S'); // answers only, removed if unselected define('QA_UPDATE_SELECTED', 'S'); // answers only, removed if unselected
define('QA_UPDATE_TAGS', 'T'); // questions only define('QA_UPDATE_TAGS', 'T'); // questions only
define('QA_UPDATE_TYPE', 'Y'); // e.g. answer to comment define('QA_UPDATE_TYPE', 'Y'); // e.g. answer to comment
define('QA_UPDATE_VISIBLE', 'H'); // hidden or reshown define('QA_UPDATE_VISIBLE', 'H'); // hidden or reshown
// Character codes for types of update that only appear in the streams tables, not on the posts themselves // Character codes for types of update that only appear in the streams tables, not on the posts themselves
define('QA_UPDATE_FOLLOWS', 'F'); // if a new question was asked related to one of its answers, or for a comment that follows another define('QA_UPDATE_FOLLOWS', 'F'); // if a new question was asked related to one of its answers, or for a comment that follows another
define('QA_UPDATE_C_FOR_Q', 'U'); // if comment created was on a question of the user whose stream this appears in define('QA_UPDATE_C_FOR_Q', 'U'); // if comment created was on a question of the user whose stream this appears in
define('QA_UPDATE_C_FOR_A', 'N'); // if comment created was on an answer of the user whose stream this appears in define('QA_UPDATE_C_FOR_A', 'N'); // if comment created was on an answer of the user whose stream this appears in
/*
Omit PHP closing tag to help avoid accidental output
*/
\ No newline at end of file
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