forked from grumpydevelop/federator
initial support for articles from CN
- fixed how To and CC field (recipients) are handled in general - fixed posts in database - improved some error exceptions and prevented early breaks through try-catch blocks - we now support CN-articles on our newcontent endpoint, with create and update calls
This commit is contained in:
parent
ba88adcebd
commit
62cfd6ef0d
12 changed files with 398 additions and 150 deletions
|
@ -43,7 +43,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
/**
|
||||
* handle post call
|
||||
*
|
||||
* @param string|null $_user user to add data to inbox
|
||||
* @param string|null $_user user to add data to inbox @unused-param
|
||||
* @return string|false response
|
||||
*/
|
||||
public function post($_user)
|
||||
|
@ -59,6 +59,12 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
|
||||
$activity = is_string($_rawInput) ? json_decode($_rawInput, true) : null;
|
||||
|
||||
$dbh = $this->main->getDatabase();
|
||||
$cache = $this->main->getCache();
|
||||
$connector = $this->main->getConnector();
|
||||
|
||||
$config = $this->main->getConfig();
|
||||
|
||||
if (!is_array($activity)) {
|
||||
throw new \Federator\Exceptions\ServerError("Inbox::post Input wasn't of type array");
|
||||
}
|
||||
|
@ -68,33 +74,33 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
if ($inboxActivity === false) {
|
||||
throw new \Federator\Exceptions\ServerError("Inbox::post couldn't create inboxActivity");
|
||||
}
|
||||
$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);
|
||||
|
||||
$rootDir = PROJECT_ROOT . '/';
|
||||
$users = [];
|
||||
|
||||
// Shared inbox
|
||||
if (!isset($_user)) {
|
||||
// Save the raw input and parsed JSON to a file for inspection
|
||||
file_put_contents(
|
||||
$rootDir . 'logs/inbox.log',
|
||||
date('Y-m-d H:i:s') . ": ==== POST Inbox Activity ====\n" . json_encode($inboxActivity, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
$receivers = array_merge($inboxActivity->getTo(), $inboxActivity->getCC());
|
||||
|
||||
$sendTo = $inboxActivity->getCC();
|
||||
if ($inboxActivity->getType() === 'Undo') { // for undo the object holds the proper cc
|
||||
// For Undo, the object may hold the proper to/cc
|
||||
if ($inboxActivity->getType() === 'Undo') {
|
||||
$object = $inboxActivity->getObject();
|
||||
if ($object !== null && is_object($object)) {
|
||||
$sendTo = $object->getCC();
|
||||
$receivers = array_merge($object->getTo(), $object->getCC());
|
||||
}
|
||||
}
|
||||
|
||||
$users = [];
|
||||
$dbh = $this->main->getDatabase();
|
||||
$cache = $this->main->getCache();
|
||||
$connector = $this->main->getConnector();
|
||||
// Filter out the public address and keep only actual URLs
|
||||
$receivers = array_filter($receivers, static function (mixed $receiver): bool {
|
||||
return is_string($receiver)
|
||||
&& $receiver !== 'https://www.w3.org/ns/activitystreams#Public'
|
||||
&& (filter_var($receiver, FILTER_VALIDATE_URL) !== false);
|
||||
});
|
||||
|
||||
foreach ($sendTo as $receiver) {
|
||||
if (!in_array($username, $receivers, true)) {
|
||||
$receivers[] = $username;
|
||||
}
|
||||
foreach ($receivers as $receiver) {
|
||||
if ($receiver === '' || !is_string($receiver)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -110,25 +116,68 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
$username = basename((string) (parse_url($actor, PHP_URL_PATH) ?? ''));
|
||||
$domain = parse_url($actor, PHP_URL_HOST);
|
||||
if ($username === null || $domain === null) {
|
||||
error_log("Inbox::post no username or domain found");
|
||||
error_log("Inbox::post no username or domain found for recipient: $receiver");
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
$followers = \Federator\DIO\Followers::getFollowersByFedUser($dbh, $connector, $cache, $username . '@' . $domain);
|
||||
} catch (\Throwable $e) {
|
||||
error_log("Inbox::post get followers for user: " . $username . '@' . $domain . ". Exception: " . $e->getMessage());
|
||||
continue;
|
||||
}
|
||||
$followers = \Federator\DIO\Followers::getFollowersByFedUser($dbh, $connector, $cache, $username . '@' . $domain);
|
||||
|
||||
if (is_array($followers)) {
|
||||
$users = array_merge($users, array_column($followers, 'id'));
|
||||
}
|
||||
} else {
|
||||
$ourDomain = $config['generic']['externaldomain'];
|
||||
// check if receiver is an actor url from our domain
|
||||
if (!str_contains($receiver, $ourDomain)) {
|
||||
continue;
|
||||
}
|
||||
$receiverName = basename((string) (parse_url($receiver, PHP_URL_PATH) ?? ''));
|
||||
$domain = parse_url($receiver, PHP_URL_HOST);
|
||||
if ($receiverName === null || $domain === null) {
|
||||
error_log("Inbox::post no receiverName or domain found for receiver: " . $receiver);
|
||||
continue;
|
||||
}
|
||||
$receiver = $receiverName . '@' . $domain;
|
||||
try {
|
||||
$user = \Federator\DIO\User::getUserByName(
|
||||
$dbh,
|
||||
$receiver,
|
||||
$connector,
|
||||
$cache
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
error_log("Inbox::post get user by name: " . $receiver . ". Exception: " . $e->getMessage());
|
||||
continue;
|
||||
}
|
||||
if ($user === null || $user->id === null) {
|
||||
error_log("Inbox::post couldn't find user: $receiver");
|
||||
continue;
|
||||
}
|
||||
$users[] = $user->id;
|
||||
}
|
||||
}
|
||||
if ($_user !== false && !in_array($_user, $users, true)) {
|
||||
$users[] = $_user;
|
||||
|
||||
if (empty($users)) { // todo remove after proper implementation, debugging for now
|
||||
$rootDir = PROJECT_ROOT . '/';
|
||||
// Save the raw input and parsed JSON to a file for inspection
|
||||
file_put_contents(
|
||||
$rootDir . 'logs/inbox.log',
|
||||
date('Y-m-d H:i:s') . ": ==== POST Inbox Activity ====\n" . json_encode($inboxActivity, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
foreach ($users as $user) {
|
||||
|
||||
foreach ($users as $receiver) {
|
||||
if (!isset($user)) {
|
||||
continue;
|
||||
}
|
||||
$token = \Resque::enqueue('inbox', 'Federator\\Jobs\\InboxJob', [
|
||||
'user' => $user,
|
||||
'user' => $username . '@' . $domain,
|
||||
'recipientId' => $receiver,
|
||||
'activity' => $inboxActivity->toObject(),
|
||||
]);
|
||||
error_log("Inbox::post enqueued job for user: $user with token: $token");
|
||||
|
@ -142,32 +191,46 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
* @param \mysqli $dbh database handle
|
||||
* @param \Federator\Connector\Connector $connector connector to use
|
||||
* @param \Federator\Cache\Cache|null $cache optional caching service
|
||||
* @param string $_user user to add data to inbox
|
||||
* @param string $_user user that triggered the post
|
||||
* @param string $_recipientId recipient of the post
|
||||
* @param \Federator\Data\ActivityPub\Common\Activity $inboxActivity the activity that we received
|
||||
* @return boolean response
|
||||
*/
|
||||
public static function postForUser($dbh, $connector, $cache, $_user, $inboxActivity)
|
||||
public static function postForUser($dbh, $connector, $cache, $_user, $_recipientId, $inboxActivity)
|
||||
{
|
||||
if (!isset($_user)) {
|
||||
error_log("Inbox::postForUser no user given");
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = \Federator\DIO\User::getUserByName(
|
||||
// get sender
|
||||
$user = \Federator\DIO\FedUser::getUserByName(
|
||||
$dbh,
|
||||
$_user,
|
||||
$connector,
|
||||
$cache
|
||||
);
|
||||
if ($user === null || $user->id === null) {
|
||||
throw new \Federator\Exceptions\ServerError("Inbox::postForUser couldn't find user: $_user");
|
||||
error_log("Inbox::postForUser couldn't find user: $_user");
|
||||
return false;
|
||||
}
|
||||
|
||||
// get recipient
|
||||
$recipient = \Federator\DIO\User::getUserByName(
|
||||
$dbh,
|
||||
$_recipientId,
|
||||
$connector,
|
||||
$cache
|
||||
);
|
||||
if ($recipient === null || $recipient->id === null) {
|
||||
error_log("Inbox::postForUser couldn't find user: $_recipientId");
|
||||
return false;
|
||||
}
|
||||
|
||||
$rootDir = PROJECT_ROOT . '/';
|
||||
// Save the raw input and parsed JSON to a file for inspection
|
||||
file_put_contents(
|
||||
$rootDir . 'logs/inbox_' . $_user . '.log',
|
||||
date('Y-m-d H:i:s') . ": ==== POST " . $_user . " Inbox Activity ====\n" . json_encode($inboxActivity, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n\n",
|
||||
$rootDir . 'logs/inbox_' . $recipient->id . '.log',
|
||||
date('Y-m-d H:i:s') . ": ==== POST " . $recipient->id . " Inbox Activity ====\n" . json_encode($inboxActivity, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
|
||||
|
@ -195,12 +258,15 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
$object = $inboxActivity->getObject();
|
||||
if (is_string($object)) {
|
||||
\Federator\DIO\Posts::deletePost($dbh, $object);
|
||||
} elseif (is_object($object)) {
|
||||
$objectId = $object->getID();
|
||||
\Federator\DIO\Posts::deletePost($dbh, $objectId);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Undo':
|
||||
$object = $inboxActivity->getObject();
|
||||
if (is_object($object) && method_exists($object, 'getType')) {
|
||||
if (is_object($object)) {
|
||||
switch ($object->getType()) {
|
||||
case 'Follow':
|
||||
$success = false;
|
||||
|
|
|
@ -77,7 +77,6 @@ class NewContent implements \Federator\Api\APIInterface
|
|||
public function post($_user)
|
||||
{
|
||||
$_rawInput = file_get_contents('php://input');
|
||||
|
||||
$allHeaders = getallheaders();
|
||||
try {
|
||||
$this->main->checkSignature($allHeaders);
|
||||
|
@ -111,27 +110,94 @@ class NewContent implements \Federator\Api\APIInterface
|
|||
error_log("NewContent::post couldn't create newActivity");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($_user)) {
|
||||
$user = $newActivity->getAActor(); // url of the sender https://contentnation.net/username
|
||||
$user = str_replace(
|
||||
$posterName = str_replace(
|
||||
$domain,
|
||||
'',
|
||||
$user
|
||||
); // retrieve only the last part of the url
|
||||
} else {
|
||||
$user = $dbh->real_escape_string($_user);
|
||||
$posterName = $dbh->real_escape_string($_user);
|
||||
}
|
||||
|
||||
$users = [];
|
||||
|
||||
if ($newActivity->getType() === 'Create') {
|
||||
$followers = $this->fetchAllFollowers($dbh, $connector, $cache, $user);
|
||||
}
|
||||
if (!empty($followers)) {
|
||||
$users = array_merge($users, $followers);
|
||||
$receivers = array_merge($newActivity->getTo(), $newActivity->getCC());
|
||||
|
||||
// For Undo, the object may hold the proper to/cc
|
||||
if ($newActivity->getType() === 'Undo') {
|
||||
$object = $newActivity->getObject();
|
||||
if ($object !== null && is_object($object)) {
|
||||
$receivers = array_merge($object->getTo(), $object->getCC());
|
||||
}
|
||||
}
|
||||
|
||||
// Filter out the public address and keep only actual URLs
|
||||
$receivers = array_filter($receivers, static function (mixed $receiver): bool {
|
||||
return is_string($receiver)
|
||||
&& $receiver !== 'https://www.w3.org/ns/activitystreams#Public'
|
||||
&& (filter_var($receiver, FILTER_VALIDATE_URL) !== false);
|
||||
});
|
||||
|
||||
if (!in_array($posterName, $receivers, true)) {
|
||||
$receivers[] = $posterName;
|
||||
}
|
||||
foreach ($receivers as $receiver) {
|
||||
if ($receiver === '' || !is_string($receiver)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_ends_with($receiver, '/followers')) {
|
||||
$actor = $newActivity->getAActor();
|
||||
if ($actor === null || !is_string($actor)) {
|
||||
error_log("NewContent::post no actor found");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($posterName === null) {
|
||||
error_log("NewContent::post no username found");
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
$followers = \Federator\DIO\Followers::getFollowersByUser($dbh, $posterName, $connector, $cache);
|
||||
} catch (\Throwable $e) {
|
||||
error_log("NewContent::post get followers for user: " . $posterName . ". Exception: " . $e->getMessage());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_array($followers)) {
|
||||
$users = array_merge($users, array_column($followers, 'id'));
|
||||
}
|
||||
} else {
|
||||
// check if receiver is an actor url and not from our domain
|
||||
if (str_contains($receiver, $domain)) {
|
||||
continue;
|
||||
}
|
||||
$receiverName = basename((string) (parse_url($receiver, PHP_URL_PATH) ?? ''));
|
||||
$domain = parse_url($receiver, PHP_URL_HOST);
|
||||
if ($receiverName === null || $domain === null) {
|
||||
error_log("NewContent::post no receiverName or domain found for receiver: " . $receiver);
|
||||
continue;
|
||||
}
|
||||
$receiver = $receiverName . '@' . $domain;
|
||||
try {
|
||||
$user = \Federator\DIO\FedUser::getUserByName(
|
||||
$dbh,
|
||||
$receiver,
|
||||
$cache
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
error_log("NewContent::post get user by name: " . $receiver . ". Exception: " . $e->getMessage());
|
||||
continue;
|
||||
}
|
||||
if ($user === null || $user->id === null) {
|
||||
error_log("NewContent::post couldn't find user: $receiver");
|
||||
continue;
|
||||
}
|
||||
$users[] = $user->id;
|
||||
}
|
||||
}
|
||||
if (empty($users)) { // todo remove after proper implementation, debugging for now
|
||||
$rootDir = PROJECT_ROOT . '/';
|
||||
// Save the raw input and parsed JSON to a file for inspection
|
||||
|
@ -141,20 +207,18 @@ class NewContent implements \Federator\Api\APIInterface
|
|||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
if ($_user !== false && !in_array($_user, $users, true)) {
|
||||
$users[] = $_user;
|
||||
}
|
||||
|
||||
foreach ($users as $user) {
|
||||
if (!isset($user)) {
|
||||
foreach ($users as $receiver) {
|
||||
if (!isset($receiver)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$token = \Resque::enqueue('inbox', 'Federator\\Jobs\\NewContentJob', [
|
||||
'user' => $user,
|
||||
'user' => $posterName,
|
||||
'recipientId' => $receiver,
|
||||
'activity' => $newActivity->toObject(),
|
||||
]);
|
||||
error_log("Inbox::post enqueued job for user: $user with token: $token");
|
||||
error_log("Inbox::post enqueued job for receiver: $receiver with token: $token");
|
||||
}
|
||||
|
||||
return json_encode($newActivity, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
|
||||
|
@ -170,17 +234,18 @@ class NewContent implements \Federator\Api\APIInterface
|
|||
* @param \Federator\Cache\Cache|null $cache
|
||||
* optional caching service
|
||||
* @param string $_user user that triggered the post
|
||||
* @param string $_recipientId recipient of the post
|
||||
* @param \Federator\Data\ActivityPub\Common\Activity $newActivity the activity that we received
|
||||
* @return boolean response
|
||||
*/
|
||||
public static function postForUser($dbh, $connector, $cache, $_user, $newActivity)
|
||||
public static function postForUser($dbh, $connector, $cache, $_user, $_recipientId, $newActivity)
|
||||
{
|
||||
if (!isset($_user)) {
|
||||
error_log("NewContent::postForUser no user given");
|
||||
return false;
|
||||
}
|
||||
|
||||
// get user
|
||||
// get sender
|
||||
$user = \Federator\DIO\User::getUserByName(
|
||||
$dbh,
|
||||
$_user,
|
||||
|
@ -192,11 +257,22 @@ class NewContent implements \Federator\Api\APIInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
// get recipient
|
||||
$recipient = \Federator\DIO\FedUser::getUserByName(
|
||||
$dbh,
|
||||
$_recipientId,
|
||||
$cache
|
||||
);
|
||||
if ($recipient === null || $recipient->id === null) {
|
||||
error_log("NewContent::postForUser couldn't find user: $_recipientId");
|
||||
return false;
|
||||
}
|
||||
|
||||
$rootDir = PROJECT_ROOT . '/';
|
||||
// Save the raw input and parsed JSON to a file for inspection
|
||||
file_put_contents(
|
||||
$rootDir . 'logs/newcontent_' . $_user . '.log',
|
||||
date('Y-m-d H:i:s') . ": ==== POST " . $_user . " NewContent Activity ====\n" . json_encode($newActivity, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n\n",
|
||||
$rootDir . 'logs/newcontent_' . $recipient->id . '.log',
|
||||
date('Y-m-d H:i:s') . ": ==== POST " . $recipient->id . " NewContent Activity ====\n" . json_encode($newActivity, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . "\n\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
|
||||
|
@ -303,6 +379,7 @@ class NewContent implements \Federator\Api\APIInterface
|
|||
break;
|
||||
|
||||
case 'Create':
|
||||
case 'Update':
|
||||
$object = $newActivity->getObject();
|
||||
if (is_object($object)) {
|
||||
switch ($object->getType()) {
|
||||
|
@ -324,40 +401,6 @@ class NewContent implements \Federator\Api\APIInterface
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch all followers from url and return the ones that belong to our server
|
||||
*
|
||||
* @param \mysqli $dbh
|
||||
* database handle
|
||||
* @param \Federator\Connector\Connector $connector
|
||||
* connector to fetch use with
|
||||
* @param \Federator\Cache\Cache|null $cache
|
||||
* optional caching service
|
||||
* @param string $userId The id of the user
|
||||
* @return string[] the names of the followers that are hosted on our server
|
||||
*/
|
||||
private static function fetchAllFollowers($dbh, $connector, $cache, string $userId): array
|
||||
{
|
||||
if (empty($userId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$users = [];
|
||||
|
||||
$apFollowers = \Federator\DIO\Followers::getFollowersByUser(
|
||||
$dbh,
|
||||
$userId,
|
||||
$connector,
|
||||
cache: $cache,
|
||||
);
|
||||
|
||||
foreach ($apFollowers as $follower) {
|
||||
$users[] = $follower->id;
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* get internal represenation as json string
|
||||
* @return string json string or html
|
||||
|
|
45
php/federator/data/activitypub/common/Update.php
Normal file
45
php/federator/data/activitypub/common/Update.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* @author Yannis Vogel (vogeldevelopment)
|
||||
**/
|
||||
|
||||
namespace Federator\Data\ActivityPub\Common;
|
||||
|
||||
class Update extends Activity
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('Update');
|
||||
parent::addContext('https://www.w3.org/ns/activitystreams');
|
||||
}
|
||||
|
||||
/**
|
||||
* convert internal state to php array
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function toObject()
|
||||
{
|
||||
$return = parent::toObject();
|
||||
$return['type'] = 'Update';
|
||||
// overwrite id from url
|
||||
if ($this->getURL() !== '') {
|
||||
$return['id'] = $this->getURL();
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* create object from json
|
||||
*
|
||||
* @param array<string,mixed> $json input json
|
||||
* @return bool true on success
|
||||
*/
|
||||
public function fromJson($json)
|
||||
{
|
||||
return parent::fromJson($json);
|
||||
}
|
||||
}
|
|
@ -647,7 +647,7 @@ class APObject implements \JsonSerializable
|
|||
if (array_key_exists('duration', $json)) {
|
||||
try {
|
||||
$this->duration = new \DateInterval($json['duration']);
|
||||
} catch (\Exception $unused_e) {
|
||||
} catch (\Throwable $unused_e) {
|
||||
error_log("error parsing duration ". $json['duration']);
|
||||
}
|
||||
}
|
||||
|
@ -875,7 +875,7 @@ class APObject implements \JsonSerializable
|
|||
$return['tag'] = $tags;
|
||||
}
|
||||
if ($this->updated > 0) {
|
||||
$return['updated'] = gmdate("Y-m-d\TH:i:S\Z", $this->updated);
|
||||
$return['updated'] = gmdate("Y-m-d\TH:i:s\Z", $this->updated);
|
||||
}
|
||||
if ($this->url !== '') {
|
||||
$return['url'] = $this->url;
|
||||
|
|
|
@ -116,6 +116,9 @@ class Factory
|
|||
case 'Undo':
|
||||
$return = new Common\Undo();
|
||||
break;
|
||||
case 'Update':
|
||||
$return = new Common\Update();
|
||||
break;
|
||||
default:
|
||||
error_log("newActivityFromJson unsupported type: " . print_r($json, true));
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ class FedUser
|
|||
$sql = 'select unix_timestamp(`validuntil`) from fedusers where id=?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::addLocalUser Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("s", $_user);
|
||||
$validuntil = 0;
|
||||
|
@ -42,7 +42,7 @@ class FedUser
|
|||
$sql .= ' values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, now() + interval 1 day)';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::addLocalUser Failed to prepare create statement");
|
||||
}
|
||||
$stmt->bind_param(
|
||||
"ssssssssssss",
|
||||
|
@ -66,7 +66,7 @@ class FedUser
|
|||
$sql .= ' where id=?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::extendUser Failed to prepare update statement");
|
||||
}
|
||||
$stmt->bind_param(
|
||||
"ssssssssssss",
|
||||
|
@ -106,7 +106,7 @@ class FedUser
|
|||
$sql = 'select id,unix_timestamp(`validuntil`) from fedusers where id=?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::extendUser Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("s", $_user);
|
||||
$validuntil = 0;
|
||||
|
@ -147,12 +147,12 @@ class FedUser
|
|||
return $user;
|
||||
}
|
||||
// check our db
|
||||
$sql = 'select id, url, name, publickey, summary, type, inboxurl, sharedinboxurl, followersurl,';
|
||||
$sql .= ' followingurl,publickeyid,outboxurl';
|
||||
$sql .= ' from fedusers where id=? and validuntil>=now()';
|
||||
$sql = 'select `id`, `url`, `name`, `publickey`, `summary`, `type`, `inboxurl`, `sharedinboxurl`, `followersurl`,';
|
||||
$sql .= ' `followingurl`, `publickeyid`, `outboxurl`';
|
||||
$sql .= ' from fedusers where `id`=? and `validuntil`>=now()';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::getUserByName Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("s", $_name);
|
||||
$user = new \Federator\Data\FedUser();
|
||||
|
@ -184,11 +184,11 @@ class FedUser
|
|||
$headers = ['Accept: application/activity+json'];
|
||||
[$response, $info] = \Federator\Main::getFromRemote($remoteURL, $headers);
|
||||
if ($info['http_code'] != 200) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::getUserByName Failed to fetch webfinger for " . $_name);
|
||||
}
|
||||
$r = json_decode($response, true);
|
||||
if ($r === false || $r === null || !is_array($r)) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::getUserByName Failed to decode webfinger for " . $_name);
|
||||
}
|
||||
// get the webwinger user url and fetch the user
|
||||
if (isset($r['links'])) {
|
||||
|
@ -200,17 +200,17 @@ class FedUser
|
|||
}
|
||||
}
|
||||
if (!isset($remoteURL)) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::getUserByName Failed to find self link in webfinger for " . $_name);
|
||||
}
|
||||
// fetch the user
|
||||
$headers = ['Accept: application/activity+json'];
|
||||
[$response, $info] = \Federator\Main::getFromRemote($remoteURL, $headers);
|
||||
if ($info['http_code'] != 200) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::getUserByName Failed to fetch user from remoteUrl for " . $_name);
|
||||
}
|
||||
$r = json_decode($response, true);
|
||||
if ($r === false || $r === null || !is_array($r)) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::getUserByName Failed to decode user for " . $_name);
|
||||
}
|
||||
$r['publicKeyId'] = $r['publicKey']['id'];
|
||||
$r['publicKey'] = $r['publicKey']['publicKeyPem'];
|
||||
|
@ -222,20 +222,20 @@ class FedUser
|
|||
$r['actorURL'] = $remoteURL;
|
||||
$data = json_encode($r);
|
||||
if ($data === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::getUserByName Failed to encode userdata " . $_name);
|
||||
}
|
||||
$user = \Federator\Data\FedUser::createFromJson($data);
|
||||
}
|
||||
}
|
||||
|
||||
if ($cache !== null && $user !== false) {
|
||||
if ($user->id === null && $user->actorURL !== null) {
|
||||
if ($user->id !== null && $user->actorURL !== null) {
|
||||
self::addLocalUser($dbh, $user, $_name);
|
||||
}
|
||||
$cache->saveRemoteFedUserByName($_name, $user);
|
||||
}
|
||||
if ($user === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("FedUser::getUserByName User not found");
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ class Followers
|
|||
$sql = 'select source_user from follows where target_user = ?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("Followers::getFollowersByUser Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("s", $id);
|
||||
$stmt->execute();
|
||||
|
@ -50,11 +50,16 @@ class Followers
|
|||
}
|
||||
$stmt->close();
|
||||
foreach ($followerIds as $followerId) {
|
||||
$user = \Federator\DIO\FedUser::getUserByName(
|
||||
$dbh,
|
||||
$followerId,
|
||||
$cache,
|
||||
);
|
||||
try {
|
||||
$user = \Federator\DIO\FedUser::getUserByName(
|
||||
$dbh,
|
||||
$followerId,
|
||||
$cache,
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
error_log("Followers::getFollowersByUser Exception: " . $e->getMessage());
|
||||
continue; // Skip this user if an exception occurs
|
||||
}
|
||||
if ($user !== false && $user->id !== null) {
|
||||
$followers[] = $user;
|
||||
}
|
||||
|
@ -67,7 +72,7 @@ class Followers
|
|||
$followers = [];
|
||||
}
|
||||
}
|
||||
// save posts to DB
|
||||
// save followers to cache
|
||||
if ($cache !== null) {
|
||||
$cache->saveRemoteFollowersOfUser($id, $followers);
|
||||
}
|
||||
|
@ -100,7 +105,7 @@ class Followers
|
|||
$sql = 'select target_user from follows where source_user = ?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("Followers::getFollowingForUser Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("s", $id);
|
||||
$stmt->execute();
|
||||
|
@ -111,11 +116,16 @@ class Followers
|
|||
}
|
||||
$stmt->close();
|
||||
foreach ($followingIds as $followingId) {
|
||||
$user = \Federator\DIO\FedUser::getUserByName(
|
||||
$dbh,
|
||||
$followingId,
|
||||
$cache,
|
||||
);
|
||||
try {
|
||||
$user = \Federator\DIO\FedUser::getUserByName(
|
||||
$dbh,
|
||||
$followingId,
|
||||
$cache,
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
error_log("Followers::getFollowingForUser Exception: " . $e->getMessage());
|
||||
continue; // Skip this user if an exception occurs
|
||||
}
|
||||
if ($user !== false && $user->id !== null) {
|
||||
$following[] = $user;
|
||||
}
|
||||
|
@ -156,7 +166,7 @@ class Followers
|
|||
$sql = 'select source_user from follows where target_user = ?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("Followers::getFollowersByFedUser Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("s", $id);
|
||||
$stmt->execute();
|
||||
|
@ -166,12 +176,17 @@ class Followers
|
|||
$followerIds[] = $sourceUser;
|
||||
}
|
||||
foreach ($followerIds as $followerId) {
|
||||
$user = \Federator\DIO\User::getUserByName(
|
||||
$dbh,
|
||||
$followerId,
|
||||
$connector,
|
||||
$cache
|
||||
);
|
||||
try {
|
||||
$user = \Federator\DIO\User::getUserByName(
|
||||
$dbh,
|
||||
$followerId,
|
||||
$connector,
|
||||
$cache
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
error_log("Followers::getFollowersByFedUser Exception: " . $e->getMessage());
|
||||
continue; // Skip this user if an exception occurs
|
||||
}
|
||||
if ($user !== false && $user->id !== null) {
|
||||
$followers[] = $user;
|
||||
}
|
||||
|
@ -193,7 +208,7 @@ class Followers
|
|||
public static function sendFollowRequest($dbh, $connector, $cache, $_user, $_targetUser, $host)
|
||||
{
|
||||
if ($dbh === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("Followers::sendFollowRequest Failed to get database handle");
|
||||
}
|
||||
$user = \Federator\DIO\User::getUserByName(
|
||||
$dbh,
|
||||
|
@ -326,7 +341,7 @@ class Followers
|
|||
$sql = 'select id from follows where source_user = ? and target_user = ?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("Followers::addFollow Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("ss", $sourceUser, $targetUserId);
|
||||
$foundId = 0;
|
||||
|
@ -349,7 +364,7 @@ class Followers
|
|||
$sql = 'select id from follows where id = ?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("Followers::addFollow Failed to prepare id-check statement");
|
||||
}
|
||||
$stmt->bind_param("s", $idurl);
|
||||
$foundId = 0;
|
||||
|
@ -365,7 +380,7 @@ class Followers
|
|||
$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();
|
||||
throw new \Federator\Exceptions\ServerError("Followers::addFollow Failed to prepare insert statement");
|
||||
}
|
||||
$stmt->bind_param("sss", $idurl, $sourceUser, $targetUserId);
|
||||
$stmt->execute();
|
||||
|
@ -386,7 +401,7 @@ class Followers
|
|||
$sql = 'delete from follows where source_user = ? and target_user = ?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("Followers::removeFollow Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("ss", $sourceUser, $targetUserId);
|
||||
$stmt->execute();
|
||||
|
|
|
@ -43,7 +43,6 @@ class Posts
|
|||
if ($posts === false) {
|
||||
$posts = [];
|
||||
}
|
||||
echo "Found " . count($posts) . " posts in DB\n";
|
||||
|
||||
// Only override $min if we found posts in our DB
|
||||
$remoteMin = $min;
|
||||
|
|
|
@ -26,7 +26,7 @@ class User
|
|||
$sql = 'select unix_timestamp(`validuntil`) from users where id=?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("User::addLocalUser Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("s", $_user);
|
||||
$validuntil = 0;
|
||||
|
@ -50,7 +50,7 @@ class User
|
|||
$sql .= ' values (?, ?, ?, ?, now() + interval 1 day, ?, ?, ?, ?, ?, ?, ?, ?)';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("User::addLocalUser Failed to prepare create statement");
|
||||
}
|
||||
$registered = gmdate('Y-m-d H:i:s', $user->registered);
|
||||
$stmt->bind_param(
|
||||
|
@ -74,7 +74,7 @@ class User
|
|||
$sql .= ' iconmediatype=?, iconurl=?, imagemediatype=?, imageurl=? where id=?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("User::addLocalUser Failed to prepare update statement");
|
||||
}
|
||||
$registered = gmdate('Y-m-d H:i:s', $user->registered);
|
||||
$stmt->bind_param(
|
||||
|
@ -110,7 +110,7 @@ class User
|
|||
$sql = "select rsaprivate from users where id=?";
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("User::getrsaprivate Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("s", $_user);
|
||||
$ret = $stmt->bind_result($rsaPrivateKey);
|
||||
|
@ -136,7 +136,7 @@ class User
|
|||
$sql = 'select id,unix_timestamp(`validuntil`) from users where id=?';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("User::extendUser Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("s", $_user);
|
||||
$validuntil = 0;
|
||||
|
@ -183,7 +183,7 @@ class User
|
|||
$sql .= 'iconmediatype,iconurl,imagemediatype,imageurl from users where id=? and validuntil>=now()';
|
||||
$stmt = $dbh->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
throw new \Federator\Exceptions\ServerError();
|
||||
throw new \Federator\Exceptions\ServerError("User::getUserByName Failed to prepare statement");
|
||||
}
|
||||
$stmt->bind_param("s", $_name);
|
||||
$user = new \Federator\Data\User();
|
||||
|
|
|
@ -54,6 +54,7 @@ class InboxJob extends \Federator\Api
|
|||
{
|
||||
error_log("InboxJob: Starting inbox job");
|
||||
$user = $this->args['user'];
|
||||
$recipientId = $this->args['recipientId'];
|
||||
$activity = $this->args['activity'];
|
||||
|
||||
$inboxActivity = \Federator\Data\ActivityPub\Factory::newActivityFromJson($activity);
|
||||
|
@ -63,7 +64,7 @@ class InboxJob extends \Federator\Api
|
|||
return false;
|
||||
}
|
||||
|
||||
\Federator\Api\FedUsers\Inbox::postForUser($this->dbh, $this->connector, $this->cache, $user, $inboxActivity);
|
||||
\Federator\Api\FedUsers\Inbox::postForUser($this->dbh, $this->connector, $this->cache, $user, $recipientId, $inboxActivity);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -54,6 +54,7 @@ class NewContentJob extends \Federator\Api
|
|||
{
|
||||
error_log("NewContentJob: Starting inbox job");
|
||||
$user = $this->args['user'];
|
||||
$recipientId = $this->args['recipientId'];
|
||||
$activity = $this->args['activity'];
|
||||
|
||||
$activity = \Federator\Data\ActivityPub\Factory::newActivityFromJson($activity);
|
||||
|
@ -63,7 +64,7 @@ class NewContentJob extends \Federator\Api
|
|||
return false;
|
||||
}
|
||||
|
||||
\Federator\Api\V1\NewContent::postForUser($this->dbh, $this->connector, $this->cache, $user, $activity);
|
||||
\Federator\Api\V1\NewContent::postForUser($this->dbh, $this->connector, $this->cache, $user, $recipientId, $activity);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -148,8 +148,8 @@ class ContentNation implements Connector
|
|||
$create->setAActor('https://' . $domain . '/' . $userId);
|
||||
$create->setID($activity['id'])
|
||||
->setPublished($activity['published'] ?? $activity['timestamp'])
|
||||
->addTo("https://www.w3.org/ns/activitystreams#Public")
|
||||
->addCC('https://' . $domain . '/' . $userId . '/followers');
|
||||
->addTo('https://' . $domain . '/' . $userId . '/followers')
|
||||
->addCC("https://www.w3.org/ns/activitystreams#Public");
|
||||
$create->setURL('https://' . $domain . '/' . $activity['profilename'] . '/' . $activity['name']);
|
||||
$create->setID('https://' . $domain . '/' . $activity['profilename'] . '/' . $activity['id']);
|
||||
$apArticle = new \Federator\Data\ActivityPub\Common\Article();
|
||||
|
@ -203,8 +203,8 @@ class ContentNation implements Connector
|
|||
$create->setAActor('https://' . $domain . '/' . $userId);
|
||||
$create->setID($activity['id'])
|
||||
->setPublished($activity['published'] ?? $activity['timestamp'])
|
||||
->addTo("https://www.w3.org/ns/activitystreams#Public")
|
||||
->addCC('https://' . $domain . '/' . $userId . '/followers');
|
||||
->addTo('https://' . $domain . '/' . $userId . '/followers')
|
||||
->addCC("https://www.w3.org/ns/activitystreams#Public");
|
||||
$commentJson = $activity;
|
||||
$commentJson['type'] = 'Note';
|
||||
$commentJson['summary'] = $activity['subject'];
|
||||
|
@ -219,7 +219,7 @@ class ContentNation implements Connector
|
|||
$note->setID($commentJson['id']);
|
||||
if (!isset($commentJson['parent']) || $commentJson['parent'] === null) {
|
||||
$note->setInReplyTo('https://' . $domain . '/' . $activity['articleOwnerName'] . '/' . $activity['articleName']);
|
||||
} elseif ($replyType === "comment") {
|
||||
} else {
|
||||
$note->setInReplyTo('https://' . $domain . '/' . $activity['articleOwnerName'] . '/' . $activity['articleName'] . "#" . $commentJson['parent']);
|
||||
}
|
||||
$url = 'https://' . $domain . '/' . $activity['articleOwnerName'] . '/' . $activity['articleName'] . '#' . $activity['id'];
|
||||
|
@ -237,7 +237,7 @@ class ContentNation implements Connector
|
|||
$like->setID($activity['id'])
|
||||
->setPublished($activity['published'] ?? $activity['timestamp']);
|
||||
// $like->addTo("https://www.w3.org/ns/activitystreams#Public")
|
||||
// ->addCC('https://' . $domain . '/' . $userId . '/followers');
|
||||
// ->addCC('https://' . $domain . '/' . $userId . '/followers');
|
||||
$like->setSummary(
|
||||
$this->main->translate(
|
||||
$activity['articlelang'],
|
||||
|
@ -392,6 +392,65 @@ class ContentNation implements Connector
|
|||
|
||||
// Handle specific fields based on the type
|
||||
switch ($jsonData['type']) {
|
||||
case 'article':
|
||||
$articleName = $jsonData['object']['name'] ?? null;
|
||||
$articleOwnerName = $jsonData['object']['ownerName'] ?? null;
|
||||
// Set Create-level fields
|
||||
$updatedOn = $jsonData['object']['modified'] ?? null;
|
||||
$originalPublished = $jsonData['object']['published'] ?? null;
|
||||
$update = $updatedOn !== $originalPublished;
|
||||
$ap['published'] = $updatedOn ?? $originalPublished;
|
||||
$ap['id'] = $ourUrl . "/" . $articleOwnerName . "/" . $articleName;
|
||||
$ap['url'] = $ourUrl . "/" . $articleOwnerName . "/" . $articleName;
|
||||
$ap['type'] = $update ? 'Update' : 'Create';
|
||||
$ap['actor'] = $ourUrl . '/' . $actorName;
|
||||
// Set Article-level fields
|
||||
$ap['object'] = [
|
||||
'type' => 'Article',
|
||||
'id' => $ourUrl . "/" . $articleOwnerName . "/" . $articleName,
|
||||
'name' => $jsonData['object']['name'] ?? null,
|
||||
'published' => $originalPublished,
|
||||
'summary' => $jsonData['object']['summary'] ?? null,
|
||||
'content' => $jsonData['object']['content'] ?? null,
|
||||
'attributedTo' => $ap['actor'],
|
||||
'url' => $ap['url'],
|
||||
'cc' => ['https://www.w3.org/ns/activitystreams#Public'],
|
||||
];
|
||||
if ($update) {
|
||||
$ap['id'] .= '#update';
|
||||
$ap['url'] .= '#update';
|
||||
$ap['object']['updated'] = $updatedOn;
|
||||
}
|
||||
$ap['cc'] = ['https://www.w3.org/ns/activitystreams#Public'];
|
||||
if (isset($jsonData['object']['tags'])) {
|
||||
if (is_array($jsonData['object']['tags'])) {
|
||||
foreach ($jsonData['object']['tags'] as $tag) {
|
||||
$ap['object']['tags'][] = $tag;
|
||||
}
|
||||
} elseif (is_string($jsonData['object']['tags']) && $jsonData['object']['tags'] !== '') {
|
||||
// If it's a single tag as a string, add it as a one-element array
|
||||
$ap['object']['tags'][] = $jsonData['object']['tags'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($jsonData['options'])) {
|
||||
if (isset($jsonData['options']['informFollowers'])) {
|
||||
if ($jsonData['options']['informFollowers'] === true) {
|
||||
$ap['to'][] = $ourUrl . '/' . $actorName . '/followers';
|
||||
$ap['object']['to'][] = $ourUrl . '/' . $actorName . '/followers';
|
||||
}
|
||||
}
|
||||
}
|
||||
$returnActivity = \Federator\Data\ActivityPub\Factory::newActivityFromJson($ap);
|
||||
if ($returnActivity === false) {
|
||||
error_log("ContentNation::jsonToActivity couldn't create article");
|
||||
$returnActivity = new \Federator\Data\ActivityPub\Common\Activity('Create');
|
||||
} else {
|
||||
$returnActivity->setID($ap['id']);
|
||||
$returnActivity->setURL($ap['url']);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'comment':
|
||||
$commentId = $jsonData['object']['id'] ?? null;
|
||||
$articleName = $jsonData['object']['articleName'] ?? null;
|
||||
|
@ -411,7 +470,7 @@ class ContentNation implements Connector
|
|||
if (isset($jsonData['options'])) {
|
||||
if (isset($jsonData['options']['informFollowers'])) {
|
||||
if ($jsonData['options']['informFollowers'] === true) {
|
||||
if ($actorName != $articleOwnerName) {
|
||||
if ($actorName !== $articleOwnerName) {
|
||||
$ap['to'][] = $ourUrl . '/' . $articleOwnerName;
|
||||
}
|
||||
$ap['to'][] = $ourUrl . '/' . $actorName . '/followers';
|
||||
|
@ -427,8 +486,13 @@ class ContentNation implements Connector
|
|||
error_log("ContentNation::jsonToActivity unknown inReplyTo type: {$replyType}");
|
||||
}
|
||||
$returnActivity = \Federator\Data\ActivityPub\Factory::newActivityFromJson($ap);
|
||||
$returnActivity->setID($ap['id']);
|
||||
$returnActivity->setURL($ap['url']);
|
||||
if ($returnActivity === false) {
|
||||
error_log("ContentNation::jsonToActivity couldn't create comment");
|
||||
$returnActivity = new \Federator\Data\ActivityPub\Common\Activity('Create');
|
||||
} else {
|
||||
$returnActivity->setID($ap['id']);
|
||||
$returnActivity->setURL($ap['url']);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'vote':
|
||||
|
@ -487,8 +551,19 @@ class ContentNation implements Connector
|
|||
} */
|
||||
|
||||
$returnActivity = \Federator\Data\ActivityPub\Factory::newActivityFromJson($ap);
|
||||
$returnActivity->setID($ap['id']);
|
||||
$returnActivity->setURL($ap['url']);
|
||||
if ($returnActivity === false) {
|
||||
error_log("ContentNation::jsonToActivity couldn't create vote");
|
||||
if ($ap['type'] === "Like") {
|
||||
$returnActivity = new \Federator\Data\ActivityPub\Common\Like();
|
||||
} elseif ($ap['type'] === "Dislike") {
|
||||
$returnActivity = new \Federator\Data\ActivityPub\Common\Dislike();
|
||||
} else {
|
||||
$returnActivity = new \Federator\Data\ActivityPub\Common\Undo();
|
||||
}
|
||||
} else {
|
||||
$returnActivity->setID($ap['id']);
|
||||
$returnActivity->setURL($ap['url']);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Add table
Reference in a new issue