public function select_pc($pcids)
 {
     $this->pcm = $this->load = [];
     $pcids = array_flip($pcids);
     foreach (pcMembers() as $cid => $p) {
         if (isset($pcids[$cid])) {
             $this->pcm[$cid] = $p;
             $this->load[$cid] = 0;
         }
     }
     return count($this->pcm);
 }
 public function json()
 {
     // find out who is light and who is heavy
     // (light => less than 0.66 * (80th percentile))
     $nass = array();
     foreach ($this->r as $cid => $x) {
         $nass[] = count($x);
     }
     sort($nass);
     $heavy_boundary = 0;
     if (count($nass)) {
         $heavy_boundary = 0.66 * $nass[(int) (0.8 * count($nass))];
     }
     $contacts = pcMembers();
     $need_contacts = [];
     foreach ($this->r as $cid => $x) {
         if (!isset($contacts[$cid]) && ctype_digit($cid)) {
             $need_contacts[] = $cid;
         }
     }
     if (count($need_contacts)) {
         $result = Dbl::q("select firstName, lastName, affiliation, email, contactId, roles, contactTags, disabled from ContactInfo where contactId ?a", $need_contacts);
         while ($result && ($row = Contact::fetch($result))) {
             $contacts[$row->contactId] = $row;
         }
     }
     $users = array();
     $tags = $this->contact->can_view_reviewer_tags();
     foreach ($this->r as $cid => $x) {
         if ($cid != "conflicts") {
             $users[$cid] = $u = (object) array();
             $p = get($contacts, $cid);
             if ($p) {
                 $u->name = Text::name_text($p);
             }
             if (count($x) < $heavy_boundary) {
                 $u->light = true;
             }
             if ($p && $tags && ($t = $p->viewable_color_classes($this->contact))) {
                 $u->color_classes = $t;
             }
         }
     }
     return (object) array("reviews" => $this->r, "deadlines" => $this->dl, "users" => $users);
 }
 function run(Contact $user, $qreq, $ssel)
 {
     global $Conf, $Opt;
     $q = $Conf->paperQuery($user, array("paperId" => $ssel->selection(), "allReviewerPreference" => 1, "allConflictType" => 1, "topics" => 1));
     $result = Dbl::qe_raw($q);
     $texts = array();
     $pcm = pcMembers();
     $has_conflict = $has_expertise = $has_topic_score = false;
     while ($prow = PaperInfo::fetch($result, $user)) {
         if (!$user->can_administer($prow, true)) {
             continue;
         }
         $conflicts = $prow->conflicts();
         foreach ($pcm as $cid => $p) {
             $pref = $prow->reviewer_preference($p);
             $conf = get($conflicts, $cid);
             $tv = $prow->topicIds ? $prow->topic_interest_score($p) : 0;
             if ($pref || $conf || $tv) {
                 $texts[$prow->paperId][] = array("paper" => $prow->paperId, "title" => $prow->title, "first" => $p->firstName, "last" => $p->lastName, "email" => $p->email, "preference" => $pref[0] ?: "", "expertise" => unparse_expertise($pref[1]), "topic_score" => $tv ?: "", "conflict" => $conf ? "conflict" : "");
                 $has_conflict = $has_conflict || $conf;
                 $has_expertise = $has_expertise || $pref[1] !== null;
                 $has_topic_score = $has_topic_score || $tv;
             }
         }
     }
     $headers = array("paper", "title", "first", "last", "email", "preference");
     if ($has_expertise) {
         $headers[] = "expertise";
     }
     if ($has_topic_score) {
         $headers[] = "topic_score";
     }
     if ($has_conflict) {
         $headers[] = "conflict";
     }
     downloadCSV($ssel->reorder($texts), $headers, "allprefs", ["selection" => true]);
 }
Esempio n. 4
0
function pc_members_selector_options($include_none)
{
    global $Opt;
    $sel = array();
    if ($include_none) {
        $sel["0"] = is_string($include_none) ? $include_none : "None";
    }
    $textarg = array("lastFirst" => @$Opt["sortByLastName"]);
    foreach (pcMembers() as $p) {
        $sel[htmlspecialchars($p->email)] = Text::name_html($p, $textarg);
    }
    return $sel;
}
Esempio n. 5
0
 function topic_interest_map()
 {
     global $Me;
     if ($this->topic_interest_map_ !== null) {
         return $this->topic_interest_map_;
     }
     if ($this->contactId <= 0) {
         return array();
     }
     if ($this->roles & self::ROLE_PCLIKE && $this !== $Me && ($pcm = pcMembers()) && $this === get($pcm, $this->contactId)) {
         $result = Dbl::qe("select contactId, topicId, interest from TopicInterest where interest!=0 order by contactId");
         foreach ($pcm as $pc) {
             $pc->topic_interest_map_ = array();
         }
         $pc = null;
         while ($row = edb_row($result)) {
             if (!$pc || $pc->contactId != $row[0]) {
                 $pc = get($pcm, $row[0]);
             }
             if ($pc) {
                 $pc->topic_interest_map_[(int) $row[1]] = (int) $row[2];
             }
         }
         Dbl::free($result);
     } else {
         $result = Dbl::qe("select topicId, interest from TopicInterest where contactId={$this->contactId} and interest!=0");
         $this->topic_interest_map_ = Dbl::fetch_iimap($result);
     }
     return $this->topic_interest_map_;
 }
