public function json()
 {
     // find out who is light and who is heavy
     // (light => less than 0.66 * (80th percentile))
     $nass = array();
     foreach ($this->r as $cid => $x) {
         $nass[] = count($x);
     }
     sort($nass);
     $heavy_boundary = 0;
     if (count($nass)) {
         $heavy_boundary = 0.66 * $nass[(int) (0.8 * count($nass))];
     }
     $contacts = pcMembers();
     $need_contacts = [];
     foreach ($this->r as $cid => $x) {
         if (!isset($contacts[$cid]) && ctype_digit($cid)) {
             $need_contacts[] = $cid;
         }
     }
     if (count($need_contacts)) {
         $result = Dbl::q("select firstName, lastName, affiliation, email, contactId, roles, contactTags, disabled from ContactInfo where contactId ?a", $need_contacts);
         while ($result && ($row = Contact::fetch($result))) {
             $contacts[$row->contactId] = $row;
         }
     }
     $users = array();
     $tags = $this->contact->can_view_reviewer_tags();
     foreach ($this->r as $cid => $x) {
         if ($cid != "conflicts") {
             $users[$cid] = $u = (object) array();
             $p = get($contacts, $cid);
             if ($p) {
                 $u->name = Text::name_text($p);
             }
             if (count($x) < $heavy_boundary) {
                 $u->light = true;
             }
             if ($p && $tags && ($t = $p->viewable_color_classes($this->contact))) {
                 $u->color_classes = $t;
             }
         }
     }
     return (object) array("reviews" => $this->r, "deadlines" => $this->dl, "users" => $users);
 }
function pcMembers()
{
    global $Conf, $Opt, $PcMembersCache;
    if (!@$PcMembersCache || $Conf->setting("pc") <= 0 || $PcMembersCache[0] < $Conf->setting("pc") || $PcMembersCache[1] != @$Opt["sortByLastName"]) {
        $pc = array();
        $result = Dbl::q("select firstName, lastName, affiliation, email, contactId, roles, contactTags, disabled from ContactInfo where (roles&" . Contact::ROLE_PC . ")!=0");
        $by_name_text = array();
        $pctags = array("pc" => "pc");
        while ($result && ($row = Contact::fetch($result))) {
            $pc[$row->contactId] = $row;
            if ($row->firstName || $row->lastName) {
                $name_text = Text::name_text($row);
                if (isset($by_name_text[$name_text])) {
                    $row->nameAmbiguous = $by_name_text[$name_text]->nameAmbiguous = true;
                }
                $by_name_text[$name_text] = $row;
            }
            if ($row->contactTags) {
                foreach (explode(" ", $row->contactTags) as $t) {
                    list($tag, $value) = TagInfo::split_index($t);
                    if ($tag) {
                        $pctags[strtolower($tag)] = $tag;
                    }
                }
            }
        }
        uasort($pc, "Contact::compare");
        ksort($pctags);
        $order = 0;
        foreach ($pc as $row) {
            $row->sort_position = $order;
            ++$order;
        }
        $PcMembersCache = array($Conf->setting("pc"), @$Opt["sortByLastName"], $pc, $pctags);
    }
    return $PcMembersCache[2];
}
Example #3
0
function load_pset_info()
{
    global $ConfSitePATH, $Conf, $PsetInfo, $PsetOverrides, $Opt;
    // read initial messages
    Messages::$main = new Messages();
    $x = json_decode(file_get_contents("{$ConfSitePATH}/src/messages.json"));
    foreach ($x as $j) {
        Messages::$main->add($j);
    }
    // read psets
    $PsetInfo = load_psets_json(false);
    // parse psets
    foreach ($PsetInfo as $pk => $p) {
        if (!is_object($p) || !isset($p->psetid)) {
            continue;
        }
        object_merge_recursive($p, $PsetInfo->_defaults);
        try {
            $pset = new Pset($pk, $p);
            Pset::register($pset);
        } catch (Exception $exception) {
            // Want to give a good error message, so discover where the error is.
            // - create pset landmark object
            $locinfo = (object) array();
            foreach (psets_json_data(false) as $fname => $data) {
                $x = Json::decode_landmarks($data, $fname);
                object_replace_recursive($locinfo, $x);
            }
            $locp = $locinfo->{$pk};
            if (isset($locinfo->_defaults)) {
                object_merge_recursive($locp, $locinfo->_defaults);
            }
            // - lookup exception path in landmark object
            $path = $exception instanceof PsetConfigException ? $exception->path : array();
            for ($pathpos = 0; $pathpos < count($path) && $locp && !is_string($locp); ++$pathpos) {
                $component = $path[$pathpos];
                $locp = is_array($locp) ? $locp[$component] : $locp->{$component};
            }
            // - report error
            if (is_object($locp) && @$locp->__LANDMARK__) {
                $locp = $locp->__LANDMARK__;
            } else {
                if (!is_string($locp)) {
                    $locp = $locinfo->{$pk}->__LANDMARK__;
                }
            }
            Multiconference::fail_message($locp . ": Configuration error: " . $exception->getMessage());
        }
    }
    // read message data
    if (!@$PsetInfo->_messagedefs) {
        $PsetInfo->_messagedefs = (object) array();
    }
    if (!@$PsetInfo->_messagedefs->SYSTEAM) {
        $PsetInfo->_messagedefs->SYSTEAM = "cs61-staff";
    }
    foreach ($PsetInfo->_messagedefs as $k => $v) {
        Messages::$main->define($k, $v);
    }
    // also create log/ and repo/ directories
    foreach (array("{$ConfSitePATH}/log", "{$ConfSitePATH}/repo") as $d) {
        if (!is_dir($d) && !mkdir($d, 02770, true)) {
            $e = error_get_last();
            Multiconference::fail_message("`{$d}` missing and cannot be created (" . $e["message"] . ").");
        }
        if (!file_exists("{$d}/.htaccess") && ($x = file_get_contents("{$ConfSitePATH}/src/.htaccess")) !== false && file_put_contents("{$d}/.htaccess", $x) != strlen($x)) {
            Multiconference::fail_message("Error creating `{$d}/.htaccess`");
        }
    }
    // if any anonymous problem sets, create anonymous usernames
    foreach (Pset::$all as $p) {
        if (!$p->disabled && $p->anonymous) {
            while ($row = Dbl::fetch_first_row(Dbl::qe("select contactId from ContactInfo where anon_username is null limit 1"))) {
                Dbl::q("update ContactInfo set anon_username='******' where contactId=?", $row[0]);
            }
        }
    }
}
 private function load_by_id($cid)
 {
     $result = Dbl::q("select ContactInfo.* from ContactInfo where contactId=?", $cid);
     if ($row = $result ? $result->fetch_object() : null) {
         $this->merge($row);
     }
     Dbl::free($result);
     return !!$row;
 }
