private static function set_paper_pc_api($user, $qreq, $prow, $type)
 {
     // canonicalize $value
     $value = $qreq->{$type};
     $pc = null;
     if ($value === "0" || $value === 0 || $value === "none") {
         $pc = 0;
     } else {
         if (is_string($value)) {
             $pc = pcByEmail($value);
         }
     }
     if (!$pc && $pc !== 0) {
         json_exit(["ok" => false, "error" => "No such PC member “" . htmlspecialchars($value) . "”."]);
     }
     if ($type == "manager" ? $user->privChair : $user->can_administer($prow)) {
         if (!$pc || $pc->isPC && $pc->can_accept_review_assignment($prow)) {
             $user->assign_paper_pc($prow, $type, $pc);
             $j = ["ok" => true, "result" => $pc ? $user->name_html_for($pc) : "None"];
             if ($user->can_view_reviewer_tags($prow)) {
                 $j["color_classes"] = $pc ? $pc->viewable_color_classes($user) : "";
             }
             json_exit($j);
         } else {
             json_exit(["ok" => false, "error" => Text::user_html($pc) . " can’t be the {$type} for paper #{$prow->paperId}."]);
         }
     } else {
         json_exit(["ok" => false, "error" => "You don’t have permission to set the {$type} for paper #{$prow->paperId}."]);
     }
 }
 public function avoid_pair_assignment($pc1, $pc2)
 {
     if (!is_numeric($pc1)) {
         $pc1 = pcByEmail($pc1);
         $pc1 = $pc1 ? $pc1->contactId : null;
     }
     if (!is_numeric($pc2)) {
         $pc2 = pcByEmail($pc2);
         $pc2 = $pc2 ? $pc2->contactId : null;
     }
     if ($pc1 && $pc2) {
         $this->badpairs[$pc1][$pc2] = $this->badpairs[$pc2][$pc1] = true;
     }
 }
function fix_one_delegation()
{
    global $Conf;
    $row = Dbl::fetch_first_row("select r.paperId, r.contactId, u.email, q.ct, q.cs, r.reviewNeedsSubmit\n            from PaperReview r\n            left join (select paperId, requestedBy, count(reviewId) ct, count(reviewSubmitted) cs\n                       from PaperReview where reviewType<" . REVIEW_SECONDARY . "\n                       group by paperId, requestedBy) q\n                on (q.paperId=r.paperId and q.requestedBy=r.contactId)\n            left join ContactInfo u on (u.contactId=r.contactId)\n            where r.reviewType=" . REVIEW_SECONDARY . " and r.reviewSubmitted is null\n            and if(coalesce(q.ct,0)=0,1,if(q.cs=0,-1,0))!=r.reviewNeedsSubmit\n            limit 1");
    if (!$row) {
        return false;
    }
    $pid = (int) $row[0];
    $req_cid = (int) $row[1];
    $req_email = $row[2];
    $prow = $Conf->paperRow(["paperId" => $pid], null);
    fwrite(STDERR, "Problem: #{$pid} review by {$req_email}\n");
    fwrite(STDERR, "  reviewNeedsSubmit {$row['5']}, " . plural($row[3] ?: 0, "delegate") . ", " . plural($row[4] ?: 0, "submitted delegate") . "\n");
    $result = Dbl::qe("select l.* from ActionLog l where paperId=? order by logId asc", $pid);
    $proposals = $confirmations = [];
    while ($row = edb_orow($result)) {
        if ($row->contactId == $req_cid && preg_match('/\\ALogged proposal for (\\S+) to review/', $row->action, $m) && ($xid = Contact::id_by_email($m[1]))) {
            $proposals[$xid] = true;
        } else {
            if (preg_match('/\\AAdded External review by (\\S+)/', $row->action, $m) && ($pc = pcByEmail($m[1])) && $pc->can_administer($prow)) {
                $confirmations[$row->contactId] = $pc->contactId;
            }
        }
    }
    Dbl::free($result);
    foreach ($proposals as $xid => $x) {
        if (isset($confirmations[$xid])) {
            $result1 = Dbl::qe("update PaperReview set requestedBy=? where paperId=? and contactId=? and requestedBy=?", $req_cid, $pid, $xid, $confirmations[$xid]);
            $result2 = Dbl::qe("update PaperReview r, PaperReview q set r.reviewNeedsSubmit=0 where r.paperId=? and r.contactId=? and q.paperId=? and q.contactId=? and q.reviewSubmitted is not null", $pid, $req_cid, $pid, $xid);
            if ($result1->affected_rows || $result2->affected_rows) {
                return true;
            }
        }
    }
    error_log("Failed to resolve paper #{$pid} review by {$req_email}");
    return false;
}
 private function normalize_pc_conflicts($pj)
 {
     $conflicts = get($pj, "pc_conflicts");
     $pj->pc_conflicts = (object) array();
     if (is_object($conflicts)) {
         $conflicts = (array) $conflicts;
     }
     foreach ($conflicts as $email => $ct) {
         if (is_int($email) && is_string($ct)) {
             list($email, $ct) = array($ct, true);
         }
         if ($ct === "none" || $ct === "" || $ct === false || $ct === 0) {
             continue;
         }
         if ($ct === "conflict") {
             $ct = true;
         }
         if (!($pccid = pcByEmail($email))) {
             $pj->bad_pc_conflicts->{$email} = true;
         } else {
             if (!is_int($ct) && !is_string($ct) && $ct !== true) {
                 $this->set_error_html("pc_conflicts", "Format error [PC conflicts]");
             } else {
                 if (is_int($ct) && isset(Conflict::$type_names[$ct])) {
                     $ctn = $ct;
                 } else {
                     if (($ctn = array_search($ct, Conflict::$type_names, true)) !== false) {
                         /* OK */
                     } else {
                         $pj->bad_pc_conflicts->{$email} = $ct;
                         $ctn = array_search("other", Conflict::$type_names, true);
                     }
                 }
                 $pj->pc_conflicts->{$email} = $ctn;
             }
         }
     }
 }