Esempio n. 6
0
 public function save($sv, $si)
 {
     global $Conf;
     if ($si->name == "tag_vote" && $sv->has_savedv("tag_vote")) {
         // check allotments
         $pcm = pcMembers();
         foreach (preg_split('/\\s+/', $sv->savedv("tag_vote")) as $t) {
             if ($t === "") {
                 continue;
             }
             $base = substr($t, 0, strpos($t, "#"));
             $allotment = substr($t, strlen($base) + 1);
             $result = Dbl::q("select paperId, tag, tagIndex from PaperTag where tag like '%~" . sqlq_for_like($base) . "'");
             $pvals = array();
             $cvals = array();
             $negative = false;
             while ($row = edb_row($result)) {
                 $who = substr($row[1], 0, strpos($row[1], "~"));
                 if ($row[2] < 0) {
                     $sv->set_error(null, "Removed " . Text::user_html($pcm[$who]) . "’s negative “{$base}” vote for paper #{$row['0']}.");
                     $negative = true;
                 } else {
                     $pvals[$row[0]] = defval($pvals, $row[0], 0) + $row[2];
                     $cvals[$who] = defval($cvals, $who, 0) + $row[2];
                 }
             }
             foreach ($cvals as $who => $what) {
                 if ($what > $allotment) {
                     $sv->set_error("tag_vote", Text::user_html($pcm[$who]) . " already has more than {$allotment} votes for tag “{$base}”.");
                 }
             }
             $q = $negative ? " or (tag like '%~" . sqlq_for_like($base) . "' and tagIndex<0)" : "";
             $Conf->qe("delete from PaperTag where tag='" . sqlq($base) . "'{$q}");
             $q = array();
             foreach ($pvals as $pid => $what) {
                 $q[] = "({$pid}, '" . sqlq($base) . "', {$what})";
             }
             if (count($q) > 0) {
                 $Conf->qe("insert into PaperTag values " . join(", ", $q));
             }
         }
     }
     if ($si->name == "tag_approval" && $sv->has_savedv("tag_approval")) {
         $pcm = pcMembers();
         foreach (preg_split('/\\s+/', $sv->savedv("tag_approval")) as $t) {
             if ($t === "") {
                 continue;
             }
             $result = $Conf->q("select paperId, tag, tagIndex from PaperTag where tag like '%~" . sqlq_for_like($t) . "'");
             $pvals = array();
             $negative = false;
             while ($row = edb_row($result)) {
                 $who = substr($row[1], 0, strpos($row[1], "~"));
                 if ($row[2] < 0) {
                     $sv->set_error(null, "Removed " . Text::user_html($pcm[$who]) . "’s negative “{$t}” approval vote for paper #{$row['0']}.");
                     $negative = true;
                 } else {
                     $pvals[$row[0]] = defval($pvals, $row[0], 0) + 1;
                 }
             }
             $q = $negative ? " or (tag like '%~" . sqlq_for_like($t) . "' and tagIndex<0)" : "";
             $Conf->qe("delete from PaperTag where tag='" . sqlq($t) . "'{$q}");
             $q = array();
             foreach ($pvals as $pid => $what) {
                 $q[] = "({$pid}, '" . sqlq($t) . "', {$what})";
             }
             if (count($q) > 0) {
                 $Conf->qe("insert into PaperTag values " . join(", ", $q));
             }
         }
     }
     TagInfo::invalidate_defined_tags();
 }
 public function pc_conflicts($email = false)
 {
     return array_intersect_key($this->conflicts($email), pcMembers());
 }
 public function content($pl, $row, $rowidx)
 {
     $y = [];
     $pcm = pcMembers();
     foreach ($row->conflicts() as $id => $type) {
         if ($pc = get($pcm, $id)) {
             $y[$pc->sort_position] = $pl->contact->reviewer_html_for($pc);
         }
     }
     ksort($y);
     return join(", ", $y);
 }
