public function editable_tags(Contact $user) { $tags = $this->viewable_tags($user); if ($tags !== "") { $privChair = $user->allow_administer($this); $dt = TagInfo::defined_tags(); $etags = array(); foreach (explode(" ", $tags) as $t) { if (!($t === "" || ($v = $dt->check(TagInfo::base($t))) && ($v->vote || $v->approval || !$privChair && (!$user->privChair || !$v->sitewide) && ($v->chair || $v->rank)))) { $etags[] = $t; } } $tags = join(" ", $etags); } return $tags; }
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 > 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 > 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 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}–{$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}–{$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 < 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)"); }
function initialize_paper_columns() { global $Conf; PaperColumn::register(new SelectorPaperColumn("sel", array("minimal" => true))); PaperColumn::register(new SelectorPaperColumn("selon", array("minimal" => true, "className" => "pl_sel"))); PaperColumn::register(new SelectorPaperColumn("selconf", array("className" => "pl_confselector"))); PaperColumn::register(new SelectorPaperColumn("selunlessconf", array("minimal" => true, "className" => "pl_sel"))); PaperColumn::register(new IdPaperColumn()); PaperColumn::register(new TitlePaperColumn()); PaperColumn::register(new StatusPaperColumn("status", false)); PaperColumn::register(new StatusPaperColumn("statusfull", true)); PaperColumn::register(new ReviewerTypePaperColumn("revtype")); PaperColumn::register(new ReviewStatusPaperColumn()); PaperColumn::register(new ReviewSubmittedPaperColumn()); PaperColumn::register(new ReviewDelegationPaperColumn()); PaperColumn::register(new AssignReviewPaperColumn()); PaperColumn::register(new TopicScorePaperColumn()); PaperColumn::register(new TopicListPaperColumn()); PaperColumn::register(new PreferencePaperColumn("pref", false)); PaperColumn::register_synonym("revpref", "pref"); PaperColumn::register(new PreferenceListPaperColumn("allpref", false)); PaperColumn::register_synonym("allrevpref", "allpref"); PaperColumn::register(new PreferenceListPaperColumn("alltopicpref", true)); PaperColumn::register_synonym("allrevtopicpref", "alltopicpref"); PaperColumn::register(new DesirabilityPaperColumn()); PaperColumn::register(new ReviewerListPaperColumn()); PaperColumn::register(new AuthorsPaperColumn()); PaperColumn::register(new CollabPaperColumn()); PaperColumn::register_synonym("co", "collab"); PaperColumn::register(new TagListPaperColumn(false)); PaperColumn::register(new SearchOptsPaperColumn()); PaperColumn::register(new AbstractPaperColumn()); PaperColumn::register(new LeadPaperColumn()); PaperColumn::register(new ShepherdPaperColumn()); PaperColumn::register(new PCConflictListPaperColumn()); PaperColumn::register(new ConflictMatchPaperColumn("authorsmatch", "authorInformation")); PaperColumn::register(new ConflictMatchPaperColumn("collabmatch", "collaborators")); PaperColumn::register(new TimestampPaperColumn()); PaperColumn::register(new FoldAllPaperColumn()); PaperColumn::register_factory("tag:", new TagPaperColumn(null, null, false)); PaperColumn::register_factory("tagval:", new TagPaperColumn(null, null, true)); PaperColumn::register_factory("opt:", new OptionPaperColumn(null)); PaperColumn::register_factory("#", new TagPaperColumn(null, null, null)); PaperColumn::register_factory("pref:", new PreferencePaperColumn(null, false)); if (PaperOption::count_option_list()) { PaperColumn::register_factory("", new OptionPaperColumn(null)); } foreach (ReviewForm::all_fields() as $f) { if ($f->has_options) { PaperColumn::register_factory("", new ScorePaperColumn(null)); break; } } if ($Conf && $Conf->setting("formulas")) { $result = Dbl::q("select * from Formula order by lower(name)"); while ($result && ($row = Formula::fetch($result))) { $fid = $row->formulaId; FormulaPaperColumn::register(new FormulaPaperColumn("formula{$fid}", $row)); } } PaperColumn::register_factory("", new FormulaPaperColumn("", null)); $tagger = new Tagger(); if ($Conf && (TagInfo::has_vote() || TagInfo::has_approval() || TagInfo::has_rank())) { $vt = array(); foreach (TagInfo::defined_tags() as $v) { if ($v->vote || $v->approval || $v->rank) { $vt[] = $v->tag; } } foreach ($vt as $n) { TagReportPaperColumn::register(new TagReportPaperColumn($n)); } } }
public function unparse_badges_html($tags) { if (is_array($tags)) { $tags = join(" ", $tags); } if (!$tags || $tags === " " || !TagInfo::has_badges()) { return ""; } if (!preg_match_all(TagInfo::badge_regex(), $tags, $m, PREG_SET_ORDER)) { return false; } $dt = TagInfo::defined_tags(); $x = ""; foreach ($m as $mx) { if (($t = $dt->check($mx[1])) && $t->badges) { $tag = $this->unparse(trim($mx[0])); $b = '<span class="badge ' . $t->badges[0] . 'badge">#' . $tag . '</span>'; if ($link = $this->link($tag)) { $b = '<a class="qq" href="' . $link . '">' . $b . '</a>'; } $x .= $b; } } return $x; }