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> &nbsp;' . Ht::entry("tag", $qreq->tag, ["size" => 15, "onfocus" => "autosub('tag',this)", "class" => "wantcrpfocus"]) . ' &nbsp;' . 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")) . "&nbsp;" . Ht::label("Gapless order") . "</div>" . "<div style='margin:2px 0'>Using: &nbsp;" . Ht::select("tagcr_method", PaperRank::methods(), $qreq->tagcr_method) . "</div>" . "<div style='margin:2px 0'>Source tag: &nbsp;~" . Ht::entry("tagcr_source", $qreq->tagcr_source, array("size" => 15)) . "</div></div>";
     }
     $actions[] = [500, "tag", "Tag", "<b>:</b> &nbsp;" . Ht::select("tagfn", $tagopt, $qreq->tagfn, $tagextra) . " &nbsp;", ["id" => "foldplacttags", "class" => "foldc fold99c", "content" => $t]];
 }
 private function do_track_permission($sv, $type, $question, $tnum, $thistrack)
 {
     $tclass = $ttag = "";
     if ($sv->use_req()) {
         $tclass = defval($sv->req, "{$type}_track{$tnum}", "");
         $ttag = defval($sv->req, "{$type}tag_track{$tnum}", "");
     } else {
         if ($thistrack && get($thistrack, $type)) {
             if ($thistrack->{$type} == "+none") {
                 $tclass = "none";
             } else {
                 $tclass = substr($thistrack->{$type}, 0, 1);
                 $ttag = substr($thistrack->{$type}, 1);
             }
         }
     }
     $hint = "";
     if (is_array($question)) {
         list($question, $hint) = [$question[0], '<p class="hint" style="margin:0;max-width:480px">' . $question[1] . '</p>'];
     }
     echo "<tr data-fold=\"true\" class=\"fold", $tclass == "" || $tclass == "none" ? "c" : "o", "\">";
     if ($type === "viewtracker") {
         echo "<td class=\"lxcaption\" colspan=\"2\" style=\"padding-top:0.5em\">";
     } else {
         echo "<td style=\"width:2em\"></td><td class=\"lxcaption\">";
     }
     echo $sv->label(["{$type}_track{$tnum}", "{$type}tag_track{$tnum}"], $question, "{$type}_track{$tnum}"), "</td><td>", Ht::select("{$type}_track{$tnum}", array("" => "Whole PC", "+" => "PC members with tag", "-" => "PC members without tag", "none" => "Administrators only"), $tclass, $sv->sjs("{$type}_track{$tnum}", array("onchange" => "void foldup(this,event,{f:this.selectedIndex==0||this.selectedIndex==3})"))), " &nbsp;</td><td style=\"min-width:120px\">", Ht::entry("{$type}tag_track{$tnum}", $ttag, $sv->sjs("{$type}tag_track{$tnum}", array("class" => "fx", "placeholder" => "(tag)"))), "</td></tr>";
     if ($hint) {
         echo "<tr><td></td><td colspan=\"3\" style=\"padding-bottom:2px\">", $hint, "</td></tr>";
     }
 }
 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> &nbsp;" . 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"> &nbsp;<span id="atab_assign_for">for</span> &nbsp;' . Ht::select("markpc", [], 0, ["id" => "markpc", "class" => "need-pcselector", "data-pcselector-selected" => $qreq->markpc]) . "</span> &nbsp;" . Ht::submit("fn", "Go", ["value" => "assign", "onclick" => "return plist_submit.call(this)"])];
 }
Beispiel #4
0
 function selectors()
 {
     $sel = array("students" => "All students");
     foreach (ContactView::pset_list(true, false) as $pset) {
         if (Contact::student_can_see_pset($pset)) {
             if (!$pset->gitless || $pset->partner) {
                 $sel[] = array("optgroup", $pset->title);
             }
             if (!$pset->gitless) {
                 $sel[$pset->urlkey . ":workingrepo"] = "{$pset->title}, working repo";
                 $sel[$pset->urlkey . ":brokenrepo"] = "{$pset->title}, broken repo";
                 $sel[$pset->urlkey . ":openrepo"] = "{$pset->title}, open repo";
                 $sel[$pset->urlkey . ":norepo"] = "{$pset->title}, no repo";
             }
             if ($pset->partner) {
                 $sel[$pset->urlkey . ":partner"] = "{$pset->title}, partner";
                 $sel[$pset->urlkey . ":nopartner"] = "{$pset->title}, no partner";
             }
         }
     }
     $sel[] = array("optgroup");
     $sel["pc"] = "TFs";
     foreach (pcTags() as $t) {
         if ($t != "pc") {
             $sel["pc:{$t}"] = "#{$t} TFs";
         }
     }
     $sel["all"] = "All users";
     $usersel = array("all" => "All", "college" => "College", "extension" => "Extension");
     return Ht::select("recipients", $sel, $this->type, array("id" => "recipients", "onchange" => "setmailpsel(this)")) . " &nbsp;" . Ht::select("userrecipients", $usersel, $this->usertype, array("id" => "userrecipients"));
 }
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> &nbsp;" . 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">&#x25b2;</a><a href="#" class="qx row_down" onclick="return author_change(this,1)" tabindex="-1">&#x25bc;</a><a href="#" class="qx row_kill" onclick="return author_change(this,Infinity)" tabindex="-1">x</a></td></tr>';
    return $t;
}
function _review_table_round_selector($prow, $rr)
{
    global $Conf;
    $sel = $Conf->round_selector_options($rr->reviewRound);
    if (count($sel) <= 1) {
        if (get($sel, "unnamed") || count($sel) == 0) {
            return "";
        }
        reset($sel);
        return '&nbsp;<span class="revround" title="Review round">' . htmlspecialchars($Conf->round_name($rr->reviewRound, true)) . "</span>";
    }
    return '&nbsp;' . Ht::form(hoturl_post("assign", "p={$prow->paperId}&amp;r={$rr->reviewId}&amp;setround=1")) . '<div class="inline">' . Ht::select("round", $sel, $Conf->round_selector_name($rr->reviewRound), array("onchange" => "save_review_round(this)", "title" => "Set review round")) . '</div></form>';
}
 function list_actions(Contact $user, $qreq, PaperList $pl, &$actions)
 {
     $xactions = SearchAction::list_subactions("get", $user, $qreq, $pl);
     foreach (PaperOption::option_ids() as $oid) {
         if ($pl->any["opt{$oid}"] && ($o = PaperOption::find($oid)) && $o->is_document()) {
             $xactions[] = GetDocument_SearchAction::make_option_action($o);
         }
     }
     usort($xactions, function ($a, $b) {
         return $a[0] - $b[0];
     });
     $sel_opt = array();
     $last_group = null;
     foreach ($xactions as $xact) {
         if ($xact[2] !== $last_group) {
             $sel_opt[] = ["optgroup", $xact[2]];
             $last_group = $xact[2];
         }
         $sel_opt[] = ["value" => $xact[1], "label" => $xact[3]];
     }
     if (!empty($sel_opt)) {
         $actions[] = [0, "get", "Download", "<b>:</b> &nbsp;" . Ht::select("getfn", $sel_opt, $qreq->getfn, ["tabindex" => 6, "class" => "wantcrpfocus", "style" => "max-width:10em"]) . "&nbsp; " . Ht::submit("fn", "Go", ["value" => "get", "tabindex" => 6, "onclick" => "return plist_submit.call(this)", "data-plist-submit-all" => 1])];
     }
 }
 public function content($pl, $row, $rowidx)
 {
     if ($row->reviewerConflictType >= CONFLICT_AUTHOR) {
         return '<span class="author">Author</span>';
     }
     $rt = $row->reviewerConflictType > 0 ? -1 : min(max($row->reviewerReviewType, 0), REVIEW_PRIMARY);
     if ($pl->reviewer_contact()->can_accept_review_assignment_ignore_conflict($row) || $rt > 0) {
         $options = array(0 => "None", REVIEW_PRIMARY => "Primary", REVIEW_SECONDARY => "Secondary", REVIEW_PC => "Optional", -1 => "Conflict");
     } else {
         $options = array(0 => "None", -1 => "Conflict");
     }
     return Ht::select("assrev{$row->paperId}", $options, $rt, ["tabindex" => 3]);
 }
    $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) ? "&amp;sort=" . urlencode($qreq->sort) : "";
    echo "<div class='aahc'><form class='assignpc' method='post' action=\"", hoturl_post("manualassign", "reviewer={$reviewer}&amp;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: &nbsp;', 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")), "&nbsp;", 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();
 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> &nbsp;" . Ht::select("getaction", $types, null, array("id" => "plact{$nlll}_d")) . "&nbsp; " . 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> &nbsp;";
         $t .= Ht::select("tagtype", array("a" => "Add", "d" => "Remove", "s" => "Define"), @$_REQUEST["tagtype"]) . ' &nbsp;tag(s) &nbsp;' . Ht::entry("tag", @$_REQUEST["tag"], array("id" => "plact{$nlll}_d", "size" => 15, "onfocus" => "autosub('tagact',this)")) . ' &nbsp;' . 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> &nbsp;";
         $t .= Ht::select("modifytype", array("disableaccount" => "Disable", "enableaccount" => "Enable", "resetpassword" => "Reset password", "sendaccount" => "Send account information"), null, array("id" => "plact{$nlll}_d")) . "&nbsp; " . Ht::submit("modifygo", "Go", array("class" => "bsm")) . "</span>";
     }
     return $t . "</div></td></tr></tfoot>\n";
 }
 $rev_rounds = $Conf->round_selector_options();
 $x = array();
 if (count($rev_rounds) > 1) {
     $x[] = 'Review round:&nbsp; ' . Ht::select("rev_roundtag", $rev_rounds, $rev_roundtag ?: "unnamed");
 } else {
     if (!@$rev_rounds["unnamed"]) {
         $x[] = 'Review round: ' . $rev_roundtag . Ht::hidden("rev_roundtag", $rev_roundtag);
     }
 }
 if ($Conf->has_topics()) {
     $x[] = "Review preferences display as “P#”, topic scores as “T#”.";
 } else {
     $x[] = "Review preferences display as “P#”.";
 }
 echo join(' <span class="barsep">·</span> ', $x), '</p>';
 echo '<div id="assignmentselector" style="display:none">', Ht::select("pcs\$", array(0 => "None", REVIEW_PRIMARY => "Primary", REVIEW_SECONDARY => "Secondary", REVIEW_PC => "Optional", -1 => "Conflict"), "@", array("id" => "pcs\$_selector", "size" => 5, "onchange" => "assigntable.sel(this,\$)", "onclick" => "assigntable.sel(null,\$)", "onblur" => "assigntable.sel(0,\$)")), '</div>';
 echo '<div class="pc_ctable">';
 $tagger = new Tagger($Me);
 foreach (pcMembers() as $pc) {
     $p = $pcx[$pc->contactId];
     if (!$pc->can_accept_review_assignment_ignore_conflict($prow)) {
         continue;
     }
     // first, name and assignment
     $color = $pc->viewable_color_classes($Me);
     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")), '&nbsp;</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;
Beispiel #12
0
function echo_grader()
{
    global $Me, $User, $Pset, $Info;
    $gradercid = $Info->gradercid();
    if ($Info->is_grading_commit() && $Me->can_see_grader($Pset, $User)) {
        $pcm = pcMembers();
        $gpc = get($pcm, $gradercid);
        $value_post = "";
        if ($Me->can_set_grader($Pset, $User)) {
            $sel = array();
            if (!$gpc) {
                $sel["none"] = "(None)";
                $sel[] = null;
            }
            foreach (pcMembers() as $pcm) {
                $sel[$pcm->email] = Text::name_html($pcm);
            }
            $value = Ht::form($Info->hoturl_post("pset", array("setgrader" => 1))) . "<div>" . Ht::select("grader", $sel, $gpc ? $gpc->email : "none", array("onchange" => "setgrader61(this)"));
            $value_post = "<span class=\"ajaxsave61\"></span></div></form>";
        } else {
            if (isset($pcm[$gradercid])) {
                $value = Text::name_html($pcm[$gradercid]);
            } else {
                $value = "???";
            }
        }
        if ($Me->privChair) {
            $value .= "&nbsp;" . become_user_link($gpc);
        }
        ContactView::echo_group("grader", $value . $value_post);
    }
}
                $checked = strpos(displayOptionsSet("uldisplay"), $f->id) !== false;
                echo Ht::checkbox("show{$f->id}", 1, $checked), "&nbsp;", Ht::label($f->name_html), "<br />";
            }
        }
        echo "</td>";
    }
    echo "<td>", Ht::submit("redisplay", "Redisplay"), "</td></tr>\n";
    if (isset($pl->scoreMax)) {
        $ss = array();
        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> &nbsp;", 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&amp;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>";
function bpSelector($i, $which)
{
    static $badPairSelector, $Qreq;
    if (!$badPairSelector) {
        $badPairSelector = pc_members_selector_options("(PC member)");
    }
    return Ht::select("bp{$which}{$i}", $badPairSelector, $Qreq["bp{$which}{$i}"] ?: "0", ["onchange" => "badpairs_click()"]);
}
 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:&nbsp; " . $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)), " &nbsp; ", $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)), ' &nbsp; ', 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), '&nbsp;<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 &gt; Submission options</a>.</small>", "</td></tr></table>\n\n";
     $Conf->footerScript("fold('final',!\$\$('cbfinal_open').checked)");
 }
Beispiel #16
0
function revrate()
{
    global $Conf, $Me;
    _subhead("", "\n<p>PC members and, optionally, external reviewers can rate one another’s\nreviews.  We hope this feedback will help reviewers improve the quality of\ntheir reviews.  The interface appears above each visible review:</p>\n\n<p><div class='rev_rating'>\n  How helpful is this review? &nbsp;<form class><div class=\"inline\">" . Ht::select("rating", ReviewForm::$rating_types, "n") . "</div></form>\n</div></p>\n\n<p>When rating a review, please consider its value for both the program\n  committee and the authors.  Helpful reviews are specific, clear, technically\n  focused, and, when possible, provide direction for the authors’ future work.\n  The rating options are:</p>\n\n<dl>\n<dt><strong>Average</strong></dt>\n<dd>The review has acceptable quality.  This is the default, and should be\n  used for most reviews.</dd>\n<dt><strong>Very helpful</strong></dt>\n<dd>Great review.  Thorough, clear, constructive, and gives\n  good ideas for next steps.</dd>\n<dt><strong>Too short</strong></dt>\n<dd>The review is incomplete or too terse.</dd>\n<dt><strong>Too vague</strong></dt>\n<dd>The review’s arguments are weak, mushy, or otherwise technically\n  unconvincing.</dd>\n<dt><strong>Too narrow</strong></dt>\n<dd>The review’s perspective seems limited; for instance, it might\n  overly privilege the reviewer’s own work.</dd>\n<dt><strong>Not constructive</strong></dt>\n<dd>The review’s tone is unnecessarily aggressive or gives little useful\n  direction.</dd>\n<dt><strong>Not correct</strong></dt>\n<dd>The review misunderstands the paper.</dd>\n</dl>\n\n<p>HotCRP reports the numbers of non-average ratings for each review.\n  It does not report who gave the ratings, and it\n  never shows rating counts to authors.</p>\n\n<p>To find which of your reviews might need work, simply\n<a href='" . hoturl("search", "q=rate:-") . "'>search for “rate:&minus;”</a>.\nTo find all reviews with positive ratings,\n<a href='" . hoturl("search", "q=re:any+rate:%2B") . "'>search for “re:any&nbsp;rate:+”</a>.\nYou may also search for reviews with specific ratings; for instance,\n<a href='" . hoturl("search", "q=rate:helpful") . "'>search for “rate:helpful”</a>.</p>");
    if ($Conf->setting("rev_ratings") == REV_RATINGS_PC) {
        $what = "only PC members";
    } else {
        if ($Conf->setting("rev_ratings") == REV_RATINGS_PC_EXTERNAL) {
            $what = "PC members and external reviewers";
        } else {
            $what = "no one";
        }
    }
    _subhead("Settings", "\n<p>Chairs set how ratings work on the <a href=\"" . hoturl("settings", "group=reviews") . "\">review settings\npage</a>.", $Me->is_reviewer() ? " Currently, {$what} can rate reviews." : "", "</p>");
    _subhead("Visibility", "\n<p>A review’s ratings are visible to any unconflicted PC members who can see\nthe review, but HotCRP tries to hide ratings from review authors if they\ncould figure out who assigned the rating: if only one PC member could\nrate a review, then that PC member’s rating is hidden from the review\nauthor.</p>");
}
    echo "<tr><td class='lxcaption'><strong>Preferences:</strong> &nbsp;</td><td class='lentry'>";
    $prefcount = array();
    $result = $Conf->qe("select contactId, count(preference) from PaperReviewPreference where preference!=0 group by contactId");
    while ($row = edb_row($result)) {
        $prefcount[$row[0]] = $row[1];
    }
    $revopt = pc_members_selector_options(false);
    foreach (pcMembers() as $pcm) {
        if (!@$prefcount[$pcm->contactId]) {
            $revopt[htmlspecialchars($pcm->email)] .= " (no preferences)";
        }
    }
    if (!isset($revopt[htmlspecialchars($reviewer_contact->email)])) {
        $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")) . "&nbsp;" . 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")) . "&nbsp;" . 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")) . "&nbsp;" . 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)")) . "&nbsp;" . Ht::label("Abstracts") . '</span>';
 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&nbsp;x&nbsp;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&nbsp;x&nbsp;9in”, “1in&nbsp;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, "&nbsp;pt");
         $sv->echo_entry_row("sub_banal_bodyleading", "Minimum leading", null, "&nbsp;pt");
         $sv->echo_entry_row("sub_banal_columns", "Columns");
         echo "</tbody></table></td></tr></table>";
     }
     echo "<h3 class=\"settings\">Conflicts &amp; 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>';
 }
Beispiel #19
0
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\")")), " &nbsp;", Ht::submit("loadtmpl", "Load", array("id" => "loadtmpl")), " &nbsp;\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)")), "&nbsp;</td><td>", Ht::label("Choose individual papers", "plimit");
echo "<span class='fx8'>:</span><br /><div class='fx8'>";
$q = defval($_REQUEST, "q", "(All)");
echo "Search&nbsp; ", Ht::entry("q", @$_REQUEST["q"], array("id" => "q", "hottemptext" => "(All)", "class" => "hotcrp_searchbox", "size" => 36, "title" => "Enter paper numbers or search terms")), " &nbsp;in &nbsp;", 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
Beispiel #20
0
function show_pset_table($pset)
{
    global $Conf, $Me, $Now, $Profile, $LastPsetFix;
    echo '<div id="', $pset->urlkey, '">';
    echo "<h3>", htmlspecialchars($pset->title), "</h3>";
    if ($Me->privChair) {
        show_pset_actions($pset);
    }
    if ($pset->disabled) {
        echo "</div>\n";
        return;
    }
    $t0 = $Profile ? microtime(true) : 0;
    // load students
    if ($Conf->opt("restrictRepoView")) {
        $view = "l2.link repoviewable";
        $viewjoin = "left join ContactLink l2 on (l2.cid=c.contactId and l2.type=" . LINK_REPOVIEW . " and l2.link=l.link)\n";
    } else {
        $view = "4 repoviewable";
        $viewjoin = "";
    }
    $result = Dbl::qe("select c.contactId, c.firstName, c.lastName, c.email,\n\tc.huid, c.github_username, c.seascode_username, c.anon_username, c.extension, c.disabled, c.dropped, c.roles, c.contactTags,\n\tgroup_concat(pl.link) pcid, group_concat(rpl.link) rpcid,\n\tr.repoid, r.cacheid, r.heads, r.url, r.open, r.working, r.lastpset, r.snapcheckat, {$view},\n\trg.gradehash, rg.gradercid, rg.placeholder, rg.placeholder_at\n\tfrom ContactInfo c\n\tleft join ContactLink l on (l.cid=c.contactId and l.type=" . LINK_REPO . " and l.pset={$pset->id})\n\t{$viewjoin}\n\tleft join Repository r on (r.repoid=l.link)\n\tleft join ContactLink pl on (pl.cid=c.contactId and pl.type=" . LINK_PARTNER . " and pl.pset={$pset->id})\n\tleft join ContactLink rpl on (rpl.cid=c.contactId and rpl.type=" . LINK_BACKPARTNER . " and rpl.pset={$pset->id})\n\tleft join RepositoryGrade rg on (rg.repoid=r.repoid and rg.pset={$pset->id})\n\twhere (c.roles&" . Contact::ROLE_PCLIKE . ")=0\n\tand (rg.repoid is not null or not c.dropped)\n\tgroup by c.contactId, r.repoid");
    $t1 = $Profile ? microtime(true) : 0;
    $anonymous = $pset->anonymous;
    if (req("anonymous") !== null && $Me->privChair) {
        $anonymous = !!req("anonymous");
    }
    $students = array();
    while ($result && ($s = Contact::fetch($result))) {
        $s->set_anonymous($anonymous);
        Contact::set_sorter($s, req("sort"));
        $students[$s->contactId] = $s;
        // maybe lastpset links are out of order
        if ($s->lastpset < $pset) {
            $LastPsetFix = true;
        }
    }
    uasort($students, "Contact::compare");
    $checkbox = $Me->privChair || !$pset->gitless && $pset->runners;
    $rows = array();
    $max_ncol = 0;
    $incomplete = array();
    $pcmembers = pcMembers();
    $jx = [];
    foreach ($students as $s) {
        if (!$s->visited) {
            $row = (object) ["student" => $s, "text" => "", "ptext" => []];
            $j = render_pset_row($pset, $students, $s, $row, $pcmembers, $anonymous);
            if ($s->pcid) {
                foreach (array_unique(explode(",", $s->pcid)) as $pcid) {
                    if (isset($students[$pcid])) {
                        $jj = render_pset_row($pset, $students, $students[$pcid], $row, $pcmembers, $anonymous);
                        $j["partners"][] = $jj;
                    }
                }
            }
            if ($row->sortprefix) {
                $j["boring"] = true;
            }
            $jx[$row->sortprefix . $s->sorter] = $j;
            $max_ncol = max($max_ncol, $row->ncol);
            if ($s->incomplete) {
                $u = $Me->user_linkpart($s);
                $incomplete[] = '<a href="' . hoturl("pset", array("pset" => $pset->urlkey, "u" => $u, "sort" => req("sort"))) . '">' . htmlspecialchars($u) . '</a>';
            }
        }
    }
    if (count($incomplete)) {
        echo '<div id="incomplete_pset', $pset->id, '" style="display:none" class="merror">', '<strong>', htmlspecialchars($pset->title), '</strong>: ', 'Your grading is incomplete. Missing grades: ', join(", ", $incomplete), '</div>', '<script>jQuery("#incomplete_pset', $pset->id, '").remove().show().appendTo("#incomplete_notices")</script>';
    }
    if ($checkbox) {
        echo Ht::form_div(hoturl_post("index", array("pset" => $pset->urlkey, "save" => 1)));
    }
    $sort_key = $anonymous ? "anon_username" : "username";
    usort($jx, function ($a, $b) use($sort_key) {
        if (get($a, "boring") != get($b, "boring")) {
            return get($a, "boring") ? 1 : -1;
        }
        return strcmp($a[$sort_key], $b[$sort_key]);
    });
    echo '<table class="s61', $anonymous ? " s61anonymous" : "", '" id="pa-pset' . $pset->id . '"></table>';
    $jd = ["checkbox" => $checkbox, "anonymous" => $anonymous, "grade_keys" => array_keys($pset->grades), "gitless" => $pset->gitless, "gitless_grades" => $pset->gitless_grades, "urlpattern" => hoturl("pset", ["pset" => $pset->urlkey, "u" => "@", "sort" => req("sort")])];
    $i = $nintotal = $last_in_total = 0;
    foreach ($pset->grades as $ge) {
        if (!$ge->no_total) {
            ++$nintotal;
            $last_in_total = $ge->name;
        }
        ++$i;
    }
    if ($nintotal > 1) {
        $jd["need_total"] = true;
    } else {
        if ($nintotal == 1) {
            $jd["total_key"] = $last_in_total;
        }
    }
    echo Ht::unstash(), '<script>pa_render_pset_table(', $pset->id, ',', json_encode($jd), ',', json_encode(array_values($jx)), ')</script>';
    if ($Me->privChair && !$pset->gitless_grades) {
        echo "<div class='g'></div>";
        $sel = array("none" => "N/A");
        foreach (pcMembers() as $pcm) {
            $sel[$pcm->email] = Text::name_html($pcm);
        }
        $sel["__random__"] = "Random";
        echo '<span class="nb" style="padding-right:2em">', Ht::select("grader", $sel, "none"), Ht::submit("setgrader", "Set grader"), '</span>';
    }
    if (!$pset->gitless) {
        $sel = array();
        foreach ($pset->runners as $r) {
            if ($Me->can_run($pset, $r)) {
                $sel[$r->name] = htmlspecialchars($r->title);
            }
        }
        if (count($sel)) {
            echo '<span class="nb" style="padding-right:2em">', Ht::select("runner", $sel), Ht::submit("runmany", "Run all"), '</span>';
        }
    }
    if ($checkbox) {
        echo "</div></form>\n";
    }
    if ($Profile) {
        $t2 = microtime(true);
        echo sprintf("<div>Δt %.06f DB, %.06f total</div>", $t1 - $t0, $t2 - $t0);
    }
    echo "</div>\n";
}
 function selectors()
 {
     return Ht::select("recipients", $this->sel, $this->type, array("id" => "recipients", "onchange" => "setmailpsel(this)"));
 }
 static function searchTypeSelector($tOpt, $type, $tabindex)
 {
     if (count($tOpt) > 1) {
         $sel_opt = array();
         foreach ($tOpt as $k => $v) {
             if (count($sel_opt) && $k === "a") {
                 $sel_opt["xxxa"] = null;
             }
             if (count($sel_opt) && ($k === "lead" || $k === "r") && !isset($sel_opt["xxxa"])) {
                 $sel_opt["xxxb"] = null;
             }
             $sel_opt[$k] = $v;
         }
         $sel_extra = array();
         if ($tabindex) {
             $sel_extra["tabindex"] = 1;
         }
         return Ht::select("t", $sel_opt, $type, $sel_extra);
     } else {
         return current($tOpt);
     }
 }
Beispiel #23
0
echo Ht::select("template", $tmpl, $_REQUEST["template"], array("onchange" => "highlightUpdate(\"loadtmpl\")")), " &nbsp;", Ht::submit("loadtmpl", "Load", array("id" => "loadtmpl")), " &nbsp;\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 nw">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>';
if ($Me->privChair) {
    echo '<td class="nw">', Ht::checkbox("plimit", 1, isset($_REQUEST["plimit"]), ["id" => "plimit", "onchange" => "fold('psel', !this.checked, 8)"]), "&nbsp;</td><td>", Ht::label("Choose papers", "plimit"), "<span class='fx8'>:&nbsp; ";
} else {
    echo '<td class="nw">Papers: &nbsp;</td><td>', Ht::hidden("plimit", 1), '<span>';
}
echo Ht::entry("q", @$_REQUEST["q"], array("id" => "q", "placeholder" => "(All)", "class" => "hotcrp_searchbox", "size" => 36)), " &nbsp;in&nbsp;";
if (count($tOpt) == 1) {
    echo htmlspecialchars($tOpt[$_REQUEST["t"]]);
} else {
    echo " ", Ht::select("t", $tOpt, $_REQUEST["t"], array("id" => "t"));
}
echo " &nbsp;", Ht::submit("psearch", "Search");
echo "</span>";
if (isset($_REQUEST["plimit"]) && !isset($_REQUEST["monreq"]) && (isset($_REQUEST["loadtmpl"]) || isset($_REQUEST["psearch"]))) {
    $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";
Beispiel #24
0
function show_pset_table($pset)
{
    global $Conf, $Me, $Now, $Opt, $Profile, $LastPsetFix;
    echo '<div id="', $pset->urlkey, '">';
    echo "<h3>", htmlspecialchars($pset->title), "</h3>";
    if ($Me->privChair) {
        show_pset_actions($pset);
    }
    if ($pset->disabled) {
        return;
    }
    $t0 = $Profile ? microtime(true) : 0;
    // load students
    if (@$Opt["restrictRepoView"]) {
        $view = "l2.link repoviewable";
        $viewjoin = "left join ContactLink l2 on (l2.cid=c.contactId and l2.type=" . LINK_REPOVIEW . " and l2.link=l.link)\n";
    } else {
        $view = "4 repoviewable";
        $viewjoin = "";
    }
    $result = Dbl::qe("select c.contactId, c.firstName, c.lastName, c.email,\n\tc.huid, c.seascode_username, c.anon_username, c.extension, c.disabled, c.dropped, c.roles, c.contactTags,\n\tpl.link pcid, group_concat(rpl.link) rpcid,\n\tr.repoid, r.cacheid, r.heads, r.url, r.open, r.working, r.lastpset, r.snapcheckat, {$view},\n\trg.gradehash, rg.gradercid, rg.placeholder, rg.placeholder_at\n\tfrom ContactInfo c\n\tleft join ContactLink l on (l.cid=c.contactId and l.type=" . LINK_REPO . " and l.pset={$pset->id})\n\t{$viewjoin}\n\tleft join Repository r on (r.repoid=l.link)\n\tleft join ContactLink pl on (pl.cid=c.contactId and pl.type=" . LINK_PARTNER . " and pl.pset={$pset->id})\n\tleft join ContactLink rpl on (rpl.cid=c.contactId and rpl.type=" . LINK_BACKPARTNER . " and rpl.pset={$pset->id})\n\tleft join RepositoryGrade rg on (rg.repoid=r.repoid and rg.pset={$pset->id})\n\twhere (c.roles&" . Contact::ROLE_PCLIKE . ")=0\n\tand (rg.repoid is not null or not c.dropped)\n\tgroup by c.contactId");
    $t1 = $Profile ? microtime(true) : 0;
    $students = array();
    while ($result && ($s = $result->fetch_object("Contact"))) {
        $s->is_anonymous = $pset->anonymous;
        Contact::set_sorter($s, @$_REQUEST["sort"]);
        $students[$s->contactId] = $s;
        // maybe lastpset links are out of order
        if ($s->lastpset < $pset) {
            $LastPsetFix = true;
        }
    }
    uasort($students, "Contact::compare");
    $checkbox = $Me->privChair || !$pset->gitless && $pset->runners;
    $rows = array();
    $max_ncol = 0;
    $incomplete = array();
    $pcmembers = pcMembers();
    foreach ($students as $s) {
        if (!isset($s->printed)) {
            $row = (object) array("student" => $s);
            $row->text = render_pset_row($pset, $students, $s, $row, $pcmembers);
            if ($s->pcid && isset($students[$s->pcid])) {
                $row->ptext = render_pset_row($pset, $students, $students[$s->pcid], $row, $pcmembers);
            }
            $rows[$row->sortprefix . $s->sorter] = $row;
            $max_ncol = max($max_ncol, $row->ncol);
            if (@$s->incomplete) {
                $u = $Me->user_linkpart($s);
                $incomplete[] = '<a href="' . hoturl("pset", array("pset" => $pset->urlkey, "u" => $u, "sort" => @$_REQUEST["sort"])) . '">' . htmlspecialchars($u) . '</a>';
            }
        }
    }
    ksort($rows, SORT_NATURAL | SORT_FLAG_CASE);
    if (count($incomplete)) {
        echo '<div id="incomplete_pset', $pset->id, '" style="display:none" class="merror">', '<strong>', htmlspecialchars($pset->title), '</strong>: ', 'Your grading is incomplete. Missing grades: ', join(", ", $incomplete), '</div>', '<script>jQuery("#incomplete_pset', $pset->id, '").remove().show().appendTo("#incomplete_notices")</script>';
    }
    if ($checkbox) {
        echo Ht::form_div(hoturl_post("index", array("pset" => $pset->urlkey, "save" => 1)));
    }
    echo '<table class="s61"><tbody>';
    $trn = 0;
    $sprefix = "";
    foreach ($rows as $row) {
        ++$trn;
        if ($row->sortprefix !== $sprefix && $row->sortprefix[0] == "~") {
            echo "\n", '<tr><td colspan="' . ($max_ncol + ($checkbox ? 2 : 1)) . '"><hr></td></tr>', "\n";
        }
        $sprefix = $row->sortprefix;
        echo '<tr class="k', $trn % 2, '">';
        if ($checkbox) {
            echo '<td class="s61rownumber">', Ht::checkbox("s61_" . $Me->user_idpart($row->student), 1, array("class" => "s61check")), '</td>';
        }
        echo '<td class="s61rownumber">', $trn, '.</td>', $row->text, "</tr>\n";
        if (@$row->ptext) {
            echo '<tr class="k', $trn % 2, ' s61partner">';
            if ($checkbox) {
                echo '<td></td>';
            }
            echo '<td></td>', $row->ptext, "</tr>\n";
        }
    }
    echo "</tbody></table>\n";
    if ($Me->privChair && !$pset->gitless_grades) {
        echo "<div class='g'></div>";
        $sel = array("none" => "N/A");
        foreach (pcMembers() as $pcm) {
            $sel[$pcm->email] = Text::name_html($pcm);
        }
        $sel["__random__"] = "Random";
        echo '<span class="nowrap" style="padding-right:2em">', Ht::select("grader", $sel, "none"), Ht::submit("setgrader", "Set grader"), '</span>';
    }
    if (!$pset->gitless) {
        $sel = array();
        foreach ($pset->runners as $r) {
            if ($Me->can_run($pset, $r)) {
                $sel[$r->name] = htmlspecialchars($r->title);
            }
        }
        if (count($sel)) {
            echo '<span class="nowrap" style="padding-right:2em">', Ht::select("runner", $sel), Ht::submit("runmany", "Run all"), '</span>';
        }
    }
    if ($checkbox) {
        echo "</div></form>\n";
    }
    if ($Profile) {
        $t2 = microtime(true);
        echo sprintf("<div>Δt %.06f DB, %.06f total</div>", $t1 - $t0, $t2 - $t0);
    }
    echo "</div>\n";
}
 function echo_editable_html(PaperOptionValue $ov, $reqv, PaperTable $pt)
 {
     $reqv = $reqv === null ? $ov->value : $reqv;
     $reqv = isset($this->selector[$reqv]) ? $reqv : 0;
     $pt->echo_editable_option_papt($this);
     echo '<div class="papev">';
     if ($this->type === "selector") {
         echo Ht::select("opt{$this->id}", $this->selector, $reqv, ["onchange" => "hiliter(this)"]);
     } else {
         foreach ($this->selector as $val => $text) {
             echo Ht::radio("opt{$this->id}", $val, $val == $reqv, ["onchange" => "hiliter(this)"]), "&nbsp;", Ht::label(htmlspecialchars($text)), "<br />\n";
         }
     }
     echo "</div></div>\n\n";
 }
            }
        }
    }
}
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> &nbsp;', '<input type="file" name="bulk" accept="text/plain,text/csv" size="30" /></div>';
echo '<div id="foldoptions" class="lg foldc fold2o">', 'By default, assign&nbsp; ', 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">&nbsp; in round &nbsp;', Ht::select("rev_roundtag", $rev_rounds, $_REQUEST["rev_roundtag"] ?: "unnamed"), '</span>';
} else {
    if (!get($rev_rounds, "unnamed")) {
        echo '<span class="fx2">&nbsp; 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), "&nbsp;</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"), " &nbsp; <span class='hint'>You’ll be able to check the assignment before it is saved.</span></div>\n";
 function list_actions(Contact $user, $qreq, PaperList $plist, &$actions)
 {
     $actions[] = [1000, "mail", "Mail", "<b>:</b> &nbsp;" . Ht::select("recipients", array("au" => "Contact authors", "rev" => "Reviewers"), $qreq->recipients, ["class" => "wantcrpfocus"]) . " &nbsp;" . Ht::submit("fn", "Go", ["value" => "mail", "onclick" => "return plist_submit.call(this)", "data-plist-submit-all" => 1])];
 }
 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 &amp; 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)"), ' &nbsp; <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? &nbsp; <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"));
 }