Skip to content

Commit

Permalink
Merge branch 'hotfix/v0.19.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenarslan committed Aug 11, 2021
2 parents bdde492 + 27aa33b commit 39f6d74
Show file tree
Hide file tree
Showing 21 changed files with 267 additions and 95 deletions.
2 changes: 1 addition & 1 deletion application/Controller/AdminAjaxController.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ private function ajaxSendToPosition() {
} else {
// execute current unit but don't return ouput
$runSession->execute();
alert('Session has been moved to desired position. If moved to a Branching Unit the sesion might have moved on.', 'alert-info');
alert('Session has been moved to desired position. If moved to a Branching Unit the session might have moved on.', 'alert-info');
}

if (Request::isAjaxRequest()) {
Expand Down
40 changes: 23 additions & 17 deletions application/Helper/RunHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,18 @@ public function getUserOverviewTable($queryParams, $page = null) {
`survey_runs`.name AS run_name,
`survey_units`.type AS unit_type,
`survey_run_sessions`.last_access,
`survey_unit_sessions`.result,
`survey_unit_sessions`.result_log,
`survey_unit_sessions`.expires
`us`.result,
`us`.result_log,
`us`.expires
FROM `survey_run_sessions`
LEFT JOIN `survey_runs` ON `survey_run_sessions`.run_id = `survey_runs`.id
LEFT JOIN `survey_run_units` ON `survey_run_sessions`.position = `survey_run_units`.position AND `survey_run_units`.run_id = `survey_run_sessions`.run_id
LEFT JOIN `survey_units` ON `survey_run_units`.unit_id = `survey_units`.id
LEFT JOIN `survey_unit_sessions` ON `survey_run_sessions`.id = `survey_unit_sessions`.run_session_id
WHERE `survey_unit_sessions`.`ended` IS NULL AND `survey_unit_sessions`.`expired` IS NULL AND {$where}
LEFT JOIN
(SELECT * FROM `survey_unit_sessions`
WHERE `survey_unit_sessions`.ended IS NULL AND `survey_unit_sessions`.expired IS NULL
ORDER BY `survey_unit_sessions`.id DESC LIMIT 1) us ON `survey_run_sessions`.id = `us`.run_session_id
WHERE {$where}
ORDER BY `survey_run_sessions`.session != :admin_code, `survey_run_sessions`.last_access DESC
LIMIT $limits
";
Expand All @@ -193,16 +196,18 @@ public function getUserOverviewExportPdoStatement($queryParams) {
`survey_run_sessions`.session,
`survey_run_sessions`.created,
`survey_run_sessions`.last_access,
`survey_unit_sessions`.result,
`survey_unit_sessions`.result_log,
`survey_unit_sessions`.expires
`us`.result,
`us`.result_log,
`us`.expires
FROM `survey_run_sessions`
LEFT JOIN `survey_runs` ON `survey_run_sessions`.run_id = `survey_runs`.id
LEFT JOIN `survey_run_units` ON `survey_run_sessions`.position = `survey_run_units`.position AND `survey_run_units`.run_id = `survey_run_sessions`.run_id
LEFT JOIN `survey_units` ON `survey_run_units`.unit_id = `survey_units`.id
LEFT JOIN `survey_unit_sessions` ON `survey_run_sessions`.id = `survey_unit_sessions`.run_session_id
WHERE `survey_unit_sessions`.`ended` IS NULL AND `survey_unit_sessions`.`expired` IS NULL AND
`survey_run_sessions`.run_id = :run_id ORDER BY `survey_run_sessions`.session != :admin_code,`survey_run_sessions`.last_access DESC
LEFT JOIN
(SELECT * FROM `survey_unit_sessions`
WHERE `survey_unit_sessions`.ended IS NULL AND `survey_unit_sessions`.expired IS NULL
ORDER BY `survey_unit_sessions`.id DESC LIMIT 1) us ON `survey_run_sessions`.id = `us`.run_session_id
WHERE `survey_run_sessions`.run_id = :run_id ORDER BY `survey_run_sessions`.session != :admin_code,`survey_run_sessions`.last_access DESC
";
$stmt = $this->db->prepare($query);
$stmt->execute($queryParams);
Expand Down Expand Up @@ -306,15 +311,16 @@ public function getEmailLogTable($queryParams) {
`survey_email_accounts`.from_name,
`survey_email_accounts`.`from`,
`survey_email_log`.recipient AS `to`,
`survey_email_log`.`sent`,
`survey_emails`.subject,
`survey_emails`.body,
`survey_email_log`.`status`,
`survey_email_log`.subject,
`survey_email_log`.sent,
`survey_email_log`.created,
`survey_unit_sessions`.result,
`survey_unit_sessions`.result_log,
`survey_run_units`.position AS position_in_run
FROM `survey_email_log`
LEFT JOIN `survey_emails` ON `survey_email_log`.email_id = `survey_emails`.id
LEFT JOIN `survey_run_units` ON `survey_emails`.id = `survey_run_units`.unit_id
LEFT JOIN `survey_email_accounts` ON `survey_emails`.account_id = `survey_email_accounts`.id
LEFT JOIN `survey_run_units` ON `survey_email_log`.email_id = `survey_run_units`.unit_id
LEFT JOIN `survey_email_accounts` ON `survey_email_log`.account_id = `survey_email_accounts`.id
LEFT JOIN `survey_unit_sessions` ON `survey_unit_sessions`.id = `survey_email_log`.session_id
LEFT JOIN `survey_run_sessions` ON `survey_unit_sessions`.run_session_id = `survey_run_sessions`.id
WHERE `survey_run_sessions`.run_id = :run_id
Expand Down
76 changes: 57 additions & 19 deletions application/Library/EmailQueue.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
<?php
/**
*
* the email queue takes emails grouped by sending accounts (to minimize opening and closing connections)
* it sends queued emails and logs the result to the email_log, the user_sessions, and a .log file (the latter is more immediately visible to the researcher)
* it also takes action if emails fail to send in certain ways
* - alarms the researcher
* - turns off the account (to stop expending effort on broken connections)
*/

use PHPMailer\PHPMailer\PHPMailer;

Expand All @@ -8,6 +16,14 @@
*
*/
class EmailQueue extends Queue {
const STATUS_QUEUED = 0;
const STATUS_SENT = 1;
const STATUS_INVALID_ATTACHMENT = -5;
const STATUS_INVALID_SENDER = -5;
const STATUS_INVALID_RECIPIENT = -4;
const STATUS_INVALID_SUBJECT = -3;
const STATUS_FAILED_TO_SEND = -2;


/**
*
Expand Down Expand Up @@ -55,14 +71,14 @@ public function __construct(DB $db, array $config) {
* @return PDOStatement
*/
protected function getEmailAccountsStatement($account_id) {
$WHERE = '';
$WHERE = 'WHERE `survey_email_log`.`status` = 0 AND `survey_email_accounts`.status = 1';
if ($account_id) {
$WHERE .= ' WHERE account_id = ' . (int) $account_id . ' ';
$WHERE .= ' AND account_id = ' . (int) $account_id . ' ';
}

$query = "SELECT account_id, `from`, from_name, host, port, tls, username, password, auth_key
FROM survey_email_queue
LEFT JOIN survey_email_accounts ON survey_email_accounts.id = survey_email_queue.account_id
$query = "SELECT account_id, `session_id`, `from`, from_name, host, port, tls, username, password, auth_key
FROM survey_email_log
LEFT JOIN survey_email_accounts ON survey_email_accounts.id = survey_email_log.account_id
{$WHERE}
GROUP BY account_id
ORDER BY RAND()
Expand All @@ -76,7 +92,7 @@ protected function getEmailAccountsStatement($account_id) {
* @return PDOStatement
*/
protected function getEmailsStatement($account_id) {
$query = 'SELECT id, subject, message, recipient, created, meta FROM survey_email_queue WHERE account_id = ' . (int) $account_id;
$query = 'SELECT id, `session_id`, subject, message, recipient, created, meta FROM survey_email_log WHERE `survey_email_log`.`status` = 0 AND account_id = ' . (int) $account_id;
return $this->db->rquery($query);
}

Expand Down Expand Up @@ -129,6 +145,28 @@ protected function closeSMTPConnection($account_id) {
}
}

protected function logResult($session_id, $status_code, $result, $result_log = null) {
$this->db->exec('UPDATE `survey_email_log`
SET `status` = :status_code,
`sent` = NOW()
WHERE `session_id` = :session_id', array(
'session_id' => $session_id,
'status_code' => $status_code));
$this->db->exec('UPDATE `survey_unit_sessions`
SET `result` = :result,
`result_log` = :resultlog
WHERE `id` = :session_id', array(
'session_id' => $session_id,
'result' => $result,
'resultlog' => $result_log));
}

protected function deactivateAccount($account_id) {
$this->db->exec('UPDATE `survey_email_accounts`
SET `status` = -1
WHERE id = :id', array("id" => (int) $account_id));
}

protected function processQueue($account_id = null) {
$emailAccountsStatement = $this->getEmailAccountsStatement($account_id);
if ($emailAccountsStatement->rowCount() <= 0) {
Expand All @@ -137,8 +175,8 @@ protected function processQueue($account_id = null) {
}

while ($account = $emailAccountsStatement->fetch(PDO::FETCH_ASSOC)) {
if (!filter_var($account['from'], FILTER_VALIDATE_EMAIL) || in_array($account['account_id'], $this->skipAccounts)) {
$this->db->exec('DELETE FROM survey_email_queue WHERE account_id = ' . (int) $account['account_id']);
if (in_array($account['account_id'], $this->skipAccounts)) {
$this->deactivateAccount($account['account_id']);
continue;
}

Expand All @@ -149,8 +187,12 @@ protected function processQueue($account_id = null) {
$mailer = $this->getSMTPConnection($account);
$emailsStatement = $this->getEmailsStatement($account['account_id']);
while ($email = $emailsStatement->fetch(PDO::FETCH_ASSOC)) {
if (!filter_var($email['recipient'], FILTER_VALIDATE_EMAIL) || !$email['subject']) {
$this->registerFailure($email, $account);
if (!filter_var($email['recipient'], FILTER_VALIDATE_EMAIL)) {
$this->logResult($email['session_id'], self::STATUS_INVALID_RECIPIENT, "error_email_invalid_recipient");
continue;
}
if (!$email['subject']) {
$this->logResult($email['session_id'], self::STATUS_INVALID_SUBJECT, "error_email_invalid_subject");
continue;
}

Expand Down Expand Up @@ -185,22 +227,18 @@ protected function processQueue($account_id = null) {
// Send mail
try {
if (($sent = $mailer->send())) {
$this->db->exec("DELETE FROM survey_email_queue WHERE id = " . (int) $email['id']);
$query = "INSERT INTO `survey_email_log` (session_id, email_id, created, recipient, sent) VALUES (:session_id, :email_id, NOW(), :recipient, :sent)";
$this->db->exec($query, array(
'session_id' => $meta['session_id'],
'email_id' => $meta['email_id'],
'recipient' => $email['recipient'],
'sent' => (int) $sent,
));
$this->logResult($email['session_id'], self::STATUS_SENT, "email_sent");
$this->dbg("Send Success. \n {$debugInfo}");
} else {
$this->dbg($mailer->ErrorInfo);
$this->logResult($email['session_id'], self::STATUS_FAILED_TO_SEND, "error_email_not_sent", $mailer->ErrorInfo);
throw new Exception($mailer->ErrorInfo);
}
} catch (Exception $e) {
//formr_log_exception($e, 'EmailQueue ' . $debugInfo);
$this->dbg("Send Failure: " . $mailer->ErrorInfo . ".\n {$debugInfo}");
$this->registerFailure($email, $account);
$this->dbg($mailer->ErrorInfo);
$this->logResult($email['session_id'], self::STATUS_FAILED_TO_SEND, "error_email_not_sent", $mailer->ErrorInfo);
// reset php mailer object for this account if smtp sending failed. Probably some limits have been hit
$this->closeSMTPConnection($account['account_id']);
$mailer = $this->getSMTPConnection($account);
Expand Down
23 changes: 16 additions & 7 deletions application/Model/Branch.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,22 @@ public function exec() {
}
if (is_array($eval)) {
$eval = array_shift($eval);
$this->session_error = "Your R code is returning more than one result. Please fix your code, so it returns only true/false.";
}

// If execution returned a timestamp in the future, then branching evaluates to FALSE
if (($time = strtotime($eval)) && $time >= time()) {
$eval = false;
} elseif (($time = strtotime($eval)) && $time < time()) {
$eval = true;
if($eval === true || $eval === false) {
$result = $eval;
} else {
// If execution returned a timestamp in the future, then branching evaluates to FALSE
if (($time = strtotime($eval)) && $time >= time()) {
$eval = false;
} elseif (($time = strtotime($eval)) && $time < time()) {
$eval = true;
} else {
$result = (bool) $eval;
}
$this->session_error = "Your R code is not returning true/false. Please fix your code soon.";
}

$result = (bool) $eval;

if ($result && ($this->automatically_jump || !$this->called_by_cron)) {
$this->session_result = "skip_true";
Expand All @@ -169,6 +175,9 @@ public function exec() {
// the condition is false and it goes on
return $this->goOn();
} else {
$this->session_result = "waiting_deprecated";
$this->session_error = "formr is phasing out support for delayed skipbackwards/forwards. Please switch to a different approach soon.";
$this->logResult();
// we wait for the condition to turn true or false, depends.
return true;
}
Expand Down
Loading

0 comments on commit 39f6d74

Please sign in to comment.