Пример #1
0
 public function delete($capdata)
 {
     assert(!$capdata || is_string($capdata->salt));
     if ($capdata) {
         Dbl::ql($this->dblink, "delete from Capability where salt=?", $capdata->salt);
     }
 }
Пример #2
0
 private static function try_list($opt, $listtype, $sort = null)
 {
     global $Conf, $Me;
     if ($listtype == "u" && $Me->privChair) {
         $searchtype = defval($opt, "t") === "all" ? "all" : "pc";
         $q = "select contactId from ContactInfo";
         if ($searchtype == "pc") {
             $q .= " where (roles&" . Contact::ROLE_PC . ")!=0";
         }
         $result = Dbl::ql("{$q} order by lastName, firstName, email");
         $a = array();
         while ($row = edb_row($result)) {
             $a[] = (int) $row[0];
         }
         Dbl::free($result);
         return self::create("u/" . $searchtype, $a, $searchtype == "pc" ? "Program committee" : "Users", hoturl_site_relative_raw("users", "t={$searchtype}"));
     } else {
         $search = new PaperSearch($Me, $opt);
         $x = $search->session_list_object($sort);
         if ($sort || $search->has_sort()) {
             $pl = new PaperList($search, array("sort" => $sort));
             $x->ids = $pl->id_array();
         }
         return $x;
     }
 }
