use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\L10n;
+use Friendica\Core\Protocol;
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
+use Friendica\Model\Conversation;
use Friendica\Model\Event;
use Friendica\Model\GContact;
-use Friendica\Model\Group;
use Friendica\Model\Item;
+use Friendica\Model\PermissionSet;
use Friendica\Model\Profile;
use Friendica\Model\User;
use Friendica\Object\Image;
const REPLY = 1; // Regular reply that is stored locally
const REPLY_RC = 2; // Reply that will be relayed
+ /**
+ * @brief Generates an array of contact and user for DFRN imports
+ *
+ * This array contains not only the receiver but also the sender of the message.
+ *
+ * @param integer $cid Contact id
+ * @param integer $uid User id
+ *
+ * @return array importer
+ */
+ public static function getImporter($cid, $uid = 0)
+ {
+ $condition = ['id' => $cid, 'blocked' => false, 'pending' => false];
+ $contact = DBA::selectFirst('contact', [], $condition);
+ if (!DBA::isResult($contact)) {
+ return [];
+ }
+
+ $contact['cpubkey'] = $contact['pubkey'];
+ $contact['cprvkey'] = $contact['prvkey'];
+ $contact['senderName'] = $contact['name'];
+
+ if ($uid != 0) {
+ $condition = ['uid' => $uid, 'account_expired' => false, 'account_removed' => false];
+ $user = DBA::selectFirst('user', [], $condition);
+ if (!DBA::isResult($user)) {
+ return [];
+ }
+
+ $user['importer_uid'] = $user['uid'];
+ $user['uprvkey'] = $user['prvkey'];
+ } else {
+ $user = ['importer_uid' => 0, 'uprvkey' => '', 'timezone' => 'UTC',
+ 'nickname' => '', 'sprvkey' => '', 'spubkey' => '',
+ 'page-flags' => 0, 'account-type' => 0, 'prvnets' => 0];
+ }
+
+ return array_merge($contact, $user);
+ }
+
/**
* @brief Generates the atom entries for delivery.php
*
// default permissions - anonymous user
- $sql_extra = " AND `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' ";
+ $sql_extra = " AND NOT `item`.`private` ";
$r = q(
"SELECT `contact`.*, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`, `user`.`account-type`
$contact = $r[0];
include_once 'include/security.php';
- $groups = Group::getIdsByContactId($contact['id']);
- if (count($groups)) {
- for ($x = 0; $x < count($groups); $x ++) {
- $groups[$x] = '<' . intval($groups[$x]) . '>' ;
- }
+ $set = PermissionSet::get($owner_id, $contact['id']);
- $gs = implode('|', $groups);
+ if (!empty($set)) {
+ $sql_extra = " AND `item`.`psid` IN (" . implode(',', $set) .")";
} else {
- $gs = '<<>>' ; // Impossible to match
- }
-
- $sql_extra = sprintf(
- "
- AND ( `allow_cid` = '' OR `allow_cid` REGEXP '<%d>' )
- AND ( `deny_cid` = '' OR NOT `deny_cid` REGEXP '<%d>' )
- AND ( `allow_gid` = '' OR `allow_gid` REGEXP '%s' )
- AND ( `deny_gid` = '' OR NOT `deny_gid` REGEXP '%s')
- ",
- intval($contact['id']),
- intval($contact['id']),
- DBA::escape($gs),
- DBA::escape($gs)
- );
+ $sql_extra = " AND NOT `item`.`private`";
+ }
}
if ($public_feed) {
foreach ($items as $item) {
// prevent private email from leaking.
- if ($item['network'] == NETWORK_MAIL) {
+ if ($item['network'] == Protocol::MAIL) {
continue;
}
}
// For backward compatibility we keep this element
- if ($owner['page-flags'] == PAGE_COMMUNITY) {
+ if ($owner['page-flags'] == Contact::PAGE_COMMUNITY) {
XML::addElement($doc, $root, "dfrn:community", 1);
}
// The former element is replaced by this one
XML::addElement($doc, $root, "dfrn:account_type", $owner["account-type"]);
- /// @todo We need a way to transmit the different page flags like "PAGE_PRVGROUP"
+ /// @todo We need a way to transmit the different page flags like "Contact::PAGE_PRVGROUP"
XML::addElement($doc, $root, "updated", DateTimeFormat::utcNow(DateTimeFormat::ATOM));
$entry->setAttribute("xmlns:statusnet", NAMESPACE_STATUSNET);
}
- if ($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid']) {
+ if ($item['private']) {
$body = Item::fixPrivatePhotos($item['body'], $owner['uid'], $item, $cid);
} else {
$body = $item['body'];
XML::addElement($doc, $entry, "georss:point", $item['coord']);
}
- if (($item['private']) || strlen($item['allow_cid']) || strlen($item['allow_gid']) || strlen($item['deny_cid']) || strlen($item['deny_gid'])) {
- XML::addElement($doc, $entry, "dfrn:private", (($item['private']) ? $item['private'] : 1));
+ if ($item['private']) {
+ XML::addElement($doc, $entry, "dfrn:private", ($item['private'] ? $item['private'] : 1));
}
if ($item['extid']) {
}
foreach ($mentioned as $mention) {
- $r = q(
- "SELECT `forum`, `prv` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s'",
- intval($owner["uid"]),
- DBA::escape(normalise_link($mention))
- );
+ $condition = ['uid' => $owner["uid"], 'nurl' => normalise_link($mention)];
+ $contact = DBA::selectFirst('contact', ['forum', 'prv'], $condition);
- if (DBA::isResult($r) && ($r[0]["forum"] || $r[0]["prv"])) {
+ if (DBA::isResult($contact) && ($contact["forum"] || $contact["prv"])) {
XML::addElement(
$doc,
$entry,
* @return int Deliver status. Negative values mean an error.
* @todo Add array type-hint for $owner, $contact
*/
- public static function deliver($owner, $contact, $atom, $dissolve = false)
+ public static function deliver($owner, $contact, $atom, $dissolve = false, $legacy_transport = false)
{
$a = get_app();
// At first try the Diaspora transport layer
- $ret = self::transmit($owner, $contact, $atom);
- if ($ret >= 200) {
- logger('Delivery via Diaspora transport layer was successful with status ' . $ret);
- return $ret;
+ if (!$dissolve && !$legacy_transport) {
+ $ret = self::transmit($owner, $contact, $atom);
+ if ($ret >= 200) {
+ logger('Delivery via Diaspora transport layer was successful with status ' . $ret);
+ return $ret;
+ }
}
$idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
$perm = (($res->perm) ? $res->perm : null);
$dfrn_version = (float) (($res->dfrn_version) ? $res->dfrn_version : 2.0);
$rino_remote_version = intval($res->rino);
- $page = (($owner['page-flags'] == PAGE_COMMUNITY) ? 1 : 0);
+ $page = (($owner['page-flags'] == Contact::PAGE_COMMUNITY) ? 1 : 0);
logger("Remote rino version: ".$rino_remote_version." for ".$contact["url"], LOGGER_DEBUG);
- if ($owner['page-flags'] == PAGE_PRVGROUP) {
+ if ($owner['page-flags'] == Contact::PAGE_PRVGROUP) {
$page = 2;
}
$final_dfrn_id = '';
if ($perm) {
- if ((($perm == 'rw') && (! intval($contact['writable'])))
- || (($perm == 'r') && (intval($contact['writable'])))
+ if ((($perm == 'rw') && !intval($contact['writable']))
+ || (($perm == 'r') && intval($contact['writable']))
) {
- q(
- "update contact set writable = %d where id = %d",
- intval(($perm == 'rw') ? 1 : 0),
- intval($contact['id'])
- );
+ DBA::update('contact', ['writable' => ($perm == 'rw')], ['id' => $contact['id']]);
+
$contact['writable'] = (string) 1 - intval($contact['writable']);
}
}
if (($contact['duplex'] && strlen($contact['pubkey']))
- || ($owner['page-flags'] == PAGE_COMMUNITY && strlen($contact['pubkey']))
+ || ($owner['page-flags'] == Contact::PAGE_COMMUNITY && strlen($contact['pubkey']))
|| ($contact['rel'] == Contact::SHARING && strlen($contact['pubkey']))
) {
openssl_public_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['pubkey']);
$postvars['dissolve'] = '1';
}
- if ((($contact['rel']) && ($contact['rel'] != Contact::SHARING) && (! $contact['blocked'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) {
+ if ((($contact['rel']) && ($contact['rel'] != Contact::SHARING) && (! $contact['blocked'])) || ($owner['page-flags'] == Contact::PAGE_COMMUNITY)) {
$postvars['data'] = $atom;
$postvars['perm'] = 'rw';
} else {
$key = openssl_random_pseudo_bytes(16);
$data = self::aesEncrypt($postvars['data'], $key);
break;
+
default:
logger("rino: invalid requested version '$rino_remote_version'");
Contact::markForArchival($contact);
if ($dfrn_version >= 2.1) {
if (($contact['duplex'] && strlen($contact['pubkey']))
- || ($owner['page-flags'] == PAGE_COMMUNITY && strlen($contact['pubkey']))
+ || ($owner['page-flags'] == Contact::PAGE_COMMUNITY && strlen($contact['pubkey']))
|| ($contact['rel'] == Contact::SHARING && strlen($contact['pubkey']))
) {
openssl_public_encrypt($key, $postvars['key'], $contact['pubkey']);
openssl_private_encrypt($key, $postvars['key'], $contact['prvkey']);
}
} else {
- if (($contact['duplex'] && strlen($contact['prvkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) {
+ if (($contact['duplex'] && strlen($contact['prvkey'])) || ($owner['page-flags'] == Contact::PAGE_COMMUNITY)) {
openssl_private_encrypt($key, $postvars['key'], $contact['prvkey']);
} else {
openssl_public_encrypt($key, $postvars['key'], $contact['pubkey']);
private static function birthdayEvent($contact, $birthday)
{
// Check for duplicates
- $r = q(
- "SELECT `id` FROM `event` WHERE `uid` = %d AND `cid` = %d AND `start` = '%s' AND `type` = '%s' LIMIT 1",
- intval($contact['uid']),
- intval($contact['id']),
- DBA::escape(DateTimeFormat::utc($birthday)),
- DBA::escape('birthday')
- );
-
- if (DBA::isResult($r)) {
+ $condition = ['uid' => $contact['uid'], 'cid' => $contact['id'],
+ 'start' => DateTimeFormat::utc($birthday), 'type' => 'birthday'];
+ if (DBA::exists('event', $condition)) {
return;
}
$fields = ['id', 'uid', 'url', 'network', 'avatar-date', 'avatar', 'name-date', 'uri-date', 'addr',
'name', 'nick', 'about', 'location', 'keywords', 'xmpp', 'bdyear', 'bd', 'hidden', 'contact-type'];
$condition = ["`uid` = ? AND `nurl` = ? AND `network` != ?",
- $importer["importer_uid"], normalise_link($author["link"]), NETWORK_STATUSNET];
+ $importer["importer_uid"], normalise_link($author["link"]), Protocol::STATUSNET];
$contact_old = DBA::selectFirst('contact', $fields, $condition);
if (DBA::isResult($contact_old)) {
$author["avatar"] = current($avatarlist);
}
+ if (empty($author['avatar']) && !empty($author['link'])) {
+ $cid = Contact::getIdForURL($author['link'], 0);
+ if (!empty($cid)) {
+ $contact = DBA::selectFirst('contact', ['avatar'], ['id' => $cid]);
+ if (DBA::isResult($contact)) {
+ $author['avatar'] = $contact['avatar'];
+ }
+ }
+ }
+
+ if (empty($author['avatar'])) {
+ logger('Empty author: ' . $xml);
+ }
+
if (DBA::isResult($contact_old) && !$onlyfetch) {
logger("Check if contact details for contact " . $contact_old["id"] . " (" . $contact_old["nick"] . ") have to be updated.", LOGGER_DEBUG);
// Update check for this field has to be done differently
$datefields = ["name-date", "uri-date"];
foreach ($datefields as $field) {
+ // The date fields arrives as '2018-07-17T10:44:45Z' - the database return '2018-07-17 10:44:45'
+ // The fields have to be in the same format to be comparable, since strtotime does add timezones.
+ $contact[$field] = DateTimeFormat::utc($contact[$field]);
+
if (strtotime($contact[$field]) > strtotime($contact_old[$field])) {
logger("Difference for contact " . $contact["id"] . " in field '" . $field . "'. New value: '" . $contact[$field] . "', old value '" . $contact_old[$field] . "'", LOGGER_DEBUG);
$update = true;
DBA::insert('mail', $msg);
+ $msg["id"] = DBA::lastInsertId();
+
// send notifications.
/// @TODO Arange this mess
$notif_params = [
// Does our member already have a friend matching this description?
- $r = q(
- "SELECT `id` FROM `contact` WHERE `name` = '%s' AND `nurl` = '%s' AND `uid` = %d LIMIT 1",
- DBA::escape($suggest["name"]),
- DBA::escape(normalise_link($suggest["url"])),
- intval($suggest["uid"])
- );
-
/*
* The valid result means the friend we're about to send a friend
* suggestion already has them in their contact, which means no further
*
* @see https://github.com/friendica/friendica/pull/3254#discussion_r107315246
*/
- if (DBA::isResult($r)) {
+ $condition = ['name' => $suggest["name"], 'nurl' => normalise_link($suggest["url"]),
+ 'uid' => $suggest["uid"]];
+ if (DBA::exists('contact', $condition)) {
return false;
}
// Do we already have an fcontact record for this person?
$fid = 0;
- $r = q(
- "SELECT `id` FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1",
- DBA::escape($suggest["url"]),
- DBA::escape($suggest["name"]),
- DBA::escape($suggest["request"])
- );
- if (DBA::isResult($r)) {
- $fid = $r[0]["id"];
+ $condition = ['url' => $suggest["url"], 'name' => $suggest["name"], 'request' => $suggest["request"]];
+ $fcontact = DBA::selectFirst('fcontact', ['id'], $condition);
+ if (DBA::isResult($fcontact)) {
+ $fid = $fcontact["id"];
- // OK, we do. Do we already have an introduction for this person ?
- $r = q(
- "SELECT `id` FROM `intro` WHERE `uid` = %d AND `fid` = %d LIMIT 1",
- intval($suggest["uid"]),
- intval($fid)
- );
-
- /*
- * The valid result means the friend we're about to send a friend
- * suggestion already has them in their contact, which means no further
- * action is required.
- *
- * @see https://github.com/friendica/friendica/pull/3254#discussion_r107315246
- */
- if (DBA::isResult($r)) {
+ // OK, we do. Do we already have an introduction for this person?
+ if (DBA::exists('intro', ['uid' => $suggest["uid"], 'fid' => $fid])) {
+ /*
+ * The valid result means the friend we're about to send a friend
+ * suggestion already has them in their contact, which means no further
+ * action is required.
+ *
+ * @see https://github.com/friendica/friendica/pull/3254#discussion_r107315246
+ */
return false;
}
}
DBA::escape($suggest["request"])
);
}
- $r = q(
- "SELECT `id` FROM `fcontact` WHERE `url` = '%s' AND `name` = '%s' AND `request` = '%s' LIMIT 1",
- DBA::escape($suggest["url"]),
- DBA::escape($suggest["name"]),
- DBA::escape($suggest["request"])
- );
+
+ $condition = ['url' => $suggest["url"], 'name' => $suggest["name"], 'request' => $suggest["request"]];
+ $fcontact = DBA::selectFirst('fcontact', ['id'], $condition);
/*
* If no record in fcontact is found, below INSERT statement will not
* link an introduction to it.
*/
- if (!DBA::isResult($r)) {
+ if (!DBA::isResult($fcontact)) {
// Database record did not get created. Quietly give up.
killme();
}
if ($item["parent-uri"] != $item["uri"]) {
$community = false;
- if ($importer["page-flags"] == PAGE_COMMUNITY || $importer["page-flags"] == PAGE_PRVGROUP) {
+ if ($importer["page-flags"] == Contact::PAGE_COMMUNITY || $importer["page-flags"] == Contact::PAGE_PRVGROUP) {
$sql_extra = "";
$community = true;
logger("possible community action");
if ($Blink && link_compare($Blink, System::baseUrl() . "/profile/" . $importer["nickname"])) {
$author = DBA::selectFirst('contact', ['name', 'thumb', 'url'], ['id' => $item['author-id']]);
+ $item['id'] = $posted_id;
+
+ $parent = Item::selectFirst(['id'], ['uri' => $item['parent-uri'], 'uid' => $importer["importer_uid"]]);
+ $item["parent"] = $parent['id'];
+
// send a notification
notification(
[
break;
case "enclosure":
$enclosure = $href;
- if (strlen($item["attach"])) {
+
+ if (!empty($item["attach"])) {
$item["attach"] .= ",";
+ } else {
+ $item["attach"] = "";
}
$item["attach"] .= '[attach]href="' . $href . '" length="' . $length . '" type="' . $type . '" title="' . $title . '"[/attach]';
$item = $header;
- $item["protocol"] = PROTOCOL_DFRN;
+ $item["protocol"] = Conversation::PARCEL_DFRN;
$item["source"] = $xml;
}
// Fetch the owner
- $owner = self::fetchauthor($xpath, $entry, $importer, "dfrn:owner", true);
+ $owner = self::fetchauthor($xpath, $entry, $importer, "dfrn:owner", true, $xml);
$owner_unknown = (isset($owner["contact-unknown"]) && $owner["contact-unknown"]);
+ $item["owner-name"] = $owner["name"];
$item["owner-link"] = $owner["link"];
+ $item["owner-avatar"] = $owner["avatar"];
$item["owner-id"] = Contact::getIdForURL($owner["link"], 0);
// fetch the author
- $author = self::fetchauthor($xpath, $entry, $importer, "atom:author", true);
+ $author = self::fetchauthor($xpath, $entry, $importer, "atom:author", true, $xml);
+ $item["author-name"] = $author["name"];
$item["author-link"] = $author["link"];
+ $item["author-avatar"] = $author["avatar"];
$item["author-id"] = Contact::getIdForURL($author["link"], 0);
$item["title"] = XML::getFirstNodeValue($xpath, "atom:title/text()", $entry);
$ev["guid"] = $item["guid"];
$ev["plink"] = $item["plink"];
- $r = q(
- "SELECT `id` FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
- DBA::escape($item["uri"]),
- intval($importer["importer_uid"])
- );
- if (DBA::isResult($r)) {
- $ev["id"] = $r[0]["id"];
+ $condition = ['uri' => $item["uri"], 'uid' => $importer["importer_uid"]];
+ $event = DBA::selectFirst('event', ['id'], $condition);
+ if (DBA::isResult($event)) {
+ $ev["id"] = $event["id"];
}
$event_id = Event::store($ev);
$header = [];
$header["uid"] = $importer["importer_uid"];
- $header["network"] = NETWORK_DFRN;
+ $header["network"] = Protocol::DFRN;
$header["wall"] = 0;
$header["origin"] = 0;
$header["contact-id"] = $importer["id"];
DBA::update('contact', ['contact-type' => $accounttype], ['id' => $importer["id"]]);
}
// A forum contact can either have set "forum" or "prv" - but not both
- if (($accounttype == ACCOUNT_TYPE_COMMUNITY) && (($forum != $importer["forum"]) || ($forum == $importer["prv"]))) {
+ if (($accounttype == Contact::ACCOUNT_TYPE_COMMUNITY) && (($forum != $importer["forum"]) || ($forum == $importer["prv"]))) {
$condition = ['(`forum` != ? OR `prv` != ?) AND `id` = ?', $forum, !$forum, $importer["id"]];
DBA::update('contact', ['forum' => $forum, 'prv' => !$forum], $condition);
}
$r = q("SELECT * FROM contact WHERE nick = '%s'
AND network = '%s' AND uid = %d AND url LIKE '%%%s%%' LIMIT 1",
DBA::escape($contact_nick),
- DBA::escape(NETWORK_DFRN),
+ DBA::escape(Protocol::DFRN),
intval(local_user()),
DBA::escape($baseurl)
);
return false;
}
- $u = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
- intval($uid)
- );
- if (!DBA::isResult($u)) {
+ $user = DBA::selectFirst('user', ['page-flags', 'nickname'], ['uid' => $uid]);
+ if (!DBA::isResult($user)) {
return false;
}
- $community_page = ($u[0]['page-flags'] == PAGE_COMMUNITY);
- $prvgroup = ($u[0]['page-flags'] == PAGE_PRVGROUP);
+ $community_page = ($user['page-flags'] == Contact::PAGE_COMMUNITY);
+ $prvgroup = ($user['page-flags'] == Contact::PAGE_PRVGROUP);
- $link = normalise_link(System::baseUrl() . '/profile/' . $u[0]['nickname']);
+ $link = normalise_link(System::baseUrl() . '/profile/' . $user['nickname']);
/*
* Diaspora uses their own hardwired link URL in @-tags
* instead of the one we supply with webfinger
*/
- $dlink = normalise_link(System::baseUrl() . '/u/' . $u[0]['nickname']);
+ $dlink = normalise_link(System::baseUrl() . '/u/' . $user['nickname']);
$cnt = preg_match_all('/[\@\!]\[url\=(.*?)\](.*?)\[\/url\]/ism', $item['body'], $matches, PREG_SET_ORDER);
if ($cnt) {