Example #5
0
 static function find_by_id($cid)
 {
     $result = Dbl::q("select ContactInfo.* from ContactInfo where contactId=" . (int) $cid);
     return self::fetch($result);
 }
 public function save($sv, $si)
 {
     global $Conf;
     if ($si->name == "tag_vote" && $sv->has_savedv("tag_vote")) {
         // check allotments
         $pcm = pcMembers();
         foreach (preg_split('/\\s+/', $sv->savedv("tag_vote")) as $t) {
             if ($t === "") {
                 continue;
             }
             $base = substr($t, 0, strpos($t, "#"));
             $allotment = substr($t, strlen($base) + 1);
             $result = Dbl::q("select paperId, tag, tagIndex from PaperTag where tag like '%~" . sqlq_for_like($base) . "'");
             $pvals = array();
             $cvals = array();
             $negative = false;
             while ($row = edb_row($result)) {
                 $who = substr($row[1], 0, strpos($row[1], "~"));
                 if ($row[2] < 0) {
                     $sv->set_error(null, "Removed " . Text::user_html($pcm[$who]) . "’s negative “{$base}” vote for paper #{$row['0']}.");
                     $negative = true;
                 } else {
                     $pvals[$row[0]] = defval($pvals, $row[0], 0) + $row[2];
                     $cvals[$who] = defval($cvals, $who, 0) + $row[2];
                 }
             }
             foreach ($cvals as $who => $what) {
                 if ($what > $allotment) {
                     $sv->set_error("tag_vote", Text::user_html($pcm[$who]) . " already has more than {$allotment} votes for tag “{$base}”.");
                 }
             }
             $q = $negative ? " or (tag like '%~" . sqlq_for_like($base) . "' and tagIndex<0)" : "";
             $Conf->qe("delete from PaperTag where tag='" . sqlq($base) . "'{$q}");
             $q = array();
             foreach ($pvals as $pid => $what) {
                 $q[] = "({$pid}, '" . sqlq($base) . "', {$what})";
             }
             if (count($q) > 0) {
                 $Conf->qe("insert into PaperTag values " . join(", ", $q));
             }
         }
     }
     if ($si->name == "tag_approval" && $sv->has_savedv("tag_approval")) {
         $pcm = pcMembers();
         foreach (preg_split('/\\s+/', $sv->savedv("tag_approval")) as $t) {
             if ($t === "") {
                 continue;
             }
             $result = $Conf->q("select paperId, tag, tagIndex from PaperTag where tag like '%~" . sqlq_for_like($t) . "'");
             $pvals = array();
             $negative = false;
             while ($row = edb_row($result)) {
                 $who = substr($row[1], 0, strpos($row[1], "~"));
                 if ($row[2] < 0) {
                     $sv->set_error(null, "Removed " . Text::user_html($pcm[$who]) . "’s negative “{$t}” approval vote for paper #{$row['0']}.");
                     $negative = true;
                 } else {
                     $pvals[$row[0]] = defval($pvals, $row[0], 0) + 1;
                 }
             }
             $q = $negative ? " or (tag like '%~" . sqlq_for_like($t) . "' and tagIndex<0)" : "";
             $Conf->qe("delete from PaperTag where tag='" . sqlq($t) . "'{$q}");
             $q = array();
             foreach ($pvals as $pid => $what) {
                 $q[] = "({$pid}, '" . sqlq($t) . "', {$what})";
             }
             if (count($q) > 0) {
                 $Conf->qe("insert into PaperTag values " . join(", ", $q));
             }
         }
     }
     TagInfo::invalidate_defined_tags();
 }