Пример #3
0
function createAnonymousReview()
{
    global $Conf, $Me, $Now, $prow, $rrows;
    Dbl::qe_raw("lock tables PaperReview write, PaperReviewRefused write, ContactInfo write, PaperConflict read, ActionLog write");
    // find an unassigned anonymous review contact
    $contactemail = unassignedAnonymousContact();
    $result = Dbl::qe_raw("select contactId from ContactInfo where email='" . sqlq($contactemail) . "'");
    if (edb_nrows($result) == 1) {
        $row = edb_row($result);
        $reqId = $row[0];
    } else {
        $result = Dbl::qe("insert into ContactInfo set firstName='Jane Q.', lastName='Public', unaccentedName='Jane Q. Public', email=?, affiliation='Unaffiliated', password='', disabled=1, creationTime={$Now}", $contactemail);
        if (!$result) {
            return $result;
        }
        $reqId = $result->insert_id;
    }
    // store the review request
    $reviewId = $Me->assign_review($prow->paperId, $reqId, REVIEW_EXTERNAL, array("mark_notify" => true, "token" => true));
    if ($reviewId) {
        $result = Dbl::ql("select reviewToken from PaperReview where reviewId={$reviewId}");
        $row = edb_row($result);
        $Conf->confirmMsg("Created a new anonymous review for paper #{$prow->paperId}. The review token is " . encode_token((int) $row[0]) . ".");
    }
    Dbl::qx_raw("unlock tables");
    $Conf->update_rev_tokens_setting(true);
    return true;
}
Пример #4
0
 function assign_review($pid, $reviewer_cid, $type, $extra = array())
 {
     global $Conf, $Now;
     $result = Dbl::qe("select reviewId, reviewType, reviewRound, reviewModified, reviewToken, requestedBy, reviewSubmitted from PaperReview where paperId=? and contactId=?", $pid, $reviewer_cid);
     $rrow = edb_orow($result);
     Dbl::free($result);
     $reviewId = $rrow ? $rrow->reviewId : 0;
     // can't delete a review that's in progress
     if ($type <= 0 && $rrow && $rrow->reviewType && $rrow->reviewModified) {
         if ($rrow->reviewType >= REVIEW_SECONDARY) {
             $type = REVIEW_PC;
         } else {
             return $reviewId;
         }
     }
     // change database
     if ($type > 0 && ($round = get($extra, "round_number")) === null) {
         $round = $Conf->current_round();
     }
     if ($type > 0 && (!$rrow || !$rrow->reviewType)) {
         $qa = "";
         if (get($extra, "mark_notify")) {
             $qa .= ", timeRequestNotified={$Now}";
         }
         if (get($extra, "token")) {
             $qa .= self::unassigned_review_token();
         }
         $new_requester_cid = $this->contactId;
         if ($new_requester = get($extra, "requester_contact")) {
             $new_requester_cid = $new_requester->contactId;
         }
         $q = "insert into PaperReview set paperId={$pid}, contactId={$reviewer_cid}, reviewType={$type}, reviewRound={$round}, timeRequested={$Now}{$qa}, requestedBy={$new_requester_cid}";
     } else {
         if ($type > 0 && ($rrow->reviewType != $type || $rrow->reviewRound != $round)) {
             $q = "update PaperReview set reviewType={$type}, reviewRound={$round}";
             if (!$rrow->reviewSubmitted) {
                 $q .= ", reviewNeedsSubmit=1";
             }
             $q .= " where reviewId={$reviewId}";
         } else {
             if ($type <= 0 && $rrow && $rrow->reviewType) {
                 $q = "delete from PaperReview where reviewId={$reviewId}";
             } else {
                 return $reviewId;
             }
         }
     }
     if (!($result = Dbl::qe_raw($q))) {
         return false;
     }
     if ($q[0] == "d") {
         $msg = "Removed " . ReviewForm::$revtype_names[$rrow->reviewType] . " review";
         $reviewId = 0;
     } else {
         if ($q[0] == "u") {
             $msg = "Changed " . ReviewForm::$revtype_names[$rrow->reviewType] . " review to " . ReviewForm::$revtype_names[$type];
         } else {
             $msg = "Added " . ReviewForm::$revtype_names[$type] . " review";
             $reviewId = $result->insert_id;
         }
     }
     $Conf->log($msg . " by " . $this->email, $reviewer_cid, $pid);
     // on new review, update PaperReviewRefused, ReviewRequest, delegation
     if ($q[0] == "i") {
         Dbl::ql("delete from PaperReviewRefused where paperId={$pid} and contactId={$reviewer_cid}");
         if ($req_email = get($extra, "requested_email")) {
             Dbl::qe("delete from ReviewRequest where paperId={$pid} and email=?", $req_email);
         }
         if ($type < REVIEW_SECONDARY) {
             self::update_review_delegation($pid, $new_requester_cid, 1);
         }
     } else {
         if ($q[0] == "d") {
             if ($rrow->reviewType < REVIEW_SECONDARY && $rrow->requestedBy > 0) {
                 self::update_review_delegation($pid, $rrow->requestedBy, -1);
             }
         } else {
             if ($type == REVIEW_SECONDARY && $rrow->reviewType != REVIEW_SECONDARY && !$rrow->reviewSubmitted) {
                 self::update_review_delegation($pid, $reviewer_cid, 0);
             }
         }
     }
     // Mark rev_tokens setting for future update by update_rev_tokens_setting
     if ($rrow && get($rrow, "reviewToken") && $type <= 0) {
         $Conf->settings["rev_tokens"] = -1;
     }
     // Set pcrev_assigntime
     if ($q[0] == "i" && $type >= REVIEW_PC && $Conf->setting("pcrev_assigntime", 0) < $Now) {
         $Conf->save_setting("pcrev_assigntime", $Now);
     }
     Contact::update_rights();
     return $reviewId;
 }
Пример #5
0
 public function mark_activity()
 {
     global $Now;
     if (!$this->activity_at || $this->activity_at < $Now) {
         $this->activity_at = $Now;
         if ($this->contactId && !$this->is_anonymous_user()) {
             $this->conf->ql("update ContactInfo set lastLogin={$Now} where contactId={$this->contactId}");
         }
         if ($this->contactDbId) {
             Dbl::ql(self::contactdb(), "update ContactInfo set activity_at={$Now} where contactDbId={$this->contactDbId}");
         }
     }
 }
Пример #6
0
function do_setting_update($sv)
{
    global $Conf, $Group, $Me, $Now, $Opt, $OptOverride;
    // parse settings
    foreach (Si::$all as $si) {
        account_value($sv, $si);
    }
    // check date relationships
    foreach (array("sub_reg" => "sub_sub", "final_soft" => "final_done") as $dn1 => $dn2) {
        list($dv1, $dv2) = [$sv->savedv($dn1), $sv->savedv($dn2)];
    }
    if (!$dv1 && $dv2) {
        $sv->save($dn1, $dv2);
    } else {
        if ($dv2 && $dv1 > $dv2) {
            $sv->set_error($dn1, unparse_setting_error(Si::get($dn1), "Must come before " . Si::get($dn2, "short_description") . "."));
            $sv->set_error($dn2);
        }
    }
    if ($sv->has_savedv("sub_sub")) {
        $sv->save("sub_update", $sv->savedv("sub_sub"));
    }
    if (get($Opt, "defaultSiteContact")) {
        if ($sv->has_savedv("opt.contactName") && get($Opt, "contactName") === $sv->savedv("opt.contactName")) {
            $sv->save("opt.contactName", null);
        }
        if ($sv->has_savedv("opt.contactEmail") && get($Opt, "contactEmail") === $sv->savedv("opt.contactEmail")) {
            $sv->save("opt.contactEmail", null);
        }
    }
    if ($sv->has_savedv("resp_active") && $sv->savedv("resp_active")) {
        foreach (explode(" ", $sv->newv("resp_rounds")) as $i => $rname) {
            $isuf = $i ? "_{$i}" : "";
            if ($sv->newv("resp_open{$isuf}") > $sv->newv("resp_done{$isuf}")) {
                $sv->set_error("resp_open{$isuf}", unparse_setting_error(Si::get("resp_open"), "Must come before " . Si::get("resp_done", "short_description") . "."));
                $sv->set_error("resp_done{$isuf}");
            }
        }
    }
    // update 'papersub'
    if ($sv->has_savedv("pc_seeall")) {
        // see also conference.php
        if ($sv->savedv("pc_seeall") <= 0) {
            $x = "timeSubmitted>0";
        } else {
            $x = "timeWithdrawn<=0";
        }
        $num = Dbl::fetch_ivalue("select paperId from Paper where {$x} limit 1") ? 1 : 0;
        if ($num != $Conf->setting("papersub")) {
            $sv->save("papersub", $num);
        }
    }
    // Setting relationships
    if ($sv->has_savedv("sub_open") && $sv->newv("sub_open", 1) <= 0 && $sv->oldv("sub_open") > 0 && $sv->newv("sub_sub") <= 0) {
        $sv->save("sub_close", $Now);
    }
    if ($sv->has_savedv("msg.clickthrough_submit")) {
        $sv->save("clickthrough_submit", null);
    }
    // make settings
    $changedn = [];
    if (!$sv->has_errors() && (count($sv->savedv) || count($sv->save_callbacks))) {
        $tables = "Settings write";
        foreach ($sv->need_lock as $t => $need) {
            if ($need) {
                $tables .= ", {$t} write";
            }
        }
        $Conf->qe("lock tables {$tables}");
        // load db settings, pre-crosscheck
        $dbsettings = array();
        $result = Dbl::qe("select name, value, data from Settings");
        while ($row = edb_row($result)) {
            $dbsettings[$row[0]] = $row;
        }
        Dbl::free($result);
        // apply settings
        foreach ($sv->save_callbacks as $si) {
            $p = $sv->parser($si);
            $p->save($sv, $si);
        }
        $dv = $aq = $av = array();
        foreach ($sv->savedv as $n => $v) {
            if (substr($n, 0, 4) === "opt." && $v !== null) {
                $okey = substr($n, 4);
                $oldv = array_key_exists($okey, $OptOverride) ? $OptOverride[$okey] : get($Opt, $okey);
                $Opt[$okey] = $v[1] === null ? $v[0] : $v[1];
                if ($oldv === $Opt[$okey]) {
                    $v = null;
                } else {
                    if (!array_key_exists($okey, $OptOverride)) {
                        $OptOverride[$okey] = $oldv;
                    }
                }
            }
            if ($v === null ? !isset($dbsettings[$n]) : isset($dbsettings[$n]) && (int) $dbsettings[$n][1] === $v[0] && $dbsettings[$n][2] === $v[1]) {
                continue;
            }
            $changedn[] = $n;
            if ($v !== null) {
                $aq[] = "(?, ?, ?)";
                array_push($av, $n, $v[0], $v[1]);
            } else {
                $dv[] = $n;
            }
        }
        if (count($dv)) {
            Dbl::qe_apply("delete from Settings where name?a", array($dv));
            //Conf::msg_info(Ht::pre_text_wrap(Dbl::format_query_apply("delete from Settings where name?a", array($dv))));
        }
        if (count($aq)) {
            Dbl::qe_apply("insert into Settings (name, value, data) values\n\t" . join(",\n\t", $aq) . "\n\ton duplicate key update value=values(value), data=values(data)", $av);
            //Conf::msg_info(Ht::pre_text_wrap(Dbl::format_query_apply("insert into Settings (name, value, data) values\n\t" . join(",\n\t", $aq) . "\n\ton duplicate key update value=values(value), data=values(data)", $av)));
        }
        $Conf->qe("unlock tables");
        if (count($changedn)) {
            $Me->log_activity("Updated settings " . join(", ", $changedn));
        }
        $Conf->load_settings();
        // contactdb may need to hear about changes to shortName
        if ($sv->has_savedv("opt.shortName") && get($Opt, "contactdb_dsn") && ($cdb = Contact::contactdb())) {
            Dbl::ql($cdb, "update Conferences set shortName=? where dbName=?", $Opt["shortName"], $Opt["dbName"]);
        }
    }
    // update the review form in case it's changed
    ReviewForm::clear_cache();
    if (!$sv->has_errors()) {
        $Conf->save_session("settings_highlight", $sv->error_fields());
        if (count($changedn)) {
            $Conf->confirmMsg("Changes saved.");
        } else {
            $Conf->warnMsg("No changes.");
        }
        $sv->report();
        redirectSelf();
    } else {
        SettingGroup::crosscheck($sv, $Group);
        $sv->report();
    }
}
    Dbl::free($result);
}
if ($papers) {
    $result = Dbl::ql(Contact::contactdb(), "select confid from Conferences where `dbname`=?", $Opt["dbName"]);
    $row = Dbl::fetch_first_row($result);
    if (!$row) {
        fwrite(STDERR, "Conference is not recored in contactdb\n");
        exit(1);
    }
    $confid = $row[0];
    $result = Dbl::ql($Conf->dblink, "select paperId, title from Paper");
    $q = array();
    while ($row = edb_row($result)) {
        $q[] = "(" . $confid . "," . $row[0] . ",'" . sqlq($row[1]) . "')";
    }
    Dbl::free($result);
    for ($i = 0; $i < count($q); $i += 25) {
        $xq = array_slice($q, $i, 25);
        Dbl::ql_raw(Contact::contactdb(), "insert into ConferencePapers (confid,paperId,title) values " . join(",", $xq) . " on duplicate key update title=values(title)");
    }
}
if ($collaborators) {
    $result = Dbl::ql($Conf->dblink, "select email, collaborators, updateTime, lastLogin from ContactInfo where collaborators is not null and collaborators!=''");
    while ($row = edb_row($result)) {
        $time = (int) $row[2] ?: (int) $row[3];
        if ($time > 0) {
            Dbl::ql(Contact::contactdb(), "update ContactInfo set collaborators=?, updateTime=? where email=? and (collaborators is null or collaborators='' or updateTime<?)", $row[1], $time, $row[0], $time);
        }
    }
    Dbl::free($result);
}
Пример #8
0
 public function delete($capdata)
 {
     if ($capdata) {
         Dbl::ql($this->dblink, "delete from Capability where capabilityId=" . $capdata->capabilityId);
     }
 }
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'");
}
Пример #10
0
 function update_schema_version($n)
 {
     if (!$n) {
         $n = Dbl::fetch_ivalue("select value from Settings where name='allowPaperOption'");
     }
     if ($n && Dbl::ql("update Settings set value={$n} where name='allowPaperOption'")) {
         $this->sversion = $this->settings["allowPaperOption"] = $n;
         return true;
     } else {
         return false;
     }
 }
Пример #11
0
    if ($qreq->fn === "events") {
        json_exit(["ok" => false]);
    }
}
if ($qreq->fn === "searchcompletion") {
    $s = new PaperSearch($Me, "");
    $Conf->ajaxExit(array("ok" => true, "searchcompletion" => $s->search_completion()));
}
// from here on: `status` and `track` requests
if ($qreq->fn === "track") {
    MeetingTracker::track_api($qreq, $Me);
}
// may fall through to act like `status`
$j = $Me->my_deadlines($Conf->paper);
if ($qreq->conflist && $Me->has_email() && ($cdb = Contact::contactdb())) {
    $j->conflist = array();
    $result = Dbl::ql($cdb, "select c.confid, siteclass, shortName, url\n        from Roles r join Conferences c on (c.confid=r.confid)\n        join ContactInfo u on (u.contactDbId=r.contactDbId)\n        where u.email=? order by r.updated_at desc", $Me->email);
    while ($row = edb_orow($result)) {
        $row->confid = (int) $row->confid;
        $j->conflist[] = $row;
    }
}
$pj = (object) array();
if ($Conf->paper && $Me->can_view_tags($Conf->paper)) {
    $Conf->paper->add_tag_info_json($pj, $Me);
}
if (count((array) $pj)) {
    $j->p = [$Conf->paper->paperId => $pj];
}
$j->ok = true;
$Conf->ajaxExit($j);
Пример #12
0
 function load_settings()
 {
     global $Now;
     // load settings from database
     $this->settings = array();
     $this->settingTexts = array();
     foreach ($this->opt_override ?: [] as $k => $v) {
         if ($v === null) {
             unset($this->opt[$k]);
         } else {
             $this->opt[$k] = $v;
         }
     }
     $this->opt_override = [];
     $this->_pc_seeall_cache = null;
     $this->deadlineCache = null;
     $result = $this->q_raw("select name, value, data from Settings");
     while ($result && ($row = $result->fetch_row())) {
         $this->settings[$row[0]] = (int) $row[1];
         if ($row[2] !== null) {
             $this->settingTexts[$row[0]] = $row[2];
         }
         if (substr($row[0], 0, 4) == "opt.") {
             $okey = substr($row[0], 4);
             $this->opt_override[$okey] = get($this->opt, $okey);
             $this->opt[$okey] = $row[2] === null ? (int) $row[1] : $row[2];
         }
     }
     Dbl::free($result);
     // update schema
     $this->sversion = $this->settings["allowPaperOption"];
     if ($this->sversion < 108) {
         require_once "updateschema.php";
         $old_nerrors = Dbl::$nerrors;
         updateSchema($this);
         Dbl::$nerrors = $old_nerrors;
     }
     // invalidate all caches after loading from backup
     if (isset($this->settings["frombackup"]) && $this->invalidate_caches()) {
         $this->qe_raw("delete from Settings where name='frombackup' and value=" . $this->settings["frombackup"]);
         unset($this->settings["frombackup"]);
     } else {
         $this->invalidate_caches(["rf" => true]);
     }
     // update options
     if (isset($this->opt["ldapLogin"]) && !$this->opt["ldapLogin"]) {
         unset($this->opt["ldapLogin"]);
     }
     if (isset($this->opt["httpAuthLogin"]) && !$this->opt["httpAuthLogin"]) {
         unset($this->opt["httpAuthLogin"]);
     }
     // set conferenceKey
     if (!isset($this->opt["conferenceKey"])) {
         if (!isset($this->settingTexts["conf_key"]) && ($key = hotcrp_random_bytes(32)) !== false) {
             $this->save_setting("conf_key", 1, $key);
         }
         $this->opt["conferenceKey"] = get($this->settingTexts, "conf_key", "");
     }
     // set capability key
     if (!get($this->settings, "cap_key") && !get($this->opt, "disableCapabilities") && !(($key = hotcrp_random_bytes(16)) !== false && ($key = base64_encode($key)) && $this->save_setting("cap_key", 1, $key))) {
         $this->opt["disableCapabilities"] = true;
     }
     // GC old capabilities
     if (defval($this->settings, "__capability_gc", 0) < $Now - 86400) {
         foreach (array($this->dblink, Contact::contactdb()) as $db) {
             if ($db) {
                 Dbl::ql($db, "delete from Capability where timeExpires>0 and timeExpires<{$Now}");
             }
         }
         $this->q_raw("insert into Settings (name, value) values ('__capability_gc', {$Now}) on duplicate key update value=values(value)");
         $this->settings["__capability_gc"] = $Now;
     }
     $this->crosscheck_settings();
     $this->crosscheck_options();
 }
