]> git.mxchange.org Git - friendica.git/blobdiff - src/Protocol/DFRN.php
Fetch more comtact data from probing, remove duplicated contacts
[friendica.git] / src / Protocol / DFRN.php
index fe2a608ec6fd0358fd94757e08ae0f6e471dfe81..5fceab3264d7ab9cc70056c7db2486db4c991124 100644 (file)
@@ -257,7 +257,7 @@ class DFRN
                        STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
                        WHERE `item`.`uid` = %d AND `item`.`wall` AND `item`.`changed` > '%s'
                        AND `item`.`visible` $sql_extra
-                       ORDER BY `item`.`parent` ".$sort.", `item`.`created` ASC LIMIT 0, 300",
+                       ORDER BY `item`.`parent` ".$sort.", `item`.`received` ASC LIMIT 0, 300",
                        intval($owner_id),
                        DBA::escape($check_date),
                        DBA::escape($sort)
@@ -1176,23 +1176,13 @@ class DFRN
         * @param string $atom     Content that will be transmitted
         * @param bool   $dissolve (to be documented)
         *
-        * @param bool   $legacy_transport
         * @return int Deliver status. Negative values mean an error.
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         * @throws \ImagickException
         * @todo  Add array type-hint for $owner, $contact
         */
-       public static function deliver($owner, $contact, $atom, $dissolve = false, $legacy_transport = false)
+       public static function deliver($owner, $contact, $atom, $dissolve = false)
        {
-               // At first try the Diaspora transport layer
-               if (!$dissolve && !$legacy_transport) {
-                       $curlResult = self::transmit($owner, $contact, $atom);
-                       if ($curlResult >= 200) {
-                               Logger::log('Delivery via Diaspora transport layer was successful with status ' . $curlResult);
-                               return $curlResult;
-                       }
-               }
-
                $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
 
                if ($contact['duplex'] && $contact['dfrn-id']) {
@@ -1465,6 +1455,11 @@ class DFRN
 
                $dest_url = ($public_batch ? $contact["batch"] : $contact["notify"]);
 
+               if (empty($dest_url)) {
+                       Logger::info('Empty destination', ['public' => $public_batch, 'contact' => $contact]);
+                       return -24;
+               }
+
                $content_type = ($public_batch ? "application/magic-envelope+xml" : "application/json");
 
                $postResult = Network::post($dest_url, $envelope, ["Content-Type: ".$content_type]);
@@ -1694,64 +1689,26 @@ class DFRN
                                Event::createBirthday($contact, $birthday);
                        }
 
-                       // Get all field names
-                       $fields = [];
-                       foreach ($contact_old as $field => $data) {
-                               $fields[$field] = $data;
-                       }
+                       $fields = ['name' => $contact['name'], 'nick' => $contact['nick'], 'about' => $contact['about'],
+                               'location' => $contact['location'], 'addr' => $contact['addr'], 'keywords' => $contact['keywords'],
+                               'bdyear' => $contact['bdyear'], 'bd' => $contact['bd'], 'hidden' => $contact['hidden'],
+                               'xmpp' => $contact['xmpp'], 'name-date' => DateTimeFormat::utc($contact['name-date']),
+                               'unsearchable' => $contact['hidden'], 'uri-date' => DateTimeFormat::utc($contact['uri-date'])];
 
-                       unset($fields["id"]);
-                       unset($fields["uid"]);
-                       unset($fields["url"]);
-                       unset($fields["avatar-date"]);
-                       unset($fields["avatar"]);
-                       unset($fields["name-date"]);
-                       unset($fields["uri-date"]);
+                       DBA::update('contact', $fields, ['id' => $contact['id'], 'network' => $contact['network']], $contact_old);
 
-                       $update = false;
-                       // 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]);
+                       // Update the public contact. Don't set the "hidden" value, this is used differently for public contacts
+                       unset($fields['hidden']);
+                       $condition = ['uid' => 0, 'nurl' => Strings::normaliseLink($contact_old['url'])];
+                       DBA::update('contact', $fields, $condition, true);
 
-                               if (strtotime($contact[$field]) > strtotime($contact_old[$field])) {
-                                       Logger::log("Difference for contact " . $contact["id"] . " in field '" . $field . "'. New value: '" . $contact[$field] . "', old value '" . $contact_old[$field] . "'", Logger::DEBUG);
-                                       $update = true;
-                               }
-                       }
+                       Contact::updateAvatar($author['avatar'], $importer['importer_uid'], $contact['id']);
 
