function run(Contact $user, $qreq, $ssel) { global $Conf; $result = Dbl::qe_raw($Conf->paperQuery($user, ["paperId" => $ssel->selection()])); $downloads = []; $opt = PaperOption::find_document($this->dt); while ($row = PaperInfo::fetch($result, $user)) { if ($whyNot = $user->perm_view_paper_option($row, $opt, true)) { Conf::msg_error(whyNotText($whyNot, "view")); } else { $downloads[] = $row->paperId; } } if (count($downloads)) { session_write_close(); // it can take a while to generate the download if ($Conf->downloadPaper($downloads, true, $this->dt)) { exit; } } // XXX how to return errors? }
private function _rows($field_list) { global $Conf; if (!$field_list) { return null; } // prepare query text $this->qopts["scores"] = array_keys($this->qopts["scores"]); if (empty($this->qopts["scores"])) { unset($this->qopts["scores"]); } $pq = $Conf->paperQuery($this->contact, $this->qopts); // make query $result = Dbl::qe_raw($pq); if (!$result) { return null; } // fetch rows $rows = array(); while ($row = PaperInfo::fetch($result, $this->contact)) { $rows[$row->paperId] = $row; } // prepare review query (see also search > getfn == "reviewers") $this->review_list = array(); if (isset($this->qopts["reviewList"]) && !empty($rows)) { $result = Dbl::qe("select Paper.paperId, reviewId, reviewType,\n reviewSubmitted, reviewModified, reviewNeedsSubmit, reviewRound,\n reviewOrdinal,\n PaperReview.contactId, lastName, firstName, email\n from Paper\n join PaperReview using (paperId)\n join ContactInfo on (PaperReview.contactId=ContactInfo.contactId)\n where paperId?a", array_keys($rows)); while ($row = edb_orow($result)) { Contact::set_sorter($row); $this->review_list[$row->paperId][] = $row; } foreach ($this->review_list as &$revlist) { usort($revlist, "PaperList::review_list_compar"); } unset($revlist); } // prepare PC topic interests if (isset($this->qopts["allReviewerPreference"])) { $ord = 0; $pcm = pcMembers(); foreach ($pcm as $pc) { $pc->prefOrdinal = sprintf("-0.%04d", $ord++); $pc->topicInterest = array(); } $result = Dbl::qe("select contactId, topicId, " . $Conf->query_topic_interest() . " from TopicInterest"); while ($row = edb_row($result)) { $pcm[$row[0]]->topicInterest[$row[1]] = $row[2]; } } // analyze rows (usually noop) foreach ($field_list as $fdef) { $fdef->analyze($this, $rows); } // sort rows if (!empty($this->sorters)) { $rows = $this->_sort($rows); if (isset($this->qopts["allReviewScores"])) { $this->_sortReviewOrdinal($rows); } } // set `any->optID` if ($nopts = PaperOption::count_option_list()) { foreach ($rows as $prow) { foreach ($prow->options() as $o) { if (!$this->any["opt{$o->id}"] && $this->contact->can_view_paper_option($prow, $o->option)) { $this->any["opt{$o->id}"] = true; --$nopts; } } if (!$nopts) { break; } } } Dbl::free($result); return $rows; }
function example_searches() { $x = parent::example_searches(); $x["attachment-count"] = array("{$this->abbr}:>2", $this); $x["attachment-filename"] = array("{$this->abbr}:*.gif", $this); return $x; }
function can_view_some_paper_option(PaperOption $opt) { if ($opt->has_document() && !$this->can_view_some_pdf() || $opt->final && !$this->can_view_some_decision()) { return false; } $oview = $opt->visibility; return $this->is_author() || $oview == "admin" && $this->is_manager() || (!$oview || $oview == "rev") && $this->is_reviewer() || $oview == "nonblind" && $this->can_view_some_authors(); }
function document_download() { global $Conf, $Me, $Opt; $documentType = HotCRPDocument::parse_dtype(@$_REQUEST["dt"]); if ($documentType === null) { $documentType = @$_REQUEST["final"] ? DTYPE_FINAL : DTYPE_SUBMISSION; } $attachment_filename = false; $docid = null; if (isset($_REQUEST["p"])) { $paperId = cvtint(@$_REQUEST["p"]); } else { if (isset($_REQUEST["paperId"])) { $paperId = cvtint(@$_REQUEST["paperId"]); } else { $s = $orig_s = preg_replace(',\\A/*,', "", Navigation::path()); $documentType = $dtname = null; if (str_starts_with($s, $Opt["downloadPrefix"])) { $s = substr($s, strlen($Opt["downloadPrefix"])); } if (preg_match(',\\Ap(?:aper)?(\\d+)/+(.*)\\z,', $s, $m)) { $paperId = intval($m[1]); if (preg_match(',\\A([^/]+)\\.[^/]+\\z,', $m[2], $mm)) { $dtname = $mm[1]; } else { if (preg_match(',\\A([^/]+)/+(.*)\\z,', $m[2], $mm)) { list($dtype, $attachment_filename) = array($m[1], $m[2]); } } } else { if (preg_match(',\\A(?:paper)?(\\d+)-?([-A-Za-z0-9_]*)(?:\\.[^/]+|/+(.*))\\z,', $s, $m)) { list($paperId, $dtname, $attachment_filename) = array(intval($m[1]), $m[2], @$m[3]); } else { if (preg_match(',\\A([A-Za-z_][-A-Za-z0-9_]*?)?-?(\\d+)(?:\\.[^/]+|/+(.*))\\z,', $s, $m)) { list($paperId, $dtname, $attachment_filename) = array(intval($m[2]), $m[1], @$m[3]); } } } if ($dtname !== null) { $documentType = HotCRPDocument::parse_dtype($dtname ?: "paper"); } if ($documentType !== null && $attachment_filename) { $o = PaperOption::find($documentType); if (!$o || $o->type != "attachments") { $documentType = null; } } } } if ($documentType === null) { document_error("404 Not Found", "Unknown document “" . htmlspecialchars($orig_s) . "”."); } $prow = $Conf->paperRow($paperId, $Me, $whyNot); if (!$prow) { document_error("404 Not Found", whyNotText($whyNot, "view")); } else { if ($whyNot = $Me->perm_view_pdf($prow)) { document_error("403 Forbidden", whyNotText($whyNot, "view")); } else { if ($documentType > 0 && !$Me->can_view_paper_option($prow, $documentType, true)) { document_error("403 Forbidden", "You don’t have permission to view this document."); } } } if ($attachment_filename) { $oa = $prow->option($documentType); foreach ($oa ? $oa->documents($prow) : array() as $doc) { if ($doc->unique_filename == $attachment_filename) { $docid = $doc; } } if (!$docid) { document_error("404 Not Found", "No such attachment “" . htmlspecialchars($orig_s) . "”."); } } // Actually download paper. session_write_close(); // to allow concurrent clicks if ($Conf->downloadPaper($prow, cvtint(@$_REQUEST["save"]) > 0, $documentType, $docid)) { exit; } document_error("500 Server Error", null); }
public function save($sv, $si) { global $Conf; $new_opts = $this->stashed_options; $current_opts = PaperOption::nonfixed_option_list(); $this->option_clean_form_positions($new_opts, $current_opts); $newj = (object) array(); uasort($new_opts, array("PaperOption", "compare")); $nextid = max($Conf->setting("next_optionid", 1), $Conf->setting("options", 1)); foreach ($new_opts as $id => $o) { $newj->{$id} = $o->unparse(); $nextid = max($nextid, $id + 1); } $sv->save("next_optionid", null); $sv->save("options", count($newj) ? json_encode($newj) : null); $deleted_ids = array(); foreach ($current_opts as $id => $o) { if (!get($new_opts, $id)) { $deleted_ids[] = $id; } } if (count($deleted_ids)) { $Conf->qe("delete from PaperOption where optionId in (" . join(",", $deleted_ids) . ")"); } // invalidate cached option list PaperOption::invalidate_option_list(); }
public function all_options() { if ($this->_all_option_array === null) { $this->_all_option_array = PaperOption::parse_paper_options($this, true); } return $this->_all_option_array; }
public function make_column($name, $errors) { $p = strpos($name, ":") ?: -1; $opts = PaperOption::search(substr($name, $p + 1)); if (count($opts) == 1) { reset($opts); $opt = current($opts); if ($opt->display() >= 0) { return self::_make_column($opt); } self::make_column_error($errors, "Option “" . htmlspecialchars(substr($name, $p + 1)) . "” can’t be displayed."); } else { if ($p > 0) { self::make_column_error($errors, "No such option “" . htmlspecialchars(substr($name, $p + 1)) . "”.", 1); } } return null; }
function save_paper_json($pj) { global $Conf, $Now; assert(!$this->hide_docids); $paperid = null; if (isset($pj->pid) && is_int($pj->pid) && $pj->pid > 0) { $paperid = $pj->pid; } else { if (!isset($pj->pid) && isset($pj->id) && is_int($pj->id) && $pj->id > 0) { $paperid = $pj->id; } else { if (isset($pj->pid) || isset($pj->id)) { $key = isset($pj->pid) ? "pid" : "id"; $this->set_error_html($key, "Format error [{$key}]"); return false; } } } if (get($pj, "error") || get($pj, "error_html")) { $this->set_error_html("error", "Refusing to save paper with error"); return false; } $this->prow = $old_pj = null; $this->paperid = $paperid ?: -1; if ($paperid) { $this->prow = $Conf->paperRow(["paperId" => $paperid, "topics" => true, "options" => true], $this->contact); } if ($this->prow) { $old_pj = $this->paper_json($this->prow, ["forceShow" => true]); } if ($pj && $old_pj && $paperid != $old_pj->pid) { $this->set_error_html("pid", "Saving paper with different ID"); return false; } $this->normalize($pj, $old_pj); if ($old_pj) { $this->normalize($old_pj, null); } if ($this->nerrors) { return false; } $this->check_invariants($pj, $old_pj); // store documents (options already stored) if (isset($pj->submission) && $pj->submission) { $this->upload_document($pj->submission, PaperOption::find_document(DTYPE_SUBMISSION)); } if (isset($pj->final) && $pj->final) { $this->upload_document($pj->final, PaperOption::find_document(DTYPE_FINAL)); } // create contacts foreach (self::contacts_array($pj) as $c) { $c->only_if_contactdb = !get($c, "contact"); $c->disabled = !!$this->disable_users; if (!Contact::create($c, !$this->no_email) && get($c, "contact")) { $this->set_error_html("contacts", "Could not create an account for contact " . Text::user_html($c) . "."); } } // catch errors if ($this->nerrors) { return false; } // update Paper table $q = array(); foreach (array("title", "abstract", "collaborators") as $k) { $v = convert_to_utf8((string) get($pj, $k)); if (!$old_pj || get($pj, $k) !== null && $v !== (string) get($old_pj, $k)) { $q[] = "{$k}='" . sqlq($v) . "'"; } } if (!$old_pj || get($pj, "authors") !== null) { $autext = convert_to_utf8(self::author_information($pj)); $old_autext = self::author_information($old_pj); if ($autext !== $old_autext || !$old_pj) { $q[] = "authorInformation='" . sqlq($autext) . "'"; } } if ($Conf->submission_blindness() == Conf::BLIND_OPTIONAL && (!$old_pj || get($pj, "nonblind") !== null && !$pj->nonblind != !$old_pj->nonblind)) { $q[] = "blind=" . (get($pj, "nonblind") ? 0 : 1); } if (!$old_pj || get($pj, "submission") !== null) { $new_id = get($pj, "submission") ? $pj->submission->docid : 1; $old_id = $old_pj && get($old_pj, "submission") ? $old_pj->submission->docid : 1; if (!$old_pj || $new_id != $old_id) { $q[] = "paperStorageId={$new_id}"; } } if (!$old_pj || get($pj, "final") !== null) { $new_id = get($pj, "final") ? $pj->final->docid : 0; $old_id = $old_pj && get($old_pj, "final") ? $old_pj->final->docid : 0; if (!$old_pj || $new_id != $old_id) { $q[] = "finalPaperStorageId={$new_id}"; } } if (get($pj, "withdrawn") !== null || get($pj, "submitted") !== null || get($pj, "draft") !== null) { if (get($pj, "submitted") !== null) { $submitted = $pj->submitted; } else { if (get($pj, "draft") !== null) { $submitted = !$pj->draft; } else { if ($old_pj) { $submitted = get($old_pj, "submitted_at") > 0; } else { $submitted = false; } } } if (get($pj, "withdrawn")) { if (!$old_pj || !get($old_pj, "withdrawn")) { $q[] = "timeWithdrawn=" . (get($pj, "withdrawn_at") ?: $Now); $q[] = "timeSubmitted=" . ($submitted ? -100 : 0); } else { if (get($old_pj, "submitted_at") > 0 !== $submitted) { $q[] = "timeSubmitted=" . ($submitted ? -100 : 0); } } } else { if ($submitted) { if (!$old_pj || !get($old_pj, "submitted")) { $q[] = "timeSubmitted=" . (get($pj, "submitted_at") ?: $Now); } if ($old_pj && get($old_pj, "withdrawn")) { $q[] = "timeWithdrawn=0"; } } else { if ($old_pj && (get($old_pj, "withdrawn") || get($old_pj, "submitted"))) { $q[] = "timeSubmitted=0"; $q[] = "timeWithdrawn=0"; } } } } if (get($pj, "final_submitted") !== null) { if ($pj->final_submitted) { $time = get($pj, "final_submitted_at") ?: $Now; } else { $time = 0; } if (!$old_pj || get($old_pj, "final_submitted_at") != $time) { $q[] = "timeFinalSubmitted={$time}"; } } if (!empty($q)) { if ($Conf->submission_blindness() == Conf::BLIND_NEVER) { $q[] = "blind=0"; } else { if ($Conf->submission_blindness() != Conf::BLIND_OPTIONAL) { $q[] = "blind=1"; } } $joindoc = $old_joindoc = null; if (get($pj, "final")) { $joindoc = $pj->final; $old_joindoc = $old_pj ? get($old_pj, "final") : null; } else { if (get($pj, "submission")) { $joindoc = $pj->submission; $old_joindoc = $old_pj ? get($old_pj, "submission") : null; } } if ($joindoc && (!$old_joindoc || $old_joindoc->docid != $joindoc->docid) && get($joindoc, "size") && get($joindoc, "timestamp")) { $q[] = "size=" . $joindoc->size; $q[] = "mimetype='" . sqlq($joindoc->mimetype) . "'"; $q[] = "sha1='" . sqlq($joindoc->sha1) . "'"; $q[] = "timestamp=" . $joindoc->timestamp; } else { if (!$joindoc) { $q[] = "size=0,mimetype='',sha1='',timestamp=0"; } } if ($paperid) { $result = Dbl::qe_raw("update Paper set " . join(",", $q) . " where paperId={$paperid}"); if ($result && $result->affected_rows === 0 && edb_nrows(Dbl::qe_raw("select paperId from Paper where paperId={$paperid}")) === 0) { $result = Dbl::qe_raw("insert into Paper set paperId={$paperid}, " . join(",", $q)); } } else { $result = Dbl::qe_raw("insert into Paper set " . join(",", $q)); if (!$result || !($paperid = $pj->pid = $result->insert_id)) { return $this->set_error_html(false, "Could not create paper."); } if (!empty($this->uploaded_documents)) { Dbl::qe_raw("update PaperStorage set paperId={$paperid} where paperStorageId in (" . join(",", $this->uploaded_documents) . ")"); } } // maybe update `papersub` settings $is_submitted = !get($pj, "withdrawn") && get($pj, "submitted"); $was_submitted = $old_pj && !get($old_pj, "withdrawn") && get($old_pj, "submitted"); if ($is_submitted != $was_submitted) { $Conf->update_papersub_setting($is_submitted); } } // update PaperTopics if (get($pj, "topics")) { $topics = self::topics_sql($pj, $paperid); $old_topics = self::topics_sql($old_pj, $paperid); if ($topics !== $old_topics) { $result = Dbl::qe_raw("delete from PaperTopic where paperId={$paperid}"); if ($topics) { $result = Dbl::qe_raw("insert into PaperTopic (topicId,paperId) values {$topics}"); } } } // update PaperOption if (get($pj, "options")) { $options = convert_to_utf8(self::options_sql($pj, $paperid)); $old_options = self::options_sql($old_pj, $paperid); if ($options !== $old_options) { $result = Dbl::qe("delete from PaperOption where paperId={$paperid} and optionId?a", array_keys($pj->parsed_options)); if ($options) { $result = Dbl::qe_raw("insert into PaperOption (paperId,optionId,value,data) values {$options}"); } } } // update PaperConflict $conflict = $this->conflicts_array($pj, $old_pj); $old_conflict = $this->conflicts_array($old_pj, null); if (join(",", array_keys($conflict)) !== join(",", array_keys($old_conflict)) || join(",", array_values($conflict)) !== join(",", array_values($old_conflict))) { $q = array(); foreach ($conflict as $email => $type) { $q[] = "'" . sqlq($email) . "'"; } $ins = array(); if (!empty($q)) { $result = Dbl::qe_raw("select contactId, email from ContactInfo where email in (" . join(",", $q) . ")"); while ($row = edb_row($result)) { $ins[] = "({$paperid},{$row['0']}," . $conflict[strtolower($row[1])] . ")"; } } $result = Dbl::qe_raw("delete from PaperConflict where paperId={$paperid}"); if (!empty($ins)) { $result = Dbl::qe_raw("insert into PaperConflict (paperId,contactId,conflictType) values " . join(",", $ins)); } } return $paperid; }
function paperOptions($id = null) { global $Conf; if ($Conf->setting("paperOption") <= 0 || $Conf->sversion <= 0) { return array(); } $svar = defval($_SESSION, "paperOption", null); if (!$svar || !is_array($svar) || count($svar) < 3 || $svar[2] < 2 || $svar[0] < $Conf->setting("paperOption")) { $opt = array(); $result = $Conf->q("select * from OptionType order by sortOrder, optionName"); $order = 0; while ($row = edb_orow($result)) { // begin backwards compatibility to old schema versions if (!isset($row->optionValues)) { $row->optionValues = ""; } if (!isset($row->type) && $row->optionValues == "i") { $row->type = PaperOption::T_NUMERIC; } else { if (!isset($row->type)) { $row->type = $row->optionValues ? PaperOption::T_SELECTOR : PaperOption::T_CHECKBOX; } } // end backwards compatibility to old schema versions $row->optionAbbrev = preg_replace("/-+\$/", "", preg_replace("/[^a-z0-9_]+/", "-", strtolower($row->optionName))); if ($row->optionAbbrev == "paper" || $row->optionAbbrev == "submission" || $row->optionAbbrev == "final" || ctype_digit($row->optionAbbrev)) { $row->optionAbbrev = "opt" . $row->optionId; } $row->sortOrder = $order++; if (!isset($row->displayType)) { $row->displayType = PaperOption::DT_NORMAL; } if ($row->type == PaperOption::T_FINALPDF) { $row->displayType = PaperOption::DT_SUBMISSION; } $row->isDocument = PaperOption::type_is_document($row->type); $row->isFinal = PaperOption::type_is_final($row->type); $opt[$row->optionId] = $row; } $_SESSION["paperOption"] = $svar = array($Conf->setting("paperOption"), $opt, 2); } return $id ? defval($svar[1], $id, null) : $svar[1]; }
public function diffs(&$diffs, $pj, $opj) { global $Conf; if (!$opj) { $diffs["new"] = true; return; } foreach (array("title", "abstract", "collaborators") as $k) { if (get_s($pj, $k) !== get_s($opj, $k)) { $diffs[$k] = true; } } if (!$this->same_authors($pj, $opj)) { $diffs["authors"] = true; } if (json_encode(get($pj, "topics") ?: (object) array()) !== json_encode(get($opj, "topics") ?: (object) array())) { $diffs["topics"] = true; } $pjopt = get($pj, "options", (object) []); $opjopt = get($opj, "options", (object) []); foreach (PaperOption::option_list() as $o) { $oabbr = $o->abbr; if (!get($pjopt, $oabbr) != !get($opjopt, $oabbr) || get($pjopt, $oabbr) && json_encode($pjopt->{$oabbr}) !== json_encode($opjopt->{$oabbr})) { $diffs["options"] = true; break; } } if ($Conf->subBlindOptional() && !get($pj, "nonblind") !== !get($opj, "nonblind")) { $diffs["anonymity"] = true; } if (json_encode(get($pj, "pc_conflicts")) !== json_encode(get($opj, "pc_conflicts"))) { $diffs["PC conflicts"] = true; } if (json_encode(get($pj, "submission")) !== json_encode(get($opj, "submission"))) { $diffs["submission"] = true; } if (json_encode(get($pj, "final")) !== json_encode(get($opj, "final"))) { $diffs["final copy"] = true; } }
public function mimetypes($doc = null, $docinfo = null) { global $Opt; if ($this->dtype > 0 && !$this->option) { return null; } $otype = $this->option ? $this->option->type : "pdf"; $mimetypes = array(); if (PaperOption::type_takes_pdf($otype)) { $mimetypes[] = Mimetype::lookup(".pdf"); } if (!$this->option && !defval($Opt, "disablePS")) { $mimetypes[] = Mimetype::lookup(".ps"); } if ($otype == "slides") { $mimetypes[] = Mimetype::lookup(".ppt"); $mimetypes[] = Mimetype::lookup(".pptx"); } if ($otype == "video") { $mimetypes[] = Mimetype::lookup(".mp4"); $mimetypes[] = Mimetype::lookup(".avi"); } return $mimetypes; }
function updateSchema($Conf) { global $Opt, $OK; // avoid error message abut timezone, set to $Opt // (which might be overridden by database values later) if (function_exists("date_default_timezone_set") && isset($Opt["timezone"]) && $Opt["timezone"]) { date_default_timezone_set($Opt["timezone"]); } while (($result = Dbl::ql("insert into Settings set name='__schema_lock', value=1 on duplicate key update value=1")) && $result->affected_rows == 0) { time_nanosleep(0, 200000000); } $Conf->update_schema_version(null); error_log($Opt["dbName"] . ": updating schema from version " . $Conf->sversion); if ($Conf->sversion == 6 && Dbl::ql("alter table ReviewRequest add `reason` text")) { $Conf->update_schema_version(7); } if ($Conf->sversion == 7 && Dbl::ql("alter table PaperReview add `textField7` mediumtext NOT NULL") && Dbl::ql("alter table PaperReview add `textField8` mediumtext NOT NULL") && Dbl::ql("insert into ReviewFormField set fieldName='textField7', shortName='Additional text field'") && Dbl::ql("insert into ReviewFormField set fieldName='textField8', shortName='Additional text field'")) { $Conf->update_schema_version(8); } if ($Conf->sversion == 8 && Dbl::ql("alter table ReviewFormField add `levelChar` tinyint(1) NOT NULL default '0'") && Dbl::ql("alter table PaperReviewArchive add `textField7` mediumtext NOT NULL") && Dbl::ql("alter table PaperReviewArchive add `textField8` mediumtext NOT NULL")) { $Conf->update_schema_version(9); } if ($Conf->sversion == 9 && Dbl::ql("alter table Paper add `sha1` varbinary(20) NOT NULL default ''")) { $Conf->update_schema_version(10); } if ($Conf->sversion == 10 && Dbl::ql("alter table PaperReview add `reviewRound` tinyint(1) NOT NULL default '0'") && Dbl::ql("alter table PaperReviewArchive add `reviewRound` tinyint(1) NOT NULL default '0'") && Dbl::ql("alter table PaperReview add key `reviewRound` (`reviewRound`)") && $Conf->update_schema_version(11)) { if (count($Conf->round_list()) > 1) { // update review rounds (XXX locking) $result = Dbl::ql("select paperId, tag from PaperTag where tag like '%~%'"); $rrs = array(); while ($row = edb_row($result)) { list($contact, $round) = explode("~", $row[1]); if ($round = array_search($round, $Conf->round_list())) { if (!isset($rrs[$round])) { $rrs[$round] = array(); } $rrs[$round][] = "(contactId={$contact} and paperId={$row['0']})"; } } foreach ($rrs as $round => $pairs) { $q = "update PaperReview set reviewRound={$round} where " . join(" or ", $pairs); Dbl::ql($q); } $x = trim(preg_replace('/(\\S+)\\s*/', "tag like '%~\$1' or ", $Conf->setting_data("tag_rounds"))); Dbl::ql("delete from PaperTag where " . substr($x, 0, strlen($x) - 3)); } } if ($Conf->sversion == 11 && Dbl::ql("create table `ReviewRating` (\n `reviewId` int(11) NOT NULL,\n `contactId` int(11) NOT NULL,\n `rating` tinyint(1) NOT NULL default '0',\n UNIQUE KEY `reviewContact` (`reviewId`,`contactId`),\n UNIQUE KEY `reviewContactRating` (`reviewId`,`contactId`,`rating`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8")) { $Conf->update_schema_version(12); } if ($Conf->sversion == 12 && Dbl::ql("alter table PaperReview add `reviewToken` int(11) NOT NULL default '0'")) { $Conf->update_schema_version(13); } if ($Conf->sversion == 13 && Dbl::ql("alter table OptionType add `optionValues` text NOT NULL default ''")) { $Conf->update_schema_version(14); } if ($Conf->sversion == 14 && Dbl::ql("insert into Settings (name, value) select 'rev_tokens', count(reviewId) from PaperReview where reviewToken!=0 on duplicate key update value=values(value)")) { $Conf->update_schema_version(15); } if ($Conf->sversion == 15) { // It's OK if this fails! Update 11 added reviewRound to // PaperReviewArchive (so old databases have the column), but I forgot // to upgrade schema.sql (so new databases lack the column). Dbl::ql("alter table PaperReviewArchive add `reviewRound` tinyint(1) NOT NULL default '0'"); $OK = true; $Conf->update_schema_version(16); } if ($Conf->sversion == 16 && Dbl::ql("alter table PaperReview add `reviewEditVersion` int(1) NOT NULL default '0'")) { $Conf->update_schema_version(17); } if ($Conf->sversion == 17 && Dbl::ql("alter table PaperReviewPreference add key `paperId` (`paperId`)") && Dbl::ql("create table PaperRank (\n `paperId` int(11) NOT NULL,\n `contactId` int(11) NOT NULL,\n `rank` int(11) NOT NULL,\n UNIQUE KEY `contactPaper` (`contactId`,`paperId`),\n KEY `paperId` (`paperId`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;")) { $Conf->update_schema_version(18); } if ($Conf->sversion == 18 && Dbl::ql("alter table PaperComment add `replyTo` int(11) NOT NULL")) { $Conf->update_schema_version(19); } if ($Conf->sversion == 19 && Dbl::ql("drop table PaperRank")) { $Conf->update_schema_version(20); } if ($Conf->sversion == 20 && Dbl::ql("alter table PaperComment add `timeNotified` int(11) NOT NULL default '0'")) { $Conf->update_schema_version(21); } if ($Conf->sversion == 21 && Dbl::ql("update PaperConflict set conflictType=8 where conflictType=3")) { $Conf->update_schema_version(22); } if ($Conf->sversion == 22 && Dbl::ql("insert into ChairAssistant (contactId) select contactId from Chair on duplicate key update ChairAssistant.contactId=ChairAssistant.contactId") && Dbl::ql("update ContactInfo set roles=roles+2 where roles=5")) { $Conf->update_schema_version(23); } if ($Conf->sversion == 23) { $Conf->update_schema_version(24); } if ($Conf->sversion == 24 && Dbl::ql("alter table ContactInfo add `preferredEmail` varchar(120)")) { $Conf->update_schema_version(25); } if ($Conf->sversion == 25) { if ($Conf->settings["final_done"] > 0 && !isset($Conf->settings["final_soft"]) && Dbl::ql("insert into Settings (name, value) values ('final_soft', " . $Conf->settings["final_done"] . ") on duplicate key update value=values(value)")) { $Conf->settings["final_soft"] = $Conf->settings["final_done"]; } $Conf->update_schema_version(26); } if ($Conf->sversion == 26 && Dbl::ql("alter table PaperOption add `data` text") && Dbl::ql("alter table OptionType add `type` tinyint(1) NOT NULL default '0'") && Dbl::ql("update OptionType set type=2 where optionValues='i'") && Dbl::ql("update OptionType set type=1 where type=0 and optionValues!=''")) { $Conf->update_schema_version(27); } if ($Conf->sversion == 27 && Dbl::ql("alter table PaperStorage add `sha1` varbinary(20) NOT NULL default ''") && Dbl::ql("alter table PaperStorage add `documentType` int(3) NOT NULL default '0'") && Dbl::ql("update PaperStorage s, Paper p set s.sha1=p.sha1 where s.paperStorageId=p.paperStorageId and p.finalPaperStorageId=0 and s.paperStorageId>0") && Dbl::ql("update PaperStorage s, Paper p set s.sha1=p.sha1, s.documentType=" . DTYPE_FINAL . " where s.paperStorageId=p.finalPaperStorageId and s.paperStorageId>0")) { $Conf->update_schema_version(28); } if ($Conf->sversion == 28 && Dbl::ql("alter table OptionType add `sortOrder` tinyint(1) NOT NULL default '0'")) { $Conf->update_schema_version(29); } if ($Conf->sversion == 29 && Dbl::ql("delete from Settings where name='pldisplay_default'")) { $Conf->update_schema_version(30); } if ($Conf->sversion == 30 && Dbl::ql("DROP TABLE IF EXISTS `Formula`") && Dbl::ql("CREATE TABLE `Formula` (\n `formulaId` int(11) NOT NULL auto_increment,\n `name` varchar(200) NOT NULL,\n `heading` varchar(200) NOT NULL default '',\n `headingTitle` text NOT NULL default '',\n `expression` text NOT NULL,\n `authorView` tinyint(1) NOT NULL default '1',\n PRIMARY KEY (`formulaId`),\n UNIQUE KEY `formulaId` (`formulaId`),\n UNIQUE KEY `name` (`name`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8")) { $Conf->update_schema_version(31); } if ($Conf->sversion == 31 && Dbl::ql("alter table Formula add `createdBy` int(11) NOT NULL default '0'") && Dbl::ql("alter table Formula add `timeModified` int(11) NOT NULL default '0'") && Dbl::ql("alter table Formula drop index `name`")) { $Conf->update_schema_version(32); } if ($Conf->sversion == 32 && Dbl::ql("alter table PaperComment add key `timeModified` (`timeModified`)")) { $Conf->update_schema_version(33); } if ($Conf->sversion == 33 && Dbl::ql("alter table PaperComment add `paperStorageId` int(11) NOT NULL default '0'")) { $Conf->update_schema_version(34); } if ($Conf->sversion == 34 && Dbl::ql("alter table ContactInfo add `contactTags` text")) { $Conf->update_schema_version(35); } if ($Conf->sversion == 35 && Dbl::ql("alter table ContactInfo modify `defaultWatch` int(11) NOT NULL default '2'") && Dbl::ql("alter table PaperWatch modify `watch` int(11) NOT NULL default '0'")) { $Conf->update_schema_version(36); } if ($Conf->sversion == 36 && Dbl::ql("alter table PaperReview add `reviewNotified` int(1) default NULL") && Dbl::ql("alter table PaperReviewArchive add `reviewNotified` int(1) default NULL")) { $Conf->update_schema_version(37); } if ($Conf->sversion == 37 && Dbl::ql("alter table OptionType add `displayType` tinyint(1) NOT NULL default '0'")) { $Conf->update_schema_version(38); } if ($Conf->sversion == 38 && Dbl::ql("update PaperComment set forReviewers=1 where forReviewers=-1")) { $Conf->update_schema_version(39); } if ($Conf->sversion == 39 && Dbl::ql("CREATE TABLE `MailLog` (\n `mailId` int(11) NOT NULL auto_increment,\n `recipients` varchar(200) NOT NULL,\n `paperIds` text,\n `cc` text,\n `replyto` text,\n `subject` text,\n `emailBody` text,\n PRIMARY KEY (`mailId`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8")) { $Conf->update_schema_version(40); } if ($Conf->sversion == 40 && Dbl::ql("alter table Paper add `capVersion` int(1) NOT NULL default '0'")) { $Conf->update_schema_version(41); } if ($Conf->sversion == 41 && Dbl::ql("alter table Paper modify `mimetype` varchar(80) NOT NULL default ''") && Dbl::ql("alter table PaperStorage modify `mimetype` varchar(80) NOT NULL default ''")) { $Conf->update_schema_version(42); } if ($Conf->sversion == 42 && Dbl::ql("alter table PaperComment add `ordinal` int(11) NOT NULL default '0'")) { $Conf->update_schema_version(43); } if ($Conf->sversion == 42 && ($result = Dbl::ql("describe PaperComment `ordinal`")) && ($o = edb_orow($result)) && substr($o->Type, 0, 3) == "int" && (!$o->Null || $o->Null == "NO") && (!$o->Default || $o->Default == "0")) { $Conf->update_schema_version(43); } if ($Conf->sversion == 43 && Dbl::ql("alter table Paper add `withdrawReason` text")) { $Conf->update_schema_version(44); } if ($Conf->sversion == 44 && Dbl::ql("alter table PaperStorage add `filename` varchar(255)")) { $Conf->update_schema_version(45); } if ($Conf->sversion == 45 && Dbl::ql("alter table PaperReview add `timeRequested` int(11) NOT NULL DEFAULT '0'") && Dbl::ql("alter table PaperReview add `timeRequestNotified` int(11) NOT NULL DEFAULT '0'") && Dbl::ql("alter table PaperReviewArchive add `timeRequested` int(11) NOT NULL DEFAULT '0'") && Dbl::ql("alter table PaperReviewArchive add `timeRequestNotified` int(11) NOT NULL DEFAULT '0'") && Dbl::ql("alter table PaperReview drop column `requestedOn`") && Dbl::ql("alter table PaperReviewArchive drop column `requestedOn`")) { $Conf->update_schema_version(46); } if ($Conf->sversion == 46 && Dbl::ql("alter table ContactInfo add `disabled` tinyint(1) NOT NULL DEFAULT '0'")) { $Conf->update_schema_version(47); } if ($Conf->sversion == 47 && Dbl::ql("delete from ti using TopicInterest ti left join TopicArea ta using (topicId) where ta.topicId is null")) { $Conf->update_schema_version(48); } if ($Conf->sversion == 48 && Dbl::ql("alter table PaperReview add `reviewAuthorNotified` int(11) NOT NULL DEFAULT '0'") && Dbl::ql("alter table PaperReviewArchive add `reviewAuthorNotified` int(11) NOT NULL DEFAULT '0'") && Dbl::ql("alter table PaperReviewArchive add `reviewToken` int(11) NOT NULL DEFAULT '0'")) { $Conf->update_schema_version(49); } if ($Conf->sversion == 49 && Dbl::ql("alter table PaperOption drop index `paperOption`") && Dbl::ql("alter table PaperOption add index `paperOption` (`paperId`,`optionId`,`value`)")) { $Conf->update_schema_version(50); } if ($Conf->sversion == 50 && Dbl::ql("alter table Paper add `managerContactId` int(11) NOT NULL DEFAULT '0'")) { $Conf->update_schema_version(51); } if ($Conf->sversion == 51 && Dbl::ql("alter table Paper drop column `numComments`") && Dbl::ql("alter table Paper drop column `numAuthorComments`")) { $Conf->update_schema_version(52); } // Due to a bug in the schema updater, some databases might have // sversion>=53 but no `PaperComment.commentType` column. Fix them. if (($Conf->sversion == 52 || $Conf->sversion >= 53 && ($result = Dbl::ql("show columns from PaperComment like 'commentType'")) && edb_nrows($result) == 0) && Dbl::ql("lock tables PaperComment write, Settings write") && Dbl::ql("alter table PaperComment add `commentType` int(11) NOT NULL DEFAULT '0'")) { $new_sversion = max($Conf->sversion, 53); $result = Dbl::ql("show columns from PaperComment like 'forAuthors'"); if (!$result || edb_nrows($result) == 0 || Dbl::ql("update PaperComment set commentType=" . (COMMENTTYPE_AUTHOR | COMMENTTYPE_RESPONSE) . " where forAuthors=2") && Dbl::ql("update PaperComment set commentType=commentType|" . COMMENTTYPE_DRAFT . " where forAuthors=2 and forReviewers=0") && Dbl::ql("update PaperComment set commentType=" . COMMENTTYPE_ADMINONLY . " where forAuthors=0 and forReviewers=2") && Dbl::ql("update PaperComment set commentType=" . COMMENTTYPE_PCONLY . " where forAuthors=0 and forReviewers=0") && Dbl::ql("update PaperComment set commentType=" . COMMENTTYPE_REVIEWER . " where forAuthors=0 and forReviewers=1") && Dbl::ql("update PaperComment set commentType=" . COMMENTTYPE_AUTHOR . " where forAuthors!=0 and forAuthors!=2") && Dbl::ql("update PaperComment set commentType=commentType|" . COMMENTTYPE_BLIND . " where blind=1")) { $Conf->update_schema_version($new_sversion); } } if ($Conf->sversion < 53) { Dbl::qx_raw($Conf->dblink, "alter table PaperComment drop column `commentType`"); } Dbl::ql("unlock tables"); if ($Conf->sversion == 53 && Dbl::ql("alter table PaperComment drop column `forReviewers`") && Dbl::ql("alter table PaperComment drop column `forAuthors`") && Dbl::ql("alter table PaperComment drop column `blind`")) { $Conf->update_schema_version(54); } if ($Conf->sversion == 54 && Dbl::ql("alter table PaperStorage add `infoJson` varchar(255) DEFAULT NULL")) { $Conf->update_schema_version(55); } if ($Conf->sversion == 55 && Dbl::ql("alter table ContactInfo modify `password` varbinary(2048) NOT NULL")) { $Conf->update_schema_version(56); } if ($Conf->sversion == 56 && Dbl::ql("alter table Settings modify `data` blob")) { $Conf->update_schema_version(57); } if ($Conf->sversion == 57 && Dbl::ql("DROP TABLE IF EXISTS `Capability`") && Dbl::ql("CREATE TABLE `Capability` (\n `capabilityId` int(11) NOT NULL AUTO_INCREMENT,\n `capabilityType` int(11) NOT NULL,\n `contactId` int(11) NOT NULL,\n `paperId` int(11) NOT NULL,\n `timeExpires` int(11) NOT NULL,\n `salt` varbinary(255) NOT NULL,\n `data` blob,\n PRIMARY KEY (`capabilityId`),\n UNIQUE KEY `capabilityId` (`capabilityId`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8") && Dbl::ql("DROP TABLE IF EXISTS `CapabilityMap`") && Dbl::ql("CREATE TABLE `CapabilityMap` (\n `capabilityValue` varbinary(255) NOT NULL,\n `capabilityId` int(11) NOT NULL,\n `timeExpires` int(11) NOT NULL,\n PRIMARY KEY (`capabilityValue`),\n UNIQUE KEY `capabilityValue` (`capabilityValue`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8")) { $Conf->update_schema_version(58); } if ($Conf->sversion == 58 && Dbl::ql("alter table PaperReview modify `paperSummary` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReview modify `commentsToAuthor` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReview modify `commentsToPC` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReview modify `commentsToAddress` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReview modify `weaknessOfPaper` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReview modify `strengthOfPaper` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReview modify `textField7` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReview modify `textField8` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReviewArchive modify `paperSummary` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReviewArchive modify `commentsToAuthor` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReviewArchive modify `commentsToPC` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReviewArchive modify `commentsToAddress` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReviewArchive modify `weaknessOfPaper` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReviewArchive modify `strengthOfPaper` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReviewArchive modify `textField7` mediumtext DEFAULT NULL") && Dbl::ql("alter table PaperReviewArchive modify `textField8` mediumtext DEFAULT NULL")) { $Conf->update_schema_version(59); } if ($Conf->sversion == 59 && Dbl::ql("alter table ActionLog modify `action` varbinary(4096) NOT NULL") && Dbl::ql("alter table ContactInfo modify `note` varbinary(4096) DEFAULT NULL") && Dbl::ql("alter table ContactInfo modify `collaborators` varbinary(32767) DEFAULT NULL") && Dbl::ql("alter table ContactInfo modify `contactTags` varbinary(4096) DEFAULT NULL") && Dbl::ql("alter table Formula modify `headingTitle` varbinary(4096) NOT NULL") && Dbl::ql("alter table Formula modify `expression` varbinary(4096) NOT NULL") && Dbl::ql("alter table OptionType modify `description` varbinary(8192) DEFAULT NULL") && Dbl::ql("alter table OptionType modify `optionValues` varbinary(8192) NOT NULL") && Dbl::ql("alter table PaperReviewRefused modify `reason` varbinary(32767) DEFAULT NULL") && Dbl::ql("alter table ReviewFormField modify `description` varbinary(32767) DEFAULT NULL") && Dbl::ql("alter table ReviewFormOptions modify `description` varbinary(32767) DEFAULT NULL") && Dbl::ql("alter table ReviewRequest modify `reason` varbinary(32767) DEFAULT NULL") && Dbl::ql("alter table Settings modify `data` varbinary(32767) DEFAULT NULL") && Dbl::ql("alter table ContactAddress modify `addressLine1` varchar(2048) NOT NULL") && Dbl::ql("alter table ContactAddress modify `addressLine2` varchar(2048) NOT NULL") && Dbl::ql("alter table ContactAddress modify `city` varchar(2048) NOT NULL") && Dbl::ql("alter table ContactAddress modify `state` varchar(2048) NOT NULL") && Dbl::ql("alter table ContactAddress modify `zipCode` varchar(2048) NOT NULL") && Dbl::ql("alter table ContactAddress modify `country` varchar(2048) NOT NULL") && Dbl::ql("alter table PaperTopic modify `topicId` int(11) NOT NULL") && Dbl::ql("alter table PaperTopic modify `paperId` int(11) NOT NULL") && Dbl::ql("drop table if exists ChairTag")) { $Conf->update_schema_version(60); } if ($Conf->sversion == 60 && Dbl::ql("insert into Settings (name,value,data) select concat('msg.',substr(name,1,length(name)-3)), value, data from Settings where name='homemsg' or name='conflictdefmsg'") && $Conf->update_schema_version(61)) { foreach (array("conflictdef", "home") as $k) { if (isset($Conf->settingTexts["{$k}msg"])) { $Conf->settingTexts["msg.{$k}"] = $Conf->settingTexts["{$k}msg"]; } } $Conf->settings["allowPaperOption"] = 61; } if ($Conf->sversion == 61 && Dbl::ql("alter table Capability modify `data` varbinary(4096) DEFAULT NULL")) { $Conf->update_schema_version(62); } if (!isset($Conf->settings["outcome_map"])) { $ojson = array(); $result = Dbl::ql("select * from ReviewFormOptions where fieldName='outcome'"); while ($row = edb_orow($result)) { $ojson[$row->level] = $row->description; } $Conf->save_setting("outcome_map", 1, $ojson); } if ($Conf->sversion == 62 && isset($Conf->settings["outcome_map"])) { $Conf->update_schema_version(63); } if (!isset($Conf->settings["review_form"]) && $Conf->sversion < 65) { update_schema_create_review_form($Conf); } if ($Conf->sversion == 63 && isset($Conf->settings["review_form"])) { $Conf->update_schema_version(64); } if ($Conf->sversion == 64 && Dbl::ql("drop table if exists `ReviewFormField`") && Dbl::ql("drop table if exists `ReviewFormOptions`")) { $Conf->update_schema_version(65); } if (!isset($Conf->settings["options"]) && $Conf->sversion < 67) { update_schema_create_options($Conf); } if ($Conf->sversion == 65 && isset($Conf->settings["options"])) { $Conf->update_schema_version(66); } if ($Conf->sversion == 66 && Dbl::ql("drop table if exists `OptionType`")) { $Conf->update_schema_version(67); } if ($Conf->sversion == 67 && Dbl::ql("alter table PaperComment modify `comment` varbinary(32767) DEFAULT NULL") && Dbl::ql("alter table PaperComment add `commentTags` varbinary(1024) DEFAULT NULL")) { $Conf->update_schema_version(68); } if ($Conf->sversion == 68 && Dbl::ql("alter table PaperReviewPreference add `expertise` int(4) DEFAULT NULL")) { $Conf->update_schema_version(69); } if ($Conf->sversion == 69 && Dbl::ql("alter table Paper drop column `pcPaper`")) { $Conf->update_schema_version(70); } if ($Conf->sversion == 70 && Dbl::ql("alter table ContactInfo modify `voicePhoneNumber` varbinary(256) DEFAULT NULL") && Dbl::ql("alter table ContactInfo modify `faxPhoneNumber` varbinary(256) DEFAULT NULL") && Dbl::ql("alter table ContactInfo modify `collaborators` varbinary(8192) DEFAULT NULL") && Dbl::ql("alter table ContactInfo drop column `note`") && Dbl::ql("alter table ContactInfo add `data` varbinary(32767) DEFAULT NULL")) { $Conf->update_schema_version(71); } if ($Conf->sversion == 71 && Dbl::ql("alter table Settings modify `name` varbinary(256) DEFAULT NULL") && Dbl::ql("update Settings set name=rtrim(name)")) { $Conf->update_schema_version(72); } if ($Conf->sversion == 72 && Dbl::ql("update TopicInterest set interest=-2 where interest=0") && Dbl::ql("update TopicInterest set interest=4 where interest=2") && Dbl::ql("delete from TopicInterest where interest=1")) { $Conf->update_schema_version(73); } if ($Conf->sversion == 73 && Dbl::ql("alter table PaperStorage add `size` bigint(11) DEFAULT NULL") && Dbl::ql("update PaperStorage set `size`=length(paper) where paper is not null")) { $Conf->update_schema_version(74); } if ($Conf->sversion == 74 && Dbl::ql("alter table ContactInfo drop column `visits`")) { $Conf->update_schema_version(75); } if ($Conf->sversion == 75) { foreach (array("capability_gc", "s3_scope", "s3_signing_key") as $k) { if (isset($Conf->settings[$k])) { $Conf->save_setting("__" . $k, $Conf->settings[$k], get($Conf->settingTexts, $k)); $Conf->save_setting($k, null); } } $Conf->update_schema_version(76); } if ($Conf->sversion == 76 && Dbl::ql("update PaperReviewPreference set expertise=-expertise")) { $Conf->update_schema_version(77); } if ($Conf->sversion == 77 && Dbl::ql("alter table MailLog add `q` varchar(4096)")) { $Conf->update_schema_version(78); } if ($Conf->sversion == 78 && Dbl::ql("alter table MailLog add `t` varchar(200)")) { $Conf->update_schema_version(79); } if ($Conf->sversion == 79 && Dbl::ql("alter table ContactInfo add `passwordTime` int(11) NOT NULL DEFAULT '0'")) { $Conf->update_schema_version(80); } if ($Conf->sversion == 80 && Dbl::ql("alter table PaperReview modify `reviewRound` int(11) NOT NULL DEFAULT '0'") && Dbl::ql("alter table PaperReviewArchive modify `reviewRound` int(11) NOT NULL DEFAULT '0'")) { $Conf->update_schema_version(81); } if ($Conf->sversion == 81 && Dbl::ql("alter table PaperStorage add `filterType` int(3) DEFAULT NULL") && Dbl::ql("alter table PaperStorage add `originalStorageId` int(11) DEFAULT NULL")) { $Conf->update_schema_version(82); } if ($Conf->sversion == 82 && Dbl::ql("update Settings set name='msg.resp_instrux' where name='msg.responseinstructions'")) { $Conf->update_schema_version(83); } if ($Conf->sversion == 83 && Dbl::ql("alter table PaperComment add `commentRound` int(11) NOT NULL DEFAULT '0'")) { $Conf->update_schema_version(84); } if ($Conf->sversion == 84 && Dbl::ql("insert ignore into Settings (name, value) select 'resp_active', value from Settings where name='resp_open'")) { $Conf->update_schema_version(85); } if ($Conf->sversion == 85 && Dbl::ql("DROP TABLE IF EXISTS `PCMember`") && Dbl::ql("DROP TABLE IF EXISTS `ChairAssistant`") && Dbl::ql("DROP TABLE IF EXISTS `Chair`")) { $Conf->update_schema_version(86); } if ($Conf->sversion == 86 && update_schema_transfer_address($Conf)) { $Conf->update_schema_version(87); } if ($Conf->sversion == 87 && Dbl::ql("DROP TABLE IF EXISTS `ContactAddress`")) { $Conf->update_schema_version(88); } if ($Conf->sversion == 88 && Dbl::ql("alter table ContactInfo drop key `name`") && Dbl::ql("alter table ContactInfo drop key `affiliation`") && Dbl::ql("alter table ContactInfo drop key `email_3`") && Dbl::ql("alter table ContactInfo drop key `firstName_2`") && Dbl::ql("alter table ContactInfo drop key `lastName`")) { $Conf->update_schema_version(89); } if ($Conf->sversion == 89 && update_schema_unaccented_name($Conf)) { $Conf->update_schema_version(90); } if ($Conf->sversion == 90 && Dbl::ql("alter table PaperReview add `reviewAuthorSeen` int(11) DEFAULT NULL")) { $Conf->update_schema_version(91); } if ($Conf->sversion == 91 && Dbl::ql("alter table PaperReviewArchive add `reviewAuthorSeen` int(11) DEFAULT NULL")) { $Conf->update_schema_version(92); } if ($Conf->sversion == 92 && Dbl::ql("alter table Paper drop key `titleAbstractText`") && Dbl::ql("alter table Paper drop key `allText`") && Dbl::ql("alter table Paper drop key `authorText`") && Dbl::ql("alter table Paper modify `authorInformation` varbinary(8192) DEFAULT NULL") && Dbl::ql("alter table Paper modify `abstract` varbinary(16384) DEFAULT NULL") && Dbl::ql("alter table Paper modify `collaborators` varbinary(8192) DEFAULT NULL") && Dbl::ql("alter table Paper modify `withdrawReason` varbinary(1024) DEFAULT NULL")) { $Conf->update_schema_version(93); } if ($Conf->sversion == 93 && Dbl::ql("alter table TopicArea modify `topicName` varchar(200) DEFAULT NULL")) { $Conf->update_schema_version(94); } if ($Conf->sversion == 94 && Dbl::ql("alter table PaperOption modify `data` varbinary(32768) DEFAULT NULL")) { foreach (PaperOption::nonfixed_option_list($Conf) as $xopt) { if ($xopt->type === "text") { Dbl::ql("delete from PaperOption where optionId={$xopt->id} and data=''"); } } $Conf->update_schema_version(95); } if ($Conf->sversion == 95 && Dbl::ql("alter table Capability add unique key `salt` (`salt`)") && Dbl::ql("update Capability join CapabilityMap using (capabilityId) set Capability.salt=CapabilityMap.capabilityValue") && Dbl::ql("drop table if exists `CapabilityMap`")) { $Conf->update_schema_version(96); } if ($Conf->sversion == 96 && Dbl::ql("alter table ContactInfo add `passwordIsCdb` tinyint(1) NOT NULL DEFAULT '0'")) { $Conf->update_schema_version(97); } if ($Conf->sversion == 97 && Dbl::ql("alter table PaperReview add `reviewWordCount` int(11) DEFAULT NULL") && Dbl::ql("alter table PaperReviewArchive add `reviewWordCount` int(11) DEFAULT NULL") && Dbl::ql("alter table PaperReviewArchive drop key `reviewId`") && Dbl::ql("alter table PaperReviewArchive drop key `contactPaper`") && Dbl::ql("alter table PaperReviewArchive drop key `reviewSubmitted`") && Dbl::ql("alter table PaperReviewArchive drop key `reviewNeedsSubmit`") && Dbl::ql("alter table PaperReviewArchive drop key `reviewType`") && Dbl::ql("alter table PaperReviewArchive drop key `requestedBy`")) { $Conf->update_schema_version(98); } if ($Conf->sversion == 98) { update_schema_review_word_counts($Conf); $Conf->update_schema_version(99); } if ($Conf->sversion == 99 && Dbl::ql("alter table ContactInfo ENGINE=InnoDB") && Dbl::ql("alter table Paper ENGINE=InnoDB") && Dbl::ql("alter table PaperComment ENGINE=InnoDB") && Dbl::ql("alter table PaperConflict ENGINE=InnoDB") && Dbl::ql("alter table PaperOption ENGINE=InnoDB") && Dbl::ql("alter table PaperReview ENGINE=InnoDB") && Dbl::ql("alter table PaperStorage ENGINE=InnoDB") && Dbl::ql("alter table PaperTag ENGINE=InnoDB") && Dbl::ql("alter table PaperTopic ENGINE=InnoDB") && Dbl::ql("alter table Settings ENGINE=InnoDB")) { $Conf->update_schema_version(100); } if ($Conf->sversion == 100 && Dbl::ql("alter table ActionLog ENGINE=InnoDB") && Dbl::ql("alter table Capability ENGINE=InnoDB") && Dbl::ql("alter table Formula ENGINE=InnoDB") && Dbl::ql("alter table MailLog ENGINE=InnoDB") && Dbl::ql("alter table PaperReviewArchive ENGINE=InnoDB") && Dbl::ql("alter table PaperReviewPreference ENGINE=InnoDB") && Dbl::ql("alter table PaperReviewRefused ENGINE=InnoDB") && Dbl::ql("alter table PaperWatch ENGINE=InnoDB") && Dbl::ql("alter table ReviewRating ENGINE=InnoDB") && Dbl::ql("alter table ReviewRequest ENGINE=InnoDB") && Dbl::ql("alter table TopicArea ENGINE=InnoDB") && Dbl::ql("alter table TopicInterest ENGINE=InnoDB")) { $Conf->update_schema_version(101); } if ($Conf->sversion == 101 && Dbl::ql("alter table ActionLog modify `ipaddr` varbinary(32) DEFAULT NULL") && Dbl::ql("alter table MailLog modify `recipients` varbinary(200) NOT NULL") && Dbl::ql("alter table MailLog modify `q` varbinary(4096) DEFAULT NULL") && Dbl::ql("alter table MailLog modify `t` varbinary(200) DEFAULT NULL") && Dbl::ql("alter table Paper modify `mimetype` varbinary(80) NOT NULL DEFAULT ''") && Dbl::ql("alter table PaperStorage modify `mimetype` varbinary(80) NOT NULL DEFAULT ''") && Dbl::ql("alter table PaperStorage modify `filename` varbinary(255) DEFAULT NULL") && Dbl::ql("alter table PaperStorage modify `infoJson` varbinary(8192) DEFAULT NULL")) { $Conf->update_schema_version(102); } if ($Conf->sversion == 102 && Dbl::ql("alter table PaperReview modify `paperSummary` mediumblob") && Dbl::ql("alter table PaperReview modify `commentsToAuthor` mediumblob") && Dbl::ql("alter table PaperReview modify `commentsToPC` mediumblob") && Dbl::ql("alter table PaperReview modify `commentsToAddress` mediumblob") && Dbl::ql("alter table PaperReview modify `weaknessOfPaper` mediumblob") && Dbl::ql("alter table PaperReview modify `strengthOfPaper` mediumblob") && Dbl::ql("alter table PaperReview modify `textField7` mediumblob") && Dbl::ql("alter table PaperReview modify `textField8` mediumblob") && Dbl::ql("alter table PaperReviewArchive modify `paperSummary` mediumblob") && Dbl::ql("alter table PaperReviewArchive modify `commentsToAuthor` mediumblob") && Dbl::ql("alter table PaperReviewArchive modify `commentsToPC` mediumblob") && Dbl::ql("alter table PaperReviewArchive modify `commentsToAddress` mediumblob") && Dbl::ql("alter table PaperReviewArchive modify `weaknessOfPaper` mediumblob") && Dbl::ql("alter table PaperReviewArchive modify `strengthOfPaper` mediumblob") && Dbl::ql("alter table PaperReviewArchive modify `textField7` mediumblob") && Dbl::ql("alter table PaperReviewArchive modify `textField8` mediumblob")) { $Conf->update_schema_version(103); } if ($Conf->sversion == 103 && Dbl::ql("alter table Paper modify `title` varbinary(256) DEFAULT NULL") && Dbl::ql("alter table Paper drop key `title`")) { $Conf->update_schema_version(104); } if ($Conf->sversion == 104 && Dbl::ql("alter table PaperReview add `reviewFormat` tinyint(1) DEFAULT NULL") && Dbl::ql("alter table PaperReviewArchive add `reviewFormat` tinyint(1) DEFAULT NULL")) { $Conf->update_schema_version(105); } if ($Conf->sversion == 105 && Dbl::ql("alter table PaperComment add `commentFormat` tinyint(1) DEFAULT NULL")) { $Conf->update_schema_version(106); } if ($Conf->sversion == 106 && Dbl::ql("alter table PaperComment add `authorOrdinal` int(11) NOT NULL default '0'") && Dbl::ql("update PaperComment set authorOrdinal=ordinal where commentType>=" . COMMENTTYPE_AUTHOR)) { $Conf->update_schema_version(107); } // repair missing comment ordinals; reset incorrect `ordinal`s for // author-visible comments if ($Conf->sversion == 107) { $result = Dbl::ql("select paperId, commentId from PaperComment where ordinal=0 and (commentType&" . (COMMENTTYPE_RESPONSE | COMMENTTYPE_DRAFT) . ")=0 and commentType>=" . COMMENTTYPE_PCONLY . " and commentType<" . COMMENTTYPE_AUTHOR . " order by commentId"); while ($row = edb_row($result)) { Dbl::ql("update PaperComment,\n(select coalesce(count(commentId),0) commentCount from Paper\n left join PaperComment on (PaperComment.paperId=Paper.paperId and (commentType&" . (COMMENTTYPE_RESPONSE | COMMENTTYPE_DRAFT) . ")=0 and commentType>=" . COMMENTTYPE_PCONLY . " and commentType<" . COMMENTTYPE_AUTHOR . " and commentId<{$row['1']})\n where Paper.paperId={$row['0']} group by Paper.paperId) t\nset ordinal=(t.commentCount+1) where commentId={$row['1']}"); } $result = Dbl::ql("select paperId, commentId from PaperComment where ordinal=0 and (commentType&" . (COMMENTTYPE_RESPONSE | COMMENTTYPE_DRAFT) . ")=0 and commentType>=" . COMMENTTYPE_AUTHOR . " order by commentId"); while ($row = edb_row($result)) { Dbl::ql("update PaperComment,\n(select coalesce(count(commentId),0) commentCount from Paper\n left join PaperComment on (PaperComment.paperId=Paper.paperId and (commentType&" . (COMMENTTYPE_RESPONSE | COMMENTTYPE_DRAFT) . ")=0 and commentType>=" . COMMENTTYPE_AUTHOR . " and commentId<{$row['1']})\n where Paper.paperId={$row['0']} group by Paper.paperId) t\nset authorOrdinal=(t.commentCount+1) where commentId={$row['1']}"); } $result = Dbl::ql("select paperId, commentId from PaperComment where ordinal=authorOrdinal and (commentType&" . (COMMENTTYPE_RESPONSE | COMMENTTYPE_DRAFT) . ")=0 and commentType>=" . COMMENTTYPE_AUTHOR . " order by commentId"); while ($row = edb_row($result)) { Dbl::ql("update PaperComment,\n(select coalesce(max(ordinal),0) maxOrdinal from Paper\n left join PaperComment on (PaperComment.paperId=Paper.paperId and (commentType&" . (COMMENTTYPE_RESPONSE | COMMENTTYPE_DRAFT) . ")=0 and commentType>=" . COMMENTTYPE_PCONLY . " and commentType<" . COMMENTTYPE_AUTHOR . " and commentId<{$row['1']})\n where Paper.paperId={$row['0']} group by Paper.paperId) t\nset ordinal=(t.maxOrdinal+1) where commentId={$row['1']}"); } $Conf->update_schema_version(108); } // contact tags format change if ($Conf->sversion == 108 && Dbl::ql("update ContactInfo set contactTags=substr(replace(contactTags, ' ', '#0 ') from 3)") && Dbl::ql("update ContactInfo set contactTags=replace(contactTags, '#0#0 ', '#0 ')")) { $Conf->update_schema_version(109); } if ($Conf->sversion == 109 && Dbl::ql("alter table PaperTag modify `tagIndex` float NOT NULL DEFAULT '0'")) { $Conf->update_schema_version(110); } if ($Conf->sversion == 110 && Dbl::ql("alter table ContactInfo drop `faxPhoneNumber`") && Dbl::ql("alter table ContactInfo add `country` varbinary(256) default null") && update_schema_transfer_country($Conf)) { $Conf->update_schema_version(111); } if ($Conf->sversion == 111) { update_schema_review_word_counts($Conf); $Conf->update_schema_version(112); } if ($Conf->sversion == 112 && Dbl::ql("alter table ContactInfo add `passwordUseTime` int(11) NOT NULL DEFAULT '0'") && Dbl::ql("alter table ContactInfo add `updateTime` int(11) NOT NULL DEFAULT '0'") && Dbl::ql("update ContactInfo set passwordUseTime=lastLogin where passwordUseTime=0")) { $Conf->update_schema_version(113); } if ($Conf->sversion == 113 && Dbl::ql("drop table if exists `PaperReviewArchive`")) { $Conf->update_schema_version(114); } if ($Conf->sversion == 114 && Dbl::ql("alter table PaperReview add `timeDisplayed` int(11) NOT NULL DEFAULT '0'") && Dbl::ql("alter table PaperComment add `timeDisplayed` int(11) NOT NULL DEFAULT '0'")) { $Conf->update_schema_version(115); } if ($Conf->sversion == 115 && Dbl::ql("alter table Formula drop column `authorView`")) { $Conf->update_schema_version(116); } if ($Conf->sversion == 116 && Dbl::ql("alter table PaperComment add `commentOverflow` longblob DEFAULT NULL")) { $Conf->update_schema_version(117); } if ($Conf->sversion == 117 && update_schema_drop_keys_if_exist("PaperTopic", ["paperTopic", "PRIMARY"]) && Dbl::ql("alter table PaperTopic add primary key (`paperId`,`topicId`)") && update_schema_drop_keys_if_exist("TopicInterest", ["contactTopic", "PRIMARY"]) && Dbl::ql("alter table TopicInterest add primary key (`contactId`,`topicId`)")) { $Conf->update_schema_version(118); } if ($Conf->sversion == 118 && update_schema_drop_keys_if_exist("PaperTag", ["paperTag", "PRIMARY"]) && Dbl::ql("alter table PaperTag add primary key (`paperId`,`tag`)") && update_schema_drop_keys_if_exist("PaperReviewPreference", ["paperId", "PRIMARY"]) && Dbl::ql("alter table PaperReviewPreference add primary key (`paperId`,`contactId`)") && update_schema_drop_keys_if_exist("PaperConflict", ["contactPaper", "contactPaperConflict", "PRIMARY"]) && Dbl::ql("alter table PaperConflict add primary key (`contactId`,`paperId`)") && Dbl::ql("alter table MailLog modify `paperIds` blob") && Dbl::ql("alter table MailLog modify `cc` blob") && Dbl::ql("alter table MailLog modify `replyto` blob") && Dbl::ql("alter table MailLog modify `subject` blob") && Dbl::ql("alter table MailLog modify `emailBody` blob")) { $Conf->update_schema_version(119); } if ($Conf->sversion == 119 && update_schema_drop_keys_if_exist("PaperWatch", ["contactPaper", "contactPaperWatch", "PRIMARY"]) && Dbl::ql("alter table PaperWatch add primary key (`paperId`,`contactId`)")) { $Conf->update_schema_version(120); } if ($Conf->sversion == 120 && Dbl::ql("alter table Paper add `paperFormat` tinyint(1) DEFAULT NULL")) { $Conf->update_schema_version(121); } if ($Conf->sversion == 121 && Dbl::ql_raw("update PaperReview r, Paper p set r.reviewNeedsSubmit=1 where p.paperId=r.paperId and p.timeSubmitted<=0 and r.reviewSubmitted is null") && Dbl::ql_raw("update PaperReview r, Paper p, PaperReview rq set r.reviewNeedsSubmit=0 where p.paperId=r.paperId and p.paperId=rq.paperId and p.timeSubmitted<=0 and r.reviewType=" . REVIEW_SECONDARY . " and r.contactId=rq.requestedBy and rq.reviewType<" . REVIEW_SECONDARY . " and rq.reviewSubmitted is not null") && Dbl::ql_raw("update PaperReview r, Paper p, PaperReview rq set r.reviewNeedsSubmit=-1 where p.paperId=r.paperId and p.paperId=rq.paperId and p.timeSubmitted<=0 and r.reviewType=" . REVIEW_SECONDARY . " and r.contactId=rq.requestedBy and rq.reviewType<" . REVIEW_SECONDARY . " and r.reviewNeedsSubmit=0")) { $Conf->update_schema_version(122); } if ($Conf->sversion == 122 && Dbl::ql("alter table ReviewRequest add `reviewRound` int(1) DEFAULT NULL")) { $Conf->update_schema_version(123); } if ($Conf->sversion == 123 && Dbl::ql("update ContactInfo set disabled=1 where password='' and email regexp '^anonymous[0-9]*\$'")) { $Conf->update_schema_version(124); } if ($Conf->sversion == 124 && Dbl::ql("update ContactInfo set password='' where password='******' or passwordIsCdb")) { $Conf->update_schema_version(125); } if ($Conf->sversion == 125 && Dbl::ql("alter table ContactInfo drop column `passwordIsCdb`")) { $Conf->update_schema_version(126); } if ($Conf->sversion == 126 && Dbl::ql("update ContactInfo set disabled=1, password='' where email regexp '^anonymous[0-9]*\$'")) { $Conf->update_schema_version(127); } if ($Conf->sversion == 127 && Dbl::ql("update PaperReview set reviewWordCount=null")) { $Conf->update_schema_version(128); } if ($Conf->sversion == 128 && update_schema_bad_comment_timeDisplayed($Conf)) { $Conf->update_schema_version(129); } if ($Conf->sversion == 129 && Dbl::ql("update PaperComment set timeDisplayed=1 where timeDisplayed=0 and timeNotified>0")) { $Conf->update_schema_version(130); } if ($Conf->sversion == 130 && Dbl::ql("DROP TABLE IF EXISTS `PaperTagAnno`") && Dbl::ql("CREATE TABLE `PaperTagAnno` (\n `tag` varchar(40) NOT NULL, # see TAG_MAXLEN in header.php\n `annoId` int(11) NOT NULL,\n `tagIndex` float NOT NULL DEFAULT '0',\n `heading` varbinary(8192) DEFAULT NULL,\n `annoFormat` tinyint(1) DEFAULT NULL,\n `infoJson` varbinary(32768) DEFAULT NULL,\n PRIMARY KEY (`tag`,`annoId`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8")) { $Conf->update_schema_version(131); } if ($Conf->sversion == 131 && Dbl::ql("alter table PaperStorage modify `infoJson` varbinary(32768) DEFAULT NULL")) { $Conf->update_schema_version(132); } Dbl::ql("delete from Settings where name='__schema_lock'"); }
function paperQuery($contact, $options = array()) { // Options: // "paperId" => $pid Only paperId $pid (if array, any of those) // "reviewId" => $rid Only paper reviewed by $rid // "commentId" => $c Only paper where comment is $c // "finalized" Only submitted papers // "unsub" Only unsubmitted papers // "accepted" Only accepted papers // "active" Only nonwithdrawn papers // "author" Only papers authored by $contactId // "myReviewRequests" Only reviews requested by $contactId // "myReviews" All reviews authored by $contactId // "myOutstandingReviews" All unsubmitted reviews auth by $contactId // "myReviewsOpt" myReviews, + include papers not yet reviewed // "allReviews" All reviews (multiple rows per paper) // "allReviewScores" All review scores (multiple rows per paper) // "allComments" All comments (multiple rows per paper) // "reviewerName" Include reviewer names // "commenterName" Include commenter names // "reviewer" => $cid Include reviewerConflictType/reviewerReviewType // "tags" Include paperTags // "tagIndex" => $tag Include tagIndex of named tag // "tagIndex" => tag array -- include tagIndex, tagIndex1, ... // "topics" // "options" // "scores" => array(fields to score) // "assignments" // "order" => $sql $sql is SQL 'order by' clause (or empty) global $Opt; $reviewerQuery = isset($options["myReviews"]) || isset($options["allReviews"]) || isset($options["myReviewRequests"]) || isset($options["myReviewsOpt"]) || isset($options["myOutstandingReviews"]); $allReviewerQuery = isset($options["allReviews"]) || isset($options["allReviewScores"]); $scoresQuery = !$reviewerQuery && isset($options["allReviewScores"]); if (is_object($contact)) { $contactId = $contact->contactId; } else { $contactId = (int) $contact; $contact = null; } if (isset($options["reviewer"]) && is_object($options["reviewer"])) { $reviewerContactId = $options["reviewer"]->contactId; } else { if (isset($options["reviewer"])) { $reviewerContactId = $options["reviewer"]; } else { $reviewerContactId = $contactId; } } if (get($options, "author")) { $myPaperReview = null; } else { if ($allReviewerQuery) { $myPaperReview = "MyPaperReview"; } else { $myPaperReview = "PaperReview"; } } // paper selection $paperset = array(); if (isset($options["paperId"])) { $paperset[] = self::_cvt_numeric_set($options["paperId"]); } if (isset($options["reviewId"])) { if (is_numeric($options["reviewId"])) { $result = Dbl::qe("select paperId from PaperReview where reviewId=" . $options["reviewId"]); $paperset[] = self::_cvt_numeric_set(edb_first_columns($result)); } else { if (preg_match('/^(\\d+)([A-Z][A-Z]?)$/i', $options["reviewId"], $m)) { $result = Dbl::qe("select paperId from PaperReview where paperId={$m['1']} and reviewOrdinal=" . parseReviewOrdinal($m[2])); $paperset[] = self::_cvt_numeric_set(edb_first_columns($result)); } else { $paperset[] = array(); } } } if (isset($options["commentId"])) { $result = Dbl::qe("select paperId from PaperComment where commentId" . sql_in_numeric_set(self::_cvt_numeric_set($options["commentId"]))); $paperset[] = self::_cvt_numeric_set(edb_first_columns($result)); } if (count($paperset) > 1) { $paperset = array(call_user_func_array("array_intersect", $paperset)); } $papersel = ""; if (count($paperset)) { $papersel = "paperId" . sql_in_numeric_set($paperset[0]) . " and "; } // prepare query: basic tables $where = array(); $joins = array("Paper"); $cols = array("Paper.*, PaperConflict.conflictType"); $aujoinwhere = null; if (get($options, "author") && $contact && ($aujoinwhere = $contact->actAuthorSql("PaperConflict", true))) { $where[] = $aujoinwhere; } if (get($options, "author") && !$aujoinwhere) { $joins[] = "join PaperConflict on (PaperConflict.paperId=Paper.paperId and PaperConflict.contactId={$contactId} and PaperConflict.conflictType>=" . CONFLICT_AUTHOR . ")"; } else { $joins[] = "left join PaperConflict on (PaperConflict.paperId=Paper.paperId and PaperConflict.contactId={$contactId})"; } // my review $qr = ""; if ($contact && ($tokens = $contact->review_tokens())) { $qr = " or PaperReview.reviewToken in (" . join(", ", $tokens) . ")"; } if (get($options, "myReviewRequests")) { $joins[] = "join PaperReview on (PaperReview.paperId=Paper.paperId and PaperReview.requestedBy={$contactId} and PaperReview.reviewType=" . REVIEW_EXTERNAL . ")"; } else { if (get($options, "myReviews")) { $joins[] = "join PaperReview on (PaperReview.paperId=Paper.paperId and (PaperReview.contactId={$contactId}{$qr}))"; } else { if (get($options, "myOutstandingReviews")) { $joins[] = "join PaperReview on (PaperReview.paperId=Paper.paperId and (PaperReview.contactId={$contactId}{$qr}) and PaperReview.reviewNeedsSubmit!=0)"; } else { if (get($options, "myReviewsOpt")) { $joins[] = "left join PaperReview on (PaperReview.paperId=Paper.paperId and (PaperReview.contactId={$contactId}{$qr}))"; } else { if (get($options, "allReviews") || get($options, "allReviewScores")) { $x = get($options, "reviewLimitSql") ? " and (" . $options["reviewLimitSql"] . ")" : ""; $joins[] = "join PaperReview on (PaperReview.paperId=Paper.paperId{$x})"; } else { if (!get($options, "author")) { $joins[] = "left join PaperReview on (PaperReview.paperId=Paper.paperId and (PaperReview.contactId={$contactId}{$qr}))"; } } } } } } // started reviews if (get($options, "startedReviewCount")) { $joins[] = "left join (select paperId, count(*) count from PaperReview where {$papersel}(reviewSubmitted or reviewNeedsSubmit>0) group by paperId) R_started on (R_started.paperId=Paper.paperId)"; $cols[] = "coalesce(R_started.count,0) startedReviewCount"; } // submitted reviews $j = "select paperId, count(*) count"; $before_ncols = count($cols); if (get($options, "startedReviewCount")) { $cols[] = "coalesce(R_submitted.count,0) reviewCount"; } if (get($options, "scores")) { foreach ($options["scores"] as $fid) { $cols[] = "R_submitted.{$fid}Scores"; if ($myPaperReview) { $cols[] = "{$myPaperReview}.{$fid}"; } $j .= ", group_concat({$fid} order by reviewId) {$fid}Scores"; } } if (get($options, "reviewTypes") || get($options, "reviewIdentities")) { $cols[] = "R_submitted.reviewTypes"; $j .= ", group_concat(reviewType order by reviewId) reviewTypes"; } if (get($options, "reviewIdentities")) { $cols[] = "R_submitted.reviewRequestedBys"; $j .= ", group_concat(requestedBy order by reviewId) reviewRequestedBys"; if ($this->review_blindness() == self::BLIND_OPTIONAL) { $cols[] = "R_submitted.reviewBlinds"; $j .= ", group_concat(reviewBlind order by reviewId) reviewBlinds"; } if ($contact && $contact->review_tokens()) { $cols[] = "R_submitted.reviewTokens"; $j .= ", group_concat(reviewToken order by reviewId) reviewTokens"; } } if (get($options, "reviewRounds")) { $cols[] = "R_submitted.reviewRounds"; $j .= ", group_concat(reviewRound order by reviewId) reviewRounds"; } if (get($options, "reviewWordCounts") && $this->sversion >= 99) { $cols[] = "R_submitted.reviewWordCounts"; $j .= ", group_concat(reviewWordCount order by reviewId) reviewWordCounts"; } if (get($options, "reviewOrdinals")) { $cols[] = "R_submitted.reviewOrdinals"; $j .= ", group_concat(reviewOrdinal order by reviewId) reviewOrdinals"; } if (get($options, "reviewTypes") || get($options, "scores") || get($options, "reviewContactIds") || get($options, "reviewOrdinals") || get($options, "reviewIdentities")) { $cols[] = "R_submitted.reviewContactIds"; $j .= ", group_concat(contactId order by reviewId) reviewContactIds"; } if (count($cols) != $before_ncols) { $joins[] = "left join ({$j} from PaperReview where {$papersel}reviewSubmitted>0 group by paperId) R_submitted on (R_submitted.paperId=Paper.paperId)"; } // assignments if (get($options, "assignments")) { $j = "select paperId, group_concat(contactId order by reviewId) allReviewContactIds, group_concat(reviewType order by reviewId) allReviewTypes, group_concat(reviewRound order by reviewId) allReviewRounds"; $cols[] = "R_all.allReviewContactIds, R_all.allReviewTypes, R_all.allReviewRounds"; $joins[] = "left join ({$j} from PaperReview where {$papersel}true group by paperId) R_all on (R_all.paperId=Paper.paperId)"; } // fields if (get($options, "author")) { $cols[] = "null reviewType, null reviewId, null myReviewType"; } else { // see also papercolumn.php array_push($cols, "PaperReview.reviewType, PaperReview.reviewId", "PaperReview.reviewModified, PaperReview.reviewSubmitted", "PaperReview.reviewNeedsSubmit, PaperReview.reviewOrdinal", "PaperReview.reviewBlind, PaperReview.reviewToken", "PaperReview.contactId as reviewContactId, PaperReview.requestedBy", "max({$myPaperReview}.reviewType) as myReviewType", "max({$myPaperReview}.reviewSubmitted) as myReviewSubmitted", "min({$myPaperReview}.reviewNeedsSubmit) as myReviewNeedsSubmit", "{$myPaperReview}.contactId as myReviewContactId", "PaperReview.reviewRound"); } if ($reviewerQuery || $scoresQuery) { $cols[] = "PaperReview.reviewEditVersion as reviewEditVersion"; $cols[] = ($this->sversion >= 105 ? "PaperReview.reviewFormat" : "null") . " as reviewFormat"; foreach (ReviewForm::all_fields() as $f) { if ($reviewerQuery || $f->has_options) { $cols[] = "PaperReview.{$f->id} as {$f->id}"; } } } if ($myPaperReview == "MyPaperReview") { $joins[] = "left join PaperReview as MyPaperReview on (MyPaperReview.paperId=Paper.paperId and MyPaperReview.contactId={$contactId})"; } if (get($options, "topics")) { $cols[] = "(select group_concat(topicId) from PaperTopic where PaperTopic.paperId=Paper.paperId) topicIds"; } if (get($options, "options") && (isset($this->settingTexts["options"]) || isset($Opt["optionsInclude"])) && PaperOption::count_option_list()) { $cols[] = "(select group_concat(PaperOption.optionId, '#', value) from PaperOption where paperId=Paper.paperId) optionIds"; } else { if (get($options, "options")) { $cols[] = "'' as optionIds"; } } if (get($options, "tags")) { $cols[] = "(select group_concat(' ', tag, '#', tagIndex order by tag separator '') from PaperTag where PaperTag.paperId=Paper.paperId) paperTags"; } if (get($options, "tagIndex") && !is_array($options["tagIndex"])) { $options["tagIndex"] = array($options["tagIndex"]); } if (get($options, "tagIndex")) { foreach ($options["tagIndex"] as $i => $tag) { $cols[] = "(select tagIndex from PaperTag where PaperTag.paperId=Paper.paperId and PaperTag.tag='" . sqlq($tag) . "') tagIndex" . ($i ?: ""); } } if (get($options, "reviewerPreference")) { $joins[] = "left join PaperReviewPreference on (PaperReviewPreference.paperId=Paper.paperId and PaperReviewPreference.contactId={$reviewerContactId})"; $cols[] = "coalesce(PaperReviewPreference.preference, 0) as reviewerPreference"; $cols[] = "PaperReviewPreference.expertise as reviewerExpertise"; } if (get($options, "allReviewerPreference") || get($options, "desirability")) { $subq = "select paperId"; if (get($options, "allReviewerPreference")) { $subq .= ", " . $this->query_all_reviewer_preference() . " as allReviewerPreference"; $cols[] = "APRP.allReviewerPreference"; } if (get($options, "desirability")) { $subq .= ", sum(if(preference<=-100,0,greatest(least(preference,1),-1))) as desirability"; $cols[] = "coalesce(APRP.desirability,0) as desirability"; } $subq .= " from PaperReviewPreference where {$papersel}true group by paperId"; $joins[] = "left join ({$subq}) as APRP on (APRP.paperId=Paper.paperId)"; } if (get($options, "allConflictType")) { $joins[] = "left join (select paperId, group_concat(concat(contactId,' ',conflictType) separator ',') as allConflictType from PaperConflict where {$papersel}conflictType>0 group by paperId) as AllConflict on (AllConflict.paperId=Paper.paperId)"; $cols[] = "AllConflict.allConflictType"; } if (get($options, "reviewer")) { $joins[] = "left join PaperConflict RPC on (RPC.paperId=Paper.paperId and RPC.contactId={$reviewerContactId})"; $joins[] = "left join PaperReview RPR on (RPR.paperId=Paper.paperId and RPR.contactId={$reviewerContactId})"; $cols[] = "RPC.conflictType reviewerConflictType, RPR.reviewType reviewerReviewType"; } if (get($options, "allComments")) { $joins[] = "join PaperComment on (PaperComment.paperId=Paper.paperId)"; $joins[] = "left join PaperConflict as CommentConflict on (CommentConflict.paperId=PaperComment.paperId and CommentConflict.contactId=PaperComment.contactId)"; array_push($cols, "PaperComment.commentId, PaperComment.contactId as commentContactId", "CommentConflict.conflictType as commentConflictType", "PaperComment.timeModified, PaperComment.comment", "PaperComment.replyTo, PaperComment.commentType"); } if (get($options, "reviewerName")) { if ($options["reviewerName"] === "lead" || $options["reviewerName"] === "shepherd") { $joins[] = "left join ContactInfo as ReviewerContactInfo on (ReviewerContactInfo.contactId=Paper." . $options['reviewerName'] . "ContactId)"; } else { if (get($options, "allComments")) { $joins[] = "left join ContactInfo as ReviewerContactInfo on (ReviewerContactInfo.contactId=PaperComment.contactId)"; } else { if (get($options, "reviewerName")) { $joins[] = "left join ContactInfo as ReviewerContactInfo on (ReviewerContactInfo.contactId=PaperReview.contactId)"; } } } array_push($cols, "ReviewerContactInfo.firstName as reviewFirstName", "ReviewerContactInfo.lastName as reviewLastName", "ReviewerContactInfo.email as reviewEmail", "ReviewerContactInfo.lastLogin as reviewLastLogin"); } if (get($options, "foldall")) { $cols[] = "1 as folded"; } // conditions if (count($paperset)) { $where[] = "Paper.paperId" . sql_in_numeric_set($paperset[0]); } if (get($options, "finalized")) { $where[] = "timeSubmitted>0"; } else { if (get($options, "unsub")) { $where[] = "timeSubmitted<=0"; } } if (get($options, "accepted")) { $where[] = "outcome>0"; } if (get($options, "undecided")) { $where[] = "outcome=0"; } if (get($options, "active") || get($options, "myReviews") || get($options, "myReviewRequests")) { $where[] = "timeWithdrawn<=0"; } if (get($options, "myLead")) { $where[] = "leadContactId={$contactId}"; } if (get($options, "unmanaged")) { $where[] = "managerContactId=0"; } $pq = "select " . join(",\n ", $cols) . "\nfrom " . join("\n ", $joins); if (count($where)) { $pq .= "\nwhere " . join("\n and ", $where); } // grouping and ordering if (get($options, "allComments")) { $pq .= "\ngroup by Paper.paperId, PaperComment.commentId"; } else { if ($reviewerQuery || $scoresQuery) { $pq .= "\ngroup by Paper.paperId, PaperReview.reviewId"; } else { $pq .= "\ngroup by Paper.paperId"; } } if (get($options, "order") && $options["order"] != "order by Paper.paperId") { $pq .= "\n" . $options["order"]; } else { $pq .= "\norder by Paper.paperId"; if ($reviewerQuery || $scoresQuery) { $pq .= ", PaperReview.reviewOrdinal"; } if (isset($options["allComments"])) { $pq .= ", PaperComment.commentId"; } } //Conf::msg_debugt($pq); return $pq . "\n"; }
function search_completion($category = "") { global $Conf, $Me; $res = array(); if ($this->amPC && (!$category || $category === "ss")) { foreach ($Conf->settingTexts as $k => $v) { if (substr($k, 0, 3) == "ss:" && ($v = json_decode($v))) { $res[] = $k; } } } array_push($res, "has:submission", "has:abstract", "has:finalcopy"); if ($this->amPC && $Conf->has_any_manager()) { $res[] = "has:admin"; } if ($this->amPC && $Conf->has_any_lead_or_shepherd()) { $res[] = "has:lead"; } if ($this->contact->can_view_some_decision()) { $res[] = "has:decision"; if (!$category || $category === "dec") { $res[] = array("pri" => -1, "nosort" => true, "i" => array("dec:any", "dec:none", "dec:yes", "dec:no")); $dm = $Conf->decision_map(); unset($dm[0]); $res = array_merge($res, self::simple_search_completion("dec:", $dm, Text::SEARCH_UNPRIVILEGE_EXACT)); } } if ($this->amPC || $this->contact->can_view_some_decision()) { $res[] = "has:shepherd"; } if ($this->contact->can_view_some_review()) { array_push($res, "has:re", "has:cre", "has:ire", "has:pre", "has:comment", "has:aucomment"); } if ($this->contact->is_reviewer()) { array_push($res, "has:primary", "has:secondary", "has:external"); } foreach ($Conf->resp_round_list() as $i => $rname) { if (!in_array("has:response", $res)) { $res[] = "has:response"; } if ($i) { $res[] = "has:{$rname}response"; } } if ($this->contact->can_view_some_draft_response()) { foreach ($Conf->resp_round_list() as $i => $rname) { if (!in_array("has:draftresponse", $res)) { $res[] = "has:draftresponse"; } if ($i) { $res[] = "has:draft{$rname}response"; } } } foreach (PaperOption::user_option_list($this->contact) as $o) { if ($this->contact->can_view_some_paper_option($o)) { array_push($res, "has:{$o->abbr}", "opt:{$o->abbr}"); } } if ($this->contact->is_reviewer() && $Conf->has_rounds() && (!$category || $category === "round")) { $res[] = array("pri" => -1, "nosort" => true, "i" => array("round:any", "round:none")); $rlist = array(); foreach ($Conf->round_list() as $rnum => $round) { if ($rnum && $round !== ";") { $rlist[$rnum] = $round; } } $res = array_merge($res, self::simple_search_completion("round:", $rlist)); } if ($Conf->has_topics() && (!$category || $category === "topic")) { foreach ($Conf->topic_map() as $tname) { $res[] = "topic:\"{$tname}\""; } } if (!$category || $category === "style") { $res[] = array("pri" => -1, "nosort" => true, "i" => array("style:any", "style:none", "color:any", "color:none")); foreach (explode("|", TagInfo::BASIC_COLORS) as $t) { array_push($res, "style:{$t}", "color:{$t}"); } } if (!$category || $category === "show" || $category === "hide") { $cats = array(); $pl = new PaperList(new PaperSearch($Me, "")); foreach (PaperColumn::$by_name as $c) { if (($cat = $c->completion_name()) && $c->prepare($pl, PaperColumn::PREP_COMPLETION)) { $cats[$cat] = true; } } foreach (PaperColumn::$factories as $f) { foreach ($f[1]->completion_instances($this->contact) as $c) { if (($cat = $c->completion_name()) && $c->prepare($pl, PaperColumn::PREP_COMPLETION)) { $cats[$cat] = true; } } } foreach (array_keys($cats) as $cat) { array_push($res, "show:{$cat}", "hide:{$cat}"); } array_push($res, "show:compact", "show:statistics", "show:rownumbers"); } return $res; }
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)"); }