forked from grumpydevelop/federator
		
	fix following from mastodon -> CN
This commit is contained in:
		
							parent
							
								
									5c90b4cfc9
								
							
						
					
					
						commit
						30c577c82f
					
				
					 4 changed files with 94 additions and 31 deletions
				
			
		| 
						 | 
				
			
			@ -77,6 +77,16 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
 | 
			
		|||
        $user = $inboxActivity->getAActor(); // url of the sender https://contentnation.net/username
 | 
			
		||||
        $username = basename((string) (parse_url($user, PHP_URL_PATH) ?? ''));
 | 
			
		||||
        $domain = parse_url($user, PHP_URL_HOST);
 | 
			
		||||
        $userId = $username . '@' . $domain;
 | 
			
		||||
        $user = \Federator\DIO\FedUser::getUserByName(
 | 
			
		||||
            $dbh,
 | 
			
		||||
            $userId,
 | 
			
		||||
            $cache
 | 
			
		||||
        );
 | 
			
		||||
        if ($user === null || $user->id === null) {
 | 
			
		||||
            error_log("Inbox::post couldn't find user: $userId");
 | 
			
		||||
            throw new \Federator\Exceptions\ServerError("Inbox::post couldn't find user: $userId");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $users = [];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -97,9 +107,26 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
 | 
			
		|||
                && (filter_var($receiver, FILTER_VALIDATE_URL) !== false);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (!in_array($username, $receivers, true)) {
 | 
			
		||||
            $receivers[] = $username;
 | 
			
		||||
        // Special handling for Follow and Undo follow activities
 | 
			
		||||
        if (strtolower($inboxActivity->getType()) === 'follow') {
 | 
			
		||||
            // For Follow, the object should hold the target
 | 
			
		||||
            $object = $inboxActivity->getObject();
 | 
			
		||||
            if ($object !== null && is_string($object)) {
 | 
			
		||||
                $receivers[] = $object;
 | 
			
		||||
            }
 | 
			
		||||
        } elseif (strtolower($inboxActivity->getType()) === 'undo') {
 | 
			
		||||
            $object = $inboxActivity->getObject();
 | 
			
		||||
            if ($object !== null && is_object($object)) {
 | 
			
		||||
                // For Undo, the objects object should hold the target
 | 
			
		||||
                if (strtolower($object->getType()) === 'follow') {
 | 
			
		||||
                    $objObject = $object->getObject();
 | 
			
		||||
                    if ($objObject !== null && is_string($objObject)) {
 | 
			
		||||
                        $receivers[] = $objObject;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($receivers as $receiver) {
 | 
			
		||||
            if ($receiver === '' || !is_string($receiver)) {
 | 
			
		||||
                continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -136,14 +163,14 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
 | 
			
		|||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                $receiverName = basename((string) (parse_url($receiver, PHP_URL_PATH) ?? ''));
 | 
			
		||||
                $domain = parse_url($receiver, PHP_URL_HOST);
 | 
			
		||||
                if ($receiverName === null || $domain === null) {
 | 
			
		||||
                $ourDomain = parse_url($receiver, PHP_URL_HOST);
 | 
			
		||||
                if ($receiverName === null || $ourDomain === null) {
 | 
			
		||||
                    error_log("Inbox::post no receiverName or domain found for receiver: " . $receiver);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                $receiver = $receiverName . '@' . $domain;
 | 
			
		||||
                $receiver = $receiverName . '@' . $ourDomain;
 | 
			
		||||
                try {
 | 
			
		||||
                    $user = \Federator\DIO\User::getUserByName(
 | 
			
		||||
                    $localUser = \Federator\DIO\User::getUserByName(
 | 
			
		||||
                        $dbh,
 | 
			
		||||
                        $receiver,
 | 
			
		||||
                        $connector,
 | 
			
		||||
| 
						 | 
				
			
			@ -153,11 +180,11 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
 | 
			
		|||
                    error_log("Inbox::post get user by name: " . $receiver . ". Exception: " . $e->getMessage());
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if ($user === null || $user->id === null) {
 | 
			
		||||
                if ($localUser === null || $localUser->id === null) {
 | 
			
		||||
                    error_log("Inbox::post couldn't find user: $receiver");
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                $users[] = $user->id;
 | 
			
		||||
                $users[] = $localUser->id;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -172,15 +199,15 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($users as $receiver) {
 | 
			
		||||
            if (!isset($user)) {
 | 
			
		||||
            if (!isset($receiver)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            $token = \Resque::enqueue('inbox', 'Federator\\Jobs\\InboxJob', [
 | 
			
		||||
                'user' => $username . '@' . $domain,
 | 
			
		||||
                'user' => $user->id,
 | 
			
		||||
                'recipientId' => $receiver,
 | 
			
		||||
                'activity' => $inboxActivity->toObject(),
 | 
			
		||||
            ]);
 | 
			
		||||
            error_log("Inbox::post enqueued job for user: $user with token: $token");
 | 
			
		||||
            error_log("Inbox::post enqueued job for user: $user->id with token: $token");
 | 
			
		||||
        }
 | 
			
		||||
        return "success";
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -241,12 +268,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
 | 
			
		|||
                $success = false;
 | 
			
		||||
                $actor = $inboxActivity->getAActor();
 | 
			
		||||
                if ($actor !== '') {
 | 
			
		||||
                    $followerUsername = basename((string) (parse_url($actor, PHP_URL_PATH) ?? ''));
 | 
			
		||||
                    $followerDomain = parse_url($actor, PHP_URL_HOST);
 | 
			
		||||
                    if (is_string($followerDomain)) {
 | 
			
		||||
                        $followerId = "{$followerUsername}@{$followerDomain}";
 | 
			
		||||
                        $success = \Federator\DIO\Followers::addFollow($dbh, $followerId, $user->id, $followerDomain);
 | 
			
		||||
                    }
 | 
			
		||||
                    $success = \Federator\DIO\Followers::addExternalFollow($dbh, $inboxActivity->getID(), $user->id, $recipient->id);
 | 
			
		||||
                }
 | 
			
		||||
                if ($success === false) {
 | 
			
		||||
                    error_log("Inbox::postForUser: Failed to add follower for user $user->id");
 | 
			
		||||
| 
						 | 
				
			
			@ -273,12 +295,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
 | 
			
		|||
                            if ($object instanceof \Federator\Data\ActivityPub\Common\Activity) {
 | 
			
		||||
                                $actor = $object->getAActor();
 | 
			
		||||
                                if ($actor !== '') {
 | 
			
		||||
                                    $followerUsername = basename((string) (parse_url($actor, PHP_URL_PATH) ?? ''));
 | 
			
		||||
                                    $followerDomain = parse_url($actor, PHP_URL_HOST);
 | 
			
		||||
                                    if (is_string($followerDomain)) {
 | 
			
		||||
                                        $followerId = "{$followerUsername}@{$followerDomain}";
 | 
			
		||||
                                        $success = \Federator\DIO\Followers::removeFollow($dbh, $followerId, $user->id);
 | 
			
		||||
                                    }
 | 
			
		||||
                                    $success = \Federator\DIO\Followers::removeFollow($dbh, $user->id, $recipient->id);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            if ($success === false) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -276,21 +276,21 @@ class NewContent implements \Federator\Api\APIInterface
 | 
			
		|||
 | 
			
		||||
        switch ($type) {
 | 
			
		||||
            case 'Follow':
 | 
			
		||||
                $success = false;
 | 
			
		||||
                // $success = false;
 | 
			
		||||
                $actor = $newActivity->getAActor();
 | 
			
		||||
                if ($actor !== '') {
 | 
			
		||||
                    $followerUsername = basename((string) (parse_url($actor, PHP_URL_PATH) ?? ''));
 | 
			
		||||
                    $followerDomain = parse_url($actor, PHP_URL_HOST);
 | 
			
		||||
                    // $followerUsername = basename((string) (parse_url($actor, PHP_URL_PATH) ?? ''));
 | 
			
		||||
                    // $followerDomain = parse_url($actor, PHP_URL_HOST);
 | 
			
		||||
                    $newIdUrl = \Federator\DIO\Followers::generateNewFollowId($dbh, $host);
 | 
			
		||||
                    $newActivity->setID($newIdUrl);
 | 
			
		||||
                    if (is_string($followerDomain)) {
 | 
			
		||||
                    /* if (is_string($followerDomain)) {
 | 
			
		||||
                        $followerId = "{$followerUsername}@{$followerDomain}";
 | 
			
		||||
                        // $success = \Federator\DIO\Followers::sendFollowRequest($dbh, $connector, $cache, $user->id, $followerId, $followerDomain);
 | 
			
		||||
                    }
 | 
			
		||||
                        $success = \Federator\DIO\Followers::sendFollowRequest($dbh, $connector, $cache, $user->id, $followerId, $followerDomain);
 | 
			
		||||
                    } */
 | 
			
		||||
                }
 | 
			
		||||
                if ($success === false) {
 | 
			
		||||
                /* if ($success === false) {
 | 
			
		||||
                    error_log("NewContent::postForUser Failed to add follower for user $user->id");
 | 
			
		||||
                }
 | 
			
		||||
                } */
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case 'Delete':
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,11 @@ class Follow extends Activity
 | 
			
		|||
        $this->object = $object;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getObject(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->object;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct("Follow");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -388,6 +388,47 @@ class Followers
 | 
			
		|||
        return $idurl; // Return the generated follow ID
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * add follow
 | 
			
		||||
     *
 | 
			
		||||
     * @param \mysqli $dbh database handle
 | 
			
		||||
     * @param string $followId the follow ID to use (should be an external url)
 | 
			
		||||
     * @param string $sourceUser source user id
 | 
			
		||||
     * @param string $targetUserId target user id
 | 
			
		||||
     * @return boolean true on success, false on failure
 | 
			
		||||
     */
 | 
			
		||||
    public static function addExternalFollow($dbh, $followId, $sourceUser, $targetUserId)
 | 
			
		||||
    {
 | 
			
		||||
        // Check if we already follow this user
 | 
			
		||||
        $sql = 'select id from follows where source_user = ? and target_user = ?';
 | 
			
		||||
        $stmt = $dbh->prepare($sql);
 | 
			
		||||
        if ($stmt === false) {
 | 
			
		||||
            throw new \Federator\Exceptions\ServerError("Followers::addExternalFollow Failed to prepare statement");
 | 
			
		||||
        }
 | 
			
		||||
        $stmt->bind_param("ss", $sourceUser, $targetUserId);
 | 
			
		||||
        $foundId = 0;
 | 
			
		||||
        $ret = $stmt->bind_result($foundId);
 | 
			
		||||
        $stmt->execute();
 | 
			
		||||
        if ($ret) {
 | 
			
		||||
            $stmt->fetch();
 | 
			
		||||
        }
 | 
			
		||||
        $stmt->close();
 | 
			
		||||
        if ($foundId != 0) {
 | 
			
		||||
            return false; // Already following this user
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Add follow with created_at timestamp
 | 
			
		||||
        $sql = 'insert into follows (id, source_user, target_user, created_at) values (?, ?, ?, NOW())';
 | 
			
		||||
        $stmt = $dbh->prepare($sql);
 | 
			
		||||
        if ($stmt === false) {
 | 
			
		||||
            throw new \Federator\Exceptions\ServerError("Followers::addExternalFollow Failed to prepare insert statement");
 | 
			
		||||
        }
 | 
			
		||||
        $stmt->bind_param("sss", $followId, $sourceUser, $targetUserId);
 | 
			
		||||
        $stmt->execute();
 | 
			
		||||
        $stmt->close();
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * generate new follow id
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue