public function table_html($listname, $options = array()) { global $Conf; if (!$this->_prepare()) { return null; } if (isset($options["fold"])) { foreach ($options["fold"] as $n => $v) { $this->viewmap->{$n} = $v; } } if (isset($options["table_id"])) { $this->viewmap->table_id = $options["table_id"]; } // need tags for row coloring if ($this->contact->can_view_tags(null)) { $this->qopts["tags"] = 1; } $this->table_type = $listname; // get column list, check sort $field_list = $this->_list_columns($listname); if (!$field_list) { Conf::msg_error("There is no paper list query named “" . htmlspecialchars($listname) . "”."); return null; } $field_list = $this->_columns($field_list, true); $body_attr = $this->row_attr; $rows = $this->_rows($field_list); if ($rows === null) { return null; } // return IDs if requested if (empty($rows)) { if ($altq = $this->search->alternate_query()) { $altqh = htmlspecialchars($altq); $url = $this->search->url_site_relative_raw($altq); if (substr($url, 0, 5) == "search") { $altqh = "<a href=\"" . htmlspecialchars(Navigation::siteurl() . $url) . "\">" . $altqh . "</a>"; } return "No matching papers. Did you mean “{$altqh}”?"; } else { return "No matching papers"; } } // get field array $fieldDef = array(); $ncol = $titlecol = 0; // folds: au:1, anonau:2, fullrow:3, aufull:4, force:5, rownum:6, [fields] $next_fold = 7; foreach ($field_list as $fdef) { if ($fdef->view != Column::VIEW_NONE) { $fieldDef[] = $fdef; } if ($fdef->view != Column::VIEW_NONE && $fdef->foldable) { $fdef->foldable = $next_fold; ++$next_fold; } if ($fdef->name == "title") { $titlecol = $ncol; } if ($fdef->view == Column::VIEW_COLUMN && !$fdef->is_folded) { ++$ncol; } } // count non-callout columns $skipcallout = 0; foreach ($fieldDef as $fdef) { if ($fdef->name != "id" && !isset($fdef->is_selector)) { break; } else { ++$skipcallout; } } // create render state $rstate = new PaperListRenderState($ncol, $titlecol, $skipcallout); // collect row data $body = array(); $lastheading = !empty($this->search->groupmap) ? -1 : -2; $need_render = false; foreach ($rows as $row) { ++$this->count; if ($lastheading > -2) { $lastheading = $this->_check_heading($this->_row_thenval($row), $rstate, $rows, $lastheading, $body); } $body[] = $this->_row_text($rstate, $row, $fieldDef); if ($this->need_render && !$need_render) { $Conf->footerScript('$(plinfo.render_needed)', 'plist_render_needed'); $need_render = true; } if ($this->need_render && $this->count % 16 == 15) { $body[count($body) - 1] .= " <script>plinfo.render_needed()</script>\n"; $this->need_render = false; } } if ($lastheading > -2 && $this->search->is_order_anno) { while ($lastheading + 1 < count($this->search->groupmap)) { $lastheading = $this->_check_heading($lastheading + 1, $rstate, $rows, $lastheading, $body); } } // header cells $colhead = ""; $url = $this->search->url_site_relative_raw(); if (!defval($options, "noheader")) { $colhead .= " <thead class=\"pltable\">\n <tr class=\"pl_headrow\">"; $ord = 0; $titleextra = $this->_make_title_header_extra($rstate, $fieldDef, get($options, "header_links")); foreach ($fieldDef as $fdef) { if ($fdef->view != Column::VIEW_COLUMN || $fdef->is_folded) { continue; } $colhead .= "<th class=\"pl " . $fdef->className; if ($fdef->foldable) { $colhead .= " fx" . $fdef->foldable; } $colhead .= "\">"; if ($fdef->has_content) { $colhead .= $this->_field_title($fdef, $ord); } if ($titleextra && $fdef->className == "pl_title") { $colhead .= $titleextra; $titleextra = false; } $colhead .= "</th>"; ++$ord; } $colhead .= "</tr>\n"; if ($this->search->is_order_anno) { $colhead .= " <tr class=\"pl_headrow pl_annorow\" data-anno-tag=\"{$this->search->is_order_anno}\">"; if ($rstate->titlecol) { $colhead .= "<td colspan=\"{$rstate->titlecol}\"></td>"; } $colhead .= "<td colspan=\"" . ($rstate->ncol - $rstate->titlecol) . "\"><a href=\"#\" onclick=\"return plinfo_tags.edit_anno(this)\">Annotate order</a></td></tr>\n"; } $colhead .= " </thead>\n"; } // table skeleton including fold classes $foldclasses = array(); if ($this->foldable) { $foldclasses = $this->_analyze_folds($rstate, $fieldDef); } $enter = ""; if (self::$include_stash) { $enter .= Ht::take_stash(); } $enter .= "<table class=\"pltable plt_" . htmlspecialchars($listname); if (defval($options, "class")) { $enter .= " " . $options["class"]; } if ($this->listNumber) { $enter .= " has_hotcrp_list"; } if (!empty($foldclasses)) { $enter .= " " . join(" ", $foldclasses); } if ($this->viewmap->table_id) { $enter .= "\" id=\"" . $this->viewmap->table_id; } if (defval($options, "attributes")) { foreach ($options["attributes"] as $n => $v) { $enter .= "\" {$n}=\"" . htmlspecialchars($v); } } if ($this->search->is_order_anno) { $enter .= "\" data-order-tag=\"{$this->search->is_order_anno}"; } foreach ($body_attr as $k => $v) { $enter .= "\" {$k}=\"" . htmlspecialchars($v); } if ($this->listNumber) { $enter .= '" data-hotcrp-list="' . $this->listNumber; } $enter .= "\" data-fold=\"true\">\n"; $exit = "</table>"; // maybe make columns, maybe not $tbody_class = "pltable"; if ($this->viewmap->columns && !empty($rstate->ids) && $this->_column_split($rstate, $colhead, $body)) { $enter = '<div class="plsplit_col_ctr_ctr"><div class="plsplit_col_ctr">' . $enter; $exit = $exit . "</div></div>"; $ncol = $rstate->split_ncol; $tbody_class = "pltable_split"; } else { $enter .= $colhead; $tbody_class .= $rstate->hascolors ? " pltable_colored" : ""; } // footer $foot = ""; if ($this->viewmap->statistics && !$this->viewmap->columns) { $foot .= $this->_statistics_rows($rstate, $fieldDef); } if ($fieldDef[0] instanceof SelectorPaperColumn && !defval($options, "nofooter")) { $foot .= $this->_footer($ncol, get_s($options, "footer_extra")); } if ($foot) { $enter .= ' <tfoot' . ($rstate->hascolors ? ' class="pltable_colored"' : "") . ">\n" . $foot . " </tfoot>\n"; } // body $enter .= " <tbody class=\"{$tbody_class}\">\n"; // header scripts to set up delegations if ($this->_header_script) { $enter .= ' <script>' . $this->_header_script . "</script>\n"; } // session variable to remember the list if ($this->listNumber) { $sl = $this->search->create_session_list_object($rstate->ids, self::_listDescription($listname), $this->sortdef()); if (isset($this->qreq->sort)) { $url .= (strpos($url, "?") ? "&" : "?") . "sort=" . urlencode($this->qreq->sort); } $sl->url = $url; if (get($options, "list_properties")) { foreach ($options["list_properties"] as $k => $v) { $sl->{$k} = $v; } } SessionList::change($this->listNumber, $sl); } foreach ($fieldDef as $fdef) { if ($fdef->has_content) { $this->any[$fdef->name] = true; } } if ($rstate->has_openau) { $this->any->openau = true; } if ($rstate->has_anonau) { $this->any->anonau = true; } $this->ids = $rstate->ids; return $enter . join("", $body) . " </tbody>\n" . $exit; }
function footer() { global $Opt, $Me, $ConfSitePATH; echo "</div>\n", "<div id='footer'>\n <div id='footer_crp'>", defval($Opt, "extraFooter", ""), "<a href='http://read.seas.harvard.edu/~kohler/hotcrp/'>HotCRP</a>"; if (!defval($Opt, "noFooterVersion", 0)) { if ($Me && $Me->privChair) { echo " v", HOTCRP_VERSION; if (is_dir("{$ConfSitePATH}/.git")) { $args = array(); exec("export GIT_DIR=" . escapeshellarg($ConfSitePATH) . "/.git; git rev-parse HEAD 2>/dev/null; git rev-parse v" . HOTCRP_VERSION . " 2>/dev/null", $args); if (count($args) == 2 && $args[0] != $args[1]) { echo " [", substr($args[0], 0, 7), "...]"; } } } else { echo "<!-- Version ", HOTCRP_VERSION, " -->"; } } echo "</div>\n <hr class=\"c\" /></div>\n"; echo Ht::take_stash(), "</body>\n</html>\n"; }
public function run() { global $Conf, $Me, $Qreq, $SSel, $pcsel, $badpairs, $scoreselector; assert($this->ok); session_write_close(); // this might take a long time set_time_limit(240); // prepare autoassigner if ($Qreq->seed && is_numeric($Qreq->seed)) { srand((int) $Qreq->seed); } $this->autoassigner = $autoassigner = new Autoassigner($SSel->selection()); if ($Qreq->pctyp === "sel") { $n = $autoassigner->select_pc(array_keys($pcsel)); if ($n == 0) { Conf::msg_error("Select one or more PC members to assign."); return null; } } if ($Qreq->balance === "all") { $autoassigner->set_balance(Autoassigner::BALANCE_ALL); } foreach ($badpairs as $cid1 => $bp) { foreach ($bp as $cid2 => $x) { $autoassigner->avoid_pair_assignment($cid1, $cid2); } } if ($Qreq->method === "random") { $autoassigner->set_method(Autoassigner::METHOD_RANDOM); } else { $autoassigner->set_method(Autoassigner::METHOD_MCMF); } $autoassigner->add_progressf(array($this, "progress")); $this->live = true; echo '<div id="propass" class="propass">'; $this->start_at = microtime(true); if ($this->atype === "prefconflict") { $autoassigner->run_prefconflict($Qreq->t); } else { if ($this->atype === "clear") { $autoassigner->run_clear($this->reviewtype); } else { if ($this->atype === "lead" || $this->atype === "shepherd") { $autoassigner->run_paperpc($this->atype, $Qreq["{$this->atype}score"]); } else { if ($this->atype === "revpc") { $autoassigner->run_reviews_per_pc($this->reviewtype, $Qreq->rev_roundtag, cvtint($Qreq->revpcct)); } else { if ($this->atype === "revadd") { $autoassigner->run_more_reviews($this->reviewtype, $Qreq->rev_roundtag, cvtint($Qreq->revaddct)); } else { if ($this->atype === "rev") { $autoassigner->run_ensure_reviews($this->reviewtype, $Qreq->rev_roundtag, cvtint($Qreq->revct)); } else { if ($this->atype === "discorder") { $autoassigner->run_discussion_order($this->discordertag); } } } } } } } if ($this->live) { echo $this->result_html(), "</div>\n"; } else { PaperList::$include_stash = false; $result_html = $this->result_html(); echo Ht::take_stash(), '<script>$$("propass").innerHTML=', json_encode($result_html), ";</script>\n"; } if ($this->autoassigner->assignments()) { $Conf->footer(); exit; } }
function footer() { global $Me, $ConfSitePATH; echo "</div>\n", "<div id='footer'>\n"; $footy = $this->opt("extraFooter", ""); if (false) { $footy .= "<a href='http://read.seas.harvard.edu/~kohler/hotcrp/'>HotCRP</a> Conference Management Software"; } if (!$this->opt("noFooterVersion")) { if ($Me && $Me->privChair) { if (is_dir("{$ConfSitePATH}/.git")) { $args = array(); exec("export GIT_DIR=" . escapeshellarg($ConfSitePATH) . "/.git; git rev-parse HEAD 2>/dev/null", $args); if (count($args) == 2 && $args[0] != $args[1]) { $footy .= " [" . substr($args[0], 0, 7) . "...]"; } } } } if ($footy) { echo "<div id='footer_crp'>{$footy}</div>"; } echo "<div class='clear'></div></div>\n"; echo Ht::take_stash(), "</body>\n</html>\n"; }