Пример #13
0
 function load_settings()
 {
     global $Opt, $OptOverride, $Now, $OK;
     // load settings from database
     $this->settings = array();
     $this->settingTexts = array();
     $this->_pc_seeall_cache = null;
     $this->deadlineCache = null;
     $result = $this->q("select name, value, data from Settings");
     while ($result && ($row = $result->fetch_row())) {
         $this->settings[$row[0]] = (int) $row[1];
         if ($row[2] !== null) {
             $this->settingTexts[$row[0]] = $row[2];
         }
         if (substr($row[0], 0, 4) == "opt.") {
             $okey = substr($row[0], 4);
             if (!array_key_exists($okey, $OptOverride)) {
                 $OptOverride[$okey] = @$Opt[$okey];
             }
             $Opt[$okey] = $row[2] === null ? $row[1] : $row[2];
         }
     }
     Dbl::free($result);
     // update schema
     if ($this->settings["allowPaperOption"] < 91) {
         require_once "updateschema.php";
         $oldOK = $OK;
         updateSchema($this);
         $OK = $oldOK;
     }
     $this->sversion = $this->settings["allowPaperOption"];
     // invalidate caches after loading from backup
     if (isset($this->settings["frombackup"]) && $this->invalidateCaches()) {
         $this->qe("delete from Settings where name='frombackup' and value=" . $this->settings["frombackup"]);
         unset($this->settings["frombackup"]);
     }
     // update options
     if (isset($Opt["ldapLogin"]) && !$Opt["ldapLogin"]) {
         unset($Opt["ldapLogin"]);
     }
     if (isset($Opt["httpAuthLogin"]) && !$Opt["httpAuthLogin"]) {
         unset($Opt["httpAuthLogin"]);
     }
     // set conferenceKey
     if (!isset($Opt["conferenceKey"])) {
         if (!isset($this->settingTexts["conf_key"]) && ($key = hotcrp_random_bytes(32)) !== false) {
             $this->save_setting("conf_key", 1, $key);
         }
         $Opt["conferenceKey"] = defval($this->settingTexts, "conf_key", "");
     }
     // set capability key
     if (!@$this->settings["cap_key"] && !@$Opt["disableCapabilities"] && !(($key = hotcrp_random_bytes(16)) !== false && ($key = base64_encode($key)) && $this->save_setting("cap_key", 1, $key))) {
         $Opt["disableCapabilities"] = true;
     }
     // GC old capabilities
     if ($this->sversion >= 58 && defval($this->settings, "__capability_gc", 0) < $Now - 86400) {
         foreach (array($this->dblink, Contact::contactdb()) as $db) {
             if ($db) {
                 Dbl::ql($db, "delete from Capability where timeExpires>0 and timeExpires<{$Now}");
                 Dbl::ql($db, "delete from CapabilityMap where timeExpires>0 and timeExpires<{$Now}");
             }
         }
         $this->q("insert into Settings (name, value) values ('__capability_gc', {$Now}) on duplicate key update value=values(value)");
         $this->settings["__capability_gc"] = $Now;
     }
     $this->crosscheck_settings();
     $this->crosscheck_options();
 }
