define('FRIENDICA_CODENAME', 'Asparagus');
define('FRIENDICA_VERSION', '3.6-dev');
define('DFRN_PROTOCOL_VERSION', '2.23');
-define('DB_UPDATE_VERSION', 1240);
+define('DB_UPDATE_VERSION', 1241);
define('NEW_UPDATE_ROUTINE_VERSION', 1170);
/**
-- ------------------------------------------
-- Friendica 3.6-dev (Asparagus)
--- DB_UPDATE_VERSION 1239
+-- DB_UPDATE_VERSION 1241
-- ------------------------------------------
--
CREATE TABLE IF NOT EXISTS `oembed` (
`url` varbinary(255) NOT NULL,
+ `maxwidth` int(11) NOT NULL,
`content` mediumtext,
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
- PRIMARY KEY(`url`),
+ PRIMARY KEY(`url`,`maxwidth`),
INDEX `created` (`created`)
) DEFAULT COLLATE utf8mb4_general_ci;
INDEX `created` (`created`)
) DEFAULT COLLATE utf8mb4_general_ci;
+--
+-- TABLE participation
+--
+CREATE TABLE IF NOT EXISTS `participation` (
+ `iid` int(10) unsigned NOT NULL,
+ `server` varchar(60) NOT NULL,
+ `cid` int(10) unsigned NOT NULL,
+ PRIMARY KEY(`iid`,`server`)
+) DEFAULT COLLATE utf8mb4_general_ci;
+
--
-- TABLE pconfig
--
| [notify-threads](help/database/db_notify-threads) | |
| [oembed](help/database/db_oembed) | cache for OEmbed queries |
| [parsed_url](help/database/db_parsed_url) | cache for "parse_url" queries |
+| [participation](help/database/db_participation) | Storage for participation messages from Diaspora |
| [pconfig](help/database/db_pconfig) | personal (per user) configuration storage |
| [photo](help/database/db_photo) | photo storage |
| [poll](help/database/db_poll) | data for polls |
--- /dev/null
+Table participation
+===================
+
+| Field | Description | Type | Null | Key | Default | Extra |
+|-------------|------------------|------------------|------|-----|---------------------|-------|
+| iid | item id | int(10) unsigned | NO | PRI | | |
+| server | Name of server | varchar(60) | NO | PRI | | |
+| cid | contact id | int(10) unsigned | NO | | | |
+
+Return to [database documentation](help/database)
"created" => array("created"),
)
);
+ $database["participation"] = array(
+ "fields" => array(
+ "iid" => array("type" => "int(10) unsigned", "not null" => "1", "primary" => "1", "relation" => array("item" => "id")),
+ "server" => array("type" => "varchar(60)", "not null" => "1", "primary" => "1"),
+ "cid" => array("type" => "int(10) unsigned", "not null" => "1", "relation" => array("contact" => "id")),
+ ),
+ "indexes" => array(
+ "PRIMARY" => array("iid", "server")
+ )
+ );
$database["pconfig"] = array(
"fields" => array(
"id" => array("type" => "int(11)", "not null" => "1", "extra" => "auto_increment", "primary" => "1"),
return $relay;
}
+ /**
+ * @brief Return a list of participating contacts for a thread
+ *
+ * This is used for the participation feature.
+ * One of the parameters is a contact array.
+ * This is done to avoid duplicates.
+ *
+ * @param integer $thread The id of the thread
+ * @param array $contacts The previously fetched contacts
+ *
+ * @return array of relay servers
+ */
+ public static function participantsForThread($thread, $contacts)
+ {
+ $r = dba::p("SELECT `contact`.`batch`, `contact`.`id`, `contact`.`name`, `contact`.`network`,
+ `fcontact`.`batch` AS `fbatch`, `fcontact`.`network` AS `fnetwork` FROM `participation`
+ INNER JOIN `contact` ON `contact`.`id` = `participation`.`cid`
+ LEFT JOIN `fcontact` ON `fcontact`.`url` = `contact`.`url`
+ WHERE `participation`.`iid` = ?", $thread);
+
+ while ($contact = dba::fetch($r)) {
+ if (!empty($contact['fnetwork'])) {
+ $contact['network'] = $contact['fnetwork'];
+ }
+ unset($contact['fnetwork']);
+
+ if (empty($contact['batch']) && !empty($contact['fbatch'])) {
+ $contact['batch'] = $contact['fbatch'];
+ }
+ unset($contact['fbatch']);
+
+ $exists = false;
+ foreach ($contacts as $entry) {
+ if ($entry['batch'] == $contact['batch']) {
+ $exists = true;
+ }
+ }
+
+ if (!$exists) {
+ $contacts[] = $contact;
+ }
+ }
+ dba::close($r);
+
+ return $contacts;
+ }
+
/**
* @brief repairs a signature that was double encoded
*
case "message":
return self::receiveMessage($importer, $fields);
- case "participation": // Not implemented
+ case "participation":
return self::receiveParticipation($importer, $fields);
case "photo": // Not implemented
*/
private static function receiveParticipation($importer, $data)
{
- // I'm not sure if we can fully support this message type
+ $author = strtolower(notags(unxmlify($data->author)));
+ $parent_guid = notags(unxmlify($data->parent_guid));
+
+ $contact_id = Contact::getIdForURL($author);
+ if (!$contact_id) {
+ logger('Author not found: '.$author);
+ return false;
+ }
+
+ $item = dba::selectFirst('item', ['id'], ['guid' => $parent_guid, 'origin' => true, 'private' => false]);
+ if (!DBM::is_result($item)) {
+ logger('Item not found: '.$parent_guid);
+ return false;
+ }
+
+ $author_parts = explode('@', $author);
+ if (isset($author_parts[1])) {
+ $server = $author_parts[1];
+ } else {
+ // Should never happen
+ $server = $author;
+ }
+
+ logger('Received participation for ID: '.$item['id'].' - Contact: '.$contact_id.' - Server: '.$server);
+ dba::insert('participation', ['item' => $item['id'], 'contact' => $contact_id, 'server' => $server]);
+
return true;
}
intval($owner['uid']),
intval(CONTACT_IS_SHARING)
);
+
+ // Fetch the participation list
+ // The function will ensure that there are no duplicates
+ $r1 = Diaspora::participantsForThread($item_id, $r1);
+
}
$r2 = q("SELECT `id`, `name`,`network` FROM `contact`
intval(CONTACT_IS_SHARING)
);
- $r = array_merge($r2,$r1,$r0);
+
+ $r = array_merge($r2, $r1, $r0);
if (DBM::is_result($r)) {
logger('pubdeliver '.$target_item["guid"].': '.print_r($r,true), LOGGER_DEBUG);