From 33575a94fa009c479e6c9eb330fad317e5c92d2f Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Tue, 20 Oct 2020 03:49:58 +0000
Subject: [PATCH] Follow/Unfollow contact with a single click

---
 include/conversation.php |  2 +-
 mod/follow.php           | 58 ++++++++++++++-----------
 mod/unfollow.php         | 92 +++++++++++++++++++++-------------------
 src/Model/Contact.php    |  4 +-
 src/Model/Profile.php    |  4 +-
 src/Module/Contact.php   |  4 +-
 6 files changed, 88 insertions(+), 76 deletions(-)

diff --git a/include/conversation.php b/include/conversation.php
index 7eda2277ba..baf7633a77 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -928,7 +928,7 @@ function item_photo_menu($item) {
 
 		if ((($cid == 0) || ($rel == Contact::FOLLOWER)) &&
 			in_array($item['network'], Protocol::FEDERATED)) {
-			$menu[DI::l10n()->t('Connect/Follow')] = 'follow?url=' . urlencode($item['author-link']);
+			$menu[DI::l10n()->t('Connect/Follow')] = 'follow?url=' . urlencode($item['author-link']) . '&auto=1';
 		}
 	} else {
 		$menu = [DI::l10n()->t('View Profile') => $item['author-link']];
diff --git a/mod/follow.php b/mod/follow.php
index 885730f07c..4f0c3fc6fe 100644
--- a/mod/follow.php
+++ b/mod/follow.php
@@ -41,31 +41,7 @@ function follow_post(App $a)
 		DI::baseUrl()->redirect('contact');
 	}
 
-	$url = Probe::cleanURI($_REQUEST['url']);
-	$return_path = 'follow?url=' . urlencode($url);
-
-	// Makes the connection request for friendica contacts easier
-	// This is just a precaution if maybe this page is called somewhere directly via POST
-	$_SESSION['fastlane'] = $url;
-
-	$result = Contact::createFromProbe($a->user, $url, true);
-
-	if ($result['success'] == false) {
-		// Possibly it is a remote item and not an account
-		follow_remote_item($url);
-
-		if ($result['message']) {
-			notice($result['message']);
-		}
-		DI::baseUrl()->redirect($return_path);
-	} elseif ($result['cid']) {
-		DI::baseUrl()->redirect('contact/' . $result['cid']);
-	}
-
-	notice(DI::l10n()->t('The contact could not be added.'));
-
-	DI::baseUrl()->redirect($return_path);
-	// NOTREACHED
+	follow_process($a);
 }
 
 function follow_content(App $a)
@@ -92,6 +68,10 @@ function follow_content(App $a)
 		DI::baseUrl()->redirect($return_path);
 	}
 
+	if (!empty($_REQUEST['auto'])) {
+		follow_process($a);
+	}
+
 	$submit = DI::l10n()->t('Submit Request');
 
 	// Don't try to add a pending contact
@@ -195,6 +175,34 @@ function follow_content(App $a)
 	return $o;
 }
 
+function follow_process(App $a)
+{
+	$url = Probe::cleanURI($_REQUEST['url']);
+	$return_path = 'follow?url=' . urlencode($url);
+
+	// Makes the connection request for friendica contacts easier
+	// This is just a precaution if maybe this page is called somewhere directly via POST
+	$_SESSION['fastlane'] = $url;
+
+	$result = Contact::createFromProbe($a->user, $url, true);
+
+	if ($result['success'] == false) {
+		// Possibly it is a remote item and not an account
+		follow_remote_item($url);
+
+		if ($result['message']) {
+			notice($result['message']);
+		}
+		DI::baseUrl()->redirect($return_path);
+	} elseif ($result['cid']) {
+		DI::baseUrl()->redirect('contact/' . $result['cid']);
+	}
+
+	notice(DI::l10n()->t('The contact could not be added.'));
+
+	DI::baseUrl()->redirect($return_path);
+}
+
 function follow_remote_item($url)
 {
 	$item_id = Item::fetchByLink($url, local_user());
diff --git a/mod/unfollow.php b/mod/unfollow.php
index 5ccc9c859a..d24745c8bb 100644
--- a/mod/unfollow.php
+++ b/mod/unfollow.php
@@ -31,56 +31,13 @@ use Friendica\Util\Strings;
 
 function unfollow_post(App $a)
 {
-	$base_return_path = 'contact';
-
 	if (!local_user()) {
 		notice(DI::l10n()->t('Permission denied.'));
 		DI::baseUrl()->redirect('login');
 		// NOTREACHED
 	}
 
-	$uid = local_user();
-	$url = Strings::escapeTags(trim($_REQUEST['url'] ?? ''));
-
-	$condition = ["`uid` = ? AND (`rel` = ? OR `rel` = ?) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)",
-		$uid, Contact::SHARING, Contact::FRIEND, Strings::normaliseLink($url),
-		Strings::normaliseLink($url), $url];
-	$contact = DBA::selectFirst('contact', [], $condition);
-
-	if (!DBA::isResult($contact)) {
-		notice(DI::l10n()->t("You aren't following this contact."));
-		DI::baseUrl()->redirect($base_return_path);
-		// NOTREACHED
-	}
-
-	if (!empty($_REQUEST['cancel'])) {
-		DI::baseUrl()->redirect($base_return_path . '/' . $contact['id']);
-	}
-
-	if (!in_array($contact['network'], Protocol::NATIVE_SUPPORT)) {
-		notice(DI::l10n()->t('Unfollowing is currently not supported by your network.'));
-		DI::baseUrl()->redirect($base_return_path . '/' . $contact['id']);
-		// NOTREACHED
-	}
-
-	$dissolve = ($contact['rel'] == Contact::SHARING);
-
-	$owner = User::getOwnerDataById($uid);
-	if ($owner) {
-		Contact::terminateFriendship($owner, $contact, $dissolve);
-	}
-
-	// Sharing-only contacts get deleted as there no relationship any more
-	if ($dissolve) {
-		Contact::remove($contact['id']);
-		$return_path = $base_return_path;
-	} else {
-		DBA::update('contact', ['rel' => Contact::FOLLOWER], ['id' => $contact['id']]);
-		$return_path = $base_return_path . '/' . $contact['id'];
-	}
-
-	DI::baseUrl()->redirect($return_path);
-	// NOTREACHED
+	unfollow_process();
 }
 
 function unfollow_content(App $a)
@@ -93,6 +50,10 @@ function unfollow_content(App $a)
 		// NOTREACHED
 	}
 
