function run(Contact $user, $qreq, $ssel) { global $Conf, $Opt; $q = $Conf->paperQuery($user, ["paperId" => $ssel->selection(), "topics" => true, "options" => true]); $result = Dbl::qe_raw($q); $pj = []; $ps = new PaperStatus($user, ["forceShow" => true, "hide_docids" => true]); if ($this->iszip) { $this->zipdoc = new ZipDocument($Opt["downloadPrefix"] . "data.zip"); $ps->add_document_callback([$this, "document_callback"]); } while ($prow = PaperInfo::fetch($result, $user)) { if ($user->can_administer($prow, true)) { $pj[$prow->paperId] = $ps->paper_json($prow); } else { $pj[$prow->paperId] = (object) ["pid" => $prow->paperId, "error" => "You don’t have permission to administer this paper."]; if ($this->iszip) { $this->zipdoc->warnings[] = "#{$prow->paperId}: You don’t have permission to administer this paper."; } } } $pj = array_values($ssel->reorder($pj)); if (count($pj) == 1) { $pj = $pj[0]; $pj_filename = $Opt["downloadPrefix"] . "paper" . $ssel->selection_at(0) . "-data.json"; } else { $pj_filename = $Opt["downloadPrefix"] . "data.json"; } if ($this->iszip) { $this->zipdoc->add(json_encode($pj, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n", $pj_filename); $this->zipdoc->download(); } else { header("Content-Type: application/json"); header("Content-Disposition: attachment; filename=" . mime_quote_string($pj_filename)); echo json_encode($pj, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n"; } exit; }
/** * Send the status to authors, with anonymous reviews */ function notifyAction() { $db = $this->zmax_context->db; $paperTbl = new Paper(); $paperStatusTbl = new PaperStatus(); // Load the reviews template $this->view->setFile("review", "review4author.xml"); $this->view->setBlock("review", "review_mark", "review_marks"); $this->view->setBlock("review", "review_answer", "review_answers"); // Set the subject $subject = $this->texts->mail->subj_notification; if (isset($_REQUEST['id_paper'])) { // Mail for one paper $idPaper = $_REQUEST['id_paper']; $this->view->setFile("content", "showmessage.xml"); $this->view->setBlock("content", "WARNING_TEMPLATE", " "); $paper = $paperTbl->find($idPaper)->current(); if (!empty($paper->status)) { $paper->putInView($this->view); $this->view->reviews = $paper->showReviews($this->view); $statusRow = $paperStatusTbl->find($paper->status)->current(); $mail = new Mail(Mail::SOME_USER, $subject, $this->view->getScriptPaths()); $mail->setTo($paper->emailContact); $mail->setFormat(Mail::FORMAT_HTML); $mail->loadTemplate($this->lang, $statusRow->mailTemplate); // We know the paper, so we can instantiate the mail entities $this->view->setVar("mailTemplate", $mail->getTemplate()); $this->view->assign("mailTemplate", "mailTemplate"); $mail->setTemplate($this->view->mailTemplate); // Put in the view $mail->putInView($this->view); } else { $this->content = "Cannot send notification without a status<br/>"; } echo $this->view->render("layout"); return; } else { // Batch mail. Check that all papers have a status, // and that there are no missing reviews $this->view->setFile("content", "notify.xml"); $this->view->setBlock("content", "TEMPLATE", "TEMPLATES"); $res = $db->query("SELECT count(*) AS count FROM Paper p, PaperStatus s " . " WHERE p.status = s.id AND final_status != 'Y'"); $p = $res->fetch(Zend_Db::FETCH_OBJ); if ($p->count > 0) { $this->view->content = "Cannot send notification mails: some papers do not have a status"; echo $this->view->render("layout"); exit; } $qReview = "SELECT count(*) AS count FROM Review WHERE overall IS NULL"; $res = $db->query($qReview); $p = $res->fetch(Zend_Db::FETCH_OBJ); if ($p->count > 0) { $this->view->content = "Cannot send notification mails: missing reviews"; echo $this->view->render("layout"); exit; } // OK. Now give the list of the templates that will be used $i = 0; $paperStatusList = $paperStatusTbl->fetchAll("final_status = 'Y'"); $mail = new Mail(Mail::SOME_USER, "", $this->view->getScriptPaths()); foreach ($paperStatusList as $paperStatus) { $this->view->css_class = Config::CssCLass($i++); $paperStatus->putInView($this->view); $mail->loadTemplate($this->lang, $paperStatus->mailTemplate); $this->view->setVar("template_content-{$paperStatus->id}", $mail->getTemplate()); $this->view->assign("template_content", "template_content-{$paperStatus->id}"); $this->view->append("TEMPLATES", "TEMPLATE"); } // Send the notification mails. $messages = ""; if (isset($_REQUEST['confirmed']) or isset($_REQUEST['export'])) { PaperRow::$loadAbstracts = false; $papers = $paperTbl->fetchAll(); $mail = new Mail(Mail::SOME_USER, $subject, $this->view->getScriptPaths()); $mail->setFormat(Mail::FORMAT_HTML); $mail->setCopyToChair(true); foreach ($papers as $paper) { $statusRow = $paperStatusTbl->find($paper->status)->current(); $mail->setTo($paper->emailContact); $mail->loadTemplate($this->lang, $statusRow->mailTemplate); $paper->putInView($mail->getEngine()); $mail->getEngine()->reviews = $paper->showReviews($this->view); if (isset($_REQUEST['confirmed'])) { $mail->send(); } else { $messages .= $mail->getMessage() . "\n\n"; } } } } if (isset($_REQUEST['export'])) { header("Content-disposition: attachment; filename=notificationMails.txt"); header("Content-Type: application/force-download"); header("Content-Transfer-Encoding: text\n"); header("Content-Length: " . strlen($messages)); header("Pragma: no-cache"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public"); header("Expires: 0"); echo $messages; } else { echo $this->view->render("layout"); } }
function parse_json($pj, PaperStatus $ps) { if (is_object($pj)) { $pj = [$pj]; } $result = []; foreach ($pj as $docj) { if (is_object($docj)) { $ps->upload_document($docj, $this); $result[] = [$docj->docid, "" . (count($result) + 1)]; } else { $ps->set_option_error_html($this, "Option should be a document."); } } return $result; }
function update_paper($pj, $opj, $qreq, $action, $diffs) { global $Conf, $Me, $Opt, $OK, $Error, $prow; // XXX lock tables $ps = new PaperStatus($Me); $saved = $ps->save_paper_json($pj); if (!$saved && !$prow && count($qreq->_FILES)) { $ps->set_error_html("paper", "<strong>Your uploaded files were ignored.</strong>"); } if (!get($pj, "collaborators") && $Conf->setting("sub_collab")) { $field = $Conf->setting("sub_pcconf") ? "Other conflicts" : "Potential conflicts"; $ps->set_warning_html("collaborators", "Please enter the authors’ potential conflicts in the {$field} field. If none of the authors have potential conflicts, just enter “None”."); } $Error = $ps->error_fields(); if (!$saved) { $emsg = $ps->error_html(); Conf::msg_error("There were errors in saving your paper. Please fix them and try again." . (count($emsg) ? "<ul><li>" . join("</li><li>", $emsg) . "</li></ul>" : "")); return false; } // note differences in contacts $contacts = $ocontacts = []; foreach (get($pj, "contacts", []) as $v) { $contacts[] = strtolower(is_string($v) ? $v : $v->email); } if ($opj && get($opj, "contacts")) { foreach ($opj->contacts as $v) { $ocontacts[] = strtolower($v->email); } } sort($contacts); sort($ocontacts); if (json_encode($contacts) !== json_encode($ocontacts)) { $diffs["contacts"] = true; } // submit paper if no error so far $_REQUEST["paperId"] = $_GET["paperId"] = $qreq->paperId = $pj->pid; loadRows(); if ($action === "final") { $submitkey = "timeFinalSubmitted"; $storekey = "finalPaperStorageId"; } else { $submitkey = "timeSubmitted"; $storekey = "paperStorageId"; } $wasSubmitted = $opj && get($opj, "submitted"); if (get($pj, "submitted") || $Conf->can_pc_see_all_submissions()) { $Conf->update_papersub_setting(true); } if ($wasSubmitted != get($pj, "submitted")) { $diffs["submission"] = 1; } // confirmation message if ($action == "final") { $actiontext = "Updated final version of"; $template = "@submitfinalpaper"; } else { if (get($pj, "submitted") && !$wasSubmitted) { $actiontext = "Submitted"; $template = "@submitpaper"; } else { if (!$opj) { $actiontext = "Registered new"; $template = "@registerpaper"; } else { $actiontext = "Updated"; $template = "@updatepaper"; } } } // additional information $notes = array(); if ($action == "final") { if ($prow->{$submitkey} === null || $prow->{$submitkey} <= 0) { $notes[] = "The final version has not yet been submitted."; } $deadline = $Conf->printableTimeSetting("final_soft", "span"); if ($deadline != "N/A" && $Conf->deadlinesAfter("final_soft")) { $notes[] = "<strong>The deadline for submitting final versions was {$deadline}.</strong>"; } else { if ($deadline != "N/A") { $notes[] = "You have until {$deadline} to make further changes."; } } } else { if (get($pj, "submitted")) { $notes[] = "You will receive email when reviews are available."; } else { if ($prow->size == 0 && !opt("noPapers")) { $notes[] = "The submission has not yet been uploaded."; } else { if ($Conf->setting("sub_freeze") > 0) { $notes[] = "The submission has not yet been completed."; } else { $notes[] = "The submission is marked as not ready for review."; } } } $deadline = $Conf->printableTimeSetting("sub_update", "span"); if ($deadline != "N/A" && ($prow->timeSubmitted <= 0 || $Conf->setting("sub_freeze") <= 0)) { $notes[] = "Further updates are allowed until {$deadline}."; } $deadline = $Conf->printableTimeSetting("sub_sub", "span"); if ($deadline != "N/A" && $prow->timeSubmitted <= 0) { $notes[] = "<strong>If the submission " . ($Conf->setting("sub_freeze") > 0 ? "is not completed" : "is not ready for review") . " by {$deadline}, it will not be considered.</strong>"; } } $notes = join(" ", $notes); $webnotes = ""; if (count($ps->error_html())) { $webnotes .= " <ul><li>" . join("</li><li>", $ps->error_html()) . "</li></ul>"; } if (!count($diffs)) { $Conf->warnMsg("There were no changes to submission #{$prow->paperId}. " . $notes . $webnotes); return true; } // HTML confirmation if ($prow->{$submitkey} > 0) { $Conf->confirmMsg($actiontext . " submission #{$prow->paperId}. " . $notes . $webnotes); } else { $Conf->warnMsg($actiontext . " submission #{$prow->paperId}. " . $notes . $webnotes); } // mail confirmation to all contact authors if (!$Me->privChair || $qreq->doemail > 0) { $options = array("infoNames" => 1); if ($Me->privChair && $prow->conflictType < CONFLICT_AUTHOR) { $options["adminupdate"] = true; } if ($Me->privChair && isset($qreq->emailNote)) { $options["reason"] = $qreq->emailNote; } if ($notes !== "") { $options["notes"] = preg_replace(",</?(?:span.*?|strong)>,", "", $notes) . "\n\n"; } HotCRPMailer::send_contacts($template, $prow, $options); } // other mail confirmations if ($action == "final" && $OK && !count($Error)) { $prow->notify(WATCHTYPE_FINAL_SUBMIT, "final_submit_watch_callback", $Me); } $Me->log_activity($actiontext, $prow->paperId); return true; }
// Create initial administrator user. $Admin = Contact::create(array("email" => "chair@_.com", "name" => "Jane Chair", "password" => "testchair")); $Admin->save_roles(Contact::ROLE_ADMIN | Contact::ROLE_CHAIR | Contact::ROLE_PC, $Admin); // Load data. $json = json_decode(file_get_contents("{$ConfSitePATH}/test/db.json")); if (!$json) { die_hard("* test/testdb.json error: " . json_last_error_msg() . "\n"); } foreach ($json->contacts as $c) { $us = new UserStatus(); if (!$us->save($c)) { die_hard("* failed to create user {$c->email}\n"); } } foreach ($json->papers as $p) { $ps = new PaperStatus(null); if (!$ps->save_paper_json($p)) { die_hard("* failed to create paper {$p->title}:\n" . htmlspecialchars_decode(join("\n", $ps->error_html())) . "\n"); } } $assignset = new AssignmentSet($Admin, true); $assignset->parse($json->assignments_1, null, null); $assignset->execute(); class Xassert { public static $n = 0; public static $nsuccess = 0; public static $nerror = 0; public static $emap = array(E_ERROR => "PHP Fatal Error", E_WARNING => "PHP Warning", E_NOTICE => "PHP Notice", E_USER_ERROR => "PHP Error", E_USER_WARNING => "PHP Warning", E_USER_NOTICE => "PHP Notice"); } function xassert_error_handler($errno, $emsg, $file, $line)
/** * Show the list of papers with a given status */ function acceptedAction() { // There should be a 'status' parameter $paperTbl = new Paper(); $paperStatusTbl = new PaperStatus(); $status = $this->getRequest()->getParam("status"); $paperStatus = $paperStatusTbl->find($status)->current(); // Is the 'text' format required ? if (isset($_REQUEST['format']) and $_REQUEST['format'] == "text") { $textFormat = true; $this->view->setFile("content", "accepted_simple.txt"); } else { $textFormat = false; $this->view->setFile("content", "accepted_simple.xml"); } $this->view->setBlock("content", "PAPER", "PAPERS"); $paperStatus->putInView($this->view); $paperTbl = new Paper(); $no = 1; $papers = $paperTbl->fetchAll("status='{$status}'"); foreach ($papers as $paper) { $paper->putInView($this->view); $this->view->no = $no++; $this->view->append("PAPERS", "PAPER"); } //Function from MyReview V1. Allows assignment of accepted papers to sessions. /* AdmListAcceptedPapers ($_REQUEST['status'], $this->view, $this->db_v1, 1, $this->zmax_context->texts);*/ if ($textFormat) { Header("Content-type: text/plain"); $this->view->assign("result", "content"); echo utf8_decode($this->view->result); } else { echo $this->view->render("layout"); } }
<?php // test05.php -- HotCRP paper submission tests // HotCRP is Copyright (c) 2006-2016 Eddie Kohler and Regents of the UC // Distributed under an MIT-like license; see LICENSE global $ConfSitePATH; $ConfSitePATH = preg_replace(",/[^/]+/[^/]+\$,", "", __FILE__); require_once "{$ConfSitePATH}/test/setup.php"; $Conf->save_setting("sub_open", 1); $Conf->save_setting("sub_update", $Now + 100); $Conf->save_setting("sub_sub", $Now + 100); // load users $user_estrin = Contact::find_by_email("*****@*****.**"); // pc $user_nobody = new Contact(); $ps = new PaperStatus($user_estrin); $paper1a = $ps->paper_json(1); xassert_eqq($paper1a->title, "Scalable Timers for Soft State Protocols"); $ps->save_paper_json((object) ["id" => 1, "title" => "Scalable Timers? for Soft State Protocols"]); xassert(!$ps->nerrors); $paper1b = $ps->paper_json(1); xassert_eqq($paper1b->title, "Scalable Timers? for Soft State Protocols"); $paper1b->title = $paper1a->title; $paper1b->submitted_at = $paper1a->submitted_at; xassert_eqq(json_encode($paper1b), json_encode($paper1a)); $doc = Filer::file_upload_json(["error" => UPLOAD_ERR_OK, "name" => "amazing-sample.pdf", "tmp_name" => "{$ConfSitePATH}/src/sample.pdf", "tmp_name_safe" => true, "type" => "application/pdf"]); $ps->save_paper_json((object) ["id" => 1, "submission" => $doc]); xassert(!$ps->nerrors); $paper1c = $ps->paper_json(1); xassert_eqq($paper1c->submission->sha1, "2f1bccbf1e0e98004c01ef5b26eb9619f363e38e"); xassert_exit();
foreach ($jp as $j) { ++$index; if (isset($j->pid) && is_int($j->pid) && $j->pid > 0) { $prefix = "#{$j->pid}: "; } else { if (!isset($j->pid) && isset($j->id) && is_int($j->id) && $j->id > 0) { $prefix = "#{$j->id}: "; } else { if (!isset($j->pid) && !isset($j->id)) { $prefix = "new paper #{$index}: "; } else { fwrite(STDERR, "paper #{$index}: bad pid\n"); exit(1); } } } if (!$quiet) { fwrite(STDERR, $prefix); } $ps = new PaperStatus(null, ["no_email" => true, "disable_users" => $disable_users, "allow_error" => ["topics", "options"]]); $res = $ps->save_paper_json($j); if (!$quiet) { fwrite(STDERR, $res ? "saved\n" : "failed\n"); } foreach ($ps->error_html() as $msg) { fwrite(STDERR, $prefix . htmlspecialchars_decode($msg) . "\n"); } if (!$res) { exit(1); } }
xassert_eqq($te2_cdb->affiliation, "String"); // borrow from cdb $acct = $us->save((object) ["email" => "te@_.com"]); xassert(!!$acct); $te = user("te@_.com"); xassert_eqq($te->email, "te@_.com"); xassert_eqq($te->firstName, "Te"); xassert_eqq($te->lastName, "Thamrongrattanarit"); xassert_eqq($te->affiliation, "Brandeis University"); xassert_eqq($te->collaborators, "Computational Linguistics Magazine"); // create a user in cdb: create, then delete from local db $anna = "*****@*****.**"; xassert(!user($anna)); $acct = $us->save((object) ["email" => $anna, "first" => "Anna", "last" => "Akhmatova"]); xassert(!!$acct); Dbl::qe("delete from ContactInfo where email=?", $anna); save_password($anna, "aquablouse", true); xassert(!user($anna)); $user_estrin = user("*****@*****.**"); $user_floyd = user("*****@*****.**"); $user_van = user("*****@*****.**"); $ps = new PaperStatus(null); $ps->save_paper_json((object) ["id" => 1, "authors" => ["*****@*****.**", $user_estrin->email, $user_floyd->email, $user_van->email, $anna]]); $paper1 = $Conf->paperRow(1, $user_chair); $user_anna = user($anna); xassert(!!$user_anna); xassert($user_anna->act_author_view($paper1)); xassert($user_estrin->act_author_view($paper1)); xassert($user_floyd->act_author_view($paper1)); xassert($user_van->act_author_view($paper1)); xassert_exit();