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; }
private function invariantq($q, $args = []) { $result = Dbl::ql_apply($this->dblink, $q, $args); if ($result) { self::$invariant_row = $result->fetch_row(); $result->close(); return !!self::$invariant_row; } else { return null; } }