function initialize_paper_columns()
{
    global $Conf;
    PaperColumn::register(new SelectorPaperColumn("sel", array("minimal" => true)));
    PaperColumn::register(new SelectorPaperColumn("selon", array("minimal" => true, "className" => "pl_sel")));
    PaperColumn::register(new SelectorPaperColumn("selconf", array("className" => "pl_confselector")));
    PaperColumn::register(new SelectorPaperColumn("selunlessconf", array("minimal" => true, "className" => "pl_sel")));
    PaperColumn::register(new IdPaperColumn());
    PaperColumn::register(new TitlePaperColumn());
    PaperColumn::register(new StatusPaperColumn("status", false));
    PaperColumn::register(new StatusPaperColumn("statusfull", true));
    PaperColumn::register(new ReviewerTypePaperColumn("revtype"));
    PaperColumn::register(new ReviewStatusPaperColumn());
    PaperColumn::register(new ReviewSubmittedPaperColumn());
    PaperColumn::register(new ReviewDelegationPaperColumn());
    PaperColumn::register(new AssignReviewPaperColumn());
    PaperColumn::register(new TopicScorePaperColumn());
    PaperColumn::register(new TopicListPaperColumn());
    PaperColumn::register(new PreferencePaperColumn("pref", false));
    PaperColumn::register_synonym("revpref", "pref");
    PaperColumn::register(new PreferenceListPaperColumn("allpref", false));
    PaperColumn::register_synonym("allrevpref", "allpref");
    PaperColumn::register(new PreferenceListPaperColumn("alltopicpref", true));
    PaperColumn::register_synonym("allrevtopicpref", "alltopicpref");
    PaperColumn::register(new DesirabilityPaperColumn());
    PaperColumn::register(new ReviewerListPaperColumn());
    PaperColumn::register(new AuthorsPaperColumn());
    PaperColumn::register(new CollabPaperColumn());
    PaperColumn::register_synonym("co", "collab");
    PaperColumn::register(new TagListPaperColumn(false));
    PaperColumn::register(new SearchOptsPaperColumn());
    PaperColumn::register(new AbstractPaperColumn());
    PaperColumn::register(new LeadPaperColumn());
    PaperColumn::register(new ShepherdPaperColumn());
    PaperColumn::register(new PCConflictListPaperColumn());
    PaperColumn::register(new ConflictMatchPaperColumn("authorsmatch", "authorInformation"));
    PaperColumn::register(new ConflictMatchPaperColumn("collabmatch", "collaborators"));
    PaperColumn::register(new TimestampPaperColumn());
    PaperColumn::register(new FoldAllPaperColumn());
    PaperColumn::register_factory("tag:", new TagPaperColumn(null, null, false));
    PaperColumn::register_factory("tagval:", new TagPaperColumn(null, null, true));
    PaperColumn::register_factory("opt:", new OptionPaperColumn(null));
    PaperColumn::register_factory("#", new TagPaperColumn(null, null, null));
    PaperColumn::register_factory("pref:", new PreferencePaperColumn(null, false));
    if (PaperOption::count_option_list()) {
        PaperColumn::register_factory("", new OptionPaperColumn(null));
    }
    foreach (ReviewForm::all_fields() as $f) {
        if ($f->has_options) {
            PaperColumn::register_factory("", new ScorePaperColumn(null));
            break;
        }
    }
    if ($Conf && $Conf->setting("formulas")) {
        $result = Dbl::q("select * from Formula order by lower(name)");
        while ($result && ($row = Formula::fetch($result))) {
            $fid = $row->formulaId;
            FormulaPaperColumn::register(new FormulaPaperColumn("formula{$fid}", $row));
        }
    }
    PaperColumn::register_factory("", new FormulaPaperColumn("", null));
    $tagger = new Tagger();
    if ($Conf && (TagInfo::has_vote() || TagInfo::has_approval() || TagInfo::has_rank())) {
        $vt = array();
        foreach (TagInfo::defined_tags() as $v) {
            if ($v->vote || $v->approval || $v->rank) {
                $vt[] = $v->tag;
            }
        }
        foreach ($vt as $n) {
            TagReportPaperColumn::register(new TagReportPaperColumn($n));
        }
    }
}
// scorechart.php -- HotCRP chart generator
// HotCRP is Copyright (c) 2006-2016 Eddie Kohler and Regents of the UC
// Distributed under an MIT-like license; see LICENSE
// Generates a PNG image of a bar chat.
// Arguments are passed in as v; s is graph style.
// Don't forget to change the width and height calculations in
// ReviewField::unparse_graph if you change the width and height here.
if (!isset($_REQUEST["v"])) {
    header("HTTP/1.0 400 Bad Request");
    exit;
}
// fail if no GD support so the browser displays alt text
if (!function_exists("imagecreate")) {
    require_once "src/init.php";
    Dbl::q("insert into Settings set name='__gd_required', value=1 on duplicate key update value=1");
    header("HTTP/1.0 503 Service Unavailable");
    exit;
}
// parse values
$s = isset($_REQUEST["s"]) ? $_REQUEST["s"] : 0;
$valMax = 1;
$values = array();
$maxY = $sum = 0;
foreach (explode(",", $_REQUEST["v"]) as $value) {
    $value = ctype_digit($value) && $value > 0 ? intval($value) : 0;
    $values[$valMax++] = $value;
    $maxY = max($value, $maxY);
    $sum += $value;
}
if (isset($_REQUEST["h"]) && is_numeric($_REQUEST["h"])) {
 public function load_content($doc)
 {
     global $Conf;
     $ok = false;
     $result = null;
     if (!opt("dbNoPapers") && get_i($doc, "paperStorageId") > 1) {
         $result = Dbl::q("select paper, compression from PaperStorage where paperStorageId=" . $doc->paperStorageId);
     }
     if (!$result || !($row = edb_row($result)) || $row[0] === null) {
         $doc->content = "";
     } else {
         if ($row[1] == 1) {
             $doc->content = gzinflate($row[0]);
             $ok = true;
         } else {
             $doc->content = $row[0];
             $ok = true;
         }
     }
     if (!$ok && ($s3 = self::s3_document()) && ($filename = self::s3_filename($doc))) {
         $filename = self::s3_filename($doc);
         $content = $s3->load($filename);
         if ($content !== "" && $content !== null) {
             $doc->content = $content;
             $ok = true;
         } else {
             if ($s3->status != 200) {
                 error_log("S3 error: GET {$filename}: {$s3->status} {$s3->status_text} " . json_encode($s3->response_headers));
             }
         }
     }
     if (!$ok) {
         $num = get($doc, "paperId") ? " #{$doc->paperId}" : "";
         $doc->error = true;
         if ($this->dtype == DTYPE_SUBMISSION) {
             $doc->error_text = "Paper{$num} has not been uploaded.";
         } else {
             if ($this->dtype == DTYPE_FINAL) {
                 $doc->error_text = "Paper{$num}’s final copy has not been uploaded.";
             }
         }
     }
     $doc->size = strlen($doc->content);
     $this->store_filestore($doc, true);
     // silently does nothing if error || !filestore
     return $ok;
 }
 function document_row($result, $dtype = DTYPE_SUBMISSION)
 {
     if (!($doc = edb_orow($result))) {
         return $doc;
     }
     // type doesn't matter
     if ($dtype === null && isset($doc->documentType)) {
         $dtype = $doc->documentType = (int) $doc->documentType;
     }
     $doc->docclass = new HotCRPDocument($dtype);
     // in modern versions sha1 is set at storage time; before it wasn't
     if ($doc->paperStorageId > 1 && $doc->sha1 == "" && $doc->docclass->load_content($doc)) {
         $doc->sha1 = sha1($doc->content, true);
         Dbl::q("update PaperStorage set sha1=? where paperStorageId=?", $doc->sha1, $doc->paperStorageId);
     }
     // unparse infoJson
     if ($doc->infoJson) {
         $doc->infoJson_str = $doc->infoJson;
         $doc->infoJson = json_decode($doc->infoJson);
     }
     return $doc;
 }
 function expandvar_generic($what, $isbool)
 {
     global $Conf, $Opt;
     if ($what == "%REVIEWDEADLINE%") {
         if ($this->row && @$this->row->reviewType > 0) {
             $rev = $this->row->reviewType >= REVIEW_PC ? "pc" : "ext";
         } else {
             if ($this->row && isset($this->row->roles)) {
                 $rev = $this->row->roles & Contact::ROLE_PCLIKE ? "pc" : "ext";
             } else {
                 if ($Conf->setting("pcrev_soft") != $Conf->setting("extrev_soft")) {
                     if ($isbool && $Conf->setting("pcrev_soft") > 0 == $Conf->setting("extrev_soft") > 0) {
                         return $Conf->setting("pcrev_soft") > 0;
                     } else {
                         return $isbool ? null : $what;
                     }
                 } else {
                     $rev = "ext";
                 }
             }
         }
         $what = "%DEADLINE(" . $rev . "rev_soft)%";
     }
     $len = strlen($what);
     if ($len > 12 && substr($what, 0, 10) == "%DEADLINE(" && substr($what, $len - 2) == ")%") {
         $inner = substr($what, 10, $len - 12);
         if ($isbool) {
             return $Conf->setting($inner) > 0;
         } else {
             return $Conf->printableTimeSetting($inner);
         }
     }
     if (($what == "%NUMACCEPTED%" || $what == "%NUMSUBMITTED%") && $this->_statistics === null) {
         $this->_statistics = array(0, 0);
         $result = Dbl::q("select outcome, count(paperId) from Paper where timeSubmitted>0 group by outcome");
         while ($row = edb_row($result)) {
             $this->_statistics[0] += $row[1];
             if ($row[0] > 0) {
                 $this->_statistics[1] += $row[1];
             }
         }
     }
     if ($what == "%NUMSUBMITTED%") {
         return $this->_statistics[0];
     }
     if ($what == "%NUMACCEPTED%") {
         return $this->_statistics[1];
     }
     if ($what == "%CONTACTDBDESCRIPTION%") {
         return get($Opt, "contactdb_description") ?: "HotCRP";
     }
     if (preg_match('/\\A%(OTHER|REQUESTER|REVIEWER)(CONTACT|NAME|EMAIL|FIRST|LAST)%\\z/', $what, $m)) {
         if ($m[1] === "REVIEWER") {
             $x = $this->_expand_reviewer($m[2], $isbool);
             if ($x !== false || $isbool) {
                 return $x;
             }
         } else {
             if ($c = $this->contacts[strtolower($m[1])]) {
                 return $this->expand_user($c, $m[2]);
             } else {
                 if ($isbool) {
                     return false;
                 }
             }
         }
     }
     if ($what == "%AUTHORVIEWCAPABILITY%" && @$Opt["disableCapabilities"]) {
         return "";
     }
     return self::EXPANDVAR_CONTINUE;
 }