+	if (!empty($_REQUEST['auto'])) {
+		unfollow_process();
+	}
+
 	$uid = local_user();
 	$url = Strings::escapeTags(trim($_REQUEST['url']));
 
@@ -154,3 +115,46 @@ function unfollow_content(App $a)
 
 	return $o;
 }
+
+function unfollow_process()
+{
+	$base_return_path = 'contact';
+
+	$uid = local_user();
+	$url = Strings::escapeTags(trim($_REQUEST['url'] ?? ''));
+
+	$condition = ["`uid` = ? AND (`rel` = ? OR `rel` = ?) AND (`nurl` = ? OR `alias` = ? OR `alias` = ?)",
+		$uid, Contact::SHARING, Contact::FRIEND, Strings::normaliseLink($url),
+		Strings::normaliseLink($url), $url];
+	$contact = DBA::selectFirst('contact', [], $condition);
+
+	if (!DBA::isResult($contact)) {
+		notice(DI::l10n()->t("You aren't following this contact."));
+		DI::baseUrl()->redirect($base_return_path);
+		// NOTREACHED
+	}
+
+	if (!in_array($contact['network'], Protocol::NATIVE_SUPPORT)) {
+		notice(DI::l10n()->t('Unfollowing is currently not supported by your network.'));
+		DI::baseUrl()->redirect($base_return_path . '/' . $contact['id']);
+		// NOTREACHED
+	}
+
+	$dissolve = ($contact['rel'] == Contact::SHARING);
+
+	$owner = User::getOwnerDataById($uid);
+	if ($owner) {
+		Contact::terminateFriendship($owner, $contact, $dissolve);
+	}
+
+	// Sharing-only contacts get deleted as there no relationship any more
+	if ($dissolve) {
+		Contact::remove($contact['id']);
+		$return_path = $base_return_path;
+	} else {
+		DBA::update('contact', ['rel' => Contact::FOLLOWER], ['id' => $contact['id']]);
+		$return_path = $base_return_path . '/' . $contact['id'];
+	}
+
+	DI::baseUrl()->redirect($return_path);
+}
\ No newline at end of file
diff --git a/src/Model/Contact.php b/src/Model/Contact.php
index 6bbc0921ca..428bc3684e 100644
--- a/src/Model/Contact.php
+++ b/src/Model/Contact.php
@@ -942,9 +942,9 @@ class Contact
 		$unfollow_link = '';
 		if (!$contact['self'] && in_array($contact['network'], Protocol::NATIVE_SUPPORT)) {
 			if ($contact['uid'] && in_array($contact['rel'], [self::SHARING, self::FRIEND])) {
-				$unfollow_link = 'unfollow?url=' . urlencode($contact['url']);
+				$unfollow_link = 'unfollow?url=' . urlencode($contact['url']) . '&auto=1';
 			} elseif(!$contact['pending']) {
-				$follow_link = 'follow?url=' . urlencode($contact['url']);
+				$follow_link = 'follow?url=' . urlencode($contact['url']) . '&auto=1';
 			}
 		}
 
diff --git a/src/Model/Profile.php b/src/Model/Profile.php
index e98f0048ee..b56df5bc5f 100644
--- a/src/Model/Profile.php
+++ b/src/Model/Profile.php
@@ -322,9 +322,9 @@ class Profile
 				}
 			} elseif ($profile_is_native) {
 				if ($visitor_is_following) {
-					$unfollow_link = $visitor_base_path . '/unfollow?url=' . urlencode($profile_url);
+					$unfollow_link = $visitor_base_path . '/unfollow?url=' . urlencode($profile_url) . '&auto=1';
 				} else {
-					$follow_link =  $visitor_base_path .'/follow?url=' . urlencode($profile_url);
+					$follow_link =  $visitor_base_path .'/follow?url=' . urlencode($profile_url) . '&auto=1';
 				}
 			}
 
diff --git a/src/Module/Contact.php b/src/Module/Contact.php
index 8a7be5c893..87fff3e963 100644
--- a/src/Module/Contact.php
+++ b/src/Module/Contact.php
@@ -314,9 +314,9 @@ class Contact extends BaseModule
 			$unfollow_link = '';
 			if (in_array($contact['network'], Protocol::NATIVE_SUPPORT)) {
 				if ($contact['uid'] && in_array($contact['rel'], [Model\Contact::SHARING, Model\Contact::FRIEND])) {
-					$unfollow_link = 'unfollow?url=' . urlencode($contact['url']);
+					$unfollow_link = 'unfollow?url=' . urlencode($contact['url']) . '&auto=1';
 				} elseif(!$contact['pending']) {
-					$follow_link = 'follow?url=' . urlencode($contact['url']);
+					$follow_link = 'follow?url=' . urlencode($contact['url']) . '&auto=1';
 				}
 			}