';
}
private function echo_prologue() {
global $Conf, $Me;
if ($this->started)
return;
echo Ht::form(hoturl_post("mail"));
foreach (array("recipients", "subject", "emailBody", "cc", "replyto", "q", "t", "plimit", "newrev_since") as $x)
if (isset($this->qreq[$x]))
echo Ht::hidden($x, $this->qreq[$x]);
if (!$this->group)
echo Ht::hidden("ungroup", 1);
$recipients = (string) $this->qreq->recipients;
if ($this->sending) {
echo "
",
"
In the process of sending mail. Do not leave this page until this message disappears!
",
"",
"
Sent to: ", $this->recip->unparse(),
'
',
'
',
Ht::submit("go", "Prepare more mail"),
"
",
// This next is only displayed when Javascript is off
"
Sending mail. Do not leave this page until it finishes rendering!
",
"
";
} else {
if (isset($this->qreq->emailBody)
&& $Me->privChair
&& (strpos($this->qreq->emailBody, "%REVIEWS%")
|| strpos($this->qreq->emailBody, "%COMMENTS%"))) {
if (!$Conf->can_some_author_view_review())
echo "
Although these mails contain reviews and/or comments, authors can’t see reviews or comments on the site. (Change this setting)
\n";
else if (!$Conf->can_some_author_view_review(true))
echo "
Mails to users who have not completed their own reviews will not include reviews or comments. (Change the setting)
\n";
}
if (isset($this->qreq->emailBody)
&& $Me->privChair
&& substr($recipients, 0, 4) == "dec:") {
if (!$Conf->can_some_author_view_decision())
echo "
You appear to be sending an acceptance or rejection notification, but authors can’t see paper decisions on the site. (Change this setting)
\n";
}
echo "
",
"
In the process of preparing mail. You will be able to send the prepared mail once this message disappears.
",
"",
"
Verify that the mails look correct, then select “Send” to send the checked mails. ",
"Mailing to: ", $this->recip->unparse(),
'';
if (!preg_match('/\A(?:pc\z|pc:|all\z)/', $recipients)
&& $this->qreq->plimit
&& (string) $this->qreq->q !== "")
echo " Paper selection: ", htmlspecialchars($this->qreq->q);
echo "
";
$this->echo_actions(" fx");
// This next is only displayed when Javascript is off
echo '
Scroll down to send the prepared mail once the page finishes loading.
\n";
}
private function process_prep($prep, &$last_prep, $row) {
// Don't combine senders if anything differs. Also, don't combine
// mails from different papers, unless those mails are to the same
// person.
$mail_differs = !$prep->can_merge($last_prep);
$prep_to = $prep->to;
if (!$mail_differs)
$this->groupable = true;
if ($mail_differs || !$this->group) {
if (!$last_prep->fake)
$this->send_prep($last_prep);
$last_prep = $prep;
$last_prep->contacts = array();
$last_prep->to = array();
}
if ($prep->fake || isset($last_prep->contacts[$row->contactId]))
return false;
else {
$last_prep->contacts[$row->contactId] = $row->contactId;
$this->mrecipients[$row->contactId] = true;
$last_prep->add_recipients($prep_to);
return true;
}
}
private function run() {
global $Conf, $Me, $subjectPrefix, $mailer_options;
$subject = trim((string) $this->qreq->subject);
if (substr($subject, 0, strlen($subjectPrefix)) != $subjectPrefix)
$subject = $subjectPrefix . $subject;
$emailBody = $this->qreq->emailBody;
$template = array("subject" => $subject, "body" => $emailBody);
$rest = array("cc" => $this->qreq->cc, "reply-to" => $this->qreq->replyto, "no_error_quit" => true);
$rest = array_merge($rest, $mailer_options);
// test whether this mail is paper-sensitive
$mailer = new HotCRPMailer($Conf, $Me, null, $rest);
$prep = $mailer->make_preparation($template, $rest);
$paper_sensitive = preg_match('/%[A-Z0-9]+[(%]/', $prep->subject . $prep->body);
$q = $this->recip->query($paper_sensitive);
if (!$q)
return Conf::msg_error("Bad recipients value");
$result = $Conf->qe_raw($q);
if (!$result)
return;
$recipients = (string) $this->qreq->recipients;
if ($this->sending) {
$q = "recipients=?, cc=?, replyto=?, subject=?, emailBody=?, q=?, t=?";
$qv = [$recipients, $this->qreq->cc, $this->qreq->replyto, $this->qreq->subject, $this->qreq->emailBody, $this->qreq->q, $this->qreq->t];
if ($Conf->sversion >= 146 && !$Me->privChair)
$q .= ", fromNonChair=1";
if (($log_result = $Conf->qe_apply("insert into MailLog set $q", $qv)))
$this->mailid_text = " #" . $log_result->insert_id;
// Mail format matters
$Me->log_activity("Sending mail$this->mailid_text \"$subject\"");
} else
$rest["no_send"] = true;
$mailer = new HotCRPMailer($Conf);
$mailer->combination_type = $this->recip->combination_type($paper_sensitive);
$fake_prep = new HotCRPMailPreparation($Conf);
$fake_prep->fake = true;
$last_prep = $fake_prep;
$nrows_done = 0;
$nrows_left = edb_nrows($result);
$nwarnings = 0;
$preperrors = array();
$revinform = ($recipients == "newpcrev" ? array() : null);
while (($row = PaperInfo::fetch($result, $Me))) {
++$nrows_done;
$contact = new Contact($row);
$rest["newrev_since"] = $this->recip->newrev_since;
$mailer->reset($contact, $row, $rest);
$prep = $mailer->make_preparation($template, $rest);
if ($prep->errors) {
foreach ($prep->errors as $lcfield => $hline) {
$reqfield = ($lcfield == "reply-to" ? "replyto" : $lcfield);
Ht::error_at($reqfield);
$emsg = Mailer::$email_fields[$lcfield] . " destination isn’t a valid email list:
" . htmlspecialchars($hline) . "
Make sure email address are separated by commas; put names in \"quotes\" and email addresses in <angle brackets>.";
if (!isset($preperrors[$emsg]))
Conf::msg_error($emsg);
$preperrors[$emsg] = true;
}
} else if ($this->process_prep($prep, $last_prep, $row)) {
if ((!$Me->privChair || opt("chairHidePasswords"))
&& !@$last_prep->sensitive) {
$srest = array_merge($rest, array("sensitivity" => "display"));
$mailer->reset($contact, $row, $srest);
$last_prep->sensitive = $mailer->make_preparation($template, $srest);
}
}
if ($nwarnings != $mailer->nwarnings() || $nrows_done % 5 == 0)
$this->echo_mailinfo($nrows_done, $nrows_left);
if ($nwarnings != $mailer->nwarnings()) {
$this->echo_prologue();
$nwarnings = $mailer->nwarnings();
echo "
", join(" ", $mailer->warnings()), "
";
echo Ht::unstash_script("\$\$('mailwarnings').innerHTML = \$\$('foldmailwarn$nwarnings').innerHTML;");
}
if ($this->sending && $revinform !== null)
$revinform[] = "(paperId=$row->paperId and contactId=$row->contactId)";
}
$this->process_prep($fake_prep, $last_prep, (object) array("paperId" => -1));
$this->echo_mailinfo($nrows_done, $nrows_left);
if (!$this->started && !count($preperrors))
return Conf::msg_error("No users match “" . $this->recip->unparse() . "” for that search.");
else if (!$this->started)
return false;
else if (!$this->sending)
$this->echo_actions();
if ($revinform)
$Conf->qe_raw("update PaperReview set timeRequestNotified=" . time() . " where " . join(" or ", $revinform));
echo "";
echo Ht::unstash_script("fold('mail', null);");
$Conf->footer();
exit;
}
}
// Set subject and body if necessary
if (!isset($Qreq->subject))
$Qreq->subject = $null_mailer->expand($mailTemplates["genericmailtool"]["subject"]);
if (!isset($Qreq->emailBody))
$Qreq->emailBody = $null_mailer->expand($mailTemplates["genericmailtool"]["body"]);
if (substr($Qreq->subject, 0, strlen($subjectPrefix)) == $subjectPrefix)
$Qreq->subject = substr($Qreq->subject, strlen($subjectPrefix));
if (isset($Qreq->cc) && $Me->is_manager()) // XXX should only apply to papers you administer
$Qreq->cc = simplify_whitespace($Qreq->cc);
else if ($Conf->opt("emailCc"))
$Qreq->cc = $Conf->opt("emailCc");
else
$Qreq->cc = Text::user_email_to($Conf->site_contact());
if (isset($Qreq->replyto) && $Me->is_manager()) // XXX should only apply to papers you administer
$Qreq->replyto = simplify_whitespace($Qreq->replyto);
else
$Qreq->replyto = $Conf->opt("emailReplyTo", "");
// Check or send
if (!$Qreq->loadtmpl && !$Qreq->cancel && !$Qreq->psearch && !$recip->error && $Qreq->post_ok()) {
if ($Qreq->send)
MailSender::send($recip, $Qreq);
else if ($Qreq->check || $Qreq->group || $Qreq->ungroup)
MailSender::check($recip, $Qreq);
}
if (isset($Qreq->monreq)) {
$plist = new PaperList(new PaperSearch($Me, ["t" => "req", "q" => ""]), ["foldable" => true]);
$plist->set_table_id_class("foldpl", "pltable_full");
$ptext = $plist->table_html("reqrevs", ["header_links" => true, "list" => true]);
if ($plist->count == 0)
$Conf->infoMsg("You have not requested any external reviews. Return home");
else {
echo "
Requested reviews
\n\n", $ptext, '
';
if ($plist->has("need_review"))
echo "Some of your requested external reviewers have not completed their reviews. To send them an email reminder, check the text below and then select “Prepare mail.” You’ll get a chance to review the emails and select specific reviewers to remind.";
else
echo "All of your requested external reviewers have completed their reviews. Return home";
echo "
\n\n";
if ($Me->privChair) {
$result = $Conf->qe_raw("select mailId, subject, emailBody from MailLog where fromNonChair=0 order by mailId desc limit 200");
if (edb_nrows($result)) {
echo "