function render($sv) { global $Conf, $ConfSitePATH; $rf = ReviewForm::get(); $fmap = array(); foreach ($rf->fmap as $fid => $f) { $fmap[$fid] = $f->has_options; } $samples = json_decode(file_get_contents("{$ConfSitePATH}/src/reviewformlibrary.json")); $req = array(); if ($sv->use_req()) { foreach ($rf->fmap as $fid => $f) { foreach (ReviewForm_SettingParser::$setting_prefixes as $fx) { if (isset($sv->req["{$fx}{$fid}"])) { $req["{$fx}{$fid}"] = $sv->req["{$fx}{$fid}"]; } } } } $Conf->footerHtml('<div id="review_form_caption_description" style="display:none">' . '<p>Enter an HTML description for the review form. Include any guidance you’d like to provide for reviewers. Note that complex HTML will not appear on offline review forms.</p></div>' . '<div id="review_form_caption_options" style="display:none">' . '<p>Enter one option per line, numbered starting from 1 (higher numbers are better). For example:</p> <pre class="entryexample dark">1. Reject 2. Weak reject 3. Weak accept 4. Accept</pre> <p>Or use consecutive capital letters (lower letters are better).</p> <p>Normally scores are mandatory: a review with a missing score cannot be submitted. Add a line “<code>No entry</code>” to make the score optional.</p></div>'); $Conf->footerScript("review_form_settings(" . json_encode($fmap) . "," . json_encode($rf->unparse_full_json()) . "," . json_encode($samples) . "," . json_encode($sv->error_fields()) . "," . json_encode($req) . ")"); echo Ht::hidden("has_review_form", 1), "<div id=\"reviewform_removedcontainer\"></div>", "<div id=\"reviewform_container\"></div>", Ht::button("Add score field", array("onclick" => "review_form_settings.add(1)")), "<span class='sep'></span>", Ht::button("Add text field", array("onclick" => "review_form_settings.add(0)")); }
private function echo_prologue() { global $Conf, $Me; if ($this->started) { return; } echo Ht::form_div(hoturl_post("mail")); foreach (array("recipients", "subject", "emailBody", "cc", "replyto", "q", "t", "plimit", "newrev_since") as $x) { if (isset($_REQUEST[$x])) { echo Ht::hidden($x, $_REQUEST[$x]); } } if (!$this->group) { echo Ht::hidden("ungroup", 1); } $recipients = defval($_REQUEST, "recipients", ""); if ($this->sending) { echo "<div id='foldmail' class='foldc fold2c'>", "<div class='fn fx2 merror'>In the process of sending mail. <strong>Do not leave this page until this message disappears!</strong><br /><span id='mailcount'></span></div>", "<div id='mailwarnings'></div>", "<span id='mailinfo'></span>", "<div class='fx'><div class='confirm'>Sent mail as follows.</div>", "<div class='aa'>", Ht::submit("go", "Prepare more mail"), "</div></div>", "<div class='fn2 warning'>Sending mail. <strong>Do not leave this page until it finishes rendering!</strong></div>", "</div>"; } else { if (isset($_REQUEST["emailBody"]) && $Me->privChair && (strpos($_REQUEST["emailBody"], "%REVIEWS%") || strpos($_REQUEST["emailBody"], "%COMMENTS%"))) { if (!$Conf->timeAuthorViewReviews()) { echo "<div class='warning'>Although these mails contain reviews and/or comments, authors can’t see reviews or comments on the site. (<a href='", hoturl("settings", "group=dec"), "' class='nw'>Change this setting</a>)</div>\n"; } else { if (!$Conf->timeAuthorViewReviews(true)) { echo "<div class='warning'>Mails to users who have not completed their own reviews will not include reviews or comments. (<a href='", hoturl("settings", "group=dec"), "' class='nw'>Change the setting</a>)</div>\n"; } } } if (isset($_REQUEST["emailBody"]) && $Me->privChair && substr($recipients, 0, 4) == "dec:") { if (!$Conf->timeAuthorViewDecision()) { echo "<div class='warning'>You appear to be sending an acceptance or rejection notification, but authors can’t see paper decisions on the site. (<a href='", hoturl("settings", "group=dec"), "' class='nw'>Change this setting</a>)</div>\n"; } } echo "<div id='foldmail' class='foldc fold2c'>", "<div class='fn fx2 warning'>In the process of preparing mail. You will be able to send the prepared mail once this message disappears.<br /><span id='mailcount'></span></div>", "<div id='mailwarnings'></div>", "<div class='fx info'>Verify that the mails look correct, then select “Send” to send the checked mails.<br />", "Mailing to: ", $this->recip->unparse(), "<span id='mailinfo'></span>"; if (!preg_match('/\\A(?:pc\\z|pc:|all\\z)/', $recipients) && defval($_REQUEST, "plimit") && $_REQUEST["q"] !== "") { echo "<br />Paper selection: ", htmlspecialchars($_REQUEST["q"]); } echo "</div>"; $this->echo_actions(" fx"); // This next is only displayed when Javascript is off echo '<div class="fn2 warning">Scroll down to send the prepared mail once the page finishes loading.</div>', "</div>\n"; } $Conf->echoScript("fold('mail',0,2)"); $this->started = true; }
function goPaperForm($baseUrl = null, $args = array()) { global $Conf, $Me; if ($Me->is_empty()) { return ""; } $list = SessionList::active(); $x = Ht::form_div(hoturl($baseUrl ?: "paper", array("ls" => null)), array("method" => "get", "class" => "gopaper" . ($list ? " has_hotcrp_list" : ""), "data-hotcrp-list" => $list ? $list->listno : null)); if ($baseUrl == "profile") { $x .= Ht::entry("u", "(User)", array("id" => "quicksearchq", "size" => 10, "placeholder" => "(User)")); } else { $x .= Ht::entry("p", "(All)", array("id" => "quicksearchq", "size" => 10, "placeholder" => "(All)", "class" => "hotcrp_searchbox")); } foreach ($args as $what => $val) { $x .= Ht::hidden($what, $val); } $x .= " " . Ht::submit("Search") . "</div></form>"; return $x; }
public function render_entry($name, $js = []) { $v = $this->curv($name); $t = ""; if ($si = $this->si($name)) { if ($si->size) { $js["size"] = $si->size; } if ($si->placeholder) { $js["placeholder"] = $si->placeholder; } if ($si->is_date()) { $v = $this->si_render_date_value($v, $si); } else { if ($si->type === "grace") { $v = $this->si_render_grace_value($v, $si); } } if ($si->parser) { $t = Ht::hidden("has_{$name}", 1); } } return Ht::entry($name, $v, $this->sjs($name, $js)) . $t; }
function echo_grade_entry($ge) { global $User, $Me, $Info; $key = $ge->name; $grade = $Info->current_grade_entry($key); if (!$Info->can_see_grades || $User == $Me && $grade === null && $ge->is_extra) { return; } $title = isset($ge->title) ? $ge->title : $key; $autograde = $Info->current_grade_entry($key, "autograde"); $Notes = $Info->current_info(); $class = "grader61" . ($ge->no_total ? "" : " gradepart"); if ($User == $Me) { $value = '<span class="' . $class . '" data-pa-grade="' . $ge->name . '">' . htmlspecialchars(+$grade) . '</span>'; if ($ge->max && !$ge->hide_max) { $value .= ' <span class="grademax61">of ' . htmlspecialchars($ge->max) . '</span>'; } } else { $value = '<span class="gradeholder61">' . Ht::entry($key, $grade, array("onchange" => "jQuery(this).closest('form').submit()", "class" => $class)) . '</span>'; if ($ge->max) { $value .= ' <span class="grademax61" style="display:inline-block;min-width:3.5em">of ' . htmlspecialchars($ge->max) . '</span>'; } $value .= " " . Ht::submit("Save", array("tabindex" => 1)); $value .= ' <span class="ajaxsave61"></span>'; if ($autograde && $autograde !== $grade) { $value .= ' <span class="autograde61">autograde is ' . htmlspecialchars($autograde) . '</span>'; } } $remarks = array(); if ($grade !== null && $ge->max && $grade > $ge->max && $User != $Me) { $remarks[] = array(true, "Grade is above max"); } if ($User != $Me) { echo Ht::form($Info->hoturl_post("pset", ["setgrade" => 1]), array("onsubmit" => "return gradesubmit61(this)")), "<div class=\"f-contain\">", Ht::hidden("old;" . $key, $grade); } ContactView::echo_group($title, $value, $remarks, array("nowrap" => true)); if ($User != $Me) { echo "</div></form>"; } }
function echo_linenote_entry_prototype() { echo '<tr class="diffl61 gw iscomment61"', ' data-pa-savednote="">', '<td colspan="2" class="difflnoteborder61"></td>', '<td class="difflnote61"><div class="diffnoteholder61" style="display:none">', Ht::form($this->hoturl_post("pset", array("savelinenote" => 1)), array("onsubmit" => "return savelinenote61(this)")), '<div class="f-contain">', Ht::hidden("file", ""), Ht::hidden("line", ""), Ht::hidden("iscomment", "", array("class" => "iscomment")), '<textarea class="diffnoteentry61" name="note"></textarea>', '<div class="aab aabr difflnoteaa61">', '<div class="aabut">', Ht::submit("Save comment"), '</div><div class="aabut">'; if ($this->user_can_see_grades) { echo Ht::hidden("iscomment", 1); } else { echo Ht::checkbox("iscomment", 1), ' ', Ht::label("Show immediately"); } echo '</div></div></div></form></div></td></tr>'; }
if (!$Me->can_view_run($Pset, $Runner, $RunMany ? null : $User)) { if (!$Me->isPC && !$Runner->visible) { quit("Command reserved for TFs"); } else { if ($Runner->disabled) { quit("Command disabled"); } else { quit("Can’t run command right now"); } } } } // magic multi-runner if ($Me->isPC && get($_GET, "runmany") && check_post()) { $Conf->header(htmlspecialchars($Pset->title . " " . $Runner->title), "home"); echo '<h2 id="runmany61_who"></h2>', Ht::form(hoturl_post("run")), '<div class="f-contain">', Ht::hidden("u", ""), Ht::hidden("pset", $Pset->urlkey), Ht::hidden("run", $Runner->name, ["id" => "runmany61", "data-pa-runclass" => $Runner->runclass_argument()]), '</div></form>'; echo '<div id="run61out_' . $Runner->runclass . '">', '<div class="run61" id="run61_' . $Runner->runclass . '">', '<div class="run61in"><pre class="run61pre"></pre></div>', '</div>', '</div>'; echo '<div id="runmany61_users">', htmlspecialchars($_GET["runmany"]), '</div>'; Ht::stash_script('runmany61()'); echo '<div class="clear"></div>', "\n"; $Conf->footer(); exit; } // repo $Info = user_pset_info(); $Repo = $Info->repo; $RecentCommits = $Info->recent_commits(); // can we run this? if (!$Repo) { quit("No repository to run"); } else {
function reviewTable($prow, $rrows, $crows, $rrow, $mode, $proposals = null) { global $Conf, $Me; $subrev = array(); $nonsubrev = array(); $foundRrow = $foundMyReview = $notShown = 0; $conflictType = $Me->view_conflict_type($prow); $allow_admin = $Me->allow_administer($prow); $admin = $Me->can_administer($prow); $hideUnviewable = $conflictType > 0 && !$admin || !$Me->act_pc($prow) && !$Conf->setting("extrev_view"); $show_colors = $Me->can_view_reviewer_tags($prow); $tagger = $show_colors ? new Tagger($Me) : null; $xsep = ' <span class="barsep">·</span> '; $want_scores = $mode !== "assign" && $mode !== "edit" && $mode !== "re"; $want_requested_by = false; $want_retract = false; $pcm = pcMembers(); $score_header = array(); // actual rows foreach ($rrows as $rr) { $highlight = $rrow && $rr->reviewId == $rrow->reviewId; $foundRrow += $highlight; if ($Me->is_my_review($rr)) { $foundMyReview++; } $canView = $Me->can_view_review($prow, $rr, null); // skip unsubmitted reviews if (!$canView && $hideUnviewable) { if ($rr->reviewNeedsSubmit == 1 && $rr->reviewModified) { $notShown++; } continue; } $t = ""; $tclass = $rrow && $highlight ? "hilite" : ""; // review ID $id = "Review"; if ($rr->reviewSubmitted) { $id .= " #" . $prow->paperId . unparseReviewOrdinal($rr->reviewOrdinal); } else { if ($rr->reviewType == REVIEW_SECONDARY && $rr->reviewNeedsSubmit <= 0) { $id .= " (delegated)"; } else { if ($rr->reviewModified > 0) { $id .= " (in progress)"; } else { $id .= " (not started)"; } } } $rlink = unparseReviewOrdinal($rr); if ($rrow && $rrow->reviewId == $rr->reviewId) { if ($Me->contactId == $rr->contactId && !$rr->reviewSubmitted) { $id = "Your {$id}"; } $t .= '<td><a href="' . hoturl("review", "p={$prow->paperId}&r={$rlink}") . '" class="q"><b>' . $id . '</b></a></td>'; } else { if (!$canView) { $t .= "<td>{$id}</td>"; } else { if ($rrow || $rr->reviewModified <= 0 || ($mode === "re" || $mode === "assign") && $Me->can_review($prow, $rr)) { $t .= '<td><a href="' . hoturl("review", "p={$prow->paperId}&r={$rlink}") . '">' . $id . '</a></td>'; } else { if (Navigation::page() !== "paper") { $t .= '<td><a href="' . hoturl("paper", "p={$prow->paperId}#r{$rlink}") . '">' . $id . '</a></td>'; } else { $t .= '<td><a href="#r' . $rlink . '">' . $id . '</a></td>'; } } } } // primary/secondary glyph if ($conflictType > 0 && !$admin) { $rtype = ""; } else { if ($rr->reviewType > 0) { $rtype = review_type_icon($rr->reviewType); if ($admin && $mode === "assign") { $rtype .= _review_table_round_selector($prow, $rr); } else { if ($rr->reviewRound > 0 && $Me->can_view_review_round($prow, $rr)) { $rtype .= ' <span class="revround" title="Review round">' . htmlspecialchars($Conf->round_name($rr->reviewRound, true)) . "</span>"; } } } else { $rtype = ""; } } // reviewer identity $showtoken = $rr->reviewToken && $Me->can_review($prow, $rr); if (!$Me->can_view_review_identity($prow, $rr, null)) { $t .= $rtype ? "<td>{$rtype}</td>" : '<td class="empty"></td>'; } else { if (!$showtoken || !Contact::is_anonymous_email($rr->email)) { $n = $Me->name_html_for($rr); } else { $n = "[Token " . encode_token((int) $rr->reviewToken) . "]"; } if ($allow_admin) { $n .= _review_table_actas($rr); } $t .= '<td class="rl"><span class="taghl">' . $n . '</span>' . ($rtype ? " {$rtype}" : "") . "</td>"; if ($show_colors && (get($rr, "contactRoles") || get($rr, "contactTags"))) { $tags = Contact::roles_all_contact_tags(get($rr, "contactRoles"), get($rr, "contactTags")); $tags = Tagger::strip_nonviewable($tags, $Me); if ($tags && ($color = TagInfo::color_classes($tags))) { $tclass = $color; } } } // requester if ($mode === "assign") { if (($conflictType <= 0 || $admin) && $rr->reviewType == REVIEW_EXTERNAL && !$showtoken) { $t .= '<td style="font-size:smaller">'; if ($rr->requestedBy == $Me->contactId) { $t .= "you"; } else { if ($u = get($pcm, $rr->requestedBy)) { $t .= $Me->reviewer_html_for($rr->requestedBy); } else { $t .= Text::user_html([$rr->reqFirstName, $rr->reqLastName, $rr->reqEmail]); } } $t .= '</td>'; $want_requested_by = true; } else { $t .= '<td class="empty"></td>'; } } // actions if ($mode === "assign" && ($conflictType <= 0 || $admin) && $rr->reviewType == REVIEW_EXTERNAL && $rr->reviewModified <= 0 && ($rr->requestedBy == $Me->contactId || $admin)) { $t .= '<td>' . _retract_review_request_form($prow, $rr) . '</td>'; } // scores $scores = array(); if ($want_scores && $canView) { $view_score = $Me->view_score_bound($prow, $rr); $rf = ReviewForm::get(); foreach ($rf->forder as $fid => $f) { if (!$f->has_options || $f->view_score <= $view_score || $f->round_mask && !$f->is_round_visible($rr)) { /* do nothing */ } else { if ($rr->{$fid}) { if (!get($score_header, $fid)) { $score_header[$fid] = "<th>" . $f->web_abbreviation() . "</th>"; } $scores[$fid] = '<td class="revscore" data-rf="' . $f->uid . '">' . $f->unparse_value($rr->{$fid}, ReviewField::VALUE_SC) . '</td>'; } else { if (get($score_header, $fid) === null) { $score_header[$fid] = ""; } } } } } // affix if (!$rr->reviewSubmitted) { $nonsubrev[] = array($tclass, $t, $scores); } else { $subrev[] = array($tclass, $t, $scores); } } // proposed review rows if ($proposals) { foreach ($proposals as $rr) { $t = ""; // review ID $t = "<td>Proposed review</td>"; // reviewer identity $t .= "<td>" . Text::user_html($rr); if ($allow_admin) { $t .= _review_table_actas($rr); } $t .= "</td>"; // requester if ($conflictType <= 0 || $admin) { $t .= '<td style="font-size:smaller">'; if ($rr->requestedBy == $Me->contactId) { $t .= "you"; } else { if ($u = get($pcm, $rr->requestedBy)) { $t .= $Me->reviewer_html_for($rr->requestedBy); } else { $t .= Text::user_html([$rr->reqFirstName, $rr->reqLastName, $rr->reqEmail]); } } $t .= '</td>'; $want_requested_by = true; } $t .= '<td>'; if ($admin) { $t .= '<small>' . Ht::form(hoturl_post("assign", "p={$prow->paperId}")) . '<div class="inline">' . Ht::hidden("name", $rr->name) . Ht::hidden("email", $rr->email) . Ht::hidden("reason", $rr->reason); if ($rr->reviewRound !== null) { if ($rr->reviewRound == 0) { $rname = "unnamed"; } else { $rname = $Conf->round_name($rr->reviewRound); } if ($rname) { $t .= Ht::hidden("round", $rname); } } $t .= Ht::submit("add", "Approve review", array("style" => "font-size:smaller")) . ' ' . Ht::submit("deny", "Deny request", array("style" => "font-size:smaller")) . '</div></form>'; } else { if ($rr->reqEmail === $Me->email) { $t .= _retract_review_request_form($prow, $rr); } } $t .= '</td>'; // affix $nonsubrev[] = array("", $t); } } // unfinished review notification $notetxt = ""; if ($conflictType >= CONFLICT_AUTHOR && !$admin && $notShown && $Me->can_view_review($prow, null, null)) { if ($notShown == 1) { $t = "1 review remains outstanding."; } else { $t = "{$notShown} reviews remain outstanding."; } $t .= '<br /><span class="hint">You will be emailed if new reviews are submitted or existing reviews are changed.</span>'; $notetxt = '<div class="revnotes">' . $t . "</div>"; } // completion if (count($nonsubrev) + count($subrev)) { if ($want_requested_by) { array_unshift($score_header, '<th class="revsl">Requester</th>'); } $score_header_text = join("", $score_header); $t = "<table class=\"reviewers"; if ($score_header_text) { $t .= " reviewers_scores"; } if ($list = SessionList::active()) { $t .= " has_hotcrp_list\" data-hotcrp-list=\"" . $list->listno; } $t .= "\">\n"; if ($score_header_text) { $t .= '<tr><td class="empty" colspan="2"></td>' . $score_header_text . "</tr>\n"; } foreach (array_merge($subrev, $nonsubrev) as $r) { $t .= '<tr class="rl' . ($r[0] ? " {$r['0']}" : "") . '">' . $r[1]; if (get($r, 2)) { foreach ($score_header as $fid => $header_needed) { if ($header_needed) { $x = get($r[2], $fid); $t .= $x ?: "<td class=\"revscore rs_{$fid}\"></td>"; } } } else { if (count($score_header)) { $t .= '<td colspan="' . count($score_header) . '"></td>'; } } $t .= "</tr>\n"; } if ($score_header_text) { $Conf->footerScript("review_form.score_tooltips(\$(\"table.reviewers_scores\"))", "score_tooltips"); } return $t . "</table>\n" . $notetxt; } else { return $notetxt; } }
function render($sv) { global $Conf, $Opt; echo "Can <b>authors see reviews and author-visible comments</b> for their papers?<br />"; if ($Conf->setting("resp_active")) { $no_text = "No, unless responses are open"; } else { $no_text = "No"; } if (!$Conf->setting("au_seerev", 0) && $Conf->timeAuthorViewReviews()) { $no_text .= '<div class="hint">Authors are currently able to see reviews since responses are open.</div>'; } $opts = array(Conf::AUSEEREV_NO => $no_text, Conf::AUSEEREV_YES => "Yes"); if ($sv->newv("au_seerev") == Conf::AUSEEREV_UNLESSINCOMPLETE && !get($Opt, "allow_auseerev_unlessincomplete")) { $Conf->save_setting("opt.allow_auseerev_unlessincomplete", 1); } if (get($Opt, "allow_auseerev_unlessincomplete")) { $opts[Conf::AUSEEREV_UNLESSINCOMPLETE] = "Yes, after completing any assigned reviews for other papers"; } $opts[Conf::AUSEEREV_TAGS] = "Yes, for papers with any of these tags: " . $sv->render_entry("tag_au_seerev", ["onfocus" => "\$('#au_seerev_" . Conf::AUSEEREV_TAGS . "').click()"]); $sv->echo_radio_table("au_seerev", $opts); echo Ht::hidden("has_tag_au_seerev", 1); // Authors' response echo '<div class="g"></div><table id="foldauresp" class="fold2o">'; $sv->echo_checkbox_row('resp_active', "<b>Collect authors’ responses to the reviews<span class='fx2'>:</span></b>", "void fold('auresp',!this.checked,2)"); echo '<tr class="fx2"><td></td><td><div id="auresparea">', Ht::hidden("has_resp_rounds", 1); // Response rounds if ($sv->use_req()) { $rrounds = array(1); for ($i = 1; isset($sv->req["resp_roundname_{$i}"]); ++$i) { $rrounds[$i] = $sv->req["resp_roundname_{$i}"]; } } else { $rrounds = $Conf->resp_round_list(); } $rrounds["n"] = ""; foreach ($rrounds as $i => $rname) { $isuf = $i ? "_{$i}" : ""; $rname_si = $sv->si("resp_roundname{$isuf}"); if (!$i) { $rname = $rname == "1" ? "none" : $rname; $rname_si->placeholder = "none"; } $sv->set_oldv("resp_roundname{$isuf}", $rname); echo '<div id="response', $isuf; if ($i) { echo '" style="padding-top:1em'; } if ($i === "n") { echo ';display:none'; } echo '"><table class="secondary-settings"><tbody>'; $sv->echo_entry_row("resp_roundname{$isuf}", "Response name"); if ($sv->curv("resp_open{$isuf}") === 1 && ($x = $sv->curv("resp_done{$isuf}"))) { $Conf->settings["resp_open{$isuf}"] = $x - 7 * 86400; } $sv->echo_entry_row("resp_open{$isuf}", "Start time"); $sv->echo_entry_row("resp_done{$isuf}", "Hard deadline"); $sv->echo_entry_row("resp_grace{$isuf}", "Grace period"); $sv->echo_entry_row("resp_words{$isuf}", "Word limit", $i ? null : "This is a soft limit: authors may submit longer responses. 0 means no limit."); echo '</tbody></table><div style="padding-top:4px">'; $sv->echo_message_minor("msg.resp_instrux{$isuf}", "Instructions"); echo '</div></div>', "\n"; } echo '</div><div style="padding-top:1em">', '<button type="button" onclick="settings_add_resp_round()">Add response round</button>', '</div></td></tr></table>'; $Conf->footerScript("fold('auresp',!\$\$('cbresp_active').checked,2)"); echo "<div class='g'></div>\n<hr class='hr' />\n", "Who can see paper <b>decisions</b> (accept/reject)?<br />\n"; $sv->echo_radio_table("seedec", array(Conf::SEEDEC_ADMIN => "Only administrators", Conf::SEEDEC_NCREV => "Reviewers and non-conflicted PC members", Conf::SEEDEC_REV => "Reviewers and <em>all</em> PC members", Conf::SEEDEC_ALL => "<b>Authors</b>, reviewers, and all PC members (and reviewers can see accepted papers’ author lists)")); echo "<div class='g'></div>\n"; echo "<table>\n"; $decs = $Conf->decision_map(); krsort($decs); // count papers per decision $decs_pcount = array(); $result = $Conf->qe("select outcome, count(*) from Paper where timeSubmitted>0 group by outcome"); while ($row = edb_row($result)) { $decs_pcount[$row[0]] = $row[1]; } // real decisions $n_real_decs = 0; foreach ($decs as $k => $v) { $n_real_decs += $k ? 1 : 0; } $caption = "<td class='lcaption' rowspan='{$n_real_decs}'>Current decision types</td>"; foreach ($decs as $k => $v) { if ($k) { if ($sv->use_req()) { $v = defval($sv->req, "dec{$k}", $v); } echo "<tr>", $caption, '<td class="lentry nw">', Ht::entry("dec{$k}", $v, array("size" => 35)), " ", $k > 0 ? "Accept class" : "Reject class", "</td>"; if (isset($decs_pcount[$k]) && $decs_pcount[$k]) { echo '<td class="lentry nw">', plural($decs_pcount[$k], "paper"), "</td>"; } echo "</tr>\n"; $caption = ""; } } // new decision $v = ""; $vclass = 1; if ($sv->use_req()) { $v = defval($sv->req, "decn", $v); $vclass = defval($sv->req, "dtypn", $vclass); } echo '<tr><td class="lcaption">', $sv->label("decn", "New decision type"), '<br /></td>', '<td class="lentry nw">', Ht::hidden("has_decisions", 1), Ht::entry("decn", $v, array("id" => "decn", "size" => 35)), ' ', Ht::select("dtypn", array(1 => "Accept class", -1 => "Reject class"), $vclass), "<br /><small>Examples: “Accepted as short paper”, “Early reject”</small>", "</td></tr>"; if ($sv->has_error("decn")) { echo '<tr><td></td><td class="lentry nw">', Ht::checkbox("decn_confirm", 1, false), ' <span class="error">', Ht::label("Confirm"), "</span></td></tr>"; } echo "</table>\n"; // Final versions echo "<h3 class=\"settings g\">Final versions</h3>\n"; echo '<table id="foldfinal" class="fold2o">'; $sv->echo_checkbox_row('final_open', '<b>Collect final versions of accepted papers<span class="fx">:</span></b>', "void fold('final',!this.checked,2)"); echo '<tr class="fx2"><td></td><td><table class="secondary-settings"><tbody>'; $sv->echo_entry_row("final_soft", "Deadline"); $sv->echo_entry_row("final_done", "Hard deadline"); $sv->echo_entry_row("final_grace", "Grace period"); echo "</tbody></table><div class='g'></div>"; $sv->echo_message_minor("msg.finalsubmit", "Instructions"); echo "<div class='g'></div>", "<small>To collect <em>multiple</em> final versions, such as one in 9pt and one in 11pt, add “Alternate final version” options via <a href='", hoturl("settings", "group=opt"), "'>Settings > Submission options</a>.</small>", "</td></tr></table>\n\n"; $Conf->footerScript("fold('final',!\$\$('cbfinal_open').checked)"); }
function show($prow, $rrows, $rrow, &$options) { global $Conf, $Opt, $Me, $useRequest; if (!$options) { $options = array(); } $editmode = defval($options, "edit", false); $reviewOrdinal = unparseReviewOrdinal($rrow); self::check_review_author_seen($prow, $rrow, $Me); if (!$editmode) { $rj = $this->unparse_review_json($prow, $rrow, $Me); if (get($options, "editmessage")) { $rj->message_html = $options["editmessage"]; } $Conf->echoScript("review_form.add_review(" . json_encode($rj) . ");\n"); return; } // From here on, edit mode. $forceShow = $Me->is_admin_force() ? "&forceShow=1" : ""; $reviewLinkArgs = "p={$prow->paperId}" . ($rrow ? "&r={$reviewOrdinal}" : "") . "&m=re" . $forceShow; $reviewPostLink = hoturl_post("review", $reviewLinkArgs); $reviewDownloadLink = hoturl("review", $reviewLinkArgs . "&downloadForm=1" . $forceShow); echo Ht::form($reviewPostLink, array("class" => "revcard")), '<div class="aahc">', Ht::hidden_default_submit("default", ""); if ($rrow) { echo Ht::hidden("version", defval($rrow, "reviewEditVersion", 0) + 1); } echo '<div class="revcard" id="r', $reviewOrdinal, '"><div class="revcard_head">'; // Links if ($rrow) { echo '<div class="floatright"><a href="' . hoturl("review", "r={$reviewOrdinal}&text=1" . $forceShow) . '" class="xx">', Ht::img("txt.png", "[Text]", "b"), " <u>Plain text</u></a>", "</div>"; } echo "<h3>"; if ($rrow) { echo '<a href="', hoturl("review", "r={$reviewOrdinal}" . $forceShow), '" class="q">Edit Review'; if ($rrow->reviewSubmitted) { echo " #", $reviewOrdinal; } echo "</a>"; } else { echo "Write Review"; } echo "</h3>\n"; $open = $sep = " <span class='revinfo'>"; $xsep = " <span class='barsep'>·</span> "; $showtoken = $rrow && $Me->review_token_cid($prow, $rrow); $type = ""; if ($rrow && $Me->can_view_review_round($prow, $rrow, null)) { $type = review_type_icon($rrow->reviewType); if ($rrow->reviewRound > 0 && $Me->can_view_review_round($prow, $rrow, null)) { $type .= " <span class=\"revround\" title=\"Review round\">" . htmlspecialchars($Conf->round_name($rrow->reviewRound, true)) . "</span>"; } } if ($rrow && $Me->can_view_review_identity($prow, $rrow, null) && (!$showtoken || !Contact::is_anonymous_email($rrow->email))) { echo $sep, $rrow->reviewBlind ? "[" : "", Text::user_html($rrow), $rrow->reviewBlind ? "]" : "", " ", $type; $sep = $xsep; } else { if ($type) { echo $sep, $type; $sep = $xsep; } } if ($showtoken) { echo $sep, "Review token ", encode_token((int) $rrow->reviewToken); $sep = $xsep; } if ($rrow && $rrow->reviewModified > 0 && $Me->can_view_review_time($prow, $rrow)) { echo $sep, "Updated ", $Conf->printableTime($rrow->reviewModified); $sep = $xsep; } if ($sep != $open) { echo "</span>\n"; } if (defval($options, "editmessage")) { echo "<div class='hint'>", defval($options, "editmessage"), "</div>\n"; } // download? echo '<hr class="c" />'; echo "<table class='revoff'><tr>\n <td><strong>Offline reviewing</strong> </td>\n <td>Upload form: <input type='file' name='uploadedFile' accept='text/plain' size='30' />\n ", Ht::submit("uploadForm", "Go"), "</td>\n </tr><tr>\n <td></td>\n <td><a href='{$reviewDownloadLink}'>Download form</a>\n <span class='barsep'>·</span>\n <span class='hint'><strong>Tip:</strong> Use <a href='", hoturl("search"), "'>Search</a> or <a href='", hoturl("offline"), "'>Offline reviewing</a> to download or upload many forms at once.</span></td>\n </tr></table></div>\n"; // ready? $ready = $useRequest ? defval($_REQUEST, "ready") : !($rrow && $rrow->reviewModified && !$rrow->reviewSubmitted); // review card echo '<div class="revcard_body">'; // administrator? $admin = $Me->allow_administer($prow); if ($rrow && !$Me->is_my_review($rrow) && $admin) { echo Ht::xmsg("info", "This isn’t your review, but as an administrator you can still make changes."); } // delegate? if ($rrow && !$rrow->reviewSubmitted && $rrow->contactId == $Me->contactId && $rrow->reviewType == REVIEW_SECONDARY) { $ndelegated = 0; foreach ($rrows as $rr) { if ($rr->reviewType == REVIEW_EXTERNAL && $rr->requestedBy == $rrow->contactId) { $ndelegated++; } } if ($ndelegated == 0) { $t = "As a secondary reviewer, you can <a href=\"" . hoturl("assign", "p={$rrow->paperId}") . "\">delegate this review to an external reviewer</a>, but if your external reviewer declines to review the paper, you should complete this review yourself."; } else { if ($rrow->reviewNeedsSubmit == 0) { $t = "A delegated external reviewer has submitted their review, but you can still complete your own if you’d like."; } else { $t = "Your delegated external reviewer has not yet submitted a review. If they do not, you should complete this review yourself."; } } echo Ht::xmsg("info", $t); } // top save changes if ($Me->timeReview($prow, $rrow) || $admin) { $buttons = $this->_review_buttons($prow, $rrow, "top", $reviewPostLink); echo Ht::actions($buttons, array("class" => "aab", "style" => "margin-top:0")); } // blind? if ($Conf->review_blindness() == Conf::BLIND_OPTIONAL) { echo '<div class="revet"><span class="revfn">', Ht::checkbox_h("blind", 1, $useRequest ? defval($_REQUEST, 'blind') : !$rrow || $rrow->reviewBlind), " ", Ht::label("Anonymous review"), "</span><hr class=\"c\" /></div>\n", '<div class="revhint">', htmlspecialchars(Conf::$gShortName), " allows either anonymous or open review. Check this box to submit your review anonymously (the authors won’t know who wrote the review).</div>\n", '<div class="g"></div>', "\n"; } // form body $this->webFormRows($Me, $prow, $rrow, $useRequest); // review actions if ($Me->timeReview($prow, $rrow) || $admin) { $buttons = $this->_review_buttons($prow, $rrow, "bottom", $reviewPostLink); echo Ht::actions($buttons, array("class" => "aab", "style" => "margin-bottom:0")); if ($rrow && $rrow->reviewSubmitted && !$admin) { echo '<div class="hint">Only administrators can remove or unsubmit the review at this point.</div>'; } } echo "</div></div></div></form>\n\n"; Ht::stash_script('hiliter_children("form.revcard")', "form_revcard"); }
$revopt[htmlspecialchars($reviewer_contact->email)] = Text::name_html($Me) . " (not on PC)"; } echo Ht::select("reviewer", $revopt, htmlspecialchars($reviewer_contact->email), array("onchange" => "\$\$(\"redisplayform\").submit()")), "<div class='g'></div></td></tr>\n"; } echo "<tr><td class='lxcaption'><strong>Search:</strong></td><td class='lentry'><input type='text' size='32' name='q' value=\"", htmlspecialchars(defval($_REQUEST, "q", "")), "\" /><span class='sep'></span></td>", "<td>", Ht::submit("redisplay", "Redisplay"), "</td>", "</tr>\n"; $show_data = array(); if (!$Conf->subBlindAlways() && ($Conf->subBlindNever() || $pl->any->openau)) { $show_data[] = '<span class="sep">' . Ht::checkbox("showau", 1, strpos($pldisplay, " au ") !== false, array("disabled" => !$Conf->subBlindNever() && !$pl->any->openau, "onchange" => "plinfo('au',this)", "id" => "showau")) . " " . Ht::label("Authors") . '</span>'; } if (!$Conf->subBlindNever() && $Me->privChair) { $show_data[] = '<span class="sep' . (!$Conf->subBlindAlways() ? " fx10" : "") . '">' . Ht::checkbox("showanonau", 1, strpos($pldisplay, " anonau ") !== false, array("disabled" => !$pl->any->anonau, "onchange" => (!$Conf->subBlindAlways() ? "" : "plinfo('au',this);") . "plinfo('anonau',this)", "id" => !$Conf->subBlindAlways() ? "showanonau" : "showau")) . " " . Ht::label(!$Conf->subBlindAlways() ? "Anonymous authors" : "Authors") . '</span>'; } if (!$Conf->subBlindAlways() || $Me->privChair) { $show_data[] = '<span class="sep fx10">' . Ht::checkbox("showaufull", 1, strpos($pldisplay, " aufull ") !== false, array("onchange" => "plinfo('aufull',this)", "id" => "showaufull")) . " " . Ht::label("Full author info") . "</span>"; $Conf->footerScript("plinfo.extra=function(type,dofold){var x=(type=='au'?!dofold:(\$\$('showau')||{}).checked);fold('redisplayform',!x,10)};"); } if ($pl->any->abstract) { $show_data[] = '<span class="sep">' . Ht::checkbox("showabstract", 1, strpos($pldisplay, " abstract ") !== false, array("onchange" => "plinfo('abstract',this)")) . " " . Ht::label("Abstracts") . '</span>'; } if ($pl->any->topics) { $show_data[] = '<span class="sep">' . Ht::checkbox("showtopics", 1, strpos($pldisplay, " topics ") !== false, array("onchange" => "plinfo('topics',this)")) . " " . Ht::label("Topics") . '</span>'; } if (count($show_data) && $pl->count) { echo '<tr><td class="lxcaption"><strong>Show:</strong> ', '</td><td colspan="2" class="lentry">', join('', $show_data), '</td></tr>'; } echo "</table></div></form>"; // </div></div> echo "</td></tr></table>\n"; // main form echo Ht::form_div(hoturl_post("reviewprefs", "reviewer={$reviewer}" . (defval($_REQUEST, "q") ? "&q=" . urlencode($_REQUEST["q"]) : "")), array("class" => "assignpc", "onsubmit" => "return plist_onsubmit.call(this)", "id" => "sel")), Ht::hidden("defaultact", "", array("id" => "defaultact")), Ht::hidden_default_submit("default", 1), "<div class='pltable_full_ctr'>\n", '<noscript><div style="text-align:center">', Ht::submit("update", "Save changes"), '</div></noscript>', $pl_text, "</div></div></form>\n"; $Conf->footer();
confHeader(); $Conf->footer(); exit; } if (isset($_REQUEST["refuse"]) || isset($_REQUEST["decline"])) { if (!$paperTable->editrrow || !$Me->is_my_review($paperTable->editrrow) && !$Me->can_administer($prow)) { Conf::msg_error("This review was not assigned to you, so you can’t decline it."); } else { if ($paperTable->editrrow->reviewType >= REVIEW_SECONDARY) { Conf::msg_error("PC members can’t decline their primary or secondary reviews. Contact the PC chairs directly if you really cannot finish this review."); } else { if ($paperTable->editrrow->reviewSubmitted) { Conf::msg_error("This review has already been submitted; you can’t decline it now."); } else { if (defval($_REQUEST, "refuse") == "1" || defval($_REQUEST, "decline") == "1") { $Conf->confirmMsg("<p>Select “Decline review” to decline this review (you may enter a brief explanation, if you’d like). Thank you for telling us that you cannot complete your review.</p><div class='g'></div><form method='post' action=\"" . hoturl_post("review", "p=" . $paperTable->prow->paperId . "&r=" . $paperTable->editrrow->reviewId) . "\" enctype='multipart/form-data' accept-charset='UTF-8'><div class='aahc'>" . Ht::hidden("refuse", "refuse") . " " . Ht::textarea("reason", "", array("rows" => 3, "cols" => 40, "spellcheck" => "true")) . "\n <span class='sep'></span>" . Ht::submit("Decline review") . "</div></form>"); } else { refuseReview(); Dbl::qe_raw("unlock tables"); loadRows(); } } } } } if (isset($_REQUEST["accept"])) { if (!$paperTable->editrrow || !$Me->is_my_review($paperTable->editrrow) && !$Me->can_administer($prow)) { Conf::msg_error("This review was not assigned to you, so you cannot confirm your intention to write it."); } else { if ($paperTable->editrrow->reviewModified <= 0) { Dbl::qe_raw("update PaperReview set reviewModified=1 where reviewId=" . $paperTable->editrrow->reviewId . " and coalesce(reviewModified,0)<=0");
function _searchForm($forwhat, $other = null, $size = 20) { $text = ""; if ($other && preg_match_all('/(\\w+)=([^&]*)/', $other, $matches, PREG_SET_ORDER)) { foreach ($matches as $m) { $text .= Ht::hidden($m[1], urldecode($m[2])); } } return Ht::form_div(hoturl("search"), array("method" => "get", "divclass" => "nw")) . "<input type='text' name='q' value=\"" . htmlspecialchars($forwhat) . "\" size='{$size}' /> " . Ht::submit("go", "Search") . $text . "</div></form>"; }
if ($pastDeadline && $Me->privChair) { echo "<br />", Ht::checkbox("override"), " ", Ht::label("Override deadlines"); } echo "<br /><span class='hint'><strong>Tip:</strong> You may upload a file containing several forms.</span>"; echo "</div></form></td>\n"; } echo "</tr>\n"; // Ranks if ($Conf->setting("tag_rank") && $Me->is_reviewer()) { $ranktag = $Conf->setting_data("tag_rank"); echo "<tr><td><div class='g'></div></td></tr>\n", "<tr><td><h3>Download ranking file</h3>\n<div>"; echo "<a href=\"", hoturl("search", "get=rank&tag=%7E{$ranktag}&q=&t=r&p=all"), "\">Your reviews</a>"; if ($Me->isPC) { echo "<br />\n<a href=\"", hoturl("search", "get=rank&tag=%7E{$ranktag}&q=&t=s&p=all"), "\">All submitted papers</a>"; } echo "</div></td>\n"; $disabled = $pastDeadline && !$Me->privChair ? " disabled='disabled'" : ""; echo "<td><h3>Upload ranking file</h3>\n", Ht::form_div(hoturl_post("offline", "setrank=1&tag=%7E{$ranktag}")), Ht::hidden("upload", 1), "<input type='file' name='file' accept='text/plain' size='30' {$disabled}/> ", Ht::submit("Go", array("disabled" => !!$disabled)); if ($pastDeadline && $Me->privChair) { echo "<br />", Ht::checkbox("override"), " ", Ht::label("Override deadlines"); } echo "<br /><span class='hint'><strong>Tip:</strong> Use “<a href='", hoturl("search", "q=" . urlencode("editsort:#~{$ranktag}")), "'>editsort:#~{$ranktag}</a>” to drag and drop your ranking.</span>"; echo "<br /><span class='hint'><strong>Tip:</strong> “<a href='", hoturl("search", "q=order:%7E{$ranktag}"), "'>order:~{$ranktag}</a>” searches by your ranking.</span>"; echo "</div></form></td>\n"; echo "</tr>\n"; } echo "</table>\n"; if ($text = $rf->webGuidanceRows($Me->permissive_view_score_bound())) { echo "<div class='g'></div>\n\n<table class='review'>\n<thead><tr class='id'><td></td><td class='entry'><h3>Review form information</h3></td></tr></thead>\n<tbody>", $text, "<tr class='last'>\n <td class='caption'></td>\n <td class='entry'></td>\n</tr></tbody></table>\n"; } $Conf->footer();
function echo_linenote_entry_row($file, $lineid, $note, $displayed, $lnorder) { global $Pset, $Me, $User, $Info; if (!is_array($note)) { $note = array(false, $note); } if (!$Me->isPC || $Me == $User || $displayed) { if ($Info->can_see_grades || $note[0]) { echo '<tr class="diffl61 gw">', '<td colspan="2" class="difflnoteborder61"></td>', '<td class="difflnote61">'; if ($lnorder) { $links = array(); //list($pfile, $plineid) = $lnorder->get_prev($file, $lineid); //if ($pfile) // $links[] = '<a href="#L' . $plineid . '_' // . html_id_encode($pfile) . '">← Prev</a>'; list($nfile, $nlineid) = $lnorder->get_next($file, $lineid); if ($nfile) { $links[] = '<a href="#L' . $nlineid . '_' . html_id_encode($nfile) . '">Next ></a>'; } else { $links[] = '<a href="#">Top</a>'; } if (count($links)) { echo '<div class="difflnoteptr61">', join(" ", $links), '</div>'; } } echo '<div class="note61', $note[0] ? ' commentnote' : ' gradenote', '">', htmlspecialchars($note[1]), '</div>', '<div class="clear"></div></td></tr>'; } return; } echo '<tr class="diffl61 gw', $note[0] ? ' isgrade61' : ' iscomment61', '" savednote61="', htmlspecialchars($note[1]), '">', '<td colspan="2" class="difflnoteborder61"></td>', '<td class="difflnote61">', '<div class="diffnoteholder61"', $displayed ? "" : " style=\"display:none\"", ">", Ht::form($Info->hoturl_post("pset", array("savelinenote" => 1)), array("onsubmit" => "return savelinenote61(this)")), "<div class=\"f-contain\">", Ht::hidden("file", $file), Ht::hidden("line", $lineid), Ht::hidden("iscomment", "", array("class" => "iscomment")), "<textarea class=\"diffnoteentry61\" name=\"note\">", htmlspecialchars($note[1]), "</textarea><br />"; echo Ht::submit("Comment", array("onclick" => "return setiscomment61(this,1)")), ' ', Ht::submit("Grade", array("onclick" => "return setiscomment61(this,'')")), '<span class="ajaxsave61"></span>', "</div></form></div></td></tr>"; }
private function result_html() { global $Conf, $Me, $Qreq, $SSel, $pcsel; $assignments = $this->autoassigner->assignments(); ReviewAssigner::$prefinfo = $this->autoassigner->prefinfo; ob_start(); if (!$assignments) { $Conf->warnMsg("Nothing to assign."); return ob_get_clean(); } $assignset = new AssignmentSet($Me, true); $assignset->parse(join("\n", $assignments)); list($atypes, $apids) = $assignset->types_and_papers(true); $badpairs_inputs = $badpairs_arg = array(); for ($i = 1; $i <= 20; ++$i) { if ($Qreq["bpa{$i}"] && $Qreq["bpb{$i}"]) { array_push($badpairs_inputs, Ht::hidden("bpa{$i}", $Qreq["bpa{$i}"]), Ht::hidden("bpb{$i}", $Qreq["bpb{$i}"])); $badpairs_arg[] = $Qreq["bpa{$i}"] . "-" . $Qreq["bpb{$i}"]; } } echo Ht::form_div(hoturl_post("autoassign", ["saveassignment" => 1, "assigntypes" => join(" ", $atypes), "assignpids" => join(" ", $apids), "xbadpairs" => count($badpairs_arg) ? join(" ", $badpairs_arg) : null, "profile" => $Qreq->profile, "XDEBUG_PROFILE" => $Qreq->XDEBUG_PROFILE, "seed" => $Qreq->seed])); $atype = $assignset->type_description(); echo "<h3>Proposed " . ($atype ? $atype . " " : "") . "assignment</h3>"; Conf::msg_info("Select “Apply changes” if this looks OK. (You can always alter the assignment afterwards.) Reviewer preferences, if any, are shown as “P#”."); $assignset->report_errors(); $assignset->echo_unparse_display(); // print preference unhappiness if ($Qreq->profile && $this->atype_review) { $umap = $this->autoassigner->pc_unhappiness(); sort($umap); echo '<p style="font-size:65%">Preference unhappiness: '; $usum = 0; foreach ($umap as $u) { $usum += $u; } if (count($umap) % 2 == 0) { $umedian = ($umap[count($umap) / 2 - 1] + $umap[count($umap) / 2]) / 2; } else { $umedian = $umap[(count($umap) - 1) / 2]; } echo 'mean ', sprintf("%.2f", $usum / count($umap)), ', min ', $umap[0], ', 10% ', $umap[(int) (count($umap) * 0.1)], ', 25% ', $umap[(int) (count($umap) * 0.25)], ', median ', $umedian, ', 75% ', $umap[(int) (count($umap) * 0.75)], ', 90% ', $umap[(int) (count($umap) * 0.9)], ', max ', $umap[count($umap) - 1], '<br/>Time: ', sprintf("%.6f", microtime(true) - $this->start_at); foreach ($this->autoassigner->profile as $name => $time) { echo ', ', sprintf("%s %.6f", htmlspecialchars($name), $time); } echo '</p>'; } echo "<div class='g'></div>", "<div class='aahc'><div class='aa'>\n", Ht::submit("submit", "Apply changes"), "\n ", Ht::submit("download", "Download assignment file"), "\n ", Ht::submit("cancel", "Cancel"), "\n"; foreach (array("t", "q", "a", "revtype", "revaddtype", "revpctype", "cleartype", "revct", "revaddct", "revpcct", "pctyp", "balance", "badpairs", "rev_roundtag", "method", "haspap") as $t) { if (isset($Qreq[$t])) { echo Ht::hidden($t, $Qreq[$t]); } } echo Ht::hidden("pcs", join(" ", array_keys($pcsel))), join("", $badpairs_inputs), Ht::hidden("p", join(" ", $SSel->selection())), "\n"; // save the assignment echo Ht::hidden("assignment", join("\n", $assignments)), "\n"; echo "</div></div></div></form>"; return ob_get_clean(); }
$paperList = new PaperList($search, ["sort" => true, "list" => true, "reviewer" => $pcm[$reviewer]], make_qreq()); $paperList->display .= " topics "; if ($qreq->kind != "c") { $paperList->display .= "reviewers "; } if (isset($showau)) { $search->overrideMatchPreg = true; $search->matchPreg = array(); if ($showau) { $search->matchPreg["authorInformation"] = make_match_preg($showau); } if ($showco) { $search->matchPreg["collaborators"] = make_match_preg($showco); } } $a = isset($qreq->sort) ? "&sort=" . urlencode($qreq->sort) : ""; echo "<div class='aahc'><form class='assignpc' method='post' action=\"", hoturl_post("manualassign", "reviewer={$reviewer}&kind={$qreq->kind}{$a}"), "\" enctype='multipart/form-data' accept-charset='UTF-8'><div>\n", Ht::hidden("t", $qreq->t), Ht::hidden("q", $qreq->q), Ht::hidden("papx", join(" ", $search->paperList())), "<div class=\"aa\">", Ht::submit("update", "Save assignments", array("class" => "bb")); if ($qreq->kind != "c") { $rev_rounds = $Conf->round_selector_options(); if (count($rev_rounds) > 1) { echo '<span style="padding-left:2em">Review round: ', Ht::select("rev_roundtag", $rev_rounds, $qreq->rev_roundtag ?: "unnamed", array("id" => "assrevroundtag")), '</span>'; } else { if (!@$rev_rounds["unnamed"]) { echo '<span style="padding-left:2em">Review round: ', $Conf->current_round_name(), '</span>'; } } } echo "<span style='padding-left:2em'>", Ht::checkbox(false, false, true, array("id" => "assrevimmediate")), " ", Ht::label("Automatically save assignments", "assrevimmediate"), "</span></div>\n", $paperList->table_html($qreq->kind == "c" ? "conflict" : "reviewAssignment", array("class" => "pltable_full", "table_id" => "foldpl", "header_links" => true, "nofooter" => true, "fold" => array("allrevtopicpref" => true))), "<div class='aa'>", Ht::submit("update", "Save assignments", array("class" => "bb")), "</div></div></form></div>\n"; } echo '<hr class="c" />'; $Conf->footer();
if ($Me->contactId != $Acct->contactId) { $form_params[] = "u=" . urlencode($Acct->email); } } if (isset($_REQUEST["ls"])) { $form_params[] = "ls=" . urlencode($_REQUEST["ls"]); } if ($newProfile) { echo '<div id="foldbulk" class="fold9' . (@$_REQUEST["bulkregister"] ? "o" : "c") . '"><div class="fn9">'; } echo Ht::form(hoturl_post("profile", join("&", $form_params)), array("id" => "accountform", "autocomplete" => "off")), '<div class="aahc profiletext', $need_highlight ? " alert" : "", "\">\n", Ht::password("chromefooler", "", array("style" => "display:none")), Ht::hidden("profile_contactid", $Acct->contactId); if (isset($_REQUEST["redirect"])) { echo Ht::hidden("redirect", $_REQUEST["redirect"]); } if ($Me->privChair) { echo Ht::hidden("whichpassword", ""); } echo '<div id="foldaccount" class="form foldc ', $pcrole == "no" ? "fold1c " : "fold1o ", fileUploaded($_FILES["bulk"]) ? "fold2o" : "fold2c", '">'; if ($newProfile) { create_modes(false); } echo '<div class="f-contain">', "\n\n"; if (!isset($Opt["ldapLogin"]) && !isset($Opt["httpAuthLogin"])) { echofield(0, "uemail", "Email", textinput("uemail", contact_value("uemail", "email"), 52, "account_d")); } else { if (!$newProfile) { echofield(0, "uemail", "Username", contact_value("uemail", "email")); echofield(0, "preferredEmail", "Email", textinput("preferredEmail", contact_value("preferredEmail"), 52, "account_d")); } else { echofield(0, "uemail", "Username", textinput("newUsername", contact_value("newUsername", false), 52, "account_d")); echofield(0, "preferredEmail", "Email", textinput("preferredEmail", contact_value("preferredEmail"), 52));
function render($sv) { global $Conf, $Opt; echo "<h3 class=\"settings\">Abstract and PDF</h3>\n"; echo Ht::select("sub_noabstract", [0 => "Abstract required", 2 => "Abstract optional", 1 => "No abstract"], opt_yes_no_optional("noAbstract")); echo " <span class=\"barsep\">·</span> ", Ht::select("sub_nopapers", array(0 => "PDF upload required", 2 => "PDF upload optional", 1 => "No PDF"), opt_yes_no_optional("noPapers")); if (is_executable("src/banal")) { echo "<div class='g'></div>", Ht::hidden("has_sub_banal", 1), "<table id='foldbanal' class='", $sv->curv("sub_banal") ? "foldo" : "foldc", "'>"; $sv->echo_checkbox_row("sub_banal", "PDF format checker<span class='fx'>:</span>", "void fold('banal',!this.checked)"); echo '<tr class="fx"><td></td><td class="top"><table class="secondary-settings"><tbody>'; $bsetting = explode(";", preg_replace("/>.*/", "", $Conf->setting_data("sub_banal", ""))); foreach (["papersize", "pagelimit", "columns", "textblock", "bodyfontsize", "bodyleading"] as $i => $name) { $val = get($bsetting, $i, ""); $sv->set_oldv("sub_banal_{$name}", $val == "" ? "N/A" : $val); } $sv->echo_entry_row("sub_banal_papersize", "Paper size", "Examples: “letter”, “A4”, “8.5in x 14in”,<br />“letter OR A4”"); $sv->echo_entry_row("sub_banal_pagelimit", "Page limit"); $sv->echo_entry_row("sub_banal_textblock", "Text block", "Examples: “6.5in x 9in”, “1in margins”"); echo '</tbody></table></td>', '<td><span class="sep"></span></td>', '<td class="top"><table class="secondary-settings"><tbody>'; $sv->echo_entry_row("sub_banal_bodyfontsize", "Minimum body font size", null, " pt"); $sv->echo_entry_row("sub_banal_bodyleading", "Minimum leading", null, " pt"); $sv->echo_entry_row("sub_banal_columns", "Columns"); echo "</tbody></table></td></tr></table>"; } echo "<h3 class=\"settings\">Conflicts & collaborators</h3>\n", "<table id=\"foldpcconf\" class=\"fold", $sv->curv("sub_pcconf") ? "o" : "c", "\">\n"; $sv->echo_checkbox_row("sub_pcconf", "Collect authors’ PC conflicts", "void fold('pcconf',!this.checked)"); echo "<tr class='fx'><td></td><td>"; $conf = array(); foreach (Conflict::$type_descriptions as $n => $d) { if ($n) { $conf[] = "“{$d}”"; } } $sv->echo_checkbox("sub_pcconfsel", "Require conflict descriptions (" . commajoin($conf, "or") . ")"); echo "</td></tr>\n"; $sv->echo_checkbox_row("sub_collab", "Collect authors’ other collaborators as text"); echo "</table>\n"; echo "<h3 class=\"settings\">Submission options</h3>\n"; echo "Options are selected by authors at submission time. Examples have included “PC-authored paper,” “Consider this paper for a Best Student Paper award,” and “Allow the shadow PC to see this paper.” The “option name” should be brief (“PC paper,” “Best Student Paper,” “Shadow PC”). The optional description can explain further and may use XHTML. "; echo "Add options one at a time.\n"; echo "<div class='g'></div>\n", Ht::hidden("has_options", 1); $sep = ""; $all_options = array_merge(PaperOption::nonfixed_option_list()); // get our own iterator foreach ($all_options as $o) { echo $sep; $this->render_option($sv, $o); $sep = "\n<div style=\"margin-top:3em\"></div>\n"; } echo $sep; $this->render_option($sv, null); // Topics // load topic interests $qinterest = $Conf->query_topic_interest(); $result = $Conf->q("select topicId, if({$qinterest}>0,1,0), count(*) from TopicInterest where {$qinterest}!=0 group by topicId, {$qinterest}>0"); $interests = array(); $ninterests = 0; while ($row = edb_row($result)) { if (!isset($interests[$row[0]])) { $interests[$row[0]] = array(); } $interests[$row[0]][$row[1]] = $row[2]; $ninterests += $row[2] ? 1 : 0; } echo "<h3 class=\"settings g\">Topics</h3>\n"; echo "Enter topics one per line. Authors select the topics that apply to their papers; PC members use this information to find papers they'll want to review. To delete a topic, delete its name.\n"; echo "<div class='g'></div>", Ht::hidden("has_topics", 1), "<table id='newtoptable' class='", $ninterests ? "foldo" : "foldc", "'>"; echo "<tr><th colspan='2'></th><th class='fx'><small>Low</small></th><th class='fx'><small>High</small></th></tr>"; $td1 = '<td class="lcaption">Current</td>'; foreach ($Conf->topic_map() as $tid => $tname) { if ($sv->use_req() && isset($sv->req["top{$tid}"])) { $tname = $sv->req["top{$tid}"]; } echo '<tr>', $td1, '<td class="lentry">', Ht::entry("top{$tid}", $tname, array("size" => 40, "style" => "width:20em")), '</td>'; $tinterests = defval($interests, $tid, array()); echo '<td class="fx rpentry">', get($tinterests, 0) ? '<span class="topic-2">' . $tinterests[0] . "</span>" : "", "</td>", '<td class="fx rpentry">', get($tinterests, 1) ? '<span class="topic2">' . $tinterests[1] . "</span>" : "", "</td>"; if ($td1 !== "<td></td>") { // example search echo "<td class='llentry' style='vertical-align:top' rowspan='40'><div class='f-i'>", "<div class='f-c'>Example search</div>"; $oabbrev = strtolower($tname); if (strstr($oabbrev, " ") !== false) { $oabbrev = "\"{$oabbrev}\""; } echo "“<a href=\"", hoturl("search", "q=topic:" . urlencode($oabbrev)), "\">", "topic:", htmlspecialchars($oabbrev), "</a>”", "<div class='hint'>Topic abbreviations are also allowed.</div>"; if ($ninterests) { echo "<a class='hint fn' href=\"#\" onclick=\"return fold('newtoptable')\">Show PC interest counts</a>", "<a class='hint fx' href=\"#\" onclick=\"return fold('newtoptable')\">Hide PC interest counts</a>"; } echo "</div></td>"; } echo "</tr>\n"; $td1 = "<td></td>"; } echo '<tr><td class="lcaption top">New<br><span class="hint">Enter one topic per line.</span></td><td class="lentry top">', Ht::textarea("topnew", $sv->use_req() ? get($sv->req, "topnew") : "", array("cols" => 40, "rows" => 2, "style" => "width:20em")), '</td></tr></table>'; }
} else { $Acct->change_password($_REQUEST["upassword"], true); $Acct->log_activity("Reset password"); $Conf->confirmMsg("Your password has been changed. You may now sign in to the conference site."); $capmgr->delete($capdata); $Conf->save_session("password_reset", (object) array("time" => $Now, "email" => $Acct->email, "password" => $_REQUEST["upassword"])); go(hoturl("index")); } } } $password_class = " error"; } $Conf->header("Reset Password", "resetpassword", null); if (!isset($_REQUEST["autopassword"]) || trim($_REQUEST["autopassword"]) != $_REQUEST["autopassword"] || strlen($_REQUEST["autopassword"]) < 16 || !preg_match("/\\A[-0-9A-Za-z@_+=]*\\z/", $_REQUEST["autopassword"])) { $_REQUEST["autopassword"] = Contact::random_password(); } if (!isset($_REQUEST["useauto"]) || $_REQUEST["useauto"] != "n") { $_REQUEST["useauto"] = "y"; } $confname = $Opt["longName"]; if ($Opt["shortName"] && $Opt["shortName"] != $Opt["longName"]) { $confname .= " (" . $Opt["shortName"] . ")"; } echo "<div class='homegrp'>\nWelcome to the ", htmlspecialchars($confname), " submissions site."; if (isset($Opt["conferenceSite"])) { echo " For general information about ", htmlspecialchars($Opt["shortName"]), ", see <a href=\"", htmlspecialchars($Opt["conferenceSite"]), "\">the conference site</a>."; } echo "</div>\n<hr class='home' />\n<div class='homegrp' id='homereset'>\n", Ht::form(hoturl_post("resetpassword")), '<div class="f-contain">', Ht::hidden("resetcap", $_REQUEST["resetcap"]), Ht::hidden("autopassword", $_REQUEST["autopassword"]), "<p>This form will reset the password for <b>", htmlspecialchars($Acct->email), "</b>. Use our suggested replacement password, or choose your own.</p>\n<table>\n <tr><td>", Ht::radio("useauto", "y", null), " </td><td>", Ht::label("Use password <tt>" . htmlspecialchars($_REQUEST["autopassword"]) . "</tt>"), "</td></tr>\n <tr><td>", Ht::radio("useauto", "n", null, array("id" => "usemy", "onclick" => "x=\$\$(\"login_d\");if(document.activeElement!=x)x.focus()")), " </td><td style='padding-top:1em'>", Ht::label("Use this password:"******"</td></tr>\n <tr><td></td><td><div class='f-i'>\n <div class='f-c", $password_class, "'>Password</div>\n <div class='f-e'><input id='login_d' type='password' name='upassword' size='36' tabindex='1' value='' onkeypress='if(!((x=\$\$(\"usemy\")).checked)) x.click()' /></div>\n</div>\n<div class='f-i'>\n <div class='f-c", $password_class, "'>Password (again)</div>\n <div class='f-e'><input id='login_d' type='password' name='upassword2' size='36' tabindex='1' value='' /></div>\n</div></td></tr>\n<tr><td colspan='2' style='padding-top:1em'>\n<div class='f-i'>", Ht::submit("go", "Reset password", array("tabindex" => 1)), "</div></td>\n</tr></table>\n</div></form>\n<hr class='home' /></div>\n"; $Conf->footerScript("crpfocus(\"login\", null, 2)"); echo '<hr class="c" />', "\n"; $Conf->footer();
if (!$Me->can_view_run($Pset, $Runner, $RunMany ? null : $User)) { if (!$Me->isPC && !$Runner->visible) { quit("Command reserved for TFs"); } else { if ($Runner->disabled) { quit("Command disabled"); } else { quit("Can’t run command right now"); } } } } // magic multi-runner if ($Me->isPC && @$_GET["runmany"] && check_post()) { $Conf->header(htmlspecialchars($Pset->title . " " . $Runner->title), "home"); echo '<h2 id="runmany61_who"></h2>', Ht::form(hoturl_post("run")), '<div class="f-contain">', Ht::hidden("u", ""), Ht::hidden("pset", $Pset->urlkey), Ht::hidden("run", $Runner->name, array("id" => "runmany61")), '</div></form>'; echo '<div id="run61out_' . $Runner->name . '">', '<div class="run61" id="run61_' . $Runner->name . '">', '<div class="run61in"><pre class="run61pre"></pre></div>', '</div>', '</div>'; echo '<div id="runmany61_users">', htmlspecialchars($_GET["runmany"]), '</div>'; $Conf->footerScript('runmany61()'); echo '<div class="clear"></div>', "\n"; $Conf->footer(); exit; } // repo $Info = user_pset_info(); $Repo = $Info->repo; $RecentCommits = $Info->recent_commits(); // can we run this? if (!$Repo) { quit("No repository to run"); } else {
foreach (array("A", "V", "D") as $k) { /* ghetto array_intersect_key */ if (isset(ListSorter::$score_sorts[$k])) { $ss[$k] = ListSorter::$score_sorts[$k]; } } echo "<tr><td colspan='3'><div class='g'></div><b>Sort scores by:</b> ", Ht::select("scoresort", $ss, $Conf->session("scoresort", "A")), "</td></tr>"; } echo "</table></div></form>"; echo "</div></div></td></tr>\n"; // Tab selectors echo "<tr><td class='tllx'><table><tr>\n <td><div class='tll1'><a class='tla' onclick='return crpfocus(\"contactsform\", 1)' href=''>User selection</a></div></td>\n <td><div class='tll2'><a class='tla' onclick='return crpfocus(\"contactsform\", 2)' href=''>Display options</a></div></td>\n</tr></table></td></tr>\n</table>\n\n"; } if ($Me->privChair && $_REQUEST["t"] == "pc") { $Conf->infoMsg("<p><a href='" . hoturl("profile", "u=new&role=pc") . "' class='button'>Add PC member</a></p><p>Select a PC member’s name to edit their profile or remove them from the PC.</p>"); } else { if ($Me->privChair && $_REQUEST["t"] == "all") { $Conf->infoMsg("<p><a href='" . hoturl("profile", "u=new") . "' class='button'>Create account</a></p><p>Select a user to edit their profile. Select " . Ht::img("viewas.png", "[Act as]") . " to view the site as that user would see it.</p>"); } } if (isset($pl->any->sel)) { echo Ht::form(hoturl_post("users", ["t" => $_REQUEST["t"]])), "<div>"; if (isset($_REQUEST["sort"])) { echo Ht::hidden("sort", $_REQUEST["sort"]); } } echo $pl_text; if (isset($pl->any->sel)) { echo "</div></form>"; } $Conf->footer();
<path d="M 61.71,62.611 C 66.977,55.945 70.128,47.531 70.128,38.378 C 70.128,29.161 66.936,20.696 61.609,14.01" style="fill:none;stroke:#111111;stroke-width:5;stroke-linecap:round"/> </svg><svg id="muteicon" class="fx" width="1.5em" height="1.5em" viewBox="0 0 75 75" style="position:relative;bottom:-3px"> <polygon points="39.389,13.769 22.235,28.606 6,28.606 6,47.699 21.989,47.699 39.389,62.75 39.389,13.769" style="stroke:#111111;stroke-width:5;stroke-linejoin:round;fill:#111111;" /> <path d="M 48.651772,50.269646 69.395223,25.971024" style="fill:none;stroke:#111111;stroke-width:5;stroke-linecap:round"/> <path d="M 69.395223,50.269646 48.651772,25.971024" style="fill:none;stroke:#111111;stroke-width:5;stroke-linecap:round" /> </svg></button></td>'; //echo '<span class="hidden fhn_ib"> Mute</span>'; //echo '<span class="hidden fhx_ib"> Unmute</span></button></td>'; // show-papers if ($Me->has_database_account()) { echo '<td style="padding-left:2em">', Ht::checkbox("buzzer_showpapers", 1, $show_papers, array("id" => "buzzer_showpapers", "onclick" => "trackertable_showpapers()")), " ", Ht::label("Show papers"), '</td>'; Ht::stash_script("trackertable_showpapers()"); } // kiosk mode if ($Me->privChair) { echo '<td style="padding-left:2em">', Ht::js_button("Kiosk mode", "popup(this,'kiosk',0,true)"), '</td>'; $Conf->footerHtml('<div id="popup_kiosk" class="popupc"> <p>Kiosk mode is a discussion status page with no other site privileges. It’s safe to leave a browser in kiosk mode open in the hallway.</p> <p><b>Kiosk mode will sign you out of the site.</b> Do not use kiosk mode on your main browser. Instead, sign in to another browser and navigate to this page. Or use these URLs:</p> <p><table><tr><td class="lcaption nw">With papers</td> <td>' . hoturl_absolute("buzzer", array("__PATH__" => $kiosk_keys[1])) . '</td></tr> <tr><td class="lcaption nw">Conflicts only</td> <td>' . hoturl_absolute("buzzer", array("__PATH__" => $kiosk_keys[0])) . '</td></tr></table></p>' . Ht::form_div(hoturl_post("buzzer")) . '<div class="popup_actions">' . Ht::hidden("buzzer_showpapers", 1, array("class" => "popup_populate")) . Ht::js_button("Cancel", "popup(null,'kiosk',1)") . Ht::submit("signout_to_kiosk", "Enter kiosk mode", array("class" => "bb")) . '</div></div></form>'); } echo "</tr></table></form>\n"; $Conf->footer();
if (isset($_REQUEST["saveassignment"]) && check_post() && isset($_POST["file"]) && get($_POST, "assignment_size_estimate") >= 1000) { complete_assignment("keep_browser_alive"); finish_browser_alive(); } echo Ht::form_div(hoturl_post("bulkassign", "upload=1"), array("divstyle" => "margin-top:1em")); // Upload echo '<div class="f-contain"><div class="f-i"><div class="f-e">', Ht::textarea("bulkentry", req_s("bulkentry"), ["rows" => 1, "cols" => 80, "placeholder" => "Enter assignments"]), '</div></div></div>'; echo '<div class="g"><strong>OR</strong> ', '<input type="file" name="bulk" accept="text/plain,text/csv" size="30" /></div>'; echo '<div id="foldoptions" class="lg foldc fold2o">', 'By default, assign ', Ht::select("default_action", array("primary" => "primary reviews", "secondary" => "secondary reviews", "pcreview" => "optional PC reviews", "review" => "external reviews", "conflict" => "PC conflicts", "lead" => "discussion leads", "shepherd" => "shepherds", "tag" => "add tags", "settag" => "replace tags", "preference" => "reviewer preferences"), defval($_REQUEST, "default_action", "primary"), array("id" => "tsel", "onchange" => "fold(\"options\",this.value!=\"review\");fold(\"options\",!/^(?:primary|secondary|(?:pc)?review)\$/.test(this.value),2)")); $rev_rounds = $Conf->round_selector_options(); if (count($rev_rounds) > 1) { echo '<span class="fx2"> in round ', Ht::select("rev_roundtag", $rev_rounds, $_REQUEST["rev_roundtag"] ?: "unnamed"), '</span>'; } else { if (!get($rev_rounds, "unnamed")) { echo '<span class="fx2"> in round ', $Conf->current_round_name(), '</span>'; } } echo '<div class="g"></div>', "\n"; $requestreview_template = $null_mailer->expand_template("requestreview"); echo Ht::hidden("requestreview_subject", $requestreview_template["subject"]); if (isset($_REQUEST["requestreview_body"])) { $t = $_REQUEST["requestreview_body"]; } else { $t = $requestreview_template["body"]; } echo "<table class='fx'><tr><td>", Ht::checkbox("requestreview_notify", 1, true), " </td><td>", Ht::label("Send email to external reviewers:"), "</td></tr>\n<tr><td></td><td>", Ht::textarea("requestreview_body", $t, array("class" => "tt", "cols" => 80, "rows" => 20, "spellcheck" => "true")), "</td></tr></table>\n"; echo '<div class="g"></div><div class="aa">', Ht::submit("Prepare assignments"), " <span class='hint'>You’ll be able to check the assignment before it is saved.</span></div>\n"; echo '<div style="margin-top:1.5em"><a href="', hoturl_post("search", "t=manager&q=&get=pcassignments&p=all"), '">Download current PC assignments</a></div>'; echo "</div></form>\n\n<hr style='margin-top:1em' />\n\n<div class='helppagetext'>\n<h3>Instructions</h3>\n\n<p>Upload a comma-separated value file to prepare an assignment of reviews,\nconflicts, leads, shepherds, and tags. HotCRP calculates the minimal changes\nbetween the current state and the requested assignment; you’ll confirm those\nchanges before they are committed.</p>\n\n<p>A simple example:</p>\n\n<pre class='entryexample'>paper,assignment,email\n1,primary,man@alice.org\n2,secondary,slugger@manny.com\n1,primary,slugger@manny.com</pre>\n\n<p>This assigns PC members man@alice.org and slugger@manny.com as primary\nreviewers for paper #1, and slugger@manny.com as a secondary\nreviewer for paper #2. Errors will be reported if those users aren’t PC\nmembers, or if they have conflicts with their assigned papers.</p>\n\n<p>A more complex example:</p>\n\n<pre class='entryexample'>paper,assignment,email,round\nall,clearreview,all,R2\n1,primary,man@alice.org,R2\n10,primary,slugger@manny.com,R2\n#manny OR #ramirez,primary,slugger@manny.com,R2</pre>\n\n<p>The first assignment line clears all review assignments in\nround R2. (Review assignments in other rounds are left alone.) The next\nlines assign man@alice.org as a primary reviewer for paper #1, and slugger@manny.com\nas a primary reviewer for paper #10. The last line assigns slugger@manny.com\nas a primary reviewer for all papers tagged #manny or #ramirez.</p>\n\n<p>Assignment types are:</p>\n\n<dl class=\"spaced\">\n<dt><code>review</code></dt>\n\n<dd>Assign a review. The <code>email</code> and/or <code>name</code> columns\nlocate the user. (<code>first</code> and <code>last</code> columns may be used\nin place of <code>name</code>.) The <code>reviewtype</code> column sets the\nreview type; it can be <code>primary</code>, <code>secondary</code>,\n<code>pcreview</code> (optional PC review), or <code>external</code>, or\n<code>clear</code> to unassign the review. The optional\n<code>round</code> column sets the review round.\n\n<p>Only PC members can be assigned primary, secondary, and optional PC\nreviews. Accounts will be created for new external reviewers as necessary. The\n<code>clear</code> action doesn’t delete reviews that have already been\nentered.</p>\n\n<p>Assignments can create new reviews or change existing reviews. Use\n“<code>any</code>” or “old:new” syntax in the <code>round</code> and/or\n<code>reviewtype</code> columns to restrict assignments to existing reviews.\nFor example, to create a new assignment or modify an existing review:</p>\n\n<pre class=\"entryexample\">paper,assignment,email,reviewtype,round\n1,review,drew@harvard.edu,primary,R2</pre>\n\n<p>To modify an existing review’s round (“<code>any</code>” restricts the\nassignment to existing reviews):</p>\n\n<pre class=\"entryexample\">paper,assignment,email,reviewtype,round\n1,review,drew@harvard.edu,any,R2</pre>\n\n<p>To change an existing review from round R1 to round R2:</p>\n\n<pre class=\"entryexample\">paper,assignment,email,reviewtype,round\n1,review,drew@harvard.edu,any,R1:R2</pre>\n\n<p>To change all round-R1 primary reviews to round R2:</p>\n\n<pre class=\"entryexample\">paper,assignment,email,reviewtype,round\nall,review,all,primary,R1:R2</pre>\n\n</dd>\n\n<dt><code>primary</code>, <code>secondary</code>, <code>pcreview</code>,\n<code>external</code>, <code>clearreview</code></dt>\n<dd>Like <code>review</code>, assign a primary, secondary, optional PC, or\nexternal review, or clear existing reviews.</dd>\n\n<dt><code>unsubmitreview</code></dt>\n<dd>Unsubmit a submitted review. The <code>email</code>, <code>name</code>,\n<code>reviewtype</code>, and <code>round</code> columns locate the review.</dd>\n\n<dt><code>lead</code></dt>\n<dd>Set the discussion lead. The <code>email</code>, <code>name</code>,\nand/or <code>user</code> columns locate the PC user. To clear the discussion lead,\nuse email <code>none</code> or assignment type <code>clearlead</code>.</dd>\n\n<dt><code>shepherd</code></dt>\n<dd>Set the shepherd. The <code>email</code>, <code>name</code>,\nand/or <code>user</code> columns locate the PC user. To clear the shepherd,\nuse email <code>none</code> or assignment type <code>clearshepherd</code>.</dd>\n\n<dt><code>conflict</code></dt>\n<dd>Mark a PC conflict. The <code>email</code>, <code>name</code>,\nand/or <code>user</code> columns locate the PC user. To clear a conflict,\nuse assignment type <code>clearconflict</code>.</dd>\n\n<dt><code>tag</code></dt>\n<dd>Add a tag. The <code>tag</code> column names the tag and the optional\n<code>value</code> column sets the tag value.\nTo clear a tag, use assignment type <code>cleartag</code> or value <code>none</code>.</dd>\n\n<dt><code>preference</code></dt>\n<dd>Set reviewer preference and expertise. The <code>preference</code> column\ngives the preference value.</dd>\n</dl>\n\n</div>\n"; $Conf->footerScript('$("#tsel").trigger("change");$("textarea").autogrow()'); $Conf->footer();
function render($sv) { global $Conf; // Tags $tagger = new Tagger(); echo "<h3 class=\"settings\">Tags</h3>\n"; echo "<table class=\"secondary-settings\"><tbody>"; $sv->set_oldv("tag_chair", join(" ", array_keys(TagInfo::chair_tags()))); $sv->echo_entry_row("tag_chair", "Chair-only tags", "PC members can view these tags, but only administrators can change them."); $sv->set_oldv("tag_sitewide", join(" ", array_keys(TagInfo::sitewide_tags()))); if ($sv->newv("tag_sitewide") || $Conf->has_any_manager()) { $sv->echo_entry_row("tag_sitewide", "Site-wide tags", "Chairs and administrators can view and change these tags for every paper."); } $sv->set_oldv("tag_approval", join(" ", array_keys(TagInfo::approval_tags()))); $sv->echo_entry_row("tag_approval", "Approval voting tags", "<a href=\"" . hoturl("help", "t=votetags") . "\">What is this?</a>"); $x = []; foreach (TagInfo::vote_tags() as $n => $v) { $x[] = "{$n}#{$v}"; } $sv->set_oldv("tag_vote", join(" ", $x)); $sv->echo_entry_row("tag_vote", "Allotment voting tags", "“vote#10” declares an allotment of 10 votes per PC member. <span class=\"barsep\">·</span> <a href=\"" . hoturl("help", "t=votetags") . "\">What is this?</a>"); $sv->set_oldv("tag_rank", $Conf->setting_data("tag_rank", "")); $sv->echo_entry_row("tag_rank", "Ranking tag", "The <a href='" . hoturl("offline") . "'>offline reviewing page</a> will expose support for uploading rankings by this tag. <span class='barsep'>·</span> <a href='" . hoturl("help", "t=ranking") . "'>What is this?</a>"); echo "</tbody></table>"; echo "<div class='g'></div>\n"; $sv->echo_checkbox('tag_seeall', "PC can see tags for conflicted papers"); preg_match_all('_(\\S+)=(\\S+)_', $Conf->setting_data("tag_color", ""), $m, PREG_SET_ORDER); $tag_colors = array(); foreach ($m as $x) { $tag_colors[TagInfo::canonical_color($x[2])][] = $x[1]; } $tag_colors_rows = array(); foreach (explode("|", TagInfo::BASIC_COLORS) as $k) { if ($sv->use_req()) { $v = defval($sv->req, "tag_color_{$k}", ""); } else { if (isset($tag_colors[$k])) { $v = join(" ", $tag_colors[$k]); } else { $v = ""; } } $tag_colors_rows[] = "<tr class='k0 {$k}tag'><td class='lxcaption'></td><td class='lxcaption taghl'>{$k}</td><td class='lentry' style='font-size: 10.5pt'><input type='text' name='tag_color_{$k}' value=\"" . htmlspecialchars($v) . "\" size='40' /></td></tr>"; /* MAINSIZE */ } preg_match_all('_(\\S+)=(\\S+)_', $Conf->setting_data("tag_badge", ""), $m, PREG_SET_ORDER); $tag_badges = array(); foreach ($m as $x) { $tag_badges[$x[2]][] = $x[1]; } foreach (["black" => "black label", "red" => "red label", "green" => "green label", "blue" => "blue label", "white" => "white label"] as $k => $desc) { if ($sv->use_req()) { $v = defval($sv->req, "tag_badge_{$k}", ""); } else { if (isset($tag_badges[$k])) { $v = join(" ", $tag_badges[$k]); } else { $v = ""; } } $tag_colors_rows[] = "<tr class='k0'><td class='lxcaption'></td><td class='lxcaption'><span class='badge {$k}badge' style='margin:0'>{$desc}</span><td class='lentry' style='font-size:10.5pt'><input type='text' name='tag_badge_{$k}' value=\"" . htmlspecialchars($v) . "\" size='40' /></td></tr>"; /* MAINSIZE */ } echo Ht::hidden("has_tag_color", 1), '<h3 class="settings g">Styles and colors</h3>', "<div class='hint'>Papers and PC members tagged with a style name, or with one of the associated tags, will appear in that style in lists.</div>", "<div class='smg'></div>", "<table id='foldtag_color'><tr><th colspan='2'>Style name</th><th>Tags</th></tr>", join("", $tag_colors_rows), "</table>\n"; echo '<h3 class="settings g">Tracks</h3>', "\n"; echo "<div class='hint'>Tracks control the PC members allowed to view or review different sets of papers. <span class='barsep'>·</span> <a href=\"" . hoturl("help", "t=tracks") . "\">What is this?</a></div>", Ht::hidden("has_tracks", 1), "<div class=\"smg\"></div>\n"; $this->do_track($sv, "", 0); $tracknum = 2; $trackj = $Conf->setting_json("tracks") ?: (object) array(); // existing tracks foreach ($trackj as $trackname => $x) { if ($trackname !== "_") { $this->do_track($sv, $trackname, $tracknum); ++$tracknum; } } // new tracks (if error prevented saving) if ($sv->use_req()) { for ($i = 1; isset($sv->req["name_track{$i}"]); ++$i) { $trackname = trim($sv->req["name_track{$i}"]); if (!isset($trackj->{$trackname})) { $this->do_track($sv, $trackname, $tracknum); ++$tracknum; } } } // catchall track $this->do_track($sv, "_", 1); echo Ht::button("Add track", array("onclick" => "settings_add_track()")); }
if ($password_reset && $password_reset->time < $Now - 900) { $password_reset = null; $Conf->save_session("password_reset", null); } echo '<div class="f-ii"> <div class="f-c', $email_class, '">', isset($Opt["ldapLogin"]) ? "Username" : "Email", '</div> <div class="f-e', $email_class, '">', Ht::entry("email", isset($_REQUEST["email"]) ? $_REQUEST["email"] : ($password_reset ? $password_reset->email : ""), ["size" => 36, "tabindex" => 1, "id" => "signin_email"]), '</div> </div> <div class="f-i fx"> <div class="f-c', $password_class, '">Password</div> <div class="f-e">', Ht::password("password", "", array("size" => 36, "tabindex" => 1, "id" => "signin_password")), "</div>\n</div>\n"; if ($password_reset) { $Conf->echoScript("jQuery(function(){jQuery(\"#signin_password\").val(" . json_encode($password_reset->password) . ")})"); } if (isset($Opt["ldapLogin"])) { echo Ht::hidden("action", "login"); } else { echo "<div class='f-i'>\n ", Ht::radio("action", "login", true, array("tabindex" => 2, "id" => "signin_action_login")), " ", Ht::label("<b>Sign me in</b>"), "<br />\n"; echo Ht::radio("action", "forgot", false, array("tabindex" => 2)), " ", Ht::label("I forgot my password"), "<br />\n"; echo Ht::radio("action", "new", false, array("tabindex" => 2)), " ", Ht::label("I’m a new user and want to create an account"); echo "\n</div>\n"; $Conf->footerScript("function login_type() {\n var act = jQuery(\"#homeacct input[name=action]:checked\")[0] || jQuery(\"#signin_action_login\")[0];\n fold(\"homeacct\", act.value != \"login\");\n var felt = act.value != \"login\" || !jQuery(\"#signin_email\").val().length;\n jQuery(\"#signin_\" + (felt ? \"email\" : \"password\"))[0].focus();\n jQuery(\"#signin_signin\")[0].value = {\"login\":\"Sign in\",\"forgot\":\"Reset password\",\"new\":\"Create account\"}[act.value];\n}\njQuery(\"#homeacct input[name='action']\").on('click',login_type);jQuery(login_type)"); } echo "<div class='f-i'>", Ht::submit("signin", "Sign in", array("tabindex" => 1, "id" => "signin_signin")), "</div></div></form>\n<hr class='home' /></div>\n"; $Conf->footerScript("crpfocus(\"login\", null, 2)"); } // Submissions $papersub = $Conf->setting("papersub"); $homelist = $Me->privChair || $Me->isPC && $papersub || $Me->is_reviewer() && $papersub; $home_hr = "<hr class=\"home\" />\n"; $nhome_hr = 0;
echo '<div class="ctelt"><div class="ctelti' . ($color ? " {$color}" : "") . '">'; if ($p->conflictType >= CONFLICT_AUTHOR) { echo '<div class="pctbass">', review_type_icon(-2), Ht::img("_.gif", ">", array("class" => "next", "style" => "visibility:hidden")), ' </div>', '<div id="ass' . $p->contactId . '" class="pctbname pctbname-2 taghl nw">', $Me->name_html_for($pc), '</div>'; } else { if ($p->conflictType > 0) { $revtype = -1; } else { if ($p->reviewType) { $revtype = $p->reviewType; } else { $revtype = $p->refused ? -3 : 0; } } $title = $p->refused ? "Review previously declined" : "Assignment"; // NB manualassign.php also uses the "pcs$contactId" convention echo '<div class="pctbass">' . '<div id="foldass' . $p->contactId . '" class="foldc" style="position:relative">' . '<a id="folderass' . $p->contactId . '" href="#" onclick="return assigntable.open(' . $p->contactId . ')">' . review_type_icon($revtype, false, $title) . Ht::img("_.gif", ">", array("class" => "next")) . '</a> ' . Ht::hidden("pcs{$p->contactId}", $p->conflictType == 0 ? $p->reviewType : -1, array("id" => "pcs{$p->contactId}")) . '</div></div>'; echo '<div id="ass' . $p->contactId . '" class="pctbname pctbname' . $revtype . '">' . '<span class="taghl nw">' . $Me->name_html_for($pc) . '</span>'; if ($p->conflictType == 0) { $p->topicInterestScore = $prow->topic_interest_score($pc); if ($p->reviewerPreference || $p->reviewerExpertise || $p->topicInterestScore) { echo unparse_preference_span($p); } } echo '</div>'; } // then, number of reviews echo '<div class="pctbnrev">'; $numReviews = strlen($p->allReviews); $numPrimary = preg_match_all("|" . REVIEW_PRIMARY . "|", $p->allReviews, $matches); if (!$numReviews) { echo "0 reviews";
crpmerge($MiniMe); } } } } } } $Conf->header("Merge accounts", "mergeaccounts", actionBar()); if ($MergeError) { Conf::msg_error($MergeError); } else { $Conf->infoMsg("You may have multiple accounts registered with the " . Conf::$gShortName . " conference; perhaps " . "multiple people asked you to review a paper using " . "different email addresses. " . "If you have been informed of multiple accounts, " . "enter the email address and the password " . "of the secondary account. This will merge all the information from " . "that account into this one. "); } echo "<form method='post' action=\"", hoturl_post("mergeaccounts"), "\" accept-charset='UTF-8'>\n"; // Try to prevent glasses interactions from screwing up merges echo Ht::hidden("actas", $Me->contactId); ?> <table class='form'> <tr> <td class='caption'>Email</td> <td class='entry'><input type='text' name='email' size='50' <?php if (isset($_REQUEST["email"])) { echo "value=\"", htmlspecialchars($_REQUEST["email"]), "\" "; } ?> /></td> </tr>
$capmgr->delete($capdata); $Conf->save_session("password_reset", (object) array("time" => $Now, "email" => $Acct->email, "password" => $_POST["password"])); go(hoturl("index")); } } } $password_class = " error"; } $Conf->header("Reset password", "resetpassword", null); if (!isset($_POST["autopassword"]) || trim($_POST["autopassword"]) != $_POST["autopassword"] || strlen($_POST["autopassword"]) < 16 || !preg_match("/\\A[-0-9A-Za-z@_+=]*\\z/", $_POST["autopassword"])) { $_POST["autopassword"] = Contact::random_password(); } echo "<div class='homegrp'>\nWelcome to the ", htmlspecialchars($Conf->full_name()), " submissions site."; if (opt("conferenceSite")) { echo " For general information about ", htmlspecialchars($Conf->short_name), ", see <a href=\"", htmlspecialchars(opt("conferenceSite")), "\">the conference site</a>."; } echo "</div>\n<hr class='home' />\n<div class='homegrp' id='homereset'>\n", Ht::form(hoturl_post("resetpassword")), '<div class="f-contain">', Ht::hidden("resetcap", $resetcap), Ht::hidden("autopassword", $_POST["autopassword"]), "<p>Use this form to reset your password. You may want to use the random password we’ve chosen.</p>"; echo '<table style="margin-bottom:2em">', '<tr><td class="lcaption">Your email</td><td>', htmlspecialchars($Acct->email), '</td></tr> <tr><td class="lcaption">Suggested password</td><td>', htmlspecialchars($_POST["autopassword"]), '</td></tr></table>'; echo '<div class="f-i"> <div class="f-c', $password_class, '">New password</div> <div class="f-e">', Ht::password("password", "", array("id" => "login_d", "tabindex" => 1, "size" => 36)), '</div> </div> <div class="f-i"> <div class="f-c', $password_class, '">New password (again)</div> <div class="f-e">', Ht::password("password2", "", array("tabindex" => 1, "size" => 36)), '</div> </div> <div class="f-i" style="margin-top:2em">', Ht::submit("go", "Reset password", array("tabindex" => 1)), "</div>\n</div></form>\n<hr class='home' /></div>\n"; Ht::stash_script("crpfocus(\"login\", null, 2)"); echo '<hr class="c" />', "\n"; $Conf->footer();
function render($sv) { global $Conf; $sv->echo_checkbox("rev_open", "<b>Open site for reviewing</b>"); $sv->echo_checkbox("cmt_always", "Allow comments even if reviewing is closed"); echo "<div class='g'></div>\n"; $sv->echo_checkbox('pcrev_any', "PC members can review <strong>any</strong> submitted paper"); echo "<div class='g'></div>\n"; echo "<strong>Review anonymity:</strong> Are reviewer names hidden from authors?<br />\n"; $sv->echo_radio_table("rev_blind", array(Conf::BLIND_ALWAYS => "Yes—reviews are anonymous", Conf::BLIND_NEVER => "No—reviewer names are visible to authors", Conf::BLIND_OPTIONAL => "Depends—reviewers decide whether to expose their names")); echo "<div class='g'></div>\n"; $sv->echo_checkbox('rev_notifychair', 'Notify PC chairs of newly submitted reviews by email'); // Deadlines echo "<h3 id=\"rounds\" class=\"settings g\">Deadlines & rounds</h3>\n"; echo '<p class="hint">Reviews are due by the deadline, but <em>cannot be modified</em> after the hard deadline. Most conferences don’t use hard deadlines for reviews.<br />', $sv->type_hint("date") ?: "", '</p>'; $rounds = $Conf->round_list(); if ($sv->use_req()) { for ($i = 1; isset($sv->req["roundname_{$i}"]); ++$i) { $rounds[$i] = get($sv->req, "deleteround_{$i}") ? ";" : trim(get_s($sv->req, "roundname_{$i}")); } } // prepare round selector $round_value = trim($sv->curv("rev_roundtag")); $current_round_value = $Conf->setting_data("rev_roundtag", ""); if (preg_match('/\\A(?:|\\(none\\)|\\(no name\\)|default|unnamed|#0)\\z/i', $round_value)) { $round_value = "#0"; } else { if (($round_number = $Conf->round_number($round_value, false)) || ($round_number = $Conf->round_number($current_round_value, false))) { $round_value = "#" . $round_number; } else { $round_value = $selector[$current_round_value] = $current_round_value; } } $round_map = edb_map(Dbl::ql("select reviewRound, count(*) from PaperReview group by reviewRound")); $print_round0 = true; if ($round_value !== "#0" && $round_value !== "" && $current_round_value !== "" && (!$sv->use_req() || isset($sv->req["roundname_0"])) && !$Conf->round0_defined()) { $print_round0 = false; } $selector = array(); if ($print_round0) { $selector["#0"] = "unnamed"; } for ($i = 1; $i < count($rounds); ++$i) { if ($rounds[$i] !== ";") { $selector["#{$i}"] = (object) array("label" => $rounds[$i], "id" => "rev_roundtag_{$i}"); } } echo '<div id="round_container"', count($selector) == 1 ? ' style="display:none"' : '', '>', '<table id="rev_roundtag_table"><tr><td class="lxcaption">', $sv->label("rev_roundtag", "Current round"), '</td><td>', Ht::select("rev_roundtag", $selector, $round_value, $sv->sjs("rev_roundtag")), '</td></tr></table>', '<div class="hint">This round is used for new assignments.</div><div class="g"></div></div>'; echo '<div id="roundtable">'; $num_printed = 0; for ($i = 0; $i < count($rounds); ++$i) { if ($i ? $rounds[$i] !== ";" : $print_round0) { $this->echo_round($sv, $i, $i ? $rounds[$i] : "", +get($round_map, $i), count($selector) !== 1); ++$num_printed; } } echo '</div><div id="newround" style="display:none">'; $this->echo_round($sv, '$', "", "", true); echo '</div><div class="g"></div>'; echo Ht::js_button("Add round", "review_round_settings.add();hiliter(this)"), ' <span class="hint"><a href="', hoturl("help", "t=revround"), '">What is this?</a></span>', Ht::hidden("oldroundcount", count($Conf->round_list())), Ht::hidden("has_rev_roundtag", 1); for ($i = 1; $i < count($rounds); ++$i) { if ($rounds[$i] === ";") { echo Ht::hidden("roundname_{$i}", "", array("id" => "roundname_{$i}")), Ht::hidden("deleteround_{$i}", 1); } } Ht::stash_script("review_round_settings.init()"); // External reviews echo "<h3 class=\"settings g\">External reviews</h3>\n"; echo "<div class='g'></div>"; $sv->echo_checkbox("extrev_chairreq", "PC chair must approve proposed external reviewers"); $sv->echo_checkbox("pcrev_editdelegate", "PC members can edit external reviews they requested"); echo "<div class='g'></div>\n"; $t = expandMailTemplate("requestreview", false); echo "<table id='foldmailbody_requestreview' class='", $t == expandMailTemplate("requestreview", true) ? "foldc" : "foldo", "'><tr><td>", foldbutton("mailbody_requestreview"), "</td>", "<td><a href='#' onclick='return fold(\"mailbody_requestreview\")' class='q'><strong>Mail template for external review requests</strong></a>", " <span class='fx'>(<a href='", hoturl("mail"), "'>keywords</a> allowed; set to empty for default)<br /></span>\n<textarea class='tt fx' name='mailbody_requestreview' cols='80' rows='20'>", htmlspecialchars($t["body"]), "</textarea>", "</td></tr></table>\n"; // Review visibility echo "<h3 class=\"settings g\">Visibility</h3>\n"; echo "Can PC members <strong>see all reviews</strong> except for conflicts?<br />\n"; $sv->echo_radio_table("pc_seeallrev", array(Conf::PCSEEREV_YES => "Yes", Conf::PCSEEREV_UNLESSINCOMPLETE => "Yes, unless they haven’t completed an assigned review for the same paper", Conf::PCSEEREV_UNLESSANYINCOMPLETE => "Yes, after completing all their assigned reviews", Conf::PCSEEREV_IFCOMPLETE => "Only after completing a review for the same paper")); echo "<div class='g'></div>\n"; echo "Can PC members see <strong>reviewer names</strong> except for conflicts?<br />\n"; $sv->echo_radio_table("pc_seeblindrev", array(0 => "Yes", 1 => "Only after completing a review for the same paper<br /><span class='hint'>This setting also hides reviewer-only comments from PC members who have not completed a review for the same paper.</span>")); echo "<div class='g'></div>"; echo "Can external reviewers see the other reviews for their assigned papers, once they’ve submitted their own?<br />\n"; $sv->echo_radio_table("extrev_view", array(2 => "Yes", 1 => "Yes, but they can’t see who wrote blind reviews", 0 => "No")); // Review ratings echo "<h3 class=\"settings g\">Review ratings</h3>\n"; echo "Should HotCRP collect ratings of reviews? <a class='hint' href='", hoturl("help", "t=revrate"), "'>(Learn more)</a><br />\n"; $sv->echo_radio_table("rev_ratings", array(REV_RATINGS_PC => "Yes, PC members can rate reviews", REV_RATINGS_PC_EXTERNAL => "Yes, PC members and external reviewers can rate reviews", REV_RATINGS_NONE => "No")); }