]> git.mxchange.org Git - friendica.git/blobdiff - src/Model/Contact.php
Added post update to remove duplicated contacts
[friendica.git] / src / Model / Contact.php
index 4d9260d3e9a81c0096bb2a0cf1e89cdd3ef311d3..5613dc396bf7508ba90f6a183cb0f685c0812fdc 100644 (file)
@@ -136,6 +136,66 @@ class Contact extends BaseObject
                return $contact;
        }
 
+       /**
+        * @brief Insert a row into the contact table
+        *
+        * @param array        $param               parameter array
+        * @param bool         $on_duplicate_update Do an update on a duplicate entry
+        *
+        * @return boolean was the insert successful?
+        * @throws \Exception
+        */
+       public static function insert($param, $on_duplicate_update = false)
+       {
+               $ret = DBA::insert('contact', $param, $on_duplicate_update);
+
+               $contact = DBA::selectFirst('contact', ['nurl', 'uid', 'id'], ['id' => DBA::lastInsertId()]);
+               if (!DBA::isResult($contact)) {
+                       // Shouldn't happen
+                       return $ret;
+               }
+
+               // Search for duplicated contacts and get rid of them
+               self::handleDuplicates($contact['nurl'], $contact['uid'], $contact['id']);
+
+               return $ret;
+       }
+
+       /**
+        * @param array         $fields     contains the fields that are updated
+        * @param array         $condition  condition array with the key values
+        * @param array|boolean $old_fields array with the old field values that are about to be replaced (true = update on duplicate)
+        *
+        * @return boolean was the update successfull?
+        * @throws \Exception
+        */
+       public static function update($fields, $condition, $old_fields = [])
+       {
+               $ret = DBA::update('contact', $fields, $condition, $old_fields);
+
+               // We quit when the update affected more than one row
+               if (DBA::affectedRows() > 1) {
+                       return $ret;
+               }
+
+               // Don't proceed when the command aboved queried more than one row
+               // This is not a duplicate of the test above since that only checked for affected rows
+               if (DBA::count('contact', $condition) != 1) {
+                       return $ret;
+               }
+
+               $contact = DBA::selectFirst('contact', ['nurl', 'uid', 'id'], $condition);
+               if (!DBA::isResult($contact)) {
+                       // Shouldn't happen
+                       return $ret;
+               }
+
+               // Search for duplicated contacts and get rid of them
+               self::handleDuplicates($contact['nurl'], $contact['uid'], $contact['id']);
+
+               return $ret;
+       }
+
        /**
         * @param integer $id     Contact ID
         * @param array   $fields Array of selected fields, empty for all
@@ -1564,35 +1624,38 @@ class Contact extends BaseObject
         * @return boolean Is the contact archived?
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public static function isArchived($cid)
+       public static function isArchived(int $cid)
        {
                if ($cid == 0) {
                        return false;
                }
 
-               $archived = DBA::selectFirst('contact', ['archive', 'url'], ['id' => $cid]);
-               if (!DBA::isResult($archived)) {
+               $contact = DBA::selectFirst('contact', ['archive', 'url', 'batch'], ['id' => $cid]);
+               if (!DBA::isResult($contact)) {
                        return false;
                }
 
-               if ($archived['archive']) {
+               if ($contact['archive']) {
                        return true;
                }
 
-               $apcontact = APContact::getByURL($archived['url'], false);
-               if (empty($apcontact)) {
-                       return false;
-               }
+               // Check status of ActivityPub endpoints
+               $apcontact = APContact::getByURL($contact['url'], false);
+               if (!empty($apcontact)) {
+                       if (!empty($apcontact['inbox']) && DBA::exists('inbox-status', ['archive' => true, 'url' => $apcontact['inbox']])) {
+                               return true;
+                       }
 
-               if (!empty($apcontact['inbox']) && DBA::exists('inbox-status', ['archive' => true, 'url' => $apcontact['inbox']])) {
-                       return true;
+                       if (!empty($apcontact['sharedinbox']) && DBA::exists('inbox-status', ['archive' => true, 'url' => $apcontact['sharedinbox']])) {
+                               return true;
+                       }
                }
 
-               if (!empty($apcontact['sharedinbox']) && DBA::exists('inbox-status', ['archive' => true, 'url' => $apcontact['sharedinbox']])) {
-                       return true;
-               }
+               // Check status of Diaspora endpoints
+               if (!empty($contact['batch'])) {
+                       return DBA::exists('contact', ['archive' => true, 'batch' => $contact['batch'], 'contact-type' => self::TYPE_RELAY]);
+                }
 
-               /// @todo Add tests for Diaspora endpoints as well
                return false;
        }
 
@@ -1835,13 +1898,19 @@ class Contact extends BaseObject
         /**
         * @brief Helper function for "updateFromProbe". Updates personal and public contact
         *
-        * @param array $contact The personal contact entry
-        * @param array $fields  The fields that are updated
+        * @param integer $id      contact id
+        * @param integer $uid     user id
+        * @param string  $url     The profile URL of the contact
+        * @param array   $fields  The fields that are updated
+        *
         * @throws \Exception
         */
        private static function updateContact($id, $uid, $url, array $fields)
        {
-               DBA::update('contact', $fields, ['id' => $id]);
+               if (!DBA::update('contact', $fields, ['id' => $id])) {
+                       Logger::info('Couldn\'t update contact.', ['id' => $id, 'fields' => $fields]);
+                       return;
+               }
 
                // Search for duplicated contacts and get rid of them
                if (self::handleDuplicates(Strings::normaliseLink($url), $uid, $id) || ($uid != 0)) {
@@ -1854,6 +1923,11 @@ class Contact extends BaseObject
                // Archive or unarchive the contact. We only need to do this for the public contact.
                // The archive/unarchive function will update the personal contacts by themselves.
                $contact = DBA::selectFirst('contact', [], ['id' => $id]);
+               if (!DBA::isResult($contact)) {
+                       Logger::info('Couldn\'t select contact for archival.', ['id' => $id]);
+                       return;
+               }
+
                if (!empty($fields['success_update'])) {
                        self::unmarkForArchival($contact);
                } elseif (!empty($fields['failure_update'])) {