From ef02a1cb7b7d375d1ae0f607fecca8be9e72f0c8 Mon Sep 17 00:00:00 2001
From: Michael Vogel <icarus@dabo.de>
Date: Thu, 29 Aug 2019 06:07:07 +0200
Subject: [PATCH] Check fpr duplicated contacts upon inserting them

---
 src/Model/Contact.php     | 62 +++++++++++++++------------------------
 src/Protocol/Diaspora.php |  2 +-
 2 files changed, 24 insertions(+), 40 deletions(-)

diff --git a/src/Model/Contact.php b/src/Model/Contact.php
index 5613dc396..49d4e4cc6 100644
--- a/src/Model/Contact.php
+++ b/src/Model/Contact.php
@@ -137,7 +137,8 @@ class Contact extends BaseObject
 	}
 
 	/**
-	 * @brief Insert a row into the contact table
+	 * Insert a row into the contact table
+	 * Important: You can't use DBA::lastInsertId() after this call since it will be set to 0.
 	 *
 	 * @param array        $param               parameter array
 	 * @param bool         $on_duplicate_update Do an update on a duplicate entry
@@ -148,7 +149,6 @@ class Contact extends BaseObject
 	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
@@ -161,41 +161,6 @@ class Contact extends BaseObject
 		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
@@ -1548,7 +1513,7 @@ class Contact extends BaseObject
 			if (!DBA::isResult($contact)) {
 				Logger::info('Create new contact', $fields);
 
-				DBA::insert('contact', $fields);
+				self::insert($fields);
 
 				// We intentionally aren't using lastInsertId here. There is a chance for duplicates.
 				$contact = DBA::selectFirst('contact', ['id'], $condition, ['order' => ['id']]);
@@ -1954,6 +1919,25 @@ class Contact extends BaseObject
 		DBA::update('contact', $fields, $condition);
 	}
 
+	/**
+	 * Check and remove duplicate contact entries
+	 *
+	 * @param integer $contact_id Contact ID
+	 * @throws \Exception
+	 */
+	public static function handleDuplicateByID($contact_id)
+	{
+		$contact = DBA::selectFirst('contact', ['nurl', 'uid', 'id'], ['id' => $contact_id]);
+		if (!DBA::isResult($contact)) {
+			return $ret;
+		}
+
+		// Search for duplicated contacts and get rid of them
+		self::handleDuplicates($contact['nurl'], $contact['uid'], $contact['id']);
+
+		return $ret;
+	}
+
         /**
 	 * @brief Helper function for "updateFromProbe". Remove duplicated contacts
 	 *
@@ -2325,7 +2309,7 @@ class Contact extends BaseObject
 			$new_relation = (in_array($protocol, [Protocol::MAIL]) ? self::FRIEND : self::SHARING);
 
 			// create contact record
-			DBA::insert('contact', [
+			self::insert([
 				'uid'     => $uid,
 				'created' => DateTimeFormat::utcNow(),
 				'url'     => $ret['url'],
diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php
index d578ba454..b694ab917 100644
--- a/src/Protocol/Diaspora.php
+++ b/src/Protocol/Diaspora.php
@@ -200,7 +200,7 @@ class Diaspora
 			DBA::update('contact', $fields, $condition, $old);
 		} else {
 			Logger::info('Create relay contact', ['fields' => $fields]);
-			DBA::insert('contact', $fields);
+			Contact::insert($fields);
 		}
 	}