Пример #14
0
 function render($sv)
 {
     global $Conf;
     $sv->echo_checkbox("rev_open", "<b>Open site for reviewing</b>");
     $sv->echo_checkbox("cmt_always", "Allow comments even if reviewing is closed");
     echo "<div class='g'></div>\n";
     $sv->echo_checkbox('pcrev_any', "PC members can review <strong>any</strong> submitted paper");
     echo "<div class='g'></div>\n";
     echo "<strong>Review anonymity:</strong> Are reviewer names hidden from authors?<br />\n";
     $sv->echo_radio_table("rev_blind", array(Conf::BLIND_ALWAYS => "Yes—reviews are anonymous", Conf::BLIND_NEVER => "No—reviewer names are visible to authors", Conf::BLIND_OPTIONAL => "Depends—reviewers decide whether to expose their names"));
     echo "<div class='g'></div>\n";
     $sv->echo_checkbox('rev_notifychair', 'Notify PC chairs of newly submitted reviews by email');
     // Deadlines
     echo "<h3 id=\"rounds\" class=\"settings g\">Deadlines &amp; rounds</h3>\n";
     echo '<p class="hint">Reviews are due by the deadline, but <em>cannot be modified</em> after the hard deadline. Most conferences don’t use hard deadlines for reviews.<br />', $sv->type_hint("date") ?: "", '</p>';
     $rounds = $Conf->round_list();
     if ($sv->use_req()) {
         for ($i = 1; isset($sv->req["roundname_{$i}"]); ++$i) {
             $rounds[$i] = get($sv->req, "deleteround_{$i}") ? ";" : trim(get_s($sv->req, "roundname_{$i}"));
         }
     }
     // prepare round selector
     $round_value = trim($sv->curv("rev_roundtag"));
     $current_round_value = $Conf->setting_data("rev_roundtag", "");
     if (preg_match('/\\A(?:|\\(none\\)|\\(no name\\)|default|unnamed|#0)\\z/i', $round_value)) {
         $round_value = "#0";
     } else {
         if (($round_number = $Conf->round_number($round_value, false)) || ($round_number = $Conf->round_number($current_round_value, false))) {
             $round_value = "#" . $round_number;
         } else {
             $round_value = $selector[$current_round_value] = $current_round_value;
         }
     }
     $round_map = edb_map(Dbl::ql("select reviewRound, count(*) from PaperReview group by reviewRound"));
     $print_round0 = true;
     if ($round_value !== "#0" && $round_value !== "" && $current_round_value !== "" && (!$sv->use_req() || isset($sv->req["roundname_0"])) && !$Conf->round0_defined()) {
         $print_round0 = false;
     }
     $selector = array();
     if ($print_round0) {
         $selector["#0"] = "unnamed";
     }
     for ($i = 1; $i < count($rounds); ++$i) {
         if ($rounds[$i] !== ";") {
             $selector["#{$i}"] = (object) array("label" => $rounds[$i], "id" => "rev_roundtag_{$i}");
         }
     }
     echo '<div id="round_container"', count($selector) == 1 ? ' style="display:none"' : '', '>', '<table id="rev_roundtag_table"><tr><td class="lxcaption">', $sv->label("rev_roundtag", "Current round"), '</td><td>', Ht::select("rev_roundtag", $selector, $round_value, $sv->sjs("rev_roundtag")), '</td></tr></table>', '<div class="hint">This round is used for new assignments.</div><div class="g"></div></div>';
     echo '<div id="roundtable">';
     $num_printed = 0;
     for ($i = 0; $i < count($rounds); ++$i) {
         if ($i ? $rounds[$i] !== ";" : $print_round0) {
             $this->echo_round($sv, $i, $i ? $rounds[$i] : "", +get($round_map, $i), count($selector) !== 1);
             ++$num_printed;
         }
     }
     echo '</div><div id="newround" style="display:none">';
     $this->echo_round($sv, '$', "", "", true);
     echo '</div><div class="g"></div>';
     echo Ht::js_button("Add round", "review_round_settings.add();hiliter(this)"), ' &nbsp; <span class="hint"><a href="', hoturl("help", "t=revround"), '">What is this?</a></span>', Ht::hidden("oldroundcount", count($Conf->round_list())), Ht::hidden("has_rev_roundtag", 1);
     for ($i = 1; $i < count($rounds); ++$i) {
         if ($rounds[$i] === ";") {
             echo Ht::hidden("roundname_{$i}", "", array("id" => "roundname_{$i}")), Ht::hidden("deleteround_{$i}", 1);
         }
     }
     Ht::stash_script("review_round_settings.init()");
     // External reviews
     echo "<h3 class=\"settings g\">External reviews</h3>\n";
     echo "<div class='g'></div>";
     $sv->echo_checkbox("extrev_chairreq", "PC chair must approve proposed external reviewers");
     $sv->echo_checkbox("pcrev_editdelegate", "PC members can edit external reviews they requested");
     echo "<div class='g'></div>\n";
     $t = expandMailTemplate("requestreview", false);
     echo "<table id='foldmailbody_requestreview' class='", $t == expandMailTemplate("requestreview", true) ? "foldc" : "foldo", "'><tr><td>", foldbutton("mailbody_requestreview"), "</td>", "<td><a href='#' onclick='return fold(\"mailbody_requestreview\")' class='q'><strong>Mail template for external review requests</strong></a>", " <span class='fx'>(<a href='", hoturl("mail"), "'>keywords</a> allowed; set to empty for default)<br /></span>\n<textarea class='tt fx' name='mailbody_requestreview' cols='80' rows='20'>", htmlspecialchars($t["body"]), "</textarea>", "</td></tr></table>\n";
     // Review visibility
     echo "<h3 class=\"settings g\">Visibility</h3>\n";
     echo "Can PC members <strong>see all reviews</strong> except for conflicts?<br />\n";
     $sv->echo_radio_table("pc_seeallrev", array(Conf::PCSEEREV_YES => "Yes", Conf::PCSEEREV_UNLESSINCOMPLETE => "Yes, unless they haven’t completed an assigned review for the same paper", Conf::PCSEEREV_UNLESSANYINCOMPLETE => "Yes, after completing all their assigned reviews", Conf::PCSEEREV_IFCOMPLETE => "Only after completing a review for the same paper"));
     echo "<div class='g'></div>\n";
     echo "Can PC members see <strong>reviewer names</strong> except for conflicts?<br />\n";
     $sv->echo_radio_table("pc_seeblindrev", array(0 => "Yes", 1 => "Only after completing a review for the same paper<br /><span class='hint'>This setting also hides reviewer-only comments from PC members who have not completed a review for the same paper.</span>"));
     echo "<div class='g'></div>";
     echo "Can external reviewers see the other reviews for their assigned papers, once they’ve submitted their own?<br />\n";
     $sv->echo_radio_table("extrev_view", array(2 => "Yes", 1 => "Yes, but they can’t see who wrote blind reviews", 0 => "No"));
     // Review ratings
     echo "<h3 class=\"settings g\">Review ratings</h3>\n";
     echo "Should HotCRP collect ratings of reviews? &nbsp; <a class='hint' href='", hoturl("help", "t=revrate"), "'>(Learn more)</a><br />\n";
     $sv->echo_radio_table("rev_ratings", array(REV_RATINGS_PC => "Yes, PC members can rate reviews", REV_RATINGS_PC_EXTERNAL => "Yes, PC members and external reviewers can rate reviews", REV_RATINGS_NONE => "No"));
 }