function list_actions(Contact $user, $qreq, PaperList $pl, &$actions) { if (!$user->isPC || Navigation::page() === "reviewprefs") { return; } // tagtype cell $tagopt = array("a" => "Add", "d" => "Remove", "s" => "Define", "xxxa" => null, "ao" => "Add to order", "aos" => "Add to gapless order", "so" => "Define order", "sos" => "Define gapless order", "sor" => "Define random order"); $tagextra = array("id" => "placttagtype"); if ($user->privChair) { $tagopt["xxxb"] = null; $tagopt["da"] = "Clear twiddle"; $tagopt["cr"] = "Calculate rank"; $tagextra["onchange"] = "plactions_dofold()"; Ht::stash_script("plactions_dofold()", "plactions_dofold"); } // tag name cell $t = ""; if ($user->privChair) { $t .= '<span class="fx99"><a class="q" href="#" onclick="return fold(\'placttags\')">' . expander(null, 0) . "</a></span>"; } $t .= 'tag<span class="fn99">(s)</span> ' . Ht::entry("tag", $qreq->tag, ["size" => 15, "onfocus" => "autosub('tag',this)", "class" => "wantcrpfocus"]) . ' ' . Ht::submit("fn", "Go", ["value" => "tag", "onclick" => "return plist_submit.call(this)"]); if ($user->privChair) { $t .= "<div class='fx'><div style='margin:2px 0'>" . Ht::checkbox("tagcr_gapless", 1, $qreq->tagcr_gapless, array("style" => "margin-left:0")) . " " . Ht::label("Gapless order") . "</div>" . "<div style='margin:2px 0'>Using: " . Ht::select("tagcr_method", PaperRank::methods(), $qreq->tagcr_method) . "</div>" . "<div style='margin:2px 0'>Source tag: ~" . Ht::entry("tagcr_source", $qreq->tagcr_source, array("size" => 15)) . "</div></div>"; } $actions[] = [500, "tag", "Tag", "<b>:</b> " . Ht::select("tagfn", $tagopt, $qreq->tagfn, $tagextra) . " ", ["id" => "foldplacttags", "class" => "foldc fold99c", "content" => $t]]; }
function list_actions(Contact $user, $qreq, PaperList $pl, &$actions) { global $Conf; Ht::stash_script("plactions_dofold()", "plactions_dofold"); $Conf->stash_hotcrp_pc($user); $actions[] = [700, "assign", "Assign", "<b>:</b> " . Ht::select("assignfn", array("auto" => "Automatic assignments", "zzz1" => null, "conflict" => "Conflict", "unconflict" => "No conflict", "zzz2" => null, "assign" . REVIEW_PRIMARY => "Primary review", "assign" . REVIEW_SECONDARY => "Secondary review", "assign" . REVIEW_PC => "Optional review", "assign0" => "Clear review", "zzz3" => null, "lead" => "Discussion lead", "shepherd" => "Shepherd"), $qreq->assignfn, ["class" => "wantcrpfocus", "onchange" => "plactions_dofold()"]) . '<span class="fx"> <span id="atab_assign_for">for</span> ' . Ht::select("markpc", [], 0, ["id" => "markpc", "class" => "need-pcselector", "data-pcselector-selected" => $qreq->markpc]) . "</span> " . Ht::submit("fn", "Go", ["value" => "assign", "onclick" => "return plist_submit.call(this)"])]; }
function echo_grade_cdf() { global $Conf, $Info, $Pset, $User, $Me; $sepx = $User->extension && $Pset->separate_extension_grades; $xmark = $sepx ? "extension " : ""; echo '<div id="gradecdf61" style="float:right;position:relative">', '<table class="gradecdf61table"><tbody><tr>', '<td class="yaxislabelcontainer"></td>', '<td class="plot"><div style="width:300px;height:200px"></div></td>', '</tr><tr><td></td><td class="xaxislabelcontainer"></td></tr>', '</tbody></table>', '<table class="gradecdf61summary', $sepx ? " extension" : " all", '"><tbody>', '<tr class="gradecdf61mean"><td class="cap">', $xmark, ' mean</td><td class="val"></td></tr>', '<tr class="gradecdf61median"><td class="cap">', $xmark, ' median</td><td class="val"></td></tr>', '<tr class="gradecdf61stddev"><td class="cap">', $xmark, ' stddev</td><td class="val"></td></tr>', '</tbody></table>', '</div>'; Ht::stash_script("gradecdf61(" . json_encode($Info->hoturl("pset", ["gradecdf" => 1])) . ")"); }
<svg id="soundicon" class="fn" 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.128,49.03 C 50.057,45.934 51.19,42.291 51.19,38.377 C 51.19,34.399 50.026,30.703 48.043,27.577" style="fill:none;stroke:#111111;stroke-width:5;stroke-linecap:round"/> <path d="M 55.082,20.537 C 58.777,25.523 60.966,31.694 60.966,38.377 C 60.966,44.998 58.815,51.115 55.178,56.076" style="fill:none;stroke:#111111;stroke-width:5;stroke-linecap:round"/> <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>
$Sv->report(); } $Conf->header("Settings ∕ <strong>" . SettingGroup::$all[$Group]->description . "</strong>", "settings", actionBar()); $Conf->echoScript(""); // clear out other script references echo $Conf->make_script_file("scripts/settings.js"), "\n"; echo Ht::form(hoturl_post("settings", "group={$Group}"), array("id" => "settingsform")); echo '<div class="leftmenu_menucontainer"><div class="leftmenu_list">'; foreach (SettingGroup::all() as $g) { if ($g->name === $Group) { echo '<div class="leftmenu_item_on">', $g->description, '</div>'; } else { echo '<div class="leftmenu_item">', '<a href="', hoturl("settings", "group={$g->name}"), '">', $g->description, '</a></div>'; } } echo "</div></div>\n", '<div class="leftmenu_content_container"><div class="leftmenu_content">', '<div class="leftmenu_body">'; Ht::stash_script("jQuery(\".leftmenu_item\").click(divclick)"); function doActionArea($top) { echo "<div class='aa'>", Ht::submit("update", "Save changes", array("class" => "bb")), " ", Ht::submit("cancel", "Cancel"), "</div>"; } echo "<div class='aahc'>"; doActionArea(true); echo "<div>"; $Sv->interesting_groups[$Group] = true; SettingGroup::$all[$Group]->render($Sv); echo "</div>"; doActionArea(false); echo "</div></div></div></div></form>\n"; $Conf->footerScript("hiliter_children('#settingsform');jQuery('textarea').autogrow()"); $Conf->footer();
if (!isset($_REQUEST["template"]) || !isset($tmpl[$_REQUEST["template"]])) { $_REQUEST["template"] = "genericmailtool"; } echo Ht::select("template", $tmpl, $_REQUEST["template"], array("onchange" => "highlightUpdate(\"loadtmpl\")")), " ", Ht::submit("loadtmpl", "Load", array("id" => "loadtmpl")), " \n <span class='hint'>Templates are mail texts tailored for common conference tasks.</span>\n</div>\n\n<div class='mail' style='float:left;margin:4px 1em 12px 0'><table>\n"; // ** TO echo '<tr><td class="mhnp">To:</td><td class="mhdd">', $recip->selectors(), "<div class='g'></div>\n"; // paper selection echo '<div id="foldpsel" class="fold8c fold9o fold10c">'; echo '<table class="fx9"><tr><td>', Ht::checkbox("plimit", 1, isset($_REQUEST["plimit"]), array("id" => "plimit", "onchange" => "fold('psel', !this.checked, 8)")), " </td><td>", Ht::label("Choose individual papers", "plimit"); echo "<span class='fx8'>:</span><br /><div class='fx8'>"; $q = defval($_REQUEST, "q", "(All)"); echo "Search ", Ht::entry("q", @$_REQUEST["q"], array("id" => "q", "hottemptext" => "(All)", "class" => "hotcrp_searchbox", "size" => 36, "title" => "Enter paper numbers or search terms")), " in ", Ht::select("t", $tOpt, $_REQUEST["t"], array("id" => "t")), "</div></td></tr></table>\n"; echo '<div class="fx9 g"></div></div>'; Ht::stash_script("fold(\"psel\",!\$\$(\"plimit\").checked,8);" . "setmailpsel(\$\$(\"recipients\"))"); echo "</td></tr>\n"; Ht::stash_script("mktemptext('q','(All)')"); // ** CC, REPLY-TO if ($Me->privChair) { foreach (Mailer::$email_fields as $lcfield => $field) { if ($lcfield !== "to" && $lcfield !== "bcc") { $xfield = $lcfield == "reply-to" ? "replyto" : $lcfield; $ec = isset($Error[$xfield]) ? " error" : ""; echo " <tr><td class='mhnp{$ec}'>{$field}:</td><td class='mhdp{$ec}'>", "<input type='text' class='textlite-tt' name='{$xfield}' value=\"", htmlspecialchars($_REQUEST[$xfield]), "\" size='64' />", $xfield == "replyto" ? "<div class='g'></div>" : "", "</td></tr>\n\n"; } } } // ** SUBJECT echo " <tr><td class='mhnp'>Subject:</td><td class='mhdp'>", "<tt>[", htmlspecialchars($Opt["shortName"]), "] </tt><input type='text' class='textlite-tt' name='subject' value=\"", htmlspecialchars($_REQUEST["subject"]), "\" size='64' /></td></tr>\n\n <tr><td></td><td class='mhb'>\n <textarea class='tt' rows='20' name='emailBody' cols='80'>", htmlspecialchars($_REQUEST["emailBody"]), "</textarea>\n </td></tr>\n</table></div>\n\n"; if ($Me->privChair) { $result = $Conf->qe("select * from MailLog order by mailId desc limit 18"); if (edb_nrows($result)) {
public static function color_classes($tags, $color_type_bit = 1) { if (is_array($tags)) { $tags = join(" ", $tags); } if (!$tags || $tags === " ") { return ""; } if (!preg_match_all(self::color_regex(), $tags, $m)) { return false; } $dt = self::defined_tags(); $classes = array(); foreach ($m[1] as $tag) { if (($t = $dt->check($tag)) && $t->colors) { foreach ($t->colors as $k) { $classes[] = $k . "tag"; } } else { $classes[] = self::canonical_color($tag) . "tag"; } } if ($color_type_bit > 1) { $classes = array_filter($classes, "TagInfo::classes_have_colors"); } if (count($classes) > 1) { sort($classes); $classes = array_unique($classes); } $key = join(" ", $classes); // This seems out of place---it's redundant if we're going to // generate JSON, for example---but it is convenient. if (count($classes) > 1) { $m = (int) get(self::$multicolor_map, $key); if (!($m & $color_type_bit)) { if ($color_type_bit == 1) { Ht::stash_script("make_pattern_fill(" . json_encode($key) . ")"); } self::$multicolor_map[$key] = $m | $color_type_bit; } } return $key; }
$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();
private function _analyze_folds($rstate, $fieldDef) { global $Conf; $classes = $jsmap = $jscol = array(); $has_sel = false; $ord = 0; foreach ($fieldDef as $fdef) { $j = ["name" => $fdef->name, "title" => $this->_field_title($fdef, $ord)]; if ($fdef->className != "pl_" . $fdef->name) { $j["className"] = $fdef->className; } if ($fdef->view == Column::VIEW_COLUMN) { $j["column"] = true; ++$ord; } if ($fdef->is_folded && $fdef->has_content) { $j["loadable"] = true; } if ($fdef->is_folded && $fdef->name !== "authors") { $j["missing"] = true; } if ($fdef->foldable) { $j["foldnum"] = $fdef->foldable; } $fdef->annotate_field_js($this, $j); $jscol[] = $j; if ($fdef->foldable && $fdef->name !== "authors") { $classes[] = "fold{$fdef->foldable}" . ($fdef->is_folded ? "c" : "o"); $jsmap[] = "\"{$fdef->name}\":{$fdef->foldable}"; } if (isset($fdef->is_selector)) { $has_sel = true; } } // authorship requires special handling if ($rstate->has_openau || $rstate->has_anonau) { $classes[] = "fold1" . ($this->is_folded("au") ? "c" : "o"); $jsmap[] = "\"au\":1,\"aufull\":4"; } if ($rstate->has_anonau) { $classes[] = "fold2" . ($this->is_folded("anonau") ? "c" : "o"); $jsmap[] = "\"anonau\":2"; } // total folding, row number folding if ($rstate->row_folded) { $classes[] = "fold3c"; } if ($has_sel) { $jsmap[] = "\"rownum\":6"; $classes[] = "fold6" . ($this->is_folded("rownum") ? "c" : "o"); } if ($this->contact->privChair) { $jsmap[] = "\"force\":5"; $classes[] = "fold5" . ($this->qreq->forceShow ? "o" : "c"); } if ($this->viewmap->table_id) { if (!empty($jsmap)) { Ht::stash_script("foldmap.pl={" . join(",", $jsmap) . "};"); } $args = array(); if ($this->search->q) { $args["q"] = $this->search->q; } if ($this->search->qt) { $args["qt"] = $this->search->qt; } $args["t"] = $this->search->limitName; $args["pap"] = join(" ", $rstate->ids); Ht::stash_script("plinfo.needload(" . json_encode($args) . ");" . "plinfo.set_fields(" . json_encode($jscol) . ");"); } return $classes; }
public function stash_hotcrp_pc(Contact $user) { if (!Ht::mark_stash("hotcrp_pc")) { return; } $sortbylast = opt("sortByLastName"); $hpcj = $list = []; foreach (pcMembers() as $pcm) { $hpcj[$pcm->contactId] = $j = (object) ["name" => $user->name_html_for($pcm), "email" => $pcm->email]; if ($color_classes = $user->reviewer_color_classes_for($pcm)) { $j->color_classes = $color_classes; } if ($sortbylast && $pcm->lastName) { $r = Text::analyze_name($pcm); if (strlen($r->lastName) !== strlen($r->name)) { $j->lastpos = strlen(htmlspecialchars($r->firstName)) + 1; } if ($r->nameAmbiguous && $r->name && $r->email) { $j->emailpos = strlen(htmlspecialchars($r->name)) + 1; } } $list[] = $pcm->contactId; } $hpcj["__order__"] = $list; if ($sortbylast) { $hpcj["__sort__"] = "last"; } Ht::stash_script("hotcrp_pc=" . json_encode($hpcj) . ";"); }
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"); }
static function echo_repo_last_commit_group($info, $commitgroup) { global $Me, $Conf; list($user, $repo) = array($info->user, $info->repo); if ($info->pset->gitless) { return; } if ($repo && !$info->user_can_view_repo_contents) { $value = "(unconfirmed repository)"; } else { if ($repo && $repo->snaphash) { $value = substr($repo->snaphash, 0, 7) . " " . htmlspecialchars($repo->snapcommitline); } else { if ($repo) { $value = "(checking)"; } else { $value = "(no repo yet)"; } } } $notes = array(); if ($repo && $repo->snapat && $info->can_view_repo_contents) { $n = "committed " . ago($repo->snapcommitat) . ", fetched " . ago($repo->snapat) . ", last checked " . ago($repo->snapcheckat); if ($Me->privChair) { $n .= " <small style=\"padding-left:1em;font-size:70%\">group " . $repo->cacheid . ", repo" . $repo->repoid . "</small>"; } $notes[] = $n; } if ($repo && !$info->user_can_view_repo_contents) { if ($user->is_anonymous) { $notes[] = array(true, "ERROR: The user hasn’t confirmed that they can view this repository."); } else { $uname = Text::analyze_name($user); if ($uname->name && $uname->email) { $uname = "{$uname->name} <{$uname->email}>"; } else { if ($uname->email) { $uname = "Your Name <{$uname->email}>"; } else { if ($uname->name) { $uname = "{$uname->name} <*****@*****.**>"; } else { $uname = "Your Name <*****@*****.**>"; } } } $notes[] = array(true, "ERROR: We haven’t confirmed that you can view this repository.<br>\n We only let you view repositories that you’ve committed to.<br>\n Fix this error by making a commit from your email address, " . htmlspecialchars($user->email) . ", and pushing that commit to the repository.<br>\n For example, try these commands: <pre>git commit --allow-empty --author=" . htmlspecialchars(escapeshellarg($uname)) . " \\\n -m \"Confirm repository\" && git push</pre>"); } $commitgroup = true; } if ($commitgroup) { echo "<div class=\"commitcontainer61\" data-pa-pset=\"", htmlspecialchars($info->pset->urlkey); if ($repo && $repo->snaphash && $info->can_view_repo_contents) { echo "\" data-pa-commit=\"", $repo->snaphash; } echo "\">"; Ht::stash_script("checklatest61()", "checklatest61"); } self::echo_group("last commit", $value, $notes); if ($commitgroup) { echo "</div>"; } }
function header($title, $id = "", $actionBar = null, $showTitle = true) { global $ConfSitePATH, $Me, $Now; if ($this->headerPrinted) { return; } // <head> if ($title === "Home") { $title = ""; } $this->header_head($title); // <body> echo "<body", $id ? " id=\"{$id}\"" : "", " onload=\"hotcrp_load()\">\n"; // initial load (JS's timezone offsets are negative of PHP's) Ht::stash_script("hotcrp_load.time(" . -date("Z", $Now) / 60 . "," . ($this->opt("time24hour") ? 1 : 0) . ")"); echo "<div id='prebody'>\n"; echo "<div id='header'>\n<div id='header_left_conf'><h1>"; if ($title && $showTitle && ($title == "Home" || $title == "Sign in")) { echo "<a name='' class='qq' href='", hoturl("index"), "' title='Home'>", htmlspecialchars($this->short_name), "</a>"; } else { echo "<a name='' class='uu' href='", hoturl("index"), "' title='Home'>", htmlspecialchars($this->short_name), "</a></h1></div><div id='header_left_page'><h1>", $title; } echo "</h1></div><div id='header_right'>"; if ($Me && !$Me->is_empty()) { // profile link $profile_parts = []; if ($Me->has_email() && !$Me->disabled) { $profile_parts[] = '<strong>' . htmlspecialchars($Me->email) . '</strong>'; /*echo '<a class="q" href="', hoturl("profile"), '"><strong>', htmlspecialchars($Me->email), '</strong></a> <a href="', hoturl("profile"), '">Profile</a>', $xsep;*/ } // "act as" link if (($actas = get($_SESSION, "last_actas")) && get($_SESSION, "trueuser") && ($Me->privChair || Contact::$trueuser_privChair === $Me)) { // Link becomes true user if not currently chair. if (!$Me->privChair || strcasecmp($Me->email, $actas) == 0) { $actas = $_SESSION["trueuser"]->email; } if (strcasecmp($Me->email, $actas) != 0) { $profile_parts[] = "<a href=\"" . self_href(["actas" => $actas]) . "\">" . ($Me->privChair ? htmlspecialchars($actas) : "Admin") . " " . Ht::img("viewas.png", "Act as " . htmlspecialchars($actas)) . "</a>"; } } // help, sign out $x = $id == "search" ? "t={$id}" : ($id == "settings" ? "t=chair" : ""); if (!$Me->has_email() && !isset($this->opt["httpAuthLogin"])) { $profile_parts[] = '<a href="' . hoturl("index", "signin=1") . '">Sign in</a>'; } if (!$Me->is_empty() || isset($this->opt["httpAuthLogin"])) { $profile_parts[] = '<a href="' . hoturl_post("index", "signout=1") . '">Sign out</a>'; } if (!empty($profile_parts)) { echo join(' <span class="barsep">·</span> ', $profile_parts); } } echo '<div id="maindeadline" style="display:none"></div></div>', "\n"; echo " <hr class=\"c\" />\n"; echo $actionBar; echo "</div>\n<div id=\"initialmsgs\">\n"; if ($x = $this->opt("maintenance")) { echo "<div class=\"merror\"><strong>The site is down for maintenance.</strong> ", is_string($x) ? $x : "Please check back later.", "</div>"; } $this->save_messages = false; if (($msgs = $this->session("msgs")) && count($msgs)) { $this->save_session("msgs", null); foreach ($msgs as $m) { $this->msg($m[0], $m[1]); } echo "<div id=\"initialmsgspacer\"></div>"; } echo "</div>\n"; $this->headerPrinted = true; echo "</div>\n<div class='body'>\n"; }
function footerScript($script, $uniqueid = null) { Ht::stash_script($script, $uniqueid); }
$result = Dbl::qe("select cn.*, rg.gradercid main_gradercid, rg.gradehash\n from CommitNotes cn\n left join RepositoryGrade rg on (rg.repoid=cn.repoid and rg.pset=cn.pset)\n where hasactiveflags=1"); if (edb_nrows($result)) { echo $sep; show_regrades($result); if ($Profile) { echo "<div>Δt ", sprintf("%.06f", microtime(true) - $t0), "</div>"; } $sep = "<hr />\n"; } $pctable = []; foreach (pcMembers() as $pc) { if ($pc->firstName && !$pc->firstNameAmbiguous) { $pctable[$pc->contactId] = $pc->firstName; } else { $pctable[$pc->contactId] = Text::name_text($pc); } } Ht::stash_script('peteramati_grader_map=' . json_encode($pctable) . ';'); foreach (ContactView::pset_list($Me, true) as $pset) { echo $sep; show_pset_table($pset, $Me); $sep = "<hr />\n"; } Ht::stash_script("\$('.s61check').click(click_s61check)"); if ($LastPsetFix) { $Conf->log("Repository.lastpset links are bogus", $Me); Contact::update_all_repo_lastpset(); } } echo "<div class='clear'></div>\n"; $Conf->footer();
function echo_editable_html(PaperOptionValue $ov, $reqv, PaperTable $pt) { $reqv = !!($reqv === null ? $ov->value : $reqv); $pt->echo_editable_option_papt($this, Ht::checkbox_h("opt{$this->id}", 1, $reqv) . " " . Ht::label(htmlspecialchars($this->name))); echo "</div>\n\n"; Ht::stash_script("jQuery('#opt{$this->id}_div').click(function(e){if(e.target==this)jQuery(this).find('input').click();})"); }
function goPaperForm($baseUrl = null, $args = array()) { global $Conf, $Me, $CurrentList; if ($Me->is_empty()) { return ""; } if ($baseUrl === null) { $baseUrl = $Me->isPC && $Conf->setting("rev_open") ? "review" : "paper"; } $x = "<form class='gopaper' action='" . hoturl($baseUrl) . "' method='get' accept-charset='UTF-8'><div class='inform'>"; $x .= "<input id='quicksearchq' class='textlite temptext' type='text' size='10' name='p' value='(All)' title='Enter paper numbers or search terms' />"; Ht::stash_script("mktemptext('quicksearchq','(All)')"); foreach ($args as $what => $val) { $x .= "<input type='hidden' name=\"" . htmlspecialchars($what) . "\" value=\"" . htmlspecialchars($val) . "\" />"; } if (isset($CurrentList) && $CurrentList > 0) { $x .= "<input type='hidden' name='ls' value='{$CurrentList}' />"; } $x .= " <input class='b' type='submit' value='Search' /></div></form>"; return $x; }
function echo_file_diff($file, DiffInfo $dinfo, LinenotesOrder $lnorder, $open) { $fileid = html_id_encode($file); $tabid = "file61_" . $fileid; $linenotes = $lnorder->file($file); echo '<h3><a class="fold61" href="#" onclick="return fold61(', "'#{$tabid}'", ',this)"><span class="foldarrow">', $open ? "▼" : "▶", "</span> ", htmlspecialchars($file), "</a>"; if (!$dinfo->removed) { $rawfile = $file; if ($this->repo->truncated_psetdir($this->pset) && str_starts_with($rawfile, $this->pset->directory_slash)) { $rawfile = substr($rawfile, strlen($this->pset->directory_slash)); } echo '<a style="display:inline-block;margin-left:2em;font-weight:normal" href="', $this->hoturl("raw", ["file" => $rawfile]), '">[Raw]</a>'; } echo '</h3>'; echo '<table id="', $tabid, '" class="code61 diff61 filediff61'; if ($this->pc_view) { echo " live"; } if (!$this->user_can_see_grades) { echo " hidegrade61"; } if (!$open) { echo '" style="display:none'; } echo '" data-pa-file="', htmlspecialchars($file), '" data-pa-fileid="', $fileid, "\"><tbody>\n"; if ($this->pc_view) { Ht::stash_script("jQuery('#{$tabid}').mousedown(linenote61).mouseup(linenote61)"); } foreach ($dinfo->diff as $l) { if ($l[0] == "@") { $x = array(" gx", "difflctx61", "", "", $l[3]); } else { if ($l[0] == " ") { $x = array(" gc", "difflc61", $l[1], $l[2], $l[3]); } else { if ($l[0] == "-") { $x = array(" gd", "difflc61", $l[1], "", $l[3]); } else { $x = array(" gi", "difflc61", "", $l[2], $l[3]); } } } $aln = $x[2] ? "a" . $x[2] : ""; $bln = $x[3] ? "b" . $x[3] : ""; $ak = $bk = ""; if ($linenotes && $aln && isset($linenotes->{$aln})) { $ak = ' id="L' . $aln . '_' . $fileid . '"'; } if ($bln) { $bk = ' id="L' . $bln . '_' . $fileid . '"'; } if (!$x[2] && !$x[3]) { $x[2] = $x[3] = "..."; } echo '<tr class="diffl61', $x[0], '">', '<td class="difflna61"', $ak, '>', $x[2], '</td>', '<td class="difflnb61"', $bk, '>', $x[3], '</td>', '<td class="', $x[1], '">', diff_line_code($x[4]), "</td></tr>\n"; if ($linenotes && $bln && isset($linenotes->{$bln})) { $this->echo_linenote($file, $bln, $linenotes->{$bln}, $lnorder); } if ($linenotes && $aln && isset($linenotes->{$aln})) { $this->echo_linenote($file, $aln, $linenotes->{$aln}, $lnorder); } } echo "</tbody></table>\n"; }
} 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 { if (!$Info->commit()) { quit("No commit to run"); } else {
$lnorder = new LinenotesOrder($all_linenotes, $Info->can_see_grades); $lnorder->set_diff($diff); // print line notes $notelinks = array(); foreach ($lnorder->seq() as $fl) { $f = str_starts_with($fl[0], $Pset->directory_slash) ? substr($fl[0], strlen($Pset->directory_slash)) : $fl[0]; $notelinks[] = '<a href="#L' . $fl[1] . '_' . html_id_encode($fl[0]) . '" onclick="return gotoline61(this)" class="noteref61' . (!$fl[2] && !$Info->user_can_see_grades ? " hiddennote61" : "") . '">' . htmlspecialchars($f) . ':' . substr($fl[1], 1) . '</a>'; } if (count($notelinks)) { ContactView::echo_group("notes", join(", ", $notelinks)); } // check for any linenotes $has_any_linenotes = false; foreach ($diff as $file => $dinfo) { if ($lnorder->file($file)) { $has_any_linenotes = true; break; } } // line notes foreach ($diff as $file => $dinfo) { $linenotes = $lnorder->file($file); $open = $linenotes || !$dinfo->boring || !$hasha_mine && !$hashb_mine; $Info->echo_file_diff($file, $dinfo, $lnorder, $open); } Ht::stash_script('jQuery(".diffnoteentry61").autogrow();jQuery(window).on("beforeunload",beforeunload61)'); echo "<table id=\"diff61linenotetemplate\" style=\"display:none\"><tbody>"; $Info->echo_linenote_entry_prototype(); echo "</tbody></table>"; echo "<div class='clear'></div>\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")); }