$pl_text = $pl->table_html("editReviewPreference", array("class" => "pltable_full", "table_id" => "foldpl", "attributes" => array("data-fold-session" => "pfdisplay.\$"), "footer_extra" => "<div id='plactr'>" . Ht::submit("update", "Save changes", array("class" => "hb")) . "</div>", "list_properties" => ["revprefs" => true]));
// DISPLAY OPTIONS
echo "<table id='searchform' class='tablinks1'>\n<tr><td>";
// <div class='tlx'><div class='tld1'>";
$showing_au = !$Conf->subBlindAlways() && strpos($pldisplay, " au ") !== false;
$showing_anonau = (!$Conf->subBlindNever() || $Me->privChair) && strpos($pldisplay, " anonau ") !== false;
echo Ht::form_div(hoturl("reviewprefs"), array("method" => "get", "id" => "redisplayform", "class" => $showing_au || $showing_anonau && $Conf->subBlindAlways() ? "fold10o" : "fold10c")), "<table>";
if ($Me->privChair) {
    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) {
 function run(Contact $user, $qreq, $ssel)
 {
     global $Conf;
     $allConflictTypes = Conflict::$type_descriptions;
     $allConflictTypes[CONFLICT_CHAIRMARK] = "Chair-confirmed";
     $allConflictTypes[CONFLICT_AUTHOR] = "Author";
     $allConflictTypes[CONFLICT_CONTACTAUTHOR] = "Contact";
     $result = Dbl::qe_raw($Conf->paperQuery($user, ["paperId" => $ssel->selection(), "allConflictType" => 1]));
     $pcm = pcMembers();
     $texts = array();
     while ($prow = PaperInfo::fetch($result, $user)) {
         if ($user->can_view_conflicts($prow, true)) {
             $m = [];
             foreach ($prow->conflicts() as $cid => $c) {
                 if (isset($pcm[$cid])) {
                     $pc = $pcm[$cid];
                     $m[$pc->sort_position] = [$prow->paperId, $prow->title, $pc->firstName, $pc->lastName, $pc->email, get($allConflictTypes, $c->conflictType, "Conflict")];
                 }
             }
             if ($m) {
                 ksort($m);
                 $texts[$prow->paperId] = $m;
             }
         }
     }
     downloadCSV($ssel->reorder($texts), ["paper", "title", "first", "last", "email", "conflicttype"], "pcconflicts");
 }
 private static function _pcContactIdsWithTag($tag)
 {
     if ($tag === "pc") {
         return array_keys(pcMembers());
     }
     $a = array();
     foreach (pcMembers() as $cid => $pc) {
         if ($pc->has_tag($tag)) {
             $a[] = $cid;
         }
     }
     return $a;
 }
 private function _prepare_reviewer_color(Contact $user)
 {
     $this->reviewer_color = array();
     foreach (pcMembers() as $p) {
         $this->reviewer_color[$p->contactId] = TagInfo::color_classes($p->viewable_tags($user));
     }
 }
Esempio n. 13
0
 public static function check_tagmap($cid, $tag)
 {
     if (($a = get(self::$tagmap, $tag)) === null) {
         $a = array();
         foreach (pcMembers() as $pc) {
             if (($v = $pc->tag_value($tag)) !== false) {
                 $a[$pc->contactId] = $v ?: true;
             }
         }
         self::$tagmap[$tag] = $a;
     }
     return get($a, $cid) ?: false;
 }
Esempio n. 14
0
function paper_tag_normalize($prow)
{
    $t = array();
    $pcm = pcMembers();
    foreach (explode(" ", $prow->all_tags_text()) as $tag) {
        if (($twiddle = strpos($tag, "~")) > 0 && ($c = @$pcm[substr($tag, 0, $twiddle)])) {
            $at = strpos($c->email, "@");
            $tag = ($at ? substr($c->email, 0, $at) : $c->email) . substr($tag, $twiddle);
        }
        if (strlen($tag) > 2 && substr($tag, strlen($tag) - 2) == "#0") {
            $tag = substr($tag, 0, strlen($tag) - 2);
        }
        if ($tag) {
            $t[] = $tag;
        }
    }
    usort($t, "tag_normalize_compare");
    return $t;
}
 public function stash_hotcrp_pc(Contact $user)
 {
     if (!Ht::mark_stash("hotcrp_pc")) {
         return;
     }
     $sortbylast = opt("sortByLastName");
     $hpcj = $list = [];
     foreach (pcMembers() as $pcm) {
         $hpcj[$pcm->contactId] = $j = (object) ["name" => $user->name_html_for($pcm), "email" => $pcm->email];
         if ($color_classes = $user->reviewer_color_classes_for($pcm)) {
             $j->color_classes = $color_classes;
         }
         if ($sortbylast && $pcm->lastName) {
             $r = Text::analyze_name($pcm);
             if (strlen($r->lastName) !== strlen($r->name)) {
                 $j->lastpos = strlen(htmlspecialchars($r->firstName)) + 1;
             }
             if ($r->nameAmbiguous && $r->name && $r->email) {
                 $j->emailpos = strlen(htmlspecialchars($r->name)) + 1;
             }
         }
         $list[] = $pcm->contactId;
     }
     $hpcj["__order__"] = $list;
     if ($sortbylast) {
         $hpcj["__sort__"] = "last";
     }
     Ht::stash_script("hotcrp_pc=" . json_encode($hpcj) . ";");
 }
if (is_array($qreq->papx)) {
    foreach ($qreq->papx as $p) {
        if (($p = cvtint($p)) > 0 && !isset($qreq->assrev[$p])) {
            $qreq->assrev[$p] = 0;
        }
    }
}
if (is_array($qreq->p) && $qreq->kind == "c") {
    foreach ($qreq->p as $p) {
        if (($p = cvtint($p)) > 0) {
            $qreq->assrev[$p] = -1;
        }
    }
}
$qreq->rev_roundtag = (string) $Conf->sanitize_round_name($qreq->rev_roundtag);
$pcm = pcMembers();
$reviewer = cvtint($qreq->reviewer);
if ($reviewer <= 0) {
    $reviewer = $Me->contactId;
}
if ($reviewer <= 0 || !isset($pcm[$reviewer])) {
    $reviewer = 0;
}
function saveAssignments($qreq, $reviewer)
{
    global $Conf, $Me, $Now, $pcm;
    $reviewer_contact = $pcm[$reviewer];
    $round_number = null;
    if (!count($qreq->assrev)) {
        return;
    }
function reviewTable($prow, $rrows, $crows, $rrow, $mode, $proposals = null)
{
    global $Conf, $Me;
    $subrev = array();
    $nonsubrev = array();
    $foundRrow = $foundMyReview = $notShown = 0;
    $conflictType = $Me->view_conflict_type($prow);
    $allow_admin = $Me->allow_administer($prow);
    $admin = $Me->can_administer($prow);
    $hideUnviewable = $conflictType > 0 && !$admin || !$Me->act_pc($prow) && !$Conf->setting("extrev_view");
    $show_colors = $Me->can_view_reviewer_tags($prow);
    $tagger = $show_colors ? new Tagger($Me) : null;
    $xsep = ' <span class="barsep">·</span> ';
    $want_scores = $mode !== "assign" && $mode !== "edit" && $mode !== "re";
    $want_requested_by = false;
    $want_retract = false;
    $pcm = pcMembers();
    $score_header = array();
    // actual rows
    foreach ($rrows as $rr) {
        $highlight = $rrow && $rr->reviewId == $rrow->reviewId;
        $foundRrow += $highlight;
        if ($Me->is_my_review($rr)) {
            $foundMyReview++;
        }
        $canView = $Me->can_view_review($prow, $rr, null);
        // skip unsubmitted reviews
        if (!$canView && $hideUnviewable) {
            if ($rr->reviewNeedsSubmit == 1 && $rr->reviewModified) {
                $notShown++;
            }
            continue;
        }
        $t = "";
        $tclass = $rrow && $highlight ? "hilite" : "";
        // review ID
        $id = "Review";
        if ($rr->reviewSubmitted) {
            $id .= "&nbsp;#" . $prow->paperId . unparseReviewOrdinal($rr->reviewOrdinal);
        } else {
            if ($rr->reviewType == REVIEW_SECONDARY && $rr->reviewNeedsSubmit <= 0) {
                $id .= "&nbsp;(delegated)";
            } else {
                if ($rr->reviewModified > 0) {
                    $id .= "&nbsp;(in&nbsp;progress)";
                } else {
                    $id .= "&nbsp;(not&nbsp;started)";
                }
            }
        }
        $rlink = unparseReviewOrdinal($rr);
        if ($rrow && $rrow->reviewId == $rr->reviewId) {
            if ($Me->contactId == $rr->contactId && !$rr->reviewSubmitted) {
                $id = "Your {$id}";
            }
            $t .= '<td><a href="' . hoturl("review", "p={$prow->paperId}&r={$rlink}") . '" class="q"><b>' . $id . '</b></a></td>';
        } else {
            if (!$canView) {
                $t .= "<td>{$id}</td>";
            } else {
                if ($rrow || $rr->reviewModified <= 0 || ($mode === "re" || $mode === "assign") && $Me->can_review($prow, $rr)) {
                    $t .= '<td><a href="' . hoturl("review", "p={$prow->paperId}&r={$rlink}") . '">' . $id . '</a></td>';
                } else {
                    if (Navigation::page() !== "paper") {
                        $t .= '<td><a href="' . hoturl("paper", "p={$prow->paperId}#r{$rlink}") . '">' . $id . '</a></td>';
                    } else {
                        $t .= '<td><a href="#r' . $rlink . '">' . $id . '</a></td>';
                    }
                }
            }
        }
        // primary/secondary glyph
        if ($conflictType > 0 && !$admin) {
            $rtype = "";
        } else {
            if ($rr->reviewType > 0) {
                $rtype = review_type_icon($rr->reviewType);
                if ($admin && $mode === "assign") {
                    $rtype .= _review_table_round_selector($prow, $rr);
                } else {
                    if ($rr->reviewRound > 0 && $Me->can_view_review_round($prow, $rr)) {
                        $rtype .= '&nbsp;<span class="revround" title="Review round">' . htmlspecialchars($Conf->round_name($rr->reviewRound, true)) . "</span>";
                    }
                }
            } else {
                $rtype = "";
            }
        }
        // reviewer identity
        $showtoken = $rr->reviewToken && $Me->can_review($prow, $rr);
        if (!$Me->can_view_review_identity($prow, $rr, null)) {
            $t .= $rtype ? "<td>{$rtype}</td>" : '<td class="empty"></td>';
        } else {
            if (!$showtoken || !Contact::is_anonymous_email($rr->email)) {
                $n = $Me->name_html_for($rr);
            } else {
                $n = "[Token " . encode_token((int) $rr->reviewToken) . "]";
            }
            if ($allow_admin) {
                $n .= _review_table_actas($rr);
            }
            $t .= '<td class="rl"><span class="taghl">' . $n . '</span>' . ($rtype ? " {$rtype}" : "") . "</td>";
            if ($show_colors && (get($rr, "contactRoles") || get($rr, "contactTags"))) {
                $tags = Contact::roles_all_contact_tags(get($rr, "contactRoles"), get($rr, "contactTags"));
                $tags = Tagger::strip_nonviewable($tags, $Me);
                if ($tags && ($color = TagInfo::color_classes($tags))) {
                    $tclass = $color;
                }
            }
        }
        // requester
        if ($mode === "assign") {
            if (($conflictType <= 0 || $admin) && $rr->reviewType == REVIEW_EXTERNAL && !$showtoken) {
                $t .= '<td style="font-size:smaller">';
                if ($rr->requestedBy == $Me->contactId) {
                    $t .= "you";
                } else {
                    if ($u = get($pcm, $rr->requestedBy)) {
                        $t .= $Me->reviewer_html_for($rr->requestedBy);
                    } else {
                        $t .= Text::user_html([$rr->reqFirstName, $rr->reqLastName, $rr->reqEmail]);
                    }
                }
                $t .= '</td>';
                $want_requested_by = true;
            } else {
                $t .= '<td class="empty"></td>';
            }
        }
        // actions
        if ($mode === "assign" && ($conflictType <= 0 || $admin) && $rr->reviewType == REVIEW_EXTERNAL && $rr->reviewModified <= 0 && ($rr->requestedBy == $Me->contactId || $admin)) {
            $t .= '<td>' . _retract_review_request_form($prow, $rr) . '</td>';
        }
        // scores
        $scores = array();
        if ($want_scores && $canView) {
            $view_score = $Me->view_score_bound($prow, $rr);
            $rf = ReviewForm::get();
            foreach ($rf->forder as $fid => $f) {
                if (!$f->has_options || $f->view_score <= $view_score || $f->round_mask && !$f->is_round_visible($rr)) {
                    /* do nothing */
                } else {
                    if ($rr->{$fid}) {
                        if (!get($score_header, $fid)) {
                            $score_header[$fid] = "<th>" . $f->web_abbreviation() . "</th>";
                        }
                        $scores[$fid] = '<td class="revscore" data-rf="' . $f->uid . '">' . $f->unparse_value($rr->{$fid}, ReviewField::VALUE_SC) . '</td>';
                    } else {
                        if (get($score_header, $fid) === null) {
                            $score_header[$fid] = "";
                        }
                    }
                }
            }
        }
        // affix
        if (!$rr->reviewSubmitted) {
            $nonsubrev[] = array($tclass, $t, $scores);
        } else {
            $subrev[] = array($tclass, $t, $scores);
        }
    }
    // proposed review rows
    if ($proposals) {
        foreach ($proposals as $rr) {
            $t = "";
            // review ID
            $t = "<td>Proposed review</td>";
            // reviewer identity
            $t .= "<td>" . Text::user_html($rr);
            if ($allow_admin) {
                $t .= _review_table_actas($rr);
            }
            $t .= "</td>";
            // requester
            if ($conflictType <= 0 || $admin) {
                $t .= '<td style="font-size:smaller">';
                if ($rr->requestedBy == $Me->contactId) {
                    $t .= "you";
                } else {
                    if ($u = get($pcm, $rr->requestedBy)) {
                        $t .= $Me->reviewer_html_for($rr->requestedBy);
                    } else {
                        $t .= Text::user_html([$rr->reqFirstName, $rr->reqLastName, $rr->reqEmail]);
                    }
                }
                $t .= '</td>';
                $want_requested_by = true;
            }
            $t .= '<td>';
            if ($admin) {
                $t .= '<small>' . Ht::form(hoturl_post("assign", "p={$prow->paperId}")) . '<div class="inline">' . Ht::hidden("name", $rr->name) . Ht::hidden("email", $rr->email) . Ht::hidden("reason", $rr->reason);
                if ($rr->reviewRound !== null) {
                    if ($rr->reviewRound == 0) {
                        $rname = "unnamed";
                    } else {
                        $rname = $Conf->round_name($rr->reviewRound);
                    }
                    if ($rname) {
                        $t .= Ht::hidden("round", $rname);
                    }
                }
                $t .= Ht::submit("add", "Approve review", array("style" => "font-size:smaller")) . ' ' . Ht::submit("deny", "Deny request", array("style" => "font-size:smaller")) . '</div></form>';
            } else {
                if ($rr->reqEmail === $Me->email) {
                    $t .= _retract_review_request_form($prow, $rr);
                }
            }
            $t .= '</td>';
            // affix
            $nonsubrev[] = array("", $t);
        }
    }
    // unfinished review notification
    $notetxt = "";
    if ($conflictType >= CONFLICT_AUTHOR && !$admin && $notShown && $Me->can_view_review($prow, null, null)) {
        if ($notShown == 1) {
            $t = "1 review remains outstanding.";
        } else {
            $t = "{$notShown} reviews remain outstanding.";
        }
        $t .= '<br /><span class="hint">You will be emailed if new reviews are submitted or existing reviews are changed.</span>';
        $notetxt = '<div class="revnotes">' . $t . "</div>";
    }
    // completion
    if (count($nonsubrev) + count($subrev)) {
        if ($want_requested_by) {
            array_unshift($score_header, '<th class="revsl">Requester</th>');
        }
        $score_header_text = join("", $score_header);
        $t = "<table class=\"reviewers";
        if ($score_header_text) {
            $t .= " reviewers_scores";
        }
        if ($list = SessionList::active()) {
            $t .= " has_hotcrp_list\" data-hotcrp-list=\"" . $list->listno;
        }
        $t .= "\">\n";
        if ($score_header_text) {
            $t .= '<tr><td class="empty" colspan="2"></td>' . $score_header_text . "</tr>\n";
        }
        foreach (array_merge($subrev, $nonsubrev) as $r) {
            $t .= '<tr class="rl' . ($r[0] ? " {$r['0']}" : "") . '">' . $r[1];
            if (get($r, 2)) {
                foreach ($score_header as $fid => $header_needed) {
                    if ($header_needed) {
                        $x = get($r[2], $fid);
                        $t .= $x ?: "<td class=\"revscore rs_{$fid}\"></td>";
                    }
                }
            } else {
                if (count($score_header)) {
                    $t .= '<td colspan="' . count($score_header) . '"></td>';
                }
            }
            $t .= "</tr>\n";
        }
        if ($score_header_text) {
            $Conf->footerScript("review_form.score_tooltips(\$(\"table.reviewers_scores\"))", "score_tooltips");
        }
        return $t . "</table>\n" . $notetxt;
    } else {
        return $notetxt;
    }
}
 private static function status_papers($status, $tracker, $acct)
 {
     global $Conf;
     $pids = array_slice($tracker->ids, $tracker->position, 3);
     $pc_conflicts = $acct->privChair || $acct->tracker_kiosk_state;
     $col = $j = "";
     if ($pc_conflicts) {
         $col = ", allconfs.conflictIds";
         $j = "left join (select paperId, group_concat(contactId) conflictIds from PaperConflict where paperId in (" . join(",", $pids) . ") group by paperId) allconfs on (allconfs.paperId=p.paperId)\n\t\t";
         $pcm = pcMembers();
     }
     $result = $Conf->qe("select p.paperId, p.title, p.paperFormat, p.leadContactId, p.managerContactId, r.reviewType, conf.conflictType{$col}\n            from Paper p\n            left join PaperReview r on (r.paperId=p.paperId and " . ($acct->contactId ? "r.contactId={$acct->contactId}" : "false") . ")\n            left join PaperConflict conf on (conf.paperId=p.paperId and " . ($acct->contactId ? "conf.contactId={$acct->contactId}" : "false") . ")\n            {$j}where p.paperId in (" . join(",", $pids) . ")");
     $papers = array();
     while ($row = PaperInfo::fetch($result, $acct)) {
         $papers[$row->paperId] = $p = (object) array();
         if (($acct->privChair || !$row->conflictType || !get($status, "hide_conflicts")) && $acct->tracker_kiosk_state != 1) {
             $p->pid = (int) $row->paperId;
             $p->title = $row->title;
             if ($format = $row->title_format()) {
                 $p->format = $format;
             }
         }
         if ($acct->contactId > 0 && $row->managerContactId == $acct->contactId) {
             $p->is_manager = true;
         }
         if ($row->reviewType) {
             $p->is_reviewer = true;
         }
         if ($row->conflictType) {
             $p->is_conflict = true;
         }
         if ($acct->contactId > 0 && $row->leadContactId == $acct->contactId) {
             $p->is_lead = true;
         }
         if ($pc_conflicts) {
             $p->pc_conflicts = array();
             foreach (explode(",", (string) $row->conflictIds) as $cid) {
                 if ($pc = get($pcm, $cid)) {
                     $p->pc_conflicts[$pc->sort_position] = (object) array("email" => $pc->email, "name" => Text::name_text($pc));
                 }
             }
             ksort($p->pc_conflicts);
             $p->pc_conflicts = array_values($p->pc_conflicts);
         }
     }
     Dbl::free($result);
     $status->papers = array();
     foreach ($pids as $pid) {
         $status->papers[] = $papers[$pid];
     }
 }
            $pctyp_sel[] = array($pctag, "pc_tags_members(\"{$tagname}\")", "#{$pctag}");
        }
    }
}
$pctyp_sel[] = array("__flip__", -1, "flip");
$sep = "";
foreach ($pctyp_sel as $pctyp) {
    echo $sep, "<a href='#pc_", $pctyp[0], "' onclick='", "papersel(", $pctyp[1], ",\"pcs[]\");\$\$(\"pctyp_sel\").checked=true;return false'>", $pctyp[2], "</a>";
    $sep = ", ";
}
echo ")</td></tr>\n<tr><td></td><td>";
$summary = [];
$tagger = new Tagger($Me);
$nrev = new AssignmentCountSet();
$nrev->load_rev();
foreach (pcMembers() as $p) {
    $t = '<div class="ctelt"><div class="ctelti';
    if ($k = $p->viewable_color_classes($Me)) {
        $t .= ' ' . $k;
    }
    $t .= '"><table><tr><td class="nw">' . Ht::checkbox("pcs[]", $p->contactId, isset($pcsel[$p->contactId]), ["id" => "pcsel" . (count($summary) + 1), "onclick" => "rangeclick(event,this);\$\$('pctyp_sel').checked=true"]) . '&nbsp;</td><td><span class="taghl">' . $Me->name_html_for($p) . '</span>' . AssignmentSet::review_count_report($nrev, null, $p, "") . "</td></tr></table><hr class=\"c\" />\n</div></div>";
    $summary[] = $t;
}
echo '<div class="pc_ctable">', join("", $summary), "</div>\n", "</td></tr></table>\n";
// Bad pairs
function bpSelector($i, $which)
{
    static $badPairSelector, $Qreq;
    if (!$badPairSelector) {
        $badPairSelector = pc_members_selector_options("(PC member)");
    }
Esempio n. 20
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);
    }
}
 public function apply(Contact $user, $pj, $opj, $qreq, $action)
 {
     global $Conf;
     // Title, abstract, collaborators
     foreach (array("title", "abstract", "collaborators") as $k) {
         if (isset($qreq[$k])) {
             $pj->{$k} = $qreq[$k];
         }
     }
     // Authors
     $bad_author = ["name" => "Name", "email" => "Email", "aff" => "Affiliation"];
     $authors = array();
     foreach ($qreq as $k => $v) {
         if (preg_match('/\\Aau(name|email|aff)(\\d+)\\z/', $k, $m) && ($v = simplify_whitespace($v)) !== "" && $v !== $bad_author[$m[1]]) {
             $au = $authors[$m[2]] = get($authors, $m[2]) ?: (object) array();
             $x = $m[1] == "aff" ? "affiliation" : $m[1];
             $au->{$x} = $v;
         }
     }
     if (!empty($authors)) {
         ksort($authors, SORT_NUMERIC);
         $pj->authors = array_values($authors);
     }
     // Contacts
     if ($qreq->setcontacts || $qreq->has_contacts) {
         PaperSaver::replace_contacts($pj, $qreq);
     } else {
         if (!$opj) {
             $pj->contacts = array($user);
         }
     }
     // Status
     if ($action === "submit") {
         $pj->submitted = true;
     } else {
         if ($action === "final") {
             $pj->final_submitted = true;
         } else {
             $pj->submitted = false;
         }
     }
     // Paper upload
     if ($qreq->_FILES->paperUpload) {
         if ($action === "final") {
             $pj->final = Filer::file_upload_json($qreq->_FILES->paperUpload);
         } else {
             if ($action === "update" || $action === "submit") {
                 $pj->submission = Filer::file_upload_json($qreq->_FILES->paperUpload);
             }
         }
     }
     // Blindness
     if ($action !== "final" && $Conf->subBlindOptional()) {
         $pj->nonblind = !$qreq->blind;
     }
     // Topics
     if ($qreq->has_topics) {
         $pj->topics = (object) array();
         foreach ($Conf->topic_map() as $tid => $tname) {
             if (+$qreq["top{$tid}"] > 0) {
                 $pj->topics->{$tname} = true;
             }
         }
     }
     // Options
     if (!isset($pj->options)) {
         $pj->options = (object) [];
     }
     foreach (PaperOption::option_list() as $o) {
         if ($qreq["has_opt{$o->id}"] && (!$o->final || $action === "final")) {
             $okey = $o->abbr;
             $pj->options->{$okey} = $o->parse_request(get($pj->options, $okey), $qreq, $user, $pj);
         }
     }
     if (!count(get_object_vars($pj->options))) {
         unset($pj->options);
     }
     // PC conflicts
     if ($Conf->setting("sub_pcconf") && ($action !== "final" || $user->privChair) && $qreq->has_pcconf) {
         $cmax = $user->privChair ? CONFLICT_CHAIRMARK : CONFLICT_MAXAUTHORMARK;
         $pj->pc_conflicts = (object) array();
         foreach (pcMembers() as $pcid => $pc) {
             $ctype = cvtint($qreq["pcc{$pcid}"], 0);
             $ctype = max(min($ctype, $cmax), 0);
             if ($ctype) {
                 $email = $pc->email;
                 $pj->pc_conflicts->{$email} = Conflict::$type_names[$ctype];
             }
         }
     }
 }