-                       foreach ($fields as $field => $data) {
-                               if ($contact[$field] != $contact_old[$field]) {
-                                       Logger::log("Difference for contact " . $contact["id"] . " in field '" . $field . "'. New value: '" . $contact[$field] . "', old value '" . $contact_old[$field] . "'", Logger::DEBUG);
-                                       $update = true;
-                               }
+                       $pcid = Contact::getIdForURL($contact_old['url']);
+                       if (!empty($pcid)) {
+                               Contact::updateAvatar($author['avatar'], 0, $pcid);
                        }
 
-                       if ($update) {
-                               Logger::log("Update contact data for contact " . $contact["id"] . " (" . $contact["nick"] . ")", Logger::DEBUG);
-
-                               q(
-                                       "UPDATE `contact` SET `name` = '%s', `nick` = '%s', `about` = '%s', `location` = '%s',
-                                       `addr` = '%s', `keywords` = '%s', `bdyear` = '%s', `bd` = '%s', `hidden` = %d,
-                                       `xmpp` = '%s', `name-date`  = '%s', `uri-date` = '%s'
-                                       WHERE `id` = %d AND `network` = '%s'",
-                                       DBA::escape($contact["name"]), DBA::escape($contact["nick"]), DBA::escape($contact["about"]),   DBA::escape($contact["location"]),
-                                       DBA::escape($contact["addr"]), DBA::escape($contact["keywords"]), DBA::escape($contact["bdyear"]),
-                                       DBA::escape($contact["bd"]), intval($contact["hidden"]), DBA::escape($contact["xmpp"]),
-                                       DBA::escape(DateTimeFormat::utc($contact["name-date"])), DBA::escape(DateTimeFormat::utc($contact["uri-date"])),
-                                       intval($contact["id"]), DBA::escape($contact["network"])
-                               );
-                       }
-
-                       Contact::updateAvatar(
-                               $author['avatar'],
-                               $importer['importer_uid'],
-                               $contact['id'],
-                               (strtotime($contact['avatar-date']) > strtotime($contact_old['avatar-date']) || ($author['avatar'] != $contact_old['avatar']))
-                       );
-
                        /*
                         * The generation is a sign for the reliability of the provided data.
                         * It is used in the socgraph.php to prevent that old contact data
@@ -2216,11 +2173,10 @@ class DFRN
        {
                Logger::log("Process verb ".$item["verb"]." and object-type ".$item["object-type"]." for entrytype ".$entrytype, Logger::DEBUG);
 
-               if (($entrytype == DFRN::TOP_LEVEL)) {
+               if (($entrytype == DFRN::TOP_LEVEL) && !empty($importer['id'])) {
                        // The filling of the the "contact" variable is done for legcy reasons
                        // The functions below are partly used by ostatus.php as well - where we have this variable
-                       $r = q("SELECT * FROM `contact` WHERE `id` = %d", intval($importer["id"]));
-                       $contact = $r[0];
+                       $contact = Contact::select([], ['id' => $importer['id']]);
 
                        // Big question: Do we need these functions? They were part of the "consume_feed" function.
                        // This function once was responsible for DFRN and OStatus.
@@ -2900,7 +2856,12 @@ class DFRN
        {
                // prevent looping
                if (!empty($_REQUEST['redir'])) {
-                       return;
+                       Logger::log('autoRedir might be looping because redirect has been redirected', Logger::DEBUG);
+                       // looping prevention also appears to sometimes prevent authentication for images
+                       // because browser may have multiple connections open and load an image on a connection
+                       // whose session wasn't updated when a previous redirect authenticated
+                       // Leaving commented in case looping reappears
+                       //return;
                }
 
                if ((! $contact_nick) || ($contact_nick === $a->user['nickname'])) {
@@ -2924,6 +2885,9 @@ class DFRN
                        $baseurl = substr($baseurl, $domain_st + 3);
                        $nurl = Strings::normaliseLink($baseurl);
 
+                       $r = User::getByNickname($contact_nick, ["uid"]);
+                       $contact_uid = $r["uid"];
+
                        /// @todo Why is there a query for "url" *and* "nurl"? Especially this normalising is strange.
                        $r = q("SELECT `id` FROM `contact` WHERE `uid` = (SELECT `uid` FROM `user` WHERE `nickname` = '%s' LIMIT 1)
                                        AND `nick` = '%s' AND NOT `self` AND (`url` LIKE '%%%s%%' OR `nurl` LIKE '%%%s%%') AND NOT `blocked` AND NOT `pending` LIMIT 1",
@@ -2932,9 +2896,19 @@ class DFRN
                                DBA::escape($baseurl),
                                DBA::escape($nurl)
                        );
-                       if ((! DBA::isResult($r)) || $r[0]['id'] == remote_user()) {
+                       if ((! DBA::isResult($r))) {
                                return;
                        }
+                       // test if redirect authentication already succeeded
+                       // Note that "contact" in the sense used in the $contact_nick argument to this function
+                       // and the sense in the $remote[]["cid"] in the session are opposite.
+                       // In the session variable the user currently fetching is the contact
+                       // while $contact_nick is the nick of tho user who owns the stuff being fetched.
+                       foreach (\Friendica\Core\Session::get('remote', []) as $visitor) {
+                               if ($visitor['uid'] == $contact_uid && $visitor['cid'] == $r[0]['id']) {
+                                       return;
+                               }
+                       }
 
                        $r = q("SELECT * FROM contact WHERE nick = '%s'
                                        AND network = '%s' AND uid = %d  AND url LIKE '%%%s%%' LIMIT 1",