function run(Contact $user, $qreq, $ssel)
 {
     global $Conf;
     $o = cvtint($qreq->decision);
     $decision_map = $Conf->decision_map();
     if ($o === null || !isset($decision_map[$o])) {
         return Conf::msg_error("Bad decision value.");
     }
     $result = Dbl::qe_raw($Conf->paperQuery($user, array("paperId" => $ssel->selection())));
     $success = $fails = array();
     while ($prow = PaperInfo::fetch($result, $user)) {
         if ($user->can_set_decision($prow, true)) {
             $success[] = $prow->paperId;
         } else {
             $fails[] = "#" . $prow->paperId;
         }
     }
     if (count($fails)) {
         Conf::msg_error("You cannot set paper decisions for " . pluralx($fails, "paper") . " " . commajoin($fails) . ".");
     }
     if (count($success)) {
         Dbl::qe("update Paper set outcome={$o} where paperId ?a", $success);
         $Conf->update_paperacc_setting($o > 0);
         redirectSelf(array("atab" => "decide", "decision" => $o));
     }
 }
 function run(Contact $user, $qreq, $ssel)
 {
     global $Conf;
     $mt = $qreq->assignfn;
     $mpc = (string) $qreq->markpc;
     $pc = null;
     if ($mpc != "" && $mpc != "0") {
         $pc = Contact::find_by_email($mpc);
     }
     if ($mt == "auto") {
         $t = in_array($qreq->t, array("acc", "s")) ? $qreq->t : "all";
         $q = join("+", $ssel->selection());
         go(hoturl("autoassign", "pap={$q}&t={$t}&q={$q}"));
     } else {
         if ($mt == "lead" || $mt == "shepherd") {
             if ($user->assign_paper_pc($ssel->selection(), $mt, $pc)) {
                 $Conf->confirmMsg(ucfirst(pluralx($ssel->selection(), $mt)) . " set.");
             } else {
                 if ($OK) {
                     $Conf->confirmMsg("No changes.");
                 }
             }
         } else {
             if (!$pc) {
                 Conf::msg_error("“" . htmlspecialchars($mpc) . "” is not a PC member.");
             } else {
                 if ($mt == "conflict" || $mt == "unconflict") {
                     if ($mt == "conflict") {
                         Dbl::qe("insert into PaperConflict (paperId, contactId, conflictType) (select paperId, ?, ? from Paper where paperId" . $ssel->sql_predicate() . ") on duplicate key update conflictType=greatest(conflictType, values(conflictType))", $pc->contactId, CONFLICT_CHAIRMARK);
                         $user->log_activity("Mark conflicts with {$mpc}", $ssel->selection());
                     } else {
                         Dbl::qe("delete from PaperConflict where PaperConflict.conflictType<? and contactId=? and (paperId" . $ssel->sql_predicate() . ")", CONFLICT_AUTHOR, $pc->contactId);
                         $user->log_activity("Remove conflicts with {$mpc}", $ssel->selection());
                     }
                 } else {
                     if (substr($mt, 0, 6) == "assign" && ($asstype = substr($mt, 6)) && isset(ReviewForm::$revtype_names[$asstype])) {
                         Dbl::qe_raw("lock tables PaperConflict write, PaperReview write, PaperReviewRefused write, Paper write, ActionLog write, Settings write");
                         $result = Dbl::qe_raw("select Paper.paperId, reviewId, reviewType, reviewModified, conflictType from Paper left join PaperReview on (Paper.paperId=PaperReview.paperId and PaperReview.contactId=" . $pc->contactId . ") left join PaperConflict on (Paper.paperId=PaperConflict.paperId and PaperConflict.contactId=" . $pc->contactId . ") where Paper.paperId" . $ssel->sql_predicate());
                         $conflicts = array();
                         $assigned = array();
                         $nworked = 0;
                         while ($row = PaperInfo::fetch($result, $user)) {
                             if ($asstype && $row->conflictType > 0) {
                                 $conflicts[] = $row->paperId;
                             } else {
                                 if ($asstype && $row->reviewType >= REVIEW_PC && $asstype != $row->reviewType) {
                                     $assigned[] = $row->paperId;
                                 } else {
                                     $user->assign_review($row->paperId, $pc->contactId, $asstype);
                                     $nworked++;
                                 }
                             }
                         }
                         if (count($conflicts)) {
                             Conf::msg_error("Some papers were not assigned because of conflicts (" . join(", ", $conflicts) . ").  If these conflicts are in error, remove them and try to assign again.");
                         }
                         if (count($assigned)) {
                             Conf::msg_error("Some papers were not assigned because the PC member already had an assignment (" . join(", ", $assigned) . ").");
                         }
                         if ($nworked) {
                             $Conf->confirmMsg($asstype == 0 ? "Unassigned reviews." : "Assigned reviews.");
                         }
                         Dbl::qe_raw("unlock tables");
                         $Conf->update_rev_tokens_setting(false);
                     }
                 }
             }
         }
     }
 }
