static function parse_paper_options(PaperInfo $prow, $all)
 {
     $optionIds = get($prow, "optionIds");
     if ($optionIds === "") {
         return [];
     }
     $optsel = array();
     if ($optionIds !== null) {
         preg_match_all('/(\\d+)#(\\d+)/', $optionIds, $m);
         for ($i = 0; $i < count($m[1]); ++$i) {
             arrayappend($optsel[$m[1][$i]], (int) $m[2][$i]);
         }
         $optdata = null;
     } else {
         $optdata = self::load_optdata($prow->paperId);
         foreach ($optdata as $k => $v) {
             $dot = strpos($k, ".");
             arrayappend($optsel[substr($k, 0, $dot)], (int) substr($k, $dot + 1));
         }
     }
     $option_array = array();
     foreach ($optsel as $oid => $ovalues) {
         $o = PaperOption::find($oid);
         if (!$o && !$all) {
             continue;
         }
         $needs_data = !$o || $o->needs_data();
         if ($needs_data && !$optdata) {
             $optdata = self::load_optdata($prow->paperId);
         }
         $odata = [];
         if ($needs_data) {
             foreach ($ovalues as $v) {
                 $odata[] = $optdata[$oid . "." . $v];
             }
         }
         $option_array[$oid] = new PaperOptionValue($oid, $o, $ovalues, $odata);
     }
     uasort($option_array, function ($a, $b) {
         if ($a->option && $b->option) {
             return PaperOption::compare($a->option, $b->option);
         } else {
             if ($a->option || $b->option) {
                 return $a->option ? -1 : 1;
             } else {
                 return $a->id - $b->id;
             }
         }
     });
     return $option_array;
 }
 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";
         }
     }
 }
 function run(Contact $user, $qreq, $ssel)
 {
     global $Conf;
     $type = $this->islead ? "lead" : "shepherd";
     $result = Dbl::qe_raw($Conf->paperQuery($user, array("paperId" => $ssel->selection(), "reviewerName" => $type)));
     $texts = array();
     while ($row = PaperInfo::fetch($result, $user)) {
         if ($row->reviewEmail && ($this->islead ? $user->can_view_lead($row, true) : $user->can_view_shepherd($row, true))) {
             arrayappend($texts[$row->paperId], [$row->paperId, $row->title, $row->reviewFirstName, $row->reviewLastName, $row->reviewEmail]);
         }
     }
     downloadCSV($ssel->reorder($texts), array("paper", "title", "first", "last", "{$type}email"), "{$type}s");
 }
 function run(Contact $user, $qreq, $ssel)
 {
     global $Conf;
     $result = Dbl::qe_raw($Conf->paperQuery($user, array("paperId" => $ssel->selection(), "topics" => 1)));
     $texts = array();
     $tmap = $Conf->topic_map();
     while ($row = PaperInfo::fetch($result, $user)) {
         if ($user->can_view_paper($row)) {
             $out = array();
             foreach ($row->topics() as $t) {
                 $out[] = [$row->paperId, $row->title, $tmap[$t]];
             }
             if (!count($out)) {
                 $out[] = [$row->paperId, $row->title, "<none>"];
             }
             arrayappend($texts[$row->paperId], $out);
         }
     }
     downloadCSV($ssel->reorder($texts), array("paper", "title", "topic"), "topics");
 }
 private static function make_tagmap()
 {
     global $Conf;
     self::$tagmap = $map = new TagMap();
     if (!$Conf) {
         return $map;
     }
     $ct = $Conf->setting_data("tag_chair", "");
     foreach (preg_split('/\\s+/', $ct) as $t) {
         if ($t !== "" && !$map[self::base($t)]->chair) {
             $map[self::base($t)]->chair = true;
             ++$map->nchair;
         }
     }
     foreach ($Conf->track_tags() as $t) {
         if (!$map[self::base($t)]->chair) {
             $map[self::base($t)]->chair = true;
             ++$map->nchair;
         }
     }
     $ct = $Conf->setting_data("tag_sitewide", "");
     foreach (preg_split('/\\s+/', $ct) as $t) {
         if ($t !== "" && !$map[self::base($t)]->sitewide) {
             $map[self::base($t)]->sitewide = true;
             ++$map->nsitewide;
         }
     }
     $vt = $Conf->setting_data("tag_vote", "");
     if ($vt !== "") {
         foreach (preg_split('/\\s+/', $vt) as $t) {
             if ($t !== "") {
                 list($b, $v) = self::split_index($t);
                 $map[$b]->vote = $v ? $v : 1;
                 ++$map->nvote;
             }
         }
     }
     $vt = $Conf->setting_data("tag_approval", "");
     if ($vt !== "") {
         foreach (preg_split('/\\s+/', $vt) as $t) {
             if ($t !== "") {
                 list($b, $v) = self::split_index($t);
                 $map[$b]->approval = true;
                 ++$map->napproval;
             }
         }
     }
     $rt = $Conf->setting_data("tag_rank", "");
     if ($rt !== "") {
         foreach (preg_split('/\\s+/', $rt) as $t) {
             $map[self::base($t)]->rank = true;
             ++$map->nrank;
         }
     }
     $ct = $Conf->setting_data("tag_color", "");
     if ($ct !== "") {
         foreach (explode(" ", $ct) as $k) {
             if ($k !== "" && ($p = strpos($k, "=")) !== false) {
                 arrayappend($map[substr($k, 0, $p)]->colors, self::canonical_color(substr($k, $p + 1)));
             }
         }
     }
     $bt = $Conf->setting_data("tag_badge", "");
     if ($bt !== "") {
         foreach (explode(" ", $bt) as $k) {
             if ($k !== "" && ($p = strpos($k, "=")) !== false) {
                 arrayappend($map[substr($k, 0, $p)]->badges, self::canonical_color(substr($k, $p + 1)));
                 ++$map->nbadge;
             }
         }
     }
     $xt = $Conf->setting_data("tag_order_anno", "");
     if ($xt !== "" && ($xt = json_decode($xt))) {
         foreach (get_object_vars($xt) as $t => $v) {
             if (is_object($v)) {
                 $map[$t]->order_anno = $v;
                 ++$map->norder_anno;
             }
         }
     }
     return $map;
 }