-- ------------------------------------------
--- Friendica 2021.09-dev (Siberian Iris)
--- DB_UPDATE_VERSION 1434
+-- Friendica 2021.09-rc (Siberian Iris)
+-- DB_UPDATE_VERSION 1435
-- ------------------------------------------
CREATE TABLE IF NOT EXISTS `user-contact` (
`cid` int unsigned NOT NULL DEFAULT 0 COMMENT 'Contact id of the linked public contact',
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'User id',
+ `uri-id` int unsigned COMMENT 'Id of the item-uri table entry that contains the contact url',
`blocked` boolean COMMENT 'Contact is completely blocked for this user',
`ignored` boolean COMMENT 'Posts from this contact are ignored',
`collapsed` boolean COMMENT 'Posts from this contact are collapsed',
PRIMARY KEY(`uid`,`cid`),
INDEX `cid` (`cid`),
+ UNIQUE INDEX `uri-id_uid` (`uri-id`,`uid`),
FOREIGN KEY (`cid`) REFERENCES `contact` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
- FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
+ FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE,
+ FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='User specific public contact data';
--
Fields
------
-| Field | Description | Type | Null | Key | Default | Extra |
-| --------- | ------------------------------------------- | ------------------ | ---- | --- | ------- | ----- |
-| cid | Contact id of the linked public contact | int unsigned | NO | PRI | 0 | |
-| uid | User id | mediumint unsigned | NO | PRI | 0 | |
-| blocked | Contact is completely blocked for this user | boolean | YES | | NULL | |
-| ignored | Posts from this contact are ignored | boolean | YES | | NULL | |
-| collapsed | Posts from this contact are collapsed | boolean | YES | | NULL | |
+| Field | Description | Type | Null | Key | Default | Extra |
+| --------- | ------------------------------------------------------------ | ------------------ | ---- | --- | ------- | ----- |
+| cid | Contact id of the linked public contact | int unsigned | NO | PRI | 0 | |
+| uid | User id | mediumint unsigned | NO | PRI | 0 | |
+| uri-id | Id of the item-uri table entry that contains the contact url | int unsigned | YES | | NULL | |
+| blocked | Contact is completely blocked for this user | boolean | YES | | NULL | |
+| ignored | Posts from this contact are ignored | boolean | YES | | NULL | |
+| collapsed | Posts from this contact are collapsed | boolean | YES | | NULL | |
Indexes
------------
-| Name | Fields |
-| ------- | -------- |
-| PRIMARY | uid, cid |
-| cid | cid |
+| Name | Fields |
+| ---------- | ------------------- |
+| PRIMARY | uid, cid |
+| cid | cid |
+| uri-id_uid | UNIQUE, uri-id, uid |
Foreign Keys
------------
|-------|--------------|--------------|
| cid | [contact](help/database/db_contact) | id |
| uid | [user](help/database/db_user) | uid |
+| uri-id | [item-uri](help/database/db_item-uri) | id |
Return to [database documentation](help/database)
* @param array $fields field array
* @param int $duplicate_mode Do an update on a duplicate entry
*
- * @return boolean was the insert successful?
+ * @return int id of the created contact
* @throws \Exception
*/
public static function insert(array $fields, int $duplicate_mode = Database::INSERT_DEFAULT)
$fields['created'] = DateTimeFormat::utcNow();
}
- $ret = DBA::insert('contact', $fields, $duplicate_mode);
- $contact = DBA::selectFirst('contact', ['nurl', 'uid'], ['id' => DBA::lastInsertId()]);
+ DBA::insert('contact', $fields, $duplicate_mode);
+ $contact = DBA::selectFirst('contact', [], ['id' => DBA::lastInsertId()]);
if (!DBA::isResult($contact)) {
// Shouldn't happen
- return $ret;
+ Logger::warning('Created contact could not be found', ['fields' => $fields]);
+ return 0;
}
+ Contact\User::insertForContactArray($contact);
+
// Search for duplicated contacts and get rid of them
- self::removeDuplicates($contact['nurl'], $contact['uid']);
+ if (!$contact['self']) {
+ self::removeDuplicates($contact['nurl'], $contact['uid']);
+ }
- return $ret;
+ return $contact['id'];
}
/**
// Only create the entry if it doesn't exist yet
if (!DBA::exists('contact', ['uid' => $uid, 'self' => true])) {
- $return = DBA::insert('contact', $contact);
+ $return = (bool)self::insert($contact);
}
// Create the public contact
$contact['uid'] = 0;
$contact['prvkey'] = null;
- DBA::insert('contact', $contact, Database::INSERT_IGNORE);
+ self::insert($contact, Database::INSERT_IGNORE);
}
return $return;
$contact_id = $contact['id'];
Logger::notice('Contact had been created (shortly) before', ['id' => $contact_id, 'url' => $url, 'uid' => $uid]);
} else {
- DBA::insert('contact', $fields);
- $contact_id = DBA::lastInsertId();
+ $contact_id = self::insert($fields);
if ($contact_id) {
Logger::info('Contact inserted', ['id' => $contact_id, 'url' => $url, 'uid' => $uid]);
}
*/
public static function removeDuplicates(string $nurl, int $uid)
{
- $condition = ['nurl' => $nurl, 'uid' => $uid, 'deleted' => false, 'network' => Protocol::FEDERATED];
+ $condition = ['nurl' => $nurl, 'uid' => $uid, 'self' => false, 'deleted' => false, 'network' => Protocol::FEDERATED];
$count = DBA::count('contact', $condition);
if ($count <= 1) {
return false;
$probed = false;
$ret = $arr['contact'];
} else {
- $probed = true;
+ $probed = true;
$ret = Probe::uri($url, $network, $uid);
}
}
// create contact record
- DBA::insert('contact', [
+ $contact_id = self::insert([
'uid' => $importer['uid'],
'created' => DateTimeFormat::utcNow(),
'url' => $url,
'writable' => 1,
]);
- $contact_id = DBA::lastInsertId();
-
// Ensure to always have the correct network type, independent from the connection request method
self::updateFromProbe($contact_id);
namespace Friendica\Model\Contact;
+use Friendica\Core\Logger;
+use Friendica\Core\System;
+use Friendica\Database\Database;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
+use Friendica\Model\ItemURI;
/**
* This class provides information about user related contacts based on the "user-contact" table.
*/
class User
{
+ /**
+ * Insert a user-contact for a given contact array
+ *
+ * @param array $contact
+ * @return void
+ */
+ public static function insertForContactArray(array $contact)
+ {
+ if (!isset($contact['uid']) || (empty($contact['uri-id']) && empty($contact['url']))) {
+ Logger::info('Missing contact details', ['contact' => $contact, 'callstack' => System::callstack(20)]);
+ return false;
+ }
+
+ if (empty($contact['uri-id'])) {
+ $contact['uri-id'] = ItemURI::getIdByURI($contact['url']);
+ }
+
+ $pcontact = Contact::selectFirst(['id'], ['uri-id' => $contact['uri-id'], 'uid' => 0]);
+ if (!DBA::isResult($pcontact)) {
+ Logger::info('Public contact for user not found', ['uri-id' => $contact['uri-id'], 'uid' => $contact['uid'], 'cid' => $pcontact['id']]);
+ return false;
+ }
+
+ $fields = [
+ 'cid' => $pcontact['id'],
+ 'uid' => $contact['uid'],
+ 'uri-id' => $contact['uri-id'],
+ 'blocked' => $contact['blocked'] ?? false,
+ 'ignored' => $contact['readonly'] ?? false,
+ ];
+
+ $ret = DBA::insert('user-contact', $fields, Database::INSERT_IGNORE);
+
+ Logger::info('Inserted user contact', ['uid' => $contact['uid'], 'cid' => $pcontact['id'], 'uri-id' => $contact['uri-id'], 'ret' => $ret]);
+
+ return $ret;
+ }
+
/**
* Block contact id for user id
*
$system['closeness'] = 0;
$system['baseurl'] = DI::baseUrl();
$system['gsid'] = GServer::getID($system['baseurl']);
- DBA::insert('contact', $system);
+ Contact::insert($system);
}
/**
/**
* Check if the given user id has delegations or is delegated
*
- * @param int $uid
- * @return bool
+ * @param int $uid
+ * @return bool
*/
public static function hasIdentities(int $uid):bool
{
AND NOT EXISTS(SELECT `external-id` FROM `post-user` WHERE `external-id` = `item-uri`.`id`)
AND NOT EXISTS(SELECT `uri-id` FROM `mail` WHERE `uri-id` = `item-uri`.`id`)
AND NOT EXISTS(SELECT `uri-id` FROM `event` WHERE `uri-id` = `item-uri`.`id`)
+ AND NOT EXISTS(SELECT `uri-id` FROM `user-contact` WHERE `uri-id` = `item-uri`.`id`)
AND NOT EXISTS(SELECT `uri-id` FROM `contact` WHERE `uri-id` = `item-uri`.`id`)
AND NOT EXISTS(SELECT `uri-id` FROM `apcontact` WHERE `uri-id` = `item-uri`.`id`)
AND NOT EXISTS(SELECT `uri-id` FROM `fcontact` WHERE `uri-id` = `item-uri`.`id`)
use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) {
- define('DB_UPDATE_VERSION', 1434);
+ define('DB_UPDATE_VERSION', 1435);
}
return [
"fields" => [
"cid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "primary" => "1", "foreign" => ["contact" => "id"], "comment" => "Contact id of the linked public contact"],
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "primary" => "1", "foreign" => ["user" => "uid"], "comment" => "User id"],
+ "uri-id" => ["type" => "int unsigned", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the contact url"],
"blocked" => ["type" => "boolean", "comment" => "Contact is completely blocked for this user"],
"ignored" => ["type" => "boolean", "comment" => "Posts from this contact are ignored"],
"collapsed" => ["type" => "boolean", "comment" => "Posts from this contact are collapsed"]
"indexes" => [
"PRIMARY" => ["uid", "cid"],
"cid" => ["cid"],
+ "uri-id_uid" => ["UNIQUE", "uri-id", "uid"],
]
],
"worker-ipc" => [