public function __construct($user, $rounds = null) { global $Conf; $this->contact = $user; $qp = "select PaperReview.contactId, timeRequested, reviewSubmitted, reviewRound"; if (!$this->contact->privChair) { $qp .= ", conflictType from PaperReview left join PaperConflict on (PaperConflict.paperId=PaperReview.paperId and PaperConflict.contactId=" . $this->contact->contactId . ")"; } else { $qp .= ", 0 conflictType from PaperReview"; } $qp .= " where reviewType>" . REVIEW_PC . " or (reviewType=" . REVIEW_PC . " and timeRequested>0 and reviewSubmitted>0)"; if (!$this->contact->privChair) { $qp .= " and coalesce(conflictType,0)=0"; } $qa = array(); if ($rounds) { $qp .= " and reviewRound ?a"; $qa[] = $rounds; } $result = Dbl::qe_apply($qp, $qa); while ($row = edb_row($result)) { $cid = (int) $row[4] ? "conflicts" : (int) $row[0]; $this->r[$cid][] = array((int) $row[1], (int) $row[2], (int) $row[3]); } Dbl::free($result); foreach ($Conf->round_list() as $rn => $r) { $dl = $Conf->review_deadline($rn, true, false); $this->dl[$rn] = +$Conf->setting($dl); } // maybe hide who's who if (!$this->contact->can_view_aggregated_review_identity()) { $who = $r = array(); foreach ($this->r as $cid => $data) { if ($cid === "conflicts" || $cid == $this->contact->contactId) { $r[$cid] = $data; } else { do { $ncid = mt_rand(1, 10 * count(pcMembers())); } while (isset($who[$ncid])); $who[$ncid] = true; $r["x" . $ncid] = $data; } } $this->r = $r; } }
} if (@$_POST["update"] && check_post()) { $ck = $cv = array(); $roles = 0; if (@$_POST["pctype"] === "chair") { $roles |= Contact::ROLE_CHAIR | Contact::ROLE_PC; } else { if (@$_POST["pctype"] === "pc") { $roles |= Contact::ROLE_PC; } } if (@$_POST["sysadmin"]) { $roles |= Contact::ROLE_ADMIN; } $ck[] = "roles={$roles}"; Dbl::qe_apply("update ContactInfo set " . join($ck, ",") . " where contactId=" . $User->contactId, $cv); redirectSelf(); } $Conf->header("Profile", "profile"); $xsep = " <span class='barsep'> | </span> "; echo "<div id='homeinfo'>"; echo "<h2 class='homeemail'>", Text::user_html($User), "</h2>"; if ($User->seascode_username || $User->huid) { echo '<h3><a href="', hoturl("index", array("u" => $Me->user_linkpart($User))), '">', htmlspecialchars($User->seascode_username ?: $User->huid), '</a>'; if ($Me->privChair) { echo " ", become_user_link($User); } echo "</h3>"; } if ($User->dropped) { ContactView::echo_group("", '<strong class="err">You have dropped the course.</strong> If this is incorrect, contact us.');
function save_json($cj, $actor, $send) { global $Conf, $Me, $Now; $inserting = !$this->contactId; $old_roles = $this->roles; $old_email = $this->email; $different_email = strtolower($cj->email) !== strtolower((string) $old_email); $cu = new Contact_Update($inserting, $different_email); $aupapers = null; if ($different_email) { $aupapers = self::email_authored_papers($cj->email, $cj); } // check whether this user is changing themselves $changing_other = false; if (self::contactdb() && $Me && (strcasecmp($this->email, $Me->email) != 0 || $Me->is_actas_user())) { $changing_other = true; } // Main fields foreach (array("firstName", "lastName", "email", "affiliation", "collaborators", "preferredEmail", "country") as $k) { if (isset($cj->{$k})) { $this->_save_assign_field($k, $cj->{$k}, $cu); } } if (isset($cj->phone)) { $this->_save_assign_field("voicePhoneNumber", $cj->phone, $cu); } $this->_save_assign_field("unaccentedName", Text::unaccented_name($this->firstName, $this->lastName), $cu); self::set_sorter($this); // Disabled $disabled = $this->disabled ? 1 : 0; if (isset($cj->disabled)) { $disabled = $cj->disabled ? 1 : 0; } if (($this->disabled ? 1 : 0) !== $disabled || !$this->contactId) { $cu->qv["disabled"] = $this->disabled = $disabled; } // Data $old_datastr = $this->data_str(); $data = (object) array(); foreach (array("address", "city", "state", "zip") as $k) { if (isset($cj->{$k}) && ($x = $cj->{$k})) { while (is_array($x) && $x[count($x) - 1] === "") { array_pop($x); } $data->{$k} = $x ?: null; } } $this->merge_data($data); $datastr = $this->data_str(); if ($datastr !== $old_datastr) { $cu->qv["data"] = $datastr; } // Changes to the above fields also change the updateTime. if (count($cu->qv)) { $cu->qv["updateTime"] = $this->updateTime = $Now; } // Follow if (isset($cj->follow)) { $w = 0; if (get($cj->follow, "reviews")) { $w |= WATCH_COMMENT; } if (get($cj->follow, "allreviews")) { $w |= WATCH_ALLCOMMENTS; } if (get($cj->follow, "allfinal")) { $w |= WATCHTYPE_FINAL_SUBMIT << WATCHSHIFT_ALL; } $this->_save_assign_field("defaultWatch", $w, $cu); } // Tags if (isset($cj->tags)) { $tags = array(); foreach ($cj->tags as $t) { list($tag, $value) = TagInfo::split_index($t); if (strcasecmp($tag, "pc") != 0) { $tags[$tag] = $tag . "#" . ($value ?: 0); } } ksort($tags); $t = count($tags) ? " " . join(" ", $tags) . " " : ""; $this->_save_assign_field("contactTags", $t, $cu); } // If inserting, set initial password and creation time if ($inserting) { $cu->qv["creationTime"] = $this->creationTime = $Now; $this->_create_password(self::contactdb_find_by_email($this->email), $cu); } // Initial save if (count($cu->qv)) { // always true if $inserting $q = ($inserting ? "insert into" : "update") . " ContactInfo set " . join("=?, ", array_keys($cu->qv)) . "=?" . ($inserting ? "" : " where contactId={$this->contactId}"); if (!($result = Dbl::qe_apply($Conf->dblink, $q, array_values($cu->qv)))) { return $result; } if ($inserting) { $this->contactId = $this->cid = (int) $result->insert_id; } Dbl::free($result); } // Topics if (isset($cj->topics)) { $tf = array(); foreach ($cj->topics as $k => $v) { $tf[] = "({$this->contactId},{$k},{$v})"; } $Conf->qe("delete from TopicInterest where contactId={$this->contactId}"); if (count($tf)) { $Conf->qe("insert into TopicInterest (contactId,topicId,interest) values " . join(",", $tf)); } } // Roles $roles = 0; if (isset($cj->roles)) { $roles = self::parse_roles_json($cj->roles); if ($roles !== $old_roles) { $this->save_roles($roles, $actor); } } // Update authorship if ($aupapers) { $this->save_authored_papers($aupapers); } // Update contact database $cdbu = $this->contactDbId ? $this : $this->contactdb_user_; if ($different_email) { $cdbu = null; } if (($cdb = self::contactdb()) && (!$cdbu || count($cu->cdb_uqv))) { $qv = []; if (!$cdbu) { $q = "insert into ContactInfo set firstName=?, lastName=?, email=?, affiliation=?, country=?, collaborators=?"; $qv = array($this->firstName, $this->lastName, $this->email, $this->affiliation, $this->country, $this->collaborators); if ($this->password !== "" && ($this->password[0] !== " " || $this->password[1] === "\$")) { $q .= ", password=?"; $qv[] = $this->password; } $q .= " on duplicate key update "; } else { $q = "update ContactInfo set "; } if (count($cu->cdb_uqv) && $changing_other) { $q .= join(", ", array_map(function ($k) { return "{$k}=if(coalesce({$k},'')='',?,{$k})"; }, array_keys($cu->cdb_uqv))); } else { if (count($cu->cdb_uqv)) { $q .= join("=?, ", array_keys($cu->cdb_uqv)) . "=?"; } else { $q .= "firstName=firstName"; } } if (count($cu->cdb_uqv)) { $q .= ", updateTime={$Now}"; } $qv = array_merge($qv, array_values($cu->cdb_uqv)); if ($cdbu) { $q .= " where contactDbId=" . $cdbu->contactDbId; } $result = Dbl::ql_apply($cdb, $q, $qv); Dbl::free($result); $this->contactdb_user_ = false; } // Password if (isset($cj->new_password)) { $this->change_password(get($cj, "old_password"), $cj->new_password, 0); } // Beware PC cache if (($roles | $old_roles) & Contact::ROLE_PCLIKE) { $Conf->invalidateCaches(array("pc" => 1)); } // Mark creation and activity if ($inserting) { if ($send && !$this->disabled) { $this->sendAccountInfo("create", false); } $type = $this->disabled ? "disabled " : ""; if ($Me && $Me->has_email() && $Me->email !== $this->email) { $Conf->log("Created {$type}account ({$Me->email})", $this); } else { $Conf->log("Created {$type}account", $this); } } $actor = $actor ?: $Me; if ($actor && $this->contactId == $actor->contactId) { $this->mark_activity(); } return true; }
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(); } }
public function save($req, $contact) { global $Conf, $Now; if (is_array($req)) { $req = (object) $req; } $Table = $this->prow->comment_table_name(); $LinkTable = $this->prow->table_name(); $LinkColumn = $this->prow->id_column(); $req_visibility = get($req, "visibility"); $is_response = !!($this->commentType & COMMENTTYPE_RESPONSE); if ($is_response && get($req, "submit")) { $ctype = COMMENTTYPE_RESPONSE | COMMENTTYPE_AUTHOR; } else { if ($is_response) { $ctype = COMMENTTYPE_RESPONSE | COMMENTTYPE_AUTHOR | COMMENTTYPE_DRAFT; } else { if ($req_visibility == "a" || $req_visibility == "au") { $ctype = COMMENTTYPE_AUTHOR; } else { if ($req_visibility == "p" || $req_visibility == "pc") { $ctype = COMMENTTYPE_PCONLY; } else { if ($req_visibility == "admin") { $ctype = COMMENTTYPE_ADMINONLY; } else { if ($this->commentId && $req_visibility === null) { $ctype = $this->commentType; } else { // $req->visibility == "r" || $req->visibility == "rev" $ctype = COMMENTTYPE_REVIEWER; } } } } } } if ($is_response ? $this->prow->blind : $Conf->is_review_blind(!!get($req, "blind"))) { $ctype |= COMMENTTYPE_BLIND; } // tags if ($is_response) { $ctags = " response "; if (($rname = $Conf->resp_round_name($this->commentRound)) != "1") { $ctags .= "{$rname}response "; } } else { if (get($req, "tags") && preg_match_all(',\\S+,', $req->tags, $m)) { $tagger = new Tagger($contact); $ctags = array(); foreach ($m[0] as $text) { if (($text = $tagger->check($text, Tagger::NOVALUE)) && !stri_ends_with($text, "response")) { $ctags[strtolower($text)] = $text; } } $tagger->sort($ctags); $ctags = count($ctags) ? " " . join(" ", $ctags) . " " : null; } else { $ctags = null; } } // notifications $displayed = !($ctype & COMMENTTYPE_DRAFT); // query $text = get_s($req, "text"); $q = ""; $qv = array(); if ($text === "" && $this->commentId) { $change = true; $q = "delete from {$Table} where commentId={$this->commentId}"; } else { if ($text === "") { /* do nothing */ } else { if (!$this->commentId) { $change = true; $qa = ["contactId, {$LinkColumn}, commentType, comment, commentOverflow, timeModified, replyTo"]; $qb = [$contact->contactId, $this->prow->{$LinkColumn}, $ctype, "?", "?", $Now, 0]; if (strlen($text) <= 32000) { array_push($qv, $text, null); } else { array_push($qv, UnicodeHelper::utf8_prefix($text, 200), $text); } if ($ctags !== null) { $qa[] = "commentTags"; $qb[] = "?"; $qv[] = $ctags; } if ($is_response) { $qa[] = "commentRound"; $qb[] = $this->commentRound; } if ($displayed) { $qa[] = "timeDisplayed, timeNotified"; $qb[] = "{$Now}, {$Now}"; } $q = "insert into {$Table} (" . join(", ", $qa) . ") select " . join(", ", $qb) . "\n"; if ($is_response) { // make sure there is exactly one response $q .= " from (select {$LinkTable}.{$LinkColumn}, coalesce(commentId, 0) commentId\n from {$LinkTable}\n left join {$Table} on ({$Table}.{$LinkColumn}={$LinkTable}.{$LinkColumn} and (commentType&" . COMMENTTYPE_RESPONSE . ")!=0 and commentRound={$this->commentRound})\n where {$LinkTable}.{$LinkColumn}={$this->prow->{$LinkColumn}} limit 1) t\n where t.commentId=0"; } } else { $change = $this->commentType >= COMMENTTYPE_AUTHOR != $ctype >= COMMENTTYPE_AUTHOR; if ($this->timeModified >= $Now) { $Now = $this->timeModified + 1; } // do not notify on updates within 3 hours $qa = ""; if ($this->timeNotified + 10800 < $Now || $ctype & COMMENTTYPE_RESPONSE && !($ctype & COMMENTTYPE_DRAFT) && $this->commentType & COMMENTTYPE_DRAFT) { $qa .= ", timeNotified={$Now}"; } // reset timeDisplayed if you change the comment type if ((!$this->timeDisplayed || $this->ordinal_missing($ctype)) && $text !== "" && $displayed) { $qa .= ", timeDisplayed={$Now}"; } $q = "update {$Table} set timeModified={$Now}{$qa}, commentType={$ctype}, comment=?, commentOverflow=?, commentTags=? where commentId={$this->commentId}"; if (strlen($text) <= 32000) { array_push($qv, $text, null); } else { array_push($qv, UnicodeHelper::utf8_prefix($text, 200), $text); } $qv[] = $ctags; } } } $result = Dbl::qe_apply($q, $qv); if (!$result) { return false; } $cmtid = $this->commentId ?: $result->insert_id; if (!$cmtid) { return false; } // log $contact->log_activity("Comment {$cmtid} " . ($text !== "" ? "saved" : "deleted"), $this->prow->{$LinkColumn}); // ordinal if ($text !== "" && $this->ordinal_missing($ctype)) { $this->save_ordinal($cmtid, $ctype, $Table, $LinkTable, $LinkColumn); } // reload if ($text !== "") { $comments = $this->prow->fetch_comments("commentId={$cmtid}"); $this->merge($comments[$cmtid], $this->prow); if ($this->timeNotified == $this->timeModified) { self::$watching = $this; $this->prow->notify(WATCHTYPE_COMMENT, "CommentInfo::watch_callback", $contact); self::$watching = null; } } else { $this->commentId = 0; $this->comment = ""; $this->commentTags = null; } return true; }
static function alltags_api($user, $qreq, $prow) { global $Conf; if (!$user->isPC) { json_exit(["ok" => false]); } $need_paper = $conflict_where = false; $where = $args = array(); if ($user->allow_administer(null)) { $need_paper = true; if ($Conf->has_any_manager() && !$Conf->setting("tag_seeall")) { $conflict_where = "(p.managerContactId=0 or p.managerContactId={$user->contactId} or pc.conflictType is null)"; } } else { if ($Conf->check_track_sensitivity(Track::VIEW)) { $where[] = "t.paperId ?a"; $args[] = $user->list_submitted_papers_with_viewable_tags(); } else { $need_paper = true; if ($Conf->has_any_manager() && !$Conf->setting("tag_seeall")) { $conflict_where = "(p.managerContactId={$user->contactId} or pc.conflictType is null)"; } else { if (!$Conf->setting("tag_seeall")) { $conflict_where = "pc.conflictType is null"; } } } } $q = "select distinct tag from PaperTag t"; if ($need_paper) { $q .= " join Paper p on (p.paperId=t.paperId)"; $where[] = "p.timeSubmitted>0"; } if ($conflict_where) { $q .= " left join PaperConflict pc on (pc.paperId=t.paperId and pc.contactId={$user->contactId})"; $where[] = $conflict_where; } $q .= " where " . join(" and ", $where); $tags = array(); $result = Dbl::qe_apply($q, $args); while ($row = edb_row($result)) { $twiddle = strpos($row[0], "~"); if ($twiddle === false || $twiddle == 0 && $row[0][1] === "~" && $user->privChair) { $tags[] = $row[0]; } else { if ($twiddle > 0 && substr($row[0], 0, $twiddle) == $user->contactId) { $tags[] = substr($row[0], $twiddle); } } } Dbl::free($result); json_exit(["ok" => true, "tags" => $tags]); }