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]]; }
private function do_track($sv, $trackname, $tnum) { global $Conf; echo "<div id=\"trackgroup{$tnum}\"", $tnum ? "" : " style=\"display:none\"", "><table style=\"margin-bottom:0.5em\">"; echo "<tr><td colspan=\"3\" style=\"padding-bottom:3px\">"; if ($trackname === "_") { echo "For papers not on other tracks:", Ht::hidden("name_track{$tnum}", "_"); } else { echo $sv->label("name_track{$tnum}", "For papers with tag "), Ht::entry("name_track{$tnum}", $trackname, $sv->sjs("name_track{$tnum}", array("placeholder" => "(tag)"))), ":"; } echo "</td></tr>\n"; $t = $Conf->setting_json("tracks"); $t = $t && $trackname !== "" ? get($t, $trackname) : null; $this->do_track_permission($sv, "view", "Who can see these papers?", $tnum, $t); $this->do_track_permission($sv, "viewpdf", ["Who can see PDFs?", "Assigned reviewers can always see PDFs."], $tnum, $t); $this->do_track_permission($sv, "viewrev", "Who can see reviews?", $tnum, $t); $hint = ""; if ($Conf->setting("pc_seeblindrev")) { $hint = "Regardless of this setting, PC members can’t see reviewer names until they’ve completed a review for the same paper (<a href=\"" . hoturl("settings", "group=reviews") . "\">Settings > Reviews > Visibility</a>)."; } $this->do_track_permission($sv, "viewrevid", ["Who can see reviewer names?", $hint], $tnum, $t); $this->do_track_permission($sv, "assrev", "Who can be assigned a review?", $tnum, $t); $this->do_track_permission($sv, "unassrev", "Who can self-assign a review?", $tnum, $t); if ($trackname === "_") { $this->do_track_permission($sv, "viewtracker", "Who can see the <a href=\"" . hoturl("help", "t=chair#meeting") . "\">meeting tracker</a>?", $tnum, $t); } echo "</table></div>\n\n"; }
function formulas_qrow($i, $q, $s, $errf) { if ($q === "all") { $q = ""; } $klass = ($errf ? "setting_error " : "") . "hotcrp_searchbox"; $t = '<tr><td class="lentry">' . Ht::entry("q{$i}", $q, array("size" => 40, "placeholder" => "(All)", "class" => $klass)); $t .= " <span style=\"padding-left:1em\">Style:</span> " . Ht::select("s{$i}", array("plain" => "plain", "by-tag" => "by tag", "redtag" => "red", "orangetag" => "orange", "yellowtag" => "yellow", "greentag" => "green", "bluetag" => "blue", "purpletag" => "purple", "graytag" => "gray"), $s !== "" ? $s : "by-tag"); $t .= '</td><td class="nw"><a href="#" class="qx row_up" onclick="return author_change(this,-1)" tabindex="-1">▲</a><a href="#" class="qx row_down" onclick="return author_change(this,1)" tabindex="-1">▼</a><a href="#" class="qx row_kill" onclick="return author_change(this,Infinity)" tabindex="-1">x</a></td></tr>'; return $t; }
static function echo_username_form(Contact $user, $first) { global $Me; if (!$first && !$user->seascode_username) { return; } echo Ht::form(hoturl_post("index", array("set_username" => 1, "u" => $Me->user_linkpart($user), "reposite" => "harvardseas"))), '<div class="f-contain">'; $notes = array(); if (!$user->seascode_username) { $notes[] = array(true, "Please enter your " . self::home_link("code.seas.harvard.edu") . " username and click “Save.”"); } ContactView::echo_group(self::home_link("code.seas") . " username", Ht::entry("username", $user->seascode_username) . " " . Ht::submit("Save"), $notes); echo "</div></form>"; }
function echo_all_grades() { global $Me, $User, $Pset, $Info; if ($Info->is_handout_commit()) { return; } $gj = ContactView::grade_json($Info); if (get($gj, "grades") || $Info->can_see_grades && $Me != $User) { echo_grade_total($gj); foreach ($Pset->grades as $ge) { echo_grade_entry($ge); } } $lhg = $Info->late_hours(); if ($lhg && $User == $Me && $Info->can_see_grades) { if ($lhg->hours || get($gj, "grades")) { echo '<div style="margin-top:1.5em">'; ContactView::echo_group("late hours", '<span class="grader61" data-pa-grade="late_hours">' . htmlspecialchars($lhg->hours) . '</span>', array(), array("nowrap" => true)); echo '</div>'; } } else { if ($User != $Me) { $lhag = $Info->late_hours(true); $value = '<span class="gradeholder61">' . Ht::entry("late_hours", $lhg ? $lhg->hours : "", array("onchange" => "jQuery(this).closest('form').submit()", "class" => "grader61")) . '</span>'; $value .= " " . Ht::submit("Save", array("tabindex" => 1)); $value .= ' <span class="ajaxsave61"></span>'; if ($lhag && $lhag->hours !== $lhg->hours) { $value .= ' <span class="autograde61">auto-late hours is ' . htmlspecialchars($lhag->hours) . '</span>'; } echo Ht::form($Info->hoturl_post("pset", array("setlatehours" => 1)), array("onsubmit" => "return gradesubmit61(this)")), '<div class="f-contain" style="margin-top:1.5em">'; ContactView::echo_group("late hours", $value, array(), array("nowrap" => true)); echo '</div></form>'; } } }
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; }
asort($tmpl); foreach ($tmpl as $k => &$v) { $v = $mailTemplates[$k]["mailtool_name"]; } 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
static function echo_repo_group($info, $include_tarball = false) { global $Conf, $Me, $Now; if ($info->pset->gitless) { return; } list($user, $pset, $partner, $repo) = array($info->user, $info->pset, $info->partner, $info->repo); $editable = $info->can_set_repo && !$user->is_anonymous; $repo_url = $user->seascode_repo_base($repo ? $repo->url : ""); $title = "repository"; if ($repo_url && strpos($repo_url, ":") === false) { $title = $user->repo_link($repo_url, $title); } if ($editable) { $value = Ht::entry("repo", $repo_url, array("style" => "width:32em")) . " " . Ht::submit("Save"); } else { if ($user->is_anonymous) { $value = $repo_url ? "[anonymous]" : "(none)"; } else { $value = htmlspecialchars($repo_url ? $repo_url : "(none)"); } } if ($repo_url) { $value .= ' <button class="b repoclip hottooltip" data-pa-repo="' . htmlspecialchars($repo->url) . '"'; if ($user->is_anonymous) { $value .= ' data-tooltip="[anonymous]"'; } else { $value .= ' data-tooltip="' . htmlspecialchars($repo->url) . '"'; } $value .= ' type="button" onclick="false">Copy URL to clipboard</button>'; $Conf->footerScript('$(".repoclip").each(pa_init_repoclip)', "repoclip"); if ($include_tarball && $info->commit_hash() && ($tarball_url = $info->tarball_url())) { $value .= ' <a class="bsm q" href="' . htmlspecialchars($tarball_url) . '">Download tarball for ' . substr($info->commit_hash(), 0, 7) . '</a>'; } } // check repo $notes = array(); if ($repo && !$repo->working) { if ($user->check_seascode_repo($pset, $repo, false)) { $Now = time(); $Conf->qe("update Repository set `working`={$Now} where repoid={$repo->repoid}"); } else { $notes[] = array(true, "ERROR: " . Messages::$main->expand_html("repo_unreadable", $user->repo_messagedefs($repo))); } } if (($open = $info->check_repo_open()) > 0) { $notes[] = array(true, "ERROR: " . Messages::$main->expand_html("repo_toopublic", $user->repo_messagedefs($repo))); } else { if ($open < 0 && $Me->isPC) { $notes[] = array(true, "WARNING: " . Messages::$main->expand_html("repo_toopublic_timeout", $user->repo_messagedefs($repo))); } } if ($partner && $info->partner_same) { $prepo = $partner->repo($pset->id); if (!$repo && $prepo || $repo && !$prepo || $repo && $prepo && $repo->repoid != $prepo->repoid) { if ($prepo) { $prepo_url = ", " . htmlspecialchars($user->seascode_repo_base($prepo->url)); } else { $prepo_url = ""; } $your_partner = "your partner’s"; if ($Me->isPC) { $your_partner = '<a href="' . hoturl("pset", array("pset" => $pset->urlkey, "u" => $Me->user_linkpart($partner))) . '">' . $your_partner . '</a>'; } $notes[] = array(true, "ERROR: This repository differs from {$your_partner}{$prepo_url}."); } } if ($repo && $repo_url[0] == "~" && $user->seascode_username && !preg_match("_\\A~(?:" . preg_quote($user->seascode_username) . ($partner ? "|" . preg_quote($partner->seascode_username) : "") . ")/_i", $repo_url)) { if ($partner) { $notes[] = array(true, "ERROR: This repository belongs to neither you nor your partner."); } else { $notes[] = array(true, "ERROR: This repository does not belong to you."); } } if ($repo && isset($repo->truncated_psetdir) && defval($repo->truncated_psetdir, $pset->id)) { $notes[] = array(true, "Please create your repository by cloning our repository. Creating your repository from scratch makes it harder for us to grade and harder for you to get pset updates."); } if (!$repo) { $notes[] = array(false, "Enter your " . Contact::seascode_home("code.seas") . " repository URL here."); } // edit if ($editable) { echo Ht::form(self_href(array("post" => post_value(), "set_seascode_repo" => 1, "pset" => $pset->urlkey))), '<div class="f-contain">'; } self::echo_group($title, $value, $notes); if ($editable) { echo "</div></form>\n"; } return $repo; }
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; }
function reviewTokenGroup($non_reviews) { global $Conf, $reviewTokenGroupPrinted; if ($reviewTokenGroupPrinted) { return; } $tokens = array(); foreach ($Conf->session("rev_tokens", array()) as $tt) { $tokens[] = encode_token((int) $tt); } if ($non_reviews) { echo '<div class="homegrp" id="homerev">', "<h4>Review tokens: </h4>"; } else { echo '<table id="foldrevtokens" class="', count($tokens) ? "fold2o" : "fold2c", '" style="display:inline-table">', '<tr><td class="fn2"><a class="fn2" href="#" onclick="return foldup(this,event)">Add review tokens</a></td>', '<td class="fx2">Review tokens: '; } echo Ht::form_div(hoturl_post("index")), Ht::entry("token", join(" ", $tokens), array("size" => max(15, count($tokens) * 8))), " ", Ht::submit("Save"); if (!count($tokens)) { echo '<div class="hint">Enter tokens to gain access to the corresponding reviews.</div>'; } echo '</div></form>'; if ($non_reviews) { echo '<hr class="home" /></div>', "\n"; } else { echo '</td></tr></table>', "\n"; } $reviewTokenGroupPrinted = true; }
} echo '<h2 class="homeemail"><a class="q" href="', hoturl("index", array("u" => $u)), '">', htmlspecialchars($u), '</a>'; if ($Me->privChair) { echo " ", become_user_link($User); } echo '</h2>'; if (!$User->is_anonymous && $User !== $Me) { echo '<h3>', Text::user_html($User), '</h3>'; } if (!$User->is_anonymous) { echo Ht::form(hoturl_post("index", array("set_seascode_username" => 1, "u" => $Me->user_linkpart($User)))), '<div class="f-contain">'; $notes = array(); if (!$User->seascode_username) { $notes[] = array(true, "Please enter your " . Contact::seascode_home("code.seas.harvard.edu") . " username and click “Save.”"); } ContactView::echo_group(Contact::seascode_home("code.seas") . " username", Ht::entry("username", $User->seascode_username) . " " . Ht::submit("Save"), $notes); echo "</div></form>"; } if ($User->dropped) { ContactView::echo_group("", '<strong class="err">You have dropped the course.</strong> If this is incorrect, contact us.'); } echo '<hr class="c" />', "</div>\n"; } // Per-pset function render_grades($pset, $gi, $s) { global $Me; $total = $nintotal = $max = 0; $lastintotal = null; $garr = array(); foreach ($pset->grades as $ge) {
// Hit a button to change your password echo Ht::js_button("Change password", "fold('password',null,3)", array("class" => "fn3")); // Display the following after the button is clicked echo '<div class="fx3">'; if (!$Me->can_change_password(null)) { echo '<div class="f-h">Enter your current password as well as your desired new password.</div>'; echo '<div class="f-i"><div class="', fcclass("password"), '">Current password</div>', '<div class="', feclass("password"), '">', Ht::password("oldpassword", "", array("size" => 24)), '</div>', '</div>'; } if (@$Opt["contactdb_dsn"] && @$Opt["contactdb_loginFormHeading"]) { echo $Opt["contactdb_loginFormHeading"]; } echo '<div class="f-i"><div class="f-ix"> <div class="', fcclass("password"), '">New password</div> <div class="', feclass("password"), '">', Ht::password("upassword", "", array("size" => 24, "class" => "fn")); if ($Acct->plaintext_password() && $Me->privChair) { echo Ht::entry("upasswordt", contact_value("upasswordt", "password"), array("size" => 24, "class" => "fx")); } echo '</div> </div><div class="fn f-ix"> <div class="', fcclass("password"), '">Repeat new password</div> <div class="', feclass("password"), '">', Ht::password("upassword2", "", array("size" => 24)), "</div>\n</div>\n"; if ($Acct->plaintext_password() && ($Me->privChair || Contact::password_storage_cleartext())) { echo " <div class=\"f-h\">"; if (Contact::password_storage_cleartext()) { echo "The password is stored in our database in cleartext and will be mailed to you if you have forgotten it, so don’t use a login password or any other high-security password."; } if ($Me->privChair) { $Conf->footerScript("function shift_password(dir){var form=\$\$(\"accountform\");fold(\"account\",dir);if(form&&form.whichpassword)form.whichpassword.value=dir?\"\":\"t\";return false}"); if (Contact::password_storage_cleartext()) { echo " <span class=\"sep\"></span>"; }
echo "</div>\n"; echo divClass("lead", "hotradiorelation"); doRadio('a', 'lead', 'Assign discussion lead from reviewers, preferring '); doSelect('leadscore', $scoreselector); echo "</div>\n"; echo divClass("shepherd", "hotradiorelation"); doRadio('a', 'shepherd', 'Assign shepherd from reviewers, preferring '); doSelect('shepherdscore', $scoreselector); echo "</div>\n"; echo "<div class='g'></div>", divClass("clear", "hotradiorelation"); doRadio('a', 'clear', 'Clear all '); doSelect('cleartype', array(REVIEW_PRIMARY => "primary", REVIEW_SECONDARY => "secondary", REVIEW_PC => "optional", "conflict" => "conflict", "lead" => "discussion lead", "shepherd" => "shepherd")); echo " assignments for selected papers and PC members"; echo "<div class='g'></div>", divClass("discorder", "hotradiorelation"); doRadio("a", "discorder", "Create discussion order in tag #"); echo Ht::entry("discordertag", get($Qreq, "discordertag", "discuss"), array("size" => 12, "onfocus" => 'autosub(false,this)')), ", grouping papers with similar PC conflicts</div>"; echo "</div>\n"; // PC echo "<h3>PC members</h3><table><tr><td class=\"nw\">"; doRadio("pctyp", "all", ""); echo "</td><td>", Ht::label("Use entire PC", "pctyp_all"), "</td></tr>\n"; echo "<tr><td class=\"nw\">"; doRadio('pctyp', 'sel', ''); echo "</td><td>", Ht::label("Use selected PC members:", "pctyp_sel"), " (select "; $pctyp_sel = array(array("all", 1, "all"), array("none", 0, "none")); $pctags = pcTags(); if (count($pctags)) { $tagsjson = array(); foreach (pcMembers() as $pc) { $tagsjson[$pc->contactId] = " " . trim(strtolower($pc->viewable_tags($Me))) . " "; }
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)"); }
static function echo_repo_group($info, $include_tarball = false) { global $Conf, $Me, $Now; if ($info->pset->gitless) { return; } list($user, $pset, $partner, $repo) = array($info->user, $info->pset, $info->partner, $info->repo); $editable = $info->can_set_repo && !$user->is_anonymous; $repo_url = $repo ? $repo->friendly_url() : ""; $title = "repository"; if (!RepositorySite::is_primary($repo)) { $title = $repo->reposite->friendly_siteclass() . " " . $title; } if ($repo && $repo->url) { $title = $user->link_repo($title, $repo->web_url()); } if ($editable) { $value = Ht::entry("repo", $repo_url, array("style" => "width:32em")) . " " . Ht::submit("Save"); } else { if ($user->is_anonymous) { $value = $repo_url ? "[anonymous]" : "(none)"; } else { $value = htmlspecialchars($repo_url ? $repo_url : "(none)"); } } if ($repo_url) { $value .= ' <button class="b repoclip hottooltip" data-pa-repo="' . htmlspecialchars($repo->ssh_url()) . '"'; if ($user->is_anonymous) { $value .= ' data-tooltip="[anonymous]"'; } else { $value .= ' data-tooltip="' . htmlspecialchars($repo->ssh_url()) . '"'; } $value .= ' type="button" onclick="false">Copy URL to clipboard</button>'; Ht::stash_script('$(".repoclip").each(pa_init_repoclip)', "repoclip"); if ($include_tarball && $info->commit_hash() && ($tarball_url = $info->tarball_url())) { $value .= ' <a class="bsm q" href="' . htmlspecialchars($tarball_url) . '">Download tarball for ' . substr($info->commit_hash(), 0, 7) . '</a>'; } } // check repo $ms = new MessageSet($user); if ($repo) { $repo->check_working($ms); $repo->check_open($ms); } if ($partner && $info->partner_same()) { $prepo = $partner->repo($pset->id); if (!$repo && $prepo || $repo && !$prepo || $repo && $prepo && $repo->repoid != $prepo->repoid) { if ($prepo && $repo) { $prepo_url = ", " . htmlspecialchars($prepo->friendly_url_like($repo)); } else { if ($prepo) { $prepo_url = ", " . htmlspecialchars($prepo->friendly_url()); } else { $prepo_url = ""; } } $your_partner = "your partner’s"; if ($Me->isPC) { $your_partner = '<a href="' . hoturl("pset", array("pset" => $pset->urlkey, "u" => $Me->user_linkpart($partner))) . '">' . $your_partner . '</a>'; } $ms->set_error_html("partner", "This repository differs from {$your_partner}{$prepo_url}."); } } if ($repo) { $repo->check_ownership($user, $partner, $ms); } $prefixes = ["", "WARNING: ", "ERROR: "]; $notes = array_map(function ($m) use($prefixes) { return [$m[2] > 0, $prefixes[$m[2]] . $m[1]]; }, $ms->messages(true)); if ($repo && $repo->truncated_psetdir($pset)) { $notes[] = array(true, "Please create your repository by cloning our repository. Creating your repository from scratch makes it harder for us to grade and harder for you to get pset updates."); } if (!$repo) { $repoclasses = RepositorySite::site_classes($Conf); $x = commajoin(array_map(function ($k) { return Ht::link($k::global_friendly_siteclass(), $k::global_friendly_siteurl()); }, $repoclasses), "or"); if ($editable) { $notes[] = array(false, "Enter your {$x} repository URL here."); } } // edit if ($editable) { echo Ht::form(self_href(array("post" => post_value(), "set_repo" => 1, "pset" => $pset->urlkey))), '<div class="f-contain">'; } self::echo_group($title, $value, $notes); if ($editable) { echo "</div></form>\n"; } return $repo; }
$plist = new PaperList(new PaperSearch($Me, ["t" => $_REQUEST["t"], "q" => $_REQUEST["q"]])); $ptext = $plist->table_html("reviewers", ["noheader" => true, "nofooter" => true]); echo "<div class='fx8'>"; if ($plist->count == 0) { echo "No papers match that search."; } else { echo '<div class="g"></div>', $ptext; } echo '</div>', Ht::hidden("prevt", $_REQUEST["t"]), Ht::hidden("prevq", $_REQUEST["q"]); } echo "</td></tr></table>\n"; echo '<div class="fx10" style="margin-top:0.35em">'; if (!@$_REQUEST["newrev_since"] && ($t = $Conf->setting("pcrev_informtime"))) { $_REQUEST["newrev_since"] = $Conf->parseableTime($t, true); } echo 'Assignments since: ', Ht::entry("newrev_since", @$_REQUEST["newrev_since"], array("placeholder" => "(all)", "size" => 30)), '</div>'; echo '<div class="fx9 g"></div></div>'; $Conf->footerScript("setmailpsel(\$\$(\"recipients\"))"); echo "</td></tr>\n"; // ** CC, REPLY-TO if ($Me->is_manager()) { 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} nw'>{$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 nw'>Subject:</td><td class='mhdp'>", "<tt>[", htmlspecialchars(Conf::$gShortName), "] </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", Ht::textarea("emailBody", $_REQUEST["emailBody"], array("class" => "tt", "rows" => 20, "cols" => 80, "spellcheck" => "true")), "</td></tr>\n</table></div>\n\n";
function echo_editable_html(PaperOptionValue $ov, $reqv, PaperTable $pt) { $reqv = (string) ($reqv === null ? $ov->value : $reqv); $pt->echo_editable_option_papt($this); echo '<div class="papev">', Ht::entry("opt{$this->id}", $reqv, ["size" => 8, "onchange" => "hiliter(this)"]), "</div></div>\n\n"; }
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>'; }
private function _footer($ncol, $extra) { global $Conf; if ($this->count == 0) { return ""; } $revpref = $this->table_type == "editReviewPreference"; $lllgroups = SearchAction::list_all_actions($this->contact, $this->qreq, $this); // Upload preferences (review preferences only) if ($revpref) { $lllgroups[] = [100, "uploadpref", "Upload", "<b> preference file:</b> " . "<input class=\"wantcrpfocus\" type='file' name='uploadedFile' accept='text/plain' size='20' tabindex='6' onfocus='autosub(\"uploadpref\",this)' /> " . Ht::submit("fn", "Go", ["value" => "uploadpref", "tabindex" => 6, "onclick" => "return plist_submit.call(this)", "data-plist-submit-all" => 1])]; } // Set preferences (review preferences only) if ($revpref) { $lllgroups[] = [200, "setpref", "Set preferences", "<b>:</b> " . Ht::entry("pref", "", array("class" => "wantcrpfocus", "size" => 4, "tabindex" => 6, "onfocus" => 'autosub("setpref",this)')) . " " . Ht::submit("fn", "Go", ["value" => "setpref", "tabindex" => 6, "onclick" => "return plist_submit.call(this)"])]; } usort($lllgroups, function ($a, $b) { return $a[0] - $b[0]; }); $whichlll = 1; foreach ($lllgroups as $i => $lllg) { if ($this->qreq->fn == $lllg[1] || $this->atab == $lllg[1]) { $whichlll = $i + 1; } } // Linelinks container $foot = " <tr class=\"pl_footrow\">"; if (!$this->viewmap->columns) { $foot .= '<td class="pl_footselector">' . Ht::img("_.gif", "^^", "placthook") . "</td>"; --$ncol; } $foot .= '<td id="plact" class="pl_footer linelinks' . $whichlll . '" colspan="' . $ncol . '">'; $foot .= "<table><tbody><tr>\n" . ' <td class="pl_footer_desc"><b>Select papers</b> (or <a href="' . selfHref(["selectall" => 1]) . '#plact" onclick="return papersel(true)">select all ' . $this->count . "</a>), then </td>\n" . " </tr></tbody></table>"; foreach ($lllgroups as $i => $lllg) { $x = $i + 1; $foot .= "<table><tbody><tr>\n" . " <td class=\"pl_footer_desc lll{$x}\"><a href=\"" . selfHref(["atab" => $lllg[1]]) . "#plact\" onclick=\"return crpfocus('plact',this)\">" . $lllg[2] . "</a></td>\n"; for ($j = 3; $j < count($lllg); ++$j) { $cell = is_array($lllg[$j]) ? $lllg[$j] : ["content" => $lllg[$j]]; $class = isset($cell["class"]) ? "lld{$x} " . $cell["class"] : "lld{$x}"; $foot .= " <td class=\"{$class}\""; if (isset($cell["id"])) { $foot .= " id=\"" . $cell["id"] . "\""; } $foot .= ">" . $cell["content"] . "</td>\n"; } if ($i < count($lllgroups) - 1) { $foot .= " <td> <span class='barsep'>·</span> </td>\n"; } $foot .= " </tr></tbody></table>"; } $foot .= $extra . "<hr class=\"c\" /></td>\n </tr>\n"; return $foot; }
function footer($ncol, $hascolors) { global $Conf; if ($this->count == 0) { return ""; } $t = " <tfoot class=\"pltable" . ($hascolors ? " pltable_colored" : "") . "\"><tr class=\"pl_footrow\">\n <td class=\"pl_footselector\">" . Ht::img("_.gif", "^^", "placthook") . "</td>\n <td class=\"pl_footer\" colspan=\"" . ($ncol - 1) . '">' . '<div id="plact" class="linelinks1">' . '<a name="plact"><b>Select people</b></a> (or <a href="#" onclick="return papersel(true)">select all ' . $this->count . "</a>), then "; // Begin linelinks $types = array("nameemail" => "Names and emails"); if ($this->contact->privChair) { $types["pcinfo"] = "PC info"; } $nlll = 1; $t .= "<span class=\"lll{$nlll}\"><a href=\"#\" onclick=\"return crpfocus('plact',{$nlll})\">Download</a></span><span class=\"lld{$nlll}\"><b>:</b> " . Ht::select("getaction", $types, null, array("id" => "plact{$nlll}_d")) . " " . Ht::submit("getgo", "Go", array("class" => "bsm")) . "</span>"; $barsep = " <span class='barsep'>·</span> "; if ($this->contact->privChair) { ++$nlll; $t .= $barsep; $t .= "<span class=\"lll{$nlll}\"><a href=\"#\" onclick=\"return crpfocus('plact',{$nlll})\">Tag</a></span><span class=\"lld{$nlll}\"><b>:</b> "; $t .= Ht::select("tagtype", array("a" => "Add", "d" => "Remove", "s" => "Define"), @$_REQUEST["tagtype"]) . ' tag(s) ' . Ht::entry("tag", @$_REQUEST["tag"], array("id" => "plact{$nlll}_d", "size" => 15, "onfocus" => "autosub('tagact',this)")) . ' ' . Ht::submit("tagact", "Go") . '</span>'; ++$nlll; $t .= $barsep; $t .= "<span class=\"lll{$nlll}\"><a href=\"#\" onclick=\"return crpfocus('plact',{$nlll})\">Modify</a></span><span class=\"lld{$nlll}\"><b>:</b> "; $t .= Ht::select("modifytype", array("disableaccount" => "Disable", "enableaccount" => "Enable", "resetpassword" => "Reset password", "sendaccount" => "Send account information"), null, array("id" => "plact{$nlll}_d")) . " " . Ht::submit("modifygo", "Go", array("class" => "bsm")) . "</span>"; } return $t . "</div></td></tr></tfoot>\n"; }