function plural($n, $what)
{
    return (is_array($n) ? count($n) : $n) . ' ' . pluralx($n, $what);
}
 private function render_option($sv, $o)
 {
     global $Conf;
     if ($o) {
         $id = $o->id;
     } else {
         $o = PaperOption::make(array("id" => $o, "name" => "(Enter new option)", "description" => "", "type" => "checkbox", "position" => count(PaperOption::nonfixed_option_list()) + 1, "display" => "default"));
         $id = "n";
     }
     if ($sv->use_req() && isset($sv->req["optn{$id}"])) {
         $o = PaperOption::make(array("id" => $id, "name" => $sv->req["optn{$id}"], "description" => get($sv->req, "optd{$id}"), "type" => get($sv->req, "optvt{$id}", "checkbox"), "visibility" => get($sv->req, "optp{$id}", ""), "position" => get($sv->req, "optfp{$id}", 1), "display" => get($sv->req, "optdt{$id}")));
         if ($o->has_selector()) {
             $o->selector = explode("\n", rtrim(defval($sv->req, "optv{$id}", "")));
         }
     }
     echo "<table><tr><td><div class='f-contain'>\n", "  <div class='f-i'>", "<div class='f-c'>", $sv->label("optn{$id}", $id === "n" ? "New option name" : "Option name"), "</div>", "<div class='f-e'>", Ht::entry("optn{$id}", $o->name, $sv->sjs("optn{$id}", array("placeholder" => "(Enter new option)", "size" => 50))), "</div>\n", "  </div><div class='f-i'>", "<div class='f-c'>", $sv->label("optd{$id}", "Description"), "</div>", "<div class='f-e'>", Ht::textarea("optd{$id}", $o->description, array("rows" => 2, "cols" => 50, "id" => "optd{$id}")), "</div>\n", "  </div></div></td>";
     echo '<td style="padding-left:1em">';
     if ($id !== "n" && ($examples = $o->example_searches())) {
         echo '<div class="f-i"><div class="f-c">Example ' . pluralx($examples, "search") . "</div>";
         foreach ($examples as &$ex) {
             $ex = "<a href=\"" . hoturl("search", array("q" => $ex[0])) . "\">" . htmlspecialchars($ex[0]) . "</a>";
         }
         echo '<div class="f-e">', join("<br/>", $examples), "</div></div>";
     }
     echo "</td></tr>\n  <tr><td colspan='2'><table id='foldoptvis{$id}' class='fold2c fold3o'><tr>";
     echo "<td class='pad'><div class='f-i'><div class='f-c'>", $sv->label("optvt{$id}", "Type"), "</div><div class='f-e'>";
     $optvt = $o->type;
     if ($optvt == "text" && $o->display_space > 3) {
         $optvt .= ":ds_" . $o->display_space;
     }
     if ($o->final) {
         $optvt .= ":final";
     }
     $show_final = $Conf->collectFinalPapers();
     foreach (PaperOption::nonfixed_option_list() as $ox) {
         $show_final = $show_final || $ox->final;
     }
     $otypes = array();
     if ($show_final) {
         $otypes["xxx1"] = array("optgroup", "Options for submissions");
     }
     $otypes["checkbox"] = "Checkbox";
     $otypes["selector"] = "Selector";
     $otypes["radio"] = "Radio buttons";
     $otypes["numeric"] = "Numeric";
     $otypes["text"] = "Text";
     if ($o->type == "text" && $o->display_space > 3 && $o->display_space != 5) {
         $otypes[$optvt] = "Multiline text";
     } else {
         $otypes["text:ds_5"] = "Multiline text";
     }
     $otypes["pdf"] = "PDF";
     $otypes["slides"] = "Slides";
     $otypes["video"] = "Video";
     $otypes["attachments"] = "Attachments";
     if ($show_final) {
         $otypes["xxx2"] = array("optgroup", "Options for accepted papers");
         $otypes["pdf:final"] = "Alternate final version";
         $otypes["slides:final"] = "Final slides";
         $otypes["video:final"] = "Final video";
         $otypes["attachments:final"] = "Final attachments";
     }
     echo Ht::select("optvt{$id}", $otypes, $optvt, array("onchange" => "do_option_type(this)", "id" => "optvt{$id}")), "</div></div></td>\n";
     $Conf->footerScript("do_option_type(\$\$('optvt{$id}'),true)");
     echo "<td class='fn2 pad'><div class='f-i'><div class='f-c'>", $sv->label("optp{$id}", "Visibility"), "</div><div class='f-e'>", Ht::select("optp{$id}", array("admin" => "Administrators only", "rev" => "Visible to PC and reviewers", "nonblind" => "Visible if authors are visible"), $o->visibility, array("id" => "optp{$id}")), "</div></div></td>\n";
     echo "<td class='pad'><div class='f-i'><div class='f-c'>", $sv->label("optfp{$id}", "Form order"), "</div><div class='f-e'>";
     $x = array();
     // can't use "foreach (PaperOption::nonfixed_option_list())" because caller
     // uses cursor
     for ($n = 0; $n < count(PaperOption::nonfixed_option_list()); ++$n) {
         $x[$n + 1] = ordinal($n + 1);
     }
     if ($id === "n") {
         $x[$n + 1] = ordinal($n + 1);
     } else {
         $x["delete"] = "Delete option";
     }
     echo Ht::select("optfp{$id}", $x, $o->position, array("id" => "optfp{$id}")), "</div></div></td>\n";
     echo "<td class='pad fn3'><div class='f-i'><div class='f-c'>", $sv->label("optdt{$id}", "Display"), "</div><div class='f-e'>";
     echo Ht::select("optdt{$id}", ["default" => "Default", "prominent" => "Prominent", "topics" => "With topics", "submission" => "Near submission"], $o->display_name(), array("id" => "optdt{$id}")), "</div></div></td>\n";
     if (isset($otypes["pdf:final"])) {
         echo "<td class='pad fx2'><div class='f-i'><div class='f-c'>&nbsp;</div><div class='f-e hint' style='margin-top:0.7ex'>(Set by accepted authors during final version submission period)</div></div></td>\n";
     }
     echo "</tr></table>";
     $rows = 3;
     if (PaperOption::type_has_selector($optvt) && count($o->selector)) {
         $value = join("\n", $o->selector) . "\n";
         $rows = max(count($o->selector), 3);
     } else {
         $value = "";
     }
     echo "<div id='foldoptv{$id}' class='", PaperOption::type_has_selector($optvt) ? "foldo" : "foldc", "'><div class='fx'>", "<div class='hint' style='margin-top:1ex'>Enter choices one per line.  The first choice will be the default.</div>", Ht::textarea("optv{$id}", $value, $sv->sjs("optv{$id}", array("rows" => $rows, "cols" => 50))), "</div></div>";
     echo "</td></tr></table>\n";
 }
     $sep = $xsep;
 }
 if ($Conf->setting("rev_tokens")) {
     echo $sep;
     reviewTokenGroup(false);
     $sep = $xsep;
 }
 if ($myrow && $Conf->setting("rev_ratings") != REV_RATINGS_NONE) {
     $badratings = PaperSearch::unusableRatings($Me->privChair, $Me->contactId);
     $qx = count($badratings) ? " and not (PaperReview.reviewId in (" . join(",", $badratings) . "))" : "";
     $result = Dbl::qe_raw("select rating, count(PaperReview.reviewId) from PaperReview join ReviewRating on (PaperReview.contactId={$Me->contactId} and PaperReview.reviewId=ReviewRating.reviewId{$qx}) group by rating order by rating desc");
     if (edb_nrows($result)) {
         $a = array();
         while ($row = edb_row($result)) {
             if (isset(ReviewForm::$rating_types[$row[0]])) {
                 $a[] = "<a href=\"" . hoturl("search", "q=re:me+rate:%22" . urlencode(ReviewForm::$rating_types[$row[0]]) . "%22") . "\" title='List rated reviews'>{$row['1']} &ldquo;" . htmlspecialchars(ReviewForm::$rating_types[$row[0]]) . "&rdquo; " . pluralx($row[1], "rating") . "</a>";
             }
         }
         if (count($a) > 0) {
             echo "<div class='hint g'>\nYour reviews have received ", commajoin($a);
             if (count($a) > 1) {
                 echo " (these sets might overlap)";
             }
             echo ".<a class='help' href='", hoturl("help", "t=revrate"), "' title='About ratings'>?</a></div>\n";
         }
     }
 }
 if ($Me->has_review()) {
     $plist = new PaperList(new PaperSearch($Me, ["q" => "re:me"]), ["list" => true]);
     $ptext = $plist->table_html("reviewerHome");
     if ($plist->count > 0) {
    if (count($tracks->soleAuthor)) {
        $Conf->footerHtml("<div id='popup_d' class='popupc'>\n  <p><strong>This user cannot be deleted</strong> because they are the sole\n  contact for " . pluralx($tracks->soleAuthor, "paper") . " " . textArrayPapers($tracks->soleAuthor) . ".\n  Delete these papers from the database or add alternate paper contacts and\n  you will be able to delete this user.</p>\n  <div class='popup_actions'>" . Ht::js_button("Close", "popup(null,'d',1)") . "</div></div>");
    } else {
        if (count($tracks->author) + count($tracks->review) + count($tracks->comment)) {
            $x = $y = array();
            if (count($tracks->author)) {
                $x[] = "contact for " . pluralx($tracks->author, "paper") . " " . textArrayPapers($tracks->author);
                $y[] = "delete " . pluralx($tracks->author, "this") . " " . pluralx($tracks->author, "authorship association");
            }
            if (count($tracks->review)) {
                $x[] = "reviewer for " . pluralx($tracks->review, "paper") . " " . textArrayPapers($tracks->review);
                $y[] = "<strong>permanently delete</strong> " . pluralx($tracks->review, "this") . " " . pluralx($tracks->review, "review");
            }
            if (count($tracks->comment)) {
                $x[] = "commenter for " . pluralx($tracks->comment, "paper") . " " . textArrayPapers($tracks->comment);
                $y[] = "<strong>permanently delete</strong> " . pluralx($tracks->comment, "this") . " " . pluralx($tracks->comment, "comment");
            }
            $dialog = "<p>This user is " . commajoin($x) . ".\n  Deleting the user will also " . commajoin($y) . ".</p>";
        } else {
            $dialog = "";
        }
        $Conf->footerHtml("<div id='popup_d' class='popupc'>\n  <p>Be careful: This will permanently delete all information about this\n  user from the database and <strong>cannot be undone</strong>.</p>\n  {$dialog}\n  <form method='post' action=\"" . hoturl_post("profile", "u=" . urlencode($Acct->email)) . "\" enctype='multipart/form-data' accept-charset='UTF-8'>\n    <div class='popup_actions'>" . Ht::js_button("Cancel", "popup(null,'d',1)") . Ht::submit("delete", "Delete user", array("class" => "bb")) . "</div></form></div>");
    }
}
if (!$newProfile && $Acct->contactId == $Me->contactId) {
    $buttons[] = Ht::submit("merge", "Merge with another account", array("style" => "margin-left:2ex"));
}
echo "    <tr>\n";
foreach ($buttons as $b) {
    $x = is_array($b) ? $b[0] : $b;
    echo "      <td class='ptb_button'>", $x, "</td>\n";
 private static function _paperCommaJoin($pl, $a, $single)
 {
     while (preg_match('/\\b(\\w+)\\*/', $pl, $m)) {
         $pl = preg_replace('/\\b' . $m[1] . '\\*/', pluralx(count($a), $m[1]), $pl);
     }
     if ($single) {
         return preg_replace('/\\|.*/', "", $pl);
     }
     $pids = array();
     foreach ($a as &$x) {
         if (preg_match('/\\A(#?)(\\d+)([A-Z]*)\\z/', $x, $m)) {
             $x = "<a href=\"" . hoturl("paper", ["p" => $m[2], "anchor" => $m[3] ? "r{$m['2']}{$m['3']}" : null]) . "\">" . $x . "</a>";
             $pids[] = $m[2];
         }
     }
     $t = str_replace("|", "", $pl) . commajoin($a);
     if (count($pids) > 1) {
         $t = '<span class="has_hotcrp_list" data-hotcrp-list="p/s/' . join("+", $pids) . '">' . $t . '</span>';
     }
     return $t;
 }
function searchQuickref()
{
    global $rowidx, $Conf, $Opt, $Me;
    // how to report author searches?
    if ($Conf->subBlindNever()) {
        $aunote = "";
    } else {
        if (!$Conf->subBlindAlways()) {
            $aunote = "<br /><span class='hint'>Search uses fields visible to the searcher. For example, PC member searches do not examine anonymous authors.</span>";
        } else {
            $aunote = "<br /><span class='hint'>Search uses fields visible to the searcher. For example, PC member searches do not examine authors.</span>";
        }
    }
    // does a reviewer tag exist?
    $retag = meaningful_pc_tag() ?: "";
    _searchQuickrefRow("Basics", "", "all papers in the search category");
    _searchQuickrefRow("", "story", "“story” in title, abstract, authors{$aunote}");
    _searchQuickrefRow("", "119", "paper #119");
    _searchQuickrefRow("", "1 2 5 12-24 kernel", "papers in the numbered set with “kernel” in title, abstract, authors");
    _searchQuickrefRow("", "\"802\"", "“802” in title, abstract, authors (not paper #802)");
    _searchQuickrefRow("", "very new", "“very” <em>and</em> “new” in title, abstract, authors");
    _searchQuickrefRow("", "very AND new", "the same");
    _searchQuickrefRow("", "\"very new\"", "the phrase “very new” in title, abstract, authors");
    _searchQuickrefRow("", "very OR new", "<em>either</em> “very” <em>or</em> “new” in title, abstract, authors");
    _searchQuickrefRow("", "(very AND new) OR newest", "use parentheses to group");
    _searchQuickrefRow("", "very -new", "“very” <em>but not</em> “new” in title, abstract, authors");
    _searchQuickrefRow("", "very NOT new", "the same");
    _searchQuickrefRow("", "ve*", "words that <em>start with</em> “ve” in title, abstract, authors");
    _searchQuickrefRow("", "*me*", "words that <em>contain</em> “me” in title, abstract, authors");
    _searchQuickrefRow("Title", "ti:flexible", "title contains “flexible”");
    _searchQuickrefRow("Abstract", "ab:\"very novel\"", "abstract contains “very novel”");
    _searchQuickrefRow("Authors", "au:poletto", "author list contains “poletto”");
    if ($Me->isPC) {
        _searchQuickrefRow("", "au:pc", "one or more authors are PC members (author email matches PC email)");
    }
    _searchQuickrefRow("Collaborators", "co:liskov", "collaborators contains “liskov”");
    _searchQuickrefRow("Topics", "topic:link", "selected topics match “link”");
    $oex = array();
    foreach (PaperOption::option_list() as $o) {
        $oex = array_merge($oex, $o->example_searches());
    }
    if (count($oex)) {
        $section = "Options";
        foreach ($oex as $extype => $oex) {
            if ($extype === "has") {
                $desc = "paper has “" . htmlspecialchars($oex[1]->name) . "” submission option";
                $oabbr = array();
                foreach (PaperOption::option_list() as $ox) {
                    if ($ox !== $oex[1]) {
                        $oabbr[] = "“has:" . htmlspecialchars($ox->abbr) . "”";
                    }
                }
                if (count($oabbr)) {
                    $desc .= '<div class="hint">Other option ' . pluralx(count($oabbr), "search") . ': ' . commajoin($oabbr) . '</div>';
                }
            } else {
                if ($extype === "yes") {
                    $desc = "same meaning; abbreviations also accepted";
                } else {
                    if ($extype === "numeric") {
                        $desc = "paper’s “" . htmlspecialchars($oex[1]->name) . "” option has value &gt; 100";
                    } else {
                        if ($extype === "selector") {
                            $desc = "paper’s “" . htmlspecialchars($oex[1]->name) . "” option has value “" . htmlspecialchars($oex[1]->selector[1]) . "”";
                        } else {
                            if ($extype === "attachment-count") {
                                $desc = "paper has more than 2 “" . htmlspecialchars($oex[1]->name) . "” attachments";
                            } else {
                                if ($extype === "attachment-filename") {
                                    $desc = "paper has an “" . htmlspecialchars($oex[1]->name) . "” attachment with a .gif extension";
                                } else {
                                    continue;
                                }
                            }
                        }
                    }
                }
            }
            _searchQuickrefRow($section, $oex[0], $desc);
            $section = "";
        }
    }
    _searchQuickrefRow("<a href='" . hoturl("help", "t=tags") . "'>Tags</a>", "#discuss", "tagged “discuss” (“tag:discuss” also works)");
    _searchQuickrefRow("", "-#discuss", "not tagged “discuss”");
    _searchQuickrefRow("", "order:discuss", "tagged “discuss”, sort by tag order (“rorder:” for reverse order)");
    _searchQuickrefRow("", "#disc*", "matches any tag that <em>starts with</em> “disc”");
    $cx = null;
    $cm = array();
    foreach (TagInfo::defined_tags() as $t) {
        foreach ($t->colors ?: array() as $c) {
            $cx = $cx ?: $c;
            if ($cx === $c) {
                $cm[] = "“{$t->tag}”";
            }
        }
    }
    if (count($cm)) {
        array_unshift($cm, "“{$cx}”");
        _searchQuickrefRow("", "style:{$cx}", "tagged to appear {$cx} (tagged " . commajoin($cm, "or") . ")");
    }
    _searchQuickrefRow("Reviews", "re:me", "you are a reviewer");
    _searchQuickrefRow("", "re:fdabek", "“fdabek” in reviewer name/email");
    if ($retag) {
        _searchQuickrefRow("", "re:#{$retag}", "has a reviewer tagged “#" . $retag . "”");
    }
    _searchQuickrefRow("", "re:4", "four reviewers (assigned and/or completed)");
    if ($retag) {
        _searchQuickrefRow("", "re:#{$retag}>1", "at least two reviewers (assigned and/or completed) tagged “#" . $retag . "”");
    }
    _searchQuickrefRow("", "re:complete<3", "less than three completed reviews<br /><span class=\"hint\">Use “cre:<3” for short.</span>");
    _searchQuickrefRow("", "re:incomplete>0", "at least one incomplete review");
    _searchQuickrefRow("", "re:inprogress", "at least one in-progress review (started, but not completed)");
    _searchQuickrefRow("", "re:primary>=2", "at least two primary reviewers");
    _searchQuickrefRow("", "re:secondary", "at least one secondary reviewer");
    _searchQuickrefRow("", "re:external", "at least one external reviewer");
    _searchQuickrefRow("", "re:primary:fdabek:complete", "“fdabek” has completed a primary review");
    if ($r = meaningful_round_name()) {
        _searchQuickrefRow("", "re:{$r}", "review in round “" . htmlspecialchars($r) . "”");
    }
    _searchQuickrefRow("", "re:auwords<100", "has a review with less than 100 words in author-visible fields");
    if ($Conf->setting("rev_ratings") != REV_RATINGS_NONE) {
        _searchQuickrefRow("", "rate:+", "review was rated positively (“rate:-” and “rate:+>2” also work; can combine with “re:”)");
    }
    _searchQuickrefRow("Comments", "has:cmt", "at least one visible reviewer comment (not including authors’ response)");
    _searchQuickrefRow("", "cmt:>=3", "at least <em>three</em> visible reviewer comments");
    _searchQuickrefRow("", "has:aucmt", "at least one reviewer comment visible to authors");
    _searchQuickrefRow("", "cmt:sylvia", "“sylvia” (in name/email) wrote at least one visible comment; can combine with counts, use reviewer tags");
    $rnames = $Conf->resp_round_list();
    if (count($rnames) > 1) {
        _searchQuickrefRow("", "has:response", "has an author’s response");
        _searchQuickrefRow("", "has:{$rnames[1]}response", "has {$rnames['1']} response");
    } else {
        _searchQuickrefRow("", "has:response", "has author’s response");
    }
    _searchQuickrefRow("", "anycmt:>1", "at least two visible comments, possibly <em>including</em> author’s response");
    _searchQuickrefRow("Leads", "lead:fdabek", "“fdabek” (in name/email) is discussion lead");
    _searchQuickrefRow("", "lead:none", "no assigned discussion lead");
    _searchQuickrefRow("", "lead:any", "some assigned discussion lead");
    _searchQuickrefRow("Shepherds", "shep:fdabek", "“fdabek” (in name/email) is shepherd (“none” and “any” also work)");
    _searchQuickrefRow("Conflicts", "conflict:me", "you have a conflict with the paper");
    _searchQuickrefRow("", "conflict:fdabek", "“fdabek” (in name/email) has a conflict with the paper<br /><span class='hint'>This search is only available to chairs and to PC members who can see the paper’s author list.</span>");
    _searchQuickrefRow("", "conflict:pc", "some PC member has a conflict with the paper");
    _searchQuickrefRow("", "conflict:pc>2", "at least three PC members have conflicts with the paper");
    _searchQuickrefRow("", "reconflict:\"1 2 3\"", "a reviewer of paper 1, 2, or 3 has a conflict with the paper");
    _searchQuickrefRow("Preferences", "pref:fdabek>0", "“fdabek” (in name/email) has review preference &gt;&nbsp;0<br /><span class='hint'>PC members can search their own preferences; chairs can search anyone’s preferences.</span>");
    _searchQuickrefRow("", "pref:X", "some PC member has a preference expertise of “X” (expert)");
    _searchQuickrefRow("Status", "status:sub", "paper is submitted for review", "t=all");
    _searchQuickrefRow("", "status:unsub", "paper is neither submitted nor withdrawn", "t=all");
    _searchQuickrefRow("", "status:withdrawn", "paper has been withdrawn", "t=all");
    _searchQuickrefRow("", "has:final", "final copy uploaded");
    foreach ($Conf->decision_map() as $dnum => $dname) {
        if ($dnum) {
            break;
        }
    }
    $qdname = strtolower($dname);
    if (strpos($qdname, " ") !== false) {
        $qdname = "\"{$qdname}\"";
    }
    _searchQuickrefRow("Decision", "dec:{$qdname}", "decision is “" . htmlspecialchars($dname) . "” (partial matches OK)");
    _searchQuickrefRow("", "dec:yes", "one of the accept decisions");
    _searchQuickrefRow("", "dec:no", "one of the reject decisions");
    _searchQuickrefRow("", "dec:any", "decision specified");
    _searchQuickrefRow("", "dec:none", "decision unspecified");
    // find names of review fields to demonstrate syntax
    $farr = array(array(), array());
    foreach (ReviewForm::all_fields() as $f) {
        $fx = $f->has_options ? 0 : 1;
        $farr[$fx][] = $f->analyze();
    }
    $t = "Review&nbsp;fields";
    if (count($farr[0])) {
        $r = $farr[0][0];
        _searchQuickrefRow($t, $r->abbreviation1() . ":{$r->typical_score}", "at least one completed review has {$r->name_html} score {$r->typical_score}");
        _searchQuickrefRow("", "{$r->abbreviation}:{$r->typical_score}", "other abbreviations accepted");
        if (count($farr[0]) > 1) {
            $r2 = $farr[0][1];
            _searchQuickrefRow("", strtolower($r2->abbreviation) . ":{$r2->typical_score}", "other fields accepted (here, {$r2->name_html})");
        }
        if (isset($r->typical_score_range)) {
            _searchQuickrefRow("", "{$r->abbreviation}:{$r->typical_score0}..{$r->typical_score}", "completed reviews’ {$r->name_html} scores are in the {$r->typical_score0}&ndash;{$r->typical_score} range<br /><small>(all scores between {$r->typical_score0} and {$r->typical_score})</small>");
            _searchQuickrefRow("", "{$r->abbreviation}:{$r->typical_score_range}", "completed reviews’ {$r->name_html} scores <em>fill</em> the {$r->typical_score0}&ndash;{$r->typical_score} range<br /><small>(all scores between {$r->typical_score0} and {$r->typical_score}, with at least one {$r->typical_score0} and at least one {$r->typical_score})</small>");
        }
        if (!$r->option_letter) {
            list($greater, $less, $hint) = array("greater", "less", "");
        } else {
            $hint = "<br /><small>(better scores are closer to A than Z)</small>";
            if (defval($Opt, "smartScoreCompare")) {
                list($greater, $less) = array("better", "worse");
            } else {
                list($greater, $less) = array("worse", "better");
            }
        }
        _searchQuickrefRow("", "{$r->abbreviation}:>{$r->typical_score}", "at least one completed review has {$r->name_html} score {$greater} than {$r->typical_score}" . $hint);
        _searchQuickrefRow("", "{$r->abbreviation}:2<={$r->typical_score}", "at least two completed reviews have {$r->name_html} score {$less} than or equal to {$r->typical_score}");
        _searchQuickrefRow("", "{$r->abbreviation}:pc>{$r->typical_score}", "at least one completed PC review has {$r->name_html} score {$greater} than {$r->typical_score}");
        _searchQuickrefRow("", "{$r->abbreviation}:pc:2>{$r->typical_score}", "at least two completed PC reviews have {$r->name_html} score {$greater} than {$r->typical_score}");
        _searchQuickrefRow("", "{$r->abbreviation}:sylvia={$r->typical_score}", "“sylvia” (reviewer name/email) gave {$r->name_html} score {$r->typical_score}");
        $t = "";
    }
    if (count($farr[1])) {
        $r = $farr[1][0];
        _searchQuickrefRow($t, $r->abbreviation1() . ":finger", "at least one completed review has “finger” in the {$r->name_html} field");
        _searchQuickrefRow($t, "{$r->abbreviation}:finger", "other abbreviations accepted");
        _searchQuickrefRow($t, "{$r->abbreviation}:any", "at least one completed review has text in the {$r->name_html} field");
    }
    if (count($farr[0])) {
        $r = $farr[0][0];
        _searchQuickrefRow("<a href=\"" . hoturl("help", "t=formulas") . "\">Formulas</a>", "formula:all({$r->abbreviation}={$r->typical_score})", "all reviews have {$r->name_html} score {$r->typical_score}<br />" . "<span class='hint'><a href=\"" . hoturl("help", "t=formulas") . "\">Formulas</a> can express complex numerical queries across review scores and preferences.</span>");
        _searchQuickrefRow("", "f:all({$r->abbreviation}={$r->typical_score})", "“f” is shorthand for “formula”");
        _searchQuickrefRow("", "formula:var({$r->abbreviation})>0.5", "variance in {$r->abbreviation} is above 0.5");
        _searchQuickrefRow("", "formula:any({$r->abbreviation}={$r->typical_score} && pref<0)", "at least one reviewer had {$r->name_html} score {$r->typical_score} and review preference &lt; 0");
    }
    _searchQuickrefRow("Display", "show:tags show:conflicts", "show tags and PC conflicts in the results");
    _searchQuickrefRow("", "hide:title", "hide title in the results");
    if (count($farr[0])) {
        $r = $farr[0][0];
        _searchQuickrefRow("", "show:max({$r->abbreviation})", "show a <a href=\"" . hoturl("help", "t=formulas") . "\">formula</a>");
        _searchQuickrefRow("", "show:statistics", "show summary statistics for formulas");
        _searchQuickrefRow("", "sort:{$r->abbreviation}", "sort by score");
        _searchQuickrefRow("", "sort:\"{$r->abbreviation} variance\"", "sort by score variance");
    }
    _searchQuickrefRow("", "sort:-status", "sort by reverse status");
    _searchQuickrefRow("", "edit:#discuss", "edit the values for tag “#discuss”");
    _searchQuickrefRow("", "search1 THEN search2", "like “search1 OR search2”, but papers matching “search1” are grouped together and appear earlier in the sorting order");
    _searchQuickrefRow("", "1-5 THEN 6-10 show:compact", "display searches in compact columns");
    _searchQuickrefRow("", "search1 HIGHLIGHT search2", "search for “search1”, but <span class=\"taghl highlightmark\">highlight</span> papers in that list that match “search2” (also try HIGHLIGHT:pink, HIGHLIGHT:green, HIGHLIGHT:blue)");
}
Beispiel #9
0
 static function send_reviewers($template, $row, $rest = array())
 {
     global $Conf, $Me, $Opt;
     $result = $Conf->qe("select ContactInfo.contactId,\n                firstName, lastName, email, preferredEmail, password, roles, disabled,\n                conflictType, reviewType myReviewType\n                from ContactInfo\n                join PaperReview on (PaperReview.contactId=ContactInfo.contactId and PaperReview.paperId={$row->paperId})\n                left join PaperConflict on (PaperConflict.contactId=ContactInfo.contactId and PaperConflict.paperId={$row->paperId})\n                group by ContactInfo.contactId");
     if (!isset($rest["cc"]) && isset($Opt["emailCc"])) {
         $rest["cc"] = $Opt["emailCc"];
     } else {
         if (!isset($rest["cc"])) {
             $rest["cc"] = Text::user_email_to(Contact::site_contact());
         }
     }
     // must set the current conflict type in $row for each contact
     $contact_info_map = $row->replace_contact_info_map(null);
     $contacts = array();
     while ($contact = edb_orow($result)) {
         $row->assign_contact_info($contact, $contact->contactId);
         self::send_to(Contact::make($contact), $template, $row, $rest);
         $contacts[] = Text::user_html($contact);
     }
     $row->replace_contact_info_map($contact_info_map);
     if ($Me->allow_administer($row) && !$row->has_author($Me) && count($contacts)) {
         $endmsg = isset($rest["infoMsg"]) ? ", " . $rest["infoMsg"] : ".";
         $Conf->infoMsg("Sent email to paper #{$row->paperId}’s " . pluralx($contacts, "reviewer") . ", " . commajoin($contacts) . $endmsg);
     }
 }
Beispiel #10
0
 private function __downloadPaper($paperId, $attachment, $documentType, $docid)
 {
     global $Opt, $Me, $zlib_output_compression;
     $result = $this->document_result($paperId, $documentType, $docid);
     if (!$result) {
         $this->log("Download error: " . $this->dblink->error, $Me, $paperId);
         return set_error_html("Database error while downloading paper.");
     } else {
         if (edb_nrows($result) == 0) {
             return set_error_html("No such document.");
         }
     }
     // Check data
     $docs = array();
     while ($doc = $this->document_row($result, $documentType)) {
         if (!$doc->mimetype) {
             $doc->mimetype = MIMETYPEID_PDF;
         }
         $doc->filename = HotCRPDocument::filename($doc);
         $docs[] = $doc;
     }
     if (count($docs) == 1 && $docs[0]->paperStorageId <= 1) {
         return set_error_html("Paper #" . $docs[0]->paperId . " hasn’t been uploaded yet.");
     }
     $downloadname = false;
     if (count($docs) > 1) {
         $downloadname = $Opt["downloadPrefix"] . pluralx(2, HotCRPDocument::unparse_dtype($documentType)) . ".zip";
     }
     return DocumentHelper::download($docs, $downloadname, $attachment);
 }