Esempio n. 22
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";
}
Esempio n. 23
0
function pcByEmail($email)
{
    $pc = pcMembers();
    foreach ($pc as $id => $row) {
        if ($row->email == $email) {
            return $row;
        }
    }
    return null;
}
 static function pcassignments_csv_data($user, $selection)
 {
     global $Conf;
     $pcm = pcMembers();
     $round_list = $Conf->round_list();
     $reviewnames = array(REVIEW_PC => "pcreview", REVIEW_SECONDARY => "secondary", REVIEW_PRIMARY => "primary");
     $any_round = false;
     $texts = array();
     $result = Dbl::qe_raw($Conf->paperQuery($user, array("paperId" => $selection, "assignments" => 1)));
     while ($prow = PaperInfo::fetch($result, $user)) {
         if (!$user->allow_administer($prow)) {
             $texts[] = array();
             $texts[] = array("paper" => $prow->paperId, "action" => "none", "title" => "You cannot override your conflict with this paper");
         } else {
             if ($prow->all_reviewers()) {
                 $texts[] = array();
                 $texts[] = array("paper" => $prow->paperId, "action" => "clearreview", "email" => "#pc", "round" => "any", "title" => $prow->title);
                 foreach ($prow->all_reviewers() as $cid) {
                     if (($pc = get($pcm, $cid)) && ($rtype = $prow->review_type($cid)) >= REVIEW_PC) {
                         $round = $prow->review_round($cid);
                         $round_name = $round ? $round_list[$round] : "none";
                         $any_round = $any_round || $round != 0;
                         $texts[] = array("paper" => $prow->paperId, "action" => $reviewnames[$rtype], "email" => $pc->email, "round" => $round_name);
                     }
                 }
             }
         }
     }
     $header = array("paper", "action", "email");
     if ($any_round) {
         $header[] = "round";
     }
     $header[] = "title";
     return [$header, $texts];
 }
Esempio n. 25
0
 function echo_unparse_display()
 {
     $this->set_my_conflicts();
     $bypaper = array();
     foreach ($this->assigners as $assigner) {
         if ($text = $assigner->unparse_display($this)) {
             $c = $assigner->contact;
             if ($c && !isset($c->sorter)) {
                 Contact::set_sorter($c);
             }
             arrayappend($bypaper[$assigner->pid], (object) array("text" => $text, "sorter" => $c ? $c->sorter : $text));
         }
     }
     AutoassignmentPaperColumn::$header = "Assignment";
     $assinfo = array();
     PaperColumn::register(new AutoassignmentPaperColumn());
     foreach ($bypaper as $pid => $list) {
         uasort($list, "Contact::compare");
         $t = "";
         foreach ($list as $x) {
             $t .= ($t ? ", " : "") . '<span class="nw">' . $x->text . '</span>';
         }
         if (isset($this->my_conflicts[$pid])) {
             if ($this->my_conflicts[$pid] !== true) {
                 $t = '<em>Hidden for conflict</em>';
             } else {
                 $t = PaperList::wrapChairConflict($t);
             }
         }
         $assinfo[$pid] = $t;
     }
     ksort($assinfo);
     AutoassignmentPaperColumn::$info = $assinfo;
     if ($this->unparse_search) {
         $query_order = "(" . $this->unparse_search . ") THEN HEADING:none " . join(" ", array_keys($assinfo));
     } else {
         $query_order = count($assinfo) ? join(" ", array_keys($assinfo)) : "NONE";
     }
     foreach ($this->unparse_columns as $k => $v) {
         $query_order .= " show:{$k}";
     }
     $query_order .= " show:autoassignment";
     $search = new PaperSearch($this->contact, array("t" => defval($_REQUEST, "t", "s"), "q" => $query_order));
     $plist = new PaperList($search);
     echo $plist->table_html("reviewers", ["nofooter" => 1]);
     $deltarev = new AssignmentCountSet();
     foreach ($this->assigners as $assigner) {
         $assigner->account($deltarev);
     }
     if (count(array_intersect_key($deltarev->bypc, pcMembers()))) {
         $summary = [];
         $tagger = new Tagger($this->contact);
         $nrev = new AssignmentCountSet();
         $deltarev->rev && $nrev->load_rev();
         $deltarev->lead && $nrev->load_lead();
         $deltarev->shepherd && $nrev->load_shepherd();
         foreach (pcMembers() as $p) {
             if ($deltarev->get($p->contactId)->ass) {
                 $t = '<div class="ctelt"><div class="ctelti';
                 if ($k = $p->viewable_color_classes($this->contact)) {
                     $t .= ' ' . $k;
                 }
                 $t .= '"><span class="taghl">' . $this->contact->name_html_for($p) . "</span>: " . plural($deltarev->get($p->contactId)->ass, "assignment") . self::review_count_report($nrev, $deltarev, $p, "After assignment:&nbsp;") . "<hr class=\"c\" /></div></div>";
                 $summary[] = $t;
             }
         }
         if (count($summary)) {
             echo "<div class=\"g\"></div>\n", "<h3>Summary</h3>\n", '<div class="pc_ctable">', join("", $summary), "</div>\n";
         }
     }
 }
Esempio n. 26
0
function pcAssignments()
{
    global $Conf, $Me, $prow;
    $pcm = pcMembers();
    $rname = (string) $Conf->sanitize_round_name(@$_REQUEST["rev_roundtag"]);
    $round_number = null;
    $where = array("(ContactInfo.roles&" . Contact::ROLE_PC . ")!=0");
    if (@$_REQUEST["reviewer"] && isset($pcm[$_REQUEST["reviewer"]])) {
        $where[] = "ContactInfo.contactId='" . $_REQUEST["reviewer"] . "'";
    }
    Dbl::qe_raw("lock tables PaperReview write, PaperReviewRefused write, PaperConflict write, ContactInfo read, ActionLog write, Settings write");
    // don't record separate PC conflicts on author conflicts
    $result = Dbl::qe_raw("select ContactInfo.contactId,\n        PaperConflict.conflictType, reviewType, reviewModified, reviewId\n        from ContactInfo\n        left join PaperConflict on (PaperConflict.contactId=ContactInfo.contactId and PaperConflict.paperId={$prow->paperId})\n        left join PaperReview on (PaperReview.contactId=ContactInfo.contactId and PaperReview.paperId={$prow->paperId})\n        where " . join(" and ", $where));
    while ($row = edb_orow($result)) {
        $pctype = defval($_REQUEST, "pcs{$row->contactId}", 0);
        if ($row->conflictType >= CONFLICT_AUTHOR) {
            continue;
        }
        // manage conflicts
        if ($row->conflictType && $pctype >= 0) {
            Dbl::qe_raw("delete from PaperConflict where paperId={$prow->paperId} and contactId={$row->contactId}");
        } else {
            if (!$row->conflictType && $pctype < 0) {
                Dbl::qe_raw("insert into PaperConflict (paperId, contactId, conflictType) values ({$prow->paperId}, {$row->contactId}, " . CONFLICT_CHAIRMARK . ")");
            }
        }
        // manage assignments
        $pctype = max($pctype, 0);
        if ($pctype != $row->reviewType && ($pctype == 0 || $pctype == REVIEW_PRIMARY || $pctype == REVIEW_SECONDARY || $pctype == REVIEW_PC) && ($pctype == 0 || $pcm[$row->contactId]->can_accept_review_assignment($prow))) {
            if ($pctype != 0 && $round_number === null) {
                $round_number = $Conf->round_number($rname, true);
            }
            $Me->assign_review($prow->paperId, $row->contactId, $pctype, array("round_number" => $round_number));
        }
    }
}
Esempio n. 27
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";
}
Esempio n. 28
0
 private function _rows($field_list)
 {
     global $Conf;
     if (!$field_list) {
         return null;
     }
     // prepare query text
     $this->qopts["scores"] = array_keys($this->qopts["scores"]);
     if (empty($this->qopts["scores"])) {
         unset($this->qopts["scores"]);
     }
     $pq = $Conf->paperQuery($this->contact, $this->qopts);
     // make query
     $result = Dbl::qe_raw($pq);
     if (!$result) {
         return null;
     }
     // fetch rows
     $rows = array();
     while ($row = PaperInfo::fetch($result, $this->contact)) {
         $rows[$row->paperId] = $row;
     }
     // prepare review query (see also search > getfn == "reviewers")
     $this->review_list = array();
     if (isset($this->qopts["reviewList"]) && !empty($rows)) {
         $result = Dbl::qe("select Paper.paperId, reviewId, reviewType,\n                reviewSubmitted, reviewModified, reviewNeedsSubmit, reviewRound,\n                reviewOrdinal,\n                PaperReview.contactId, lastName, firstName, email\n                from Paper\n                join PaperReview using (paperId)\n                join ContactInfo on (PaperReview.contactId=ContactInfo.contactId)\n                where paperId?a", array_keys($rows));
         while ($row = edb_orow($result)) {
             Contact::set_sorter($row);
             $this->review_list[$row->paperId][] = $row;
         }
         foreach ($this->review_list as &$revlist) {
             usort($revlist, "PaperList::review_list_compar");
         }
         unset($revlist);
     }
     // prepare PC topic interests
     if (isset($this->qopts["allReviewerPreference"])) {
         $ord = 0;
         $pcm = pcMembers();
         foreach ($pcm as $pc) {
             $pc->prefOrdinal = sprintf("-0.%04d", $ord++);
             $pc->topicInterest = array();
         }
         $result = Dbl::qe("select contactId, topicId, " . $Conf->query_topic_interest() . " from TopicInterest");
         while ($row = edb_row($result)) {
             $pcm[$row[0]]->topicInterest[$row[1]] = $row[2];
         }
     }
     // analyze rows (usually noop)
     foreach ($field_list as $fdef) {
         $fdef->analyze($this, $rows);
     }
     // sort rows
     if (!empty($this->sorters)) {
         $rows = $this->_sort($rows);
         if (isset($this->qopts["allReviewScores"])) {
             $this->_sortReviewOrdinal($rows);
         }
     }
     // set `any->optID`
     if ($nopts = PaperOption::count_option_list()) {
         foreach ($rows as $prow) {
             foreach ($prow->options() as $o) {
                 if (!$this->any["opt{$o->id}"] && $this->contact->can_view_paper_option($prow, $o->option)) {
                     $this->any["opt{$o->id}"] = true;
                     --$nopts;
                 }
             }
             if (!$nopts) {
                 break;
             }
         }
     }
     Dbl::free($result);
     return $rows;
 }
 function expandvar_recipient($what, $isbool)
 {
     global $Conf;
     if ($what == "%NEWASSIGNMENTS%") {
         return $this->get_new_assignments($this->recipient);
     }
     // rest is only there if we have a real paper
     if (!$this->row || get($this->row, "paperId") <= 0) {
         return self::EXPANDVAR_CONTINUE;
     }
     if ($this->preparation) {
         ++$this->preparation->paper_expansions;
     }
     if ($what == "%TITLE%") {
         return $this->row->title;
     }
     if ($what == "%TITLEHINT%") {
         if ($tw = UnicodeHelper::utf8_abbreviate($this->row->title, 40)) {
             return "\"{$tw}\"";
         } else {
             return "";
         }
     }
     if ($what == "%NUMBER%" || $what == "%PAPER%") {
         return $this->row->paperId;
     }
     if ($what == "%REVIEWNUMBER%") {
         return $this->reviewNumber;
     }
     if ($what == "%AUTHOR%" || $what == "%AUTHORS%") {
         if (!$this->permissionContact->is_site_contact && !$this->row->has_author($this->permissionContact) && !$this->permissionContact->can_view_authors($this->row, false)) {
             return $isbool ? false : "Hidden for blind review";
         }
         return rtrim($this->row->pretty_text_author_list());
     }
     if ($what == "%AUTHORVIEWCAPABILITY%" && isset($this->row->capVersion) && $this->permissionContact->act_author_view($this->row)) {
         return "cap=" . $Conf->capability_text($this->row, "a");
     }
     if ($what == "%SHEPHERD%" || $what == "%SHEPHERDNAME%" || $what == "%SHEPHERDEMAIL%") {
         $pc = pcMembers();
         if (defval($this->row, "shepherdContactId") <= 0 || !defval($pc, $this->row->shepherdContactId, null)) {
             if ($isbool) {
                 return false;
             } else {
                 if ($this->expansionType == self::EXPAND_EMAIL) {
                     return "<none>";
                 } else {
                     return "(no shepherd assigned)";
                 }
             }
         }
         $shep = $pc[$this->row->shepherdContactId];
         if ($what == "%SHEPHERD%") {
             return $this->expand_user($shep, "CONTACT");
         } else {
             if ($what == "%SHEPHERDNAME%") {
                 return $this->expand_user($shep, "NAME");
             } else {
                 return $this->expand_user($shep, "EMAIL");
             }
         }
     }
     if ($what == "%REVIEWAUTHOR%" && $this->contacts["reviewer"]) {
         return $this->_expand_reviewer("CONTACT", $isbool);
     }
     if ($what == "%REVIEWS%") {
         return $this->get_reviews();
     }
     if ($what == "%COMMENTS%") {
         return $this->get_comments(null);
     }
     $len = strlen($what);
     if ($len > 12 && substr($what, 0, 10) == "%COMMENTS(" && substr($what, $len - 2) == ")%") {
         if ($t = $this->tagger()->check(substr($what, 10, $len - 12), Tagger::NOVALUE)) {
             return $this->get_comments($t);
         }
     }
     if ($len > 12 && substr($what, 0, 10) == "%TAGVALUE(" && substr($what, $len - 2) == ")%") {
         if ($t = $this->tagger()->check(substr($what, 10, $len - 12), Tagger::NOVALUE | Tagger::NOPRIVATE)) {
             if (!isset($this->_tags[$t])) {
                 $this->_tags[$t] = array();
                 $result = Dbl::qe("select paperId, tagIndex from PaperTag where tag=?", $t);
                 while ($row = edb_row($result)) {
                     $this->_tags[$t][$row[0]] = $row[1];
                 }
             }
             $tv = defval($this->_tags[$t], $this->row->paperId);
             if ($isbool) {
                 return $tv !== null;
             } else {
                 if ($tv !== null) {
                     return $tv;
                 } else {
                     $this->_tagless[$this->row->paperId] = true;
                     return "(none)";
                 }
             }
         }
     }
     if ($this->preparation) {
         --$this->preparation->paper_expansions;
     }
     return self::EXPANDVAR_CONTINUE;
 }