proper support for undoing votes and articles

- added option to remove the like/dislike from an article/comment with creating the correct Undo activity
- added option to remove article with creating the correct Undo activity
- fixed problem where post might not be accepted/saved when no receiver was set (posterName was previously excluded from receivers)
This commit is contained in:
Yannis Vogel 2025-05-23 13:42:15 +02:00
parent 572bb376c1
commit 7a5870de95
No known key found for this signature in database
3 changed files with 284 additions and 198 deletions

View file

@ -149,11 +149,6 @@ class NewContent implements \Federator\Api\APIInterface
} }
if (str_ends_with($receiver, '/followers')) { 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) { if ($posterName === null) {
error_log("NewContent::post no username found"); error_log("NewContent::post no username found");
@ -177,6 +172,10 @@ class NewContent implements \Federator\Api\APIInterface
$receiverName = basename((string) (parse_url($receiver, PHP_URL_PATH) ?? '')); $receiverName = basename((string) (parse_url($receiver, PHP_URL_PATH) ?? ''));
$domain = parse_url($receiver, PHP_URL_HOST); $domain = parse_url($receiver, PHP_URL_HOST);
if ($receiverName === null || $domain === null) { if ($receiverName === null || $domain === null) {
if ($receiver === $posterName) {
$users[] = $receiver;
continue;
}
error_log("NewContent::post no receiverName or domain found for receiver: " . $receiver); error_log("NewContent::post no receiverName or domain found for receiver: " . $receiver);
continue; continue;
} }
@ -327,15 +326,15 @@ class NewContent implements \Federator\Api\APIInterface
error_log("NewContent::postForUser: Failed to remove follower for user $user->id"); error_log("NewContent::postForUser: Failed to remove follower for user $user->id");
} }
break; break;
case 'Vote': case 'Like':
// Undo Vote (remove vote) case 'Dislike':
if (method_exists($object, 'getObject')) { if (method_exists($object, 'getObject')) {
$targetId = $object->getObject(); $targetId = $object->getObject();
if (is_string($targetId)) { if (is_string($targetId)) {
// \Federator\DIO\Votes::removeVote($dbh, $user->id, $targetId); // \Federator\DIO\Votes::removeVote($dbh, $user->id, $targetId);
\Federator\DIO\Posts::deletePost($dbh, $targetId); \Federator\DIO\Posts::deletePost($dbh, $targetId);
} else { } else {
error_log("NewContent::postForUser: Error in Undo Vote for user $user->id, targetId is not a string"); error_log("NewContent::postForUser: Error in Undo Like/Dislike for user $user->id, targetId is not a string");
} }
} }
break; break;
@ -346,6 +345,15 @@ class NewContent implements \Federator\Api\APIInterface
\Federator\DIO\Posts::deletePost($dbh, $noteId); \Federator\DIO\Posts::deletePost($dbh, $noteId);
} }
break; break;
case 'Article':
// Undo Article (remove article)
if (method_exists($object, 'getID')) {
$articleId = $object->getID();
\Federator\DIO\Posts::deletePost($dbh, $articleId);
// also remove latest saved article-update
\Federator\DIO\Posts::deletePost($dbh, $articleId . '#update');
}
break;
} }
} else if (is_string($object)) { } else if (is_string($object)) {
\Federator\DIO\Posts::deletePost($dbh, $object); \Federator\DIO\Posts::deletePost($dbh, $object);
@ -355,25 +363,14 @@ class NewContent implements \Federator\Api\APIInterface
break; break;
case 'Like': case 'Like':
// Add Like case 'Dislike':
// Add Like/Dislike
$targetId = $newActivity->getObject(); $targetId = $newActivity->getObject();
if (is_string($targetId)) { if (is_string($targetId)) {
// \Federator\DIO\Votes::addVote($dbh, $user->id, $targetId, 'like'); // \Federator\DIO\Votes::addVote($dbh, $user->id, $targetId, 'like');
\Federator\DIO\Posts::savePost($dbh, $user->id, $newActivity); \Federator\DIO\Posts::savePost($dbh, $user->id, $newActivity);
} else { } else {
error_log("NewContent::postForUser: Error in Add Like for user $user->id, targetId is not a string"); error_log("NewContent::postForUser: Error in Add Like/Dislike for user $user->id, targetId is not a string");
return false;
}
break;
case 'Dislike':
// Add Dislike
$targetId = $newActivity->getObject();
if (is_string($targetId)) {
// \Federator\DIO\Votes::addVote($dbh, $user->id, $targetId, 'dislike');
\Federator\DIO\Posts::savePost($dbh, $user->id, $newActivity);
} else {
error_log("NewContent::postForUser: Error in Add Dislike for user $user->id, targetId is not a string");
return false; return false;
} }
break; break;

View file

@ -58,6 +58,12 @@ class Factory
case 'Vote': case 'Vote':
$return = new Common\Vote(); $return = new Common\Vote();
break; break;
case 'Like':
$return = new Common\Like();
break;
case 'Dislike':
$return = new Common\Dislike();
break;
case 'Inbox': case 'Inbox':
$return = new Common\Inbox(); $return = new Common\Inbox();
break; break;

View file

@ -368,7 +368,7 @@ class ContentNation implements Connector
* @param array<string, mixed> $jsonData the json data from our platfrom * @param array<string, mixed> $jsonData the json data from our platfrom
* @return \Federator\Data\ActivityPub\Common\Activity|false * @return \Federator\Data\ActivityPub\Common\Activity|false
*/ */
public function jsonToActivity(array $jsonData) public function jsonToActivity($jsonData)
{ {
$returnActivity = false; $returnActivity = false;
// Common fields for all activity types // Common fields for all activity types
@ -390,190 +390,273 @@ class ContentNation implements Connector
$ap['actor'] = $ourUrl . '/' . $actorName; $ap['actor'] = $ourUrl . '/' . $actorName;
// Handle specific fields based on the type if (isset($jsonData['type'])) {
switch ($jsonData['type']) { switch ($jsonData['type']) {
case 'article': case 'undo':
$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']['title'] ?? 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;
$articleOwnerName = $jsonData['object']['articleOwnerName'] ?? null;
// Set Create-level fields
$ap['published'] = $jsonData['object']['published'] ?? null;
$ap['id'] = $ourUrl . "/" . $articleOwnerName . "/" . $articleName . "#" . $commentId;
$ap['url'] = $ourUrl . "/" . $articleOwnerName . "/" . $articleName . "#" . $commentId;
$ap['type'] = 'Create';
$ap['object'] = [
'type' => 'Note',
'id' => $ourUrl . "/" . $articleOwnerName . "/" . $articleName . "#" . $commentId,
'content' => $jsonData['object']['content'] ?? null,
'summary' => $jsonData['object']['summary'] ?? null,
];
$ap['cc'] = ['https://www.w3.org/ns/activitystreams#Public'];
if (isset($jsonData['options'])) {
if (isset($jsonData['options']['informFollowers'])) {
if ($jsonData['options']['informFollowers'] === true) {
if ($actorName !== $articleOwnerName) {
$ap['to'][] = $ourUrl . '/' . $articleOwnerName;
}
$ap['to'][] = $ourUrl . '/' . $actorName . '/followers';
}
}
}
$replyType = $jsonData['object']['inReplyTo']['type'] ?? null;
if ($replyType === "article") {
$ap['object']['inReplyTo'] = $ourUrl . "/" . $articleOwnerName . "/" . $articleName;
} elseif ($replyType === "comment") {
$ap['object']['inReplyTo'] = $ourUrl . "/" . $articleOwnerName . "/" . $articleName . "#" . $jsonData['object']['inReplyTo']['id'];
} else {
error_log("ContentNation::jsonToActivity unknown inReplyTo type: {$replyType}");
}
$returnActivity = \Federator\Data\ActivityPub\Factory::newActivityFromJson($ap);
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':
$votedOn = $jsonData['object']['type'] ?? null;
$articleName = $jsonData['object']['articleName'] ?? null;
$articleOwnerName = $jsonData['object']['articleOwnerName'] ?? null;
$voteId = $jsonData['object']['id'] ?? null;
$ap['id'] = $ourUrl . '/' . $articleOwnerName . '/' . $articleName . '#' . $voteId;
$ap['url'] = $ourUrl . '/' . $articleOwnerName . '/' . $articleName . '#' . $voteId;
if (
isset($jsonData['vote']['type']) &&
strtolower($jsonData['vote']['type']) === 'undo'
) {
$ap['type'] = 'Undo'; $ap['type'] = 'Undo';
} elseif ($jsonData['vote']['value'] == 1) { $ap['actor'] = $ourUrl . '/' . $actorName;
$ap['type'] = 'Like'; $objectType = $jsonData['object']['type'] ?? null;
} elseif ($jsonData['vote']['value'] == 0) { if ($objectType === "article") {
$ap['type'] = 'Dislike'; $articleName = $jsonData['object']['name'] ?? null;
} else { $ownerName = $jsonData['object']['ownerName'] ?? null;
error_log("ContentNation::jsonToActivity unknown vote type: {$jsonData['vote']['type']} and value: {$jsonData['vote']['value']}"); $ap['id'] = $ourUrl . '/' . $ownerName . '/' . $articleName . '/undo';
break; $ap['object'] = self::generateObjectJson($ourUrl, $jsonData);
} } elseif ($objectType === "comment") {
$articleName = $jsonData['object']['articleName'] ?? null;
$objectId = $ourUrl . '/' . $articleOwnerName . '/' . $articleName; $ownerName = $jsonData['object']['articleOwnerName'] ?? null;
if ($votedOn === "comment") { $commentId = $jsonData['object']['id'] ?? null;
$objectId .= '#' . $jsonData['object']['commentId']; $ap['id'] = $ourUrl . '/' . $ownerName . '/' . $articleName . '#' . $commentId . '/undo';
} $ap['object'] = self::generateObjectJson($ourUrl, $jsonData);
} elseif ($objectType === "vote") {
$ap['object'] = $objectId; $id = $jsonData['object']['id'] ?? null;
$articleName = $jsonData['object']['articleName'] ?? null;
if ($ap['type'] === "Undo") { $articleOwnerName = $jsonData['object']['articleOwnerName'] ?? null;
$ap['object'] = $ap['id']; $ap['id'] = $ourUrl . '/' . $articleOwnerName . '/' . $articleName . '#' . $id . '/undo';
} $ap['published'] = $jsonData['object']['published'] ?? null;
$ap['actor'] = $ourUrl . '/' . $actorName;
/* if ($ap['type'] === 'Undo') { $ap['object']['id'] = $ourUrl . '/' . $articleOwnerName . '/' . $articleName . '#' . $id;
$ap['object'] = [ $ap['object']['url'] = $ourUrl . '/' . $articleOwnerName . '/' . $articleName . '#' . $id;
'id' => $objectId, $ap['object']['actor'] = $ourUrl . '/' . $actorName;
'type' => 'Vote', if ($jsonData['object']['vote']['value'] == 1) {
]; $ap['object']['type'] = 'Like';
} else if ( } elseif ($jsonData['object']['vote']['value'] == 0) {
isset($jsonData['object']['type']) && $ap['object']['type'] = 'Dislike';
$jsonData['object']['type'] === 'Article' } else {
) { error_log("ContentNation::jsonToActivity unknown vote value: {$jsonData['object']['vote']['value']}");
$ap['object'] = [ break;
'id' => $objectId, }
'type' => $jsonData['object']['type'], $ap['object']['object'] = self::generateObjectJson($ourUrl, $jsonData);
'name' => $jsonData['object']['name'] ?? null,
'author' => $jsonData['object']['author'] ?? null,
];
} else if ($jsonData['object']['type'] === 'Comment') {
$ap['object'] = [
'id' => $objectId,
'type' => 'Note',
'author' => $jsonData['object']['author'] ?? null,
];
} */
$returnActivity = \Federator\Data\ActivityPub\Factory::newActivityFromJson($ap);
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 { } else {
$returnActivity = new \Federator\Data\ActivityPub\Common\Undo(); error_log("ContentNation::jsonToActivity unknown undo type: {$objectType}");
break;
} }
} else { $returnActivity = \Federator\Data\ActivityPub\Factory::newActivityFromJson($ap);
$returnActivity->setID($ap['id']); if ($returnActivity === false) {
$returnActivity->setURL($ap['url']); error_log("ContentNation::jsonToActivity couldn't create undo");
} $returnActivity = new \Federator\Data\ActivityPub\Common\Undo();
break; } else {
$returnActivity->setID($ap['id']);
$returnActivity->setURL($ap['id']);
}
break;
default:
// Handle unsupported types or fallback to default behavior
throw new \InvalidArgumentException("ContentNation::jsonToActivity Unsupported type: {$jsonData['type']}");
}
} else {
// Handle specific fields based on the type
switch ($jsonData['object']['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;
if ($update) {
$ap['id'] .= '#update';
$ap['url'] .= '#update';
}
$ap['cc'] = ['https://www.w3.org/ns/activitystreams#Public'];
default: if (isset($jsonData['options'])) {
// Handle unsupported types or fallback to default behavior if (isset($jsonData['options']['informFollowers'])) {
throw new \InvalidArgumentException("ContentNation::jsonToActivity Unsupported activity type: {$jsonData['type']}"); if ($jsonData['options']['informFollowers'] === true) {
$ap['to'][] = $ourUrl . '/' . $actorName . '/followers';
}
}
}
$ap['object'] = self::generateObjectJson($ourUrl, $jsonData);
$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;
$articleOwnerName = $jsonData['object']['articleOwnerName'] ?? null;
// Set Create-level fields
$ap['published'] = $jsonData['object']['published'] ?? null;
$ap['actor'] = $ourUrl . '/' . $actorName;
$ap['id'] = $ourUrl . "/" . $articleOwnerName . "/" . $articleName . "#" . $commentId;
$ap['url'] = $ourUrl . "/" . $articleOwnerName . "/" . $articleName . "#" . $commentId;
$ap['type'] = 'Create';
$ap['cc'] = ['https://www.w3.org/ns/activitystreams#Public'];
if (isset($jsonData['options'])) {
if (isset($jsonData['options']['informFollowers'])) {
if ($jsonData['options']['informFollowers'] === true) {
if ($actorName !== $articleOwnerName) {
$ap['to'][] = $ourUrl . '/' . $articleOwnerName;
}
$ap['to'][] = $ourUrl . '/' . $actorName . '/followers';
}
}
}
$ap['object'] = self::generateObjectJson($ourUrl, $jsonData);
$returnActivity = \Federator\Data\ActivityPub\Factory::newActivityFromJson($ap);
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':
$articleName = $jsonData['object']['articleName'] ?? null;
$articleOwnerName = $jsonData['object']['articleOwnerName'] ?? null;
$voteId = $jsonData['object']['id'] ?? null;
$ap['published'] = $jsonData['object']['published'] ?? null;
$ap['actor'] = $ourUrl . '/' . $actorName;
$ap['id'] = $ourUrl . '/' . $articleOwnerName . '/' . $articleName . '#' . $voteId;
$ap['url'] = $ourUrl . '/' . $articleOwnerName . '/' . $articleName . '#' . $voteId;
if ($jsonData['object']['vote']['value'] == 1) {
$ap['type'] = 'Like';
} elseif ($jsonData['object']['vote']['value'] == 0) {
$ap['type'] = 'Dislike';
} else {
error_log("ContentNation::jsonToActivity unknown vote value: {$jsonData['object']['vote']['value']}");
break;
}
$ap['object'] = self::generateObjectJson($ourUrl, $jsonData);
$returnActivity = \Federator\Data\ActivityPub\Factory::newActivityFromJson($ap);
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:
// Handle unsupported types or fallback to default behavior
throw new \InvalidArgumentException("ContentNation::jsonToActivity Unsupported object type: {$jsonData['type']}");
}
} }
return $returnActivity; return $returnActivity;
} }
/**
* Convert jsonData to Activity format
*
* @param string $ourUrl the url of our instance
* @param array<string, mixed> $jsonData the json data from our platfrom
* @return array|string|false the json object data or false
*/
private static function generateObjectJson($ourUrl, $jsonData)
{
$objectType = $jsonData['object']['type'] ?? null;
$actorData = $jsonData['actor'] ?? null;
$actorName = $actorData['name'] ?? null;
$actorUrl = $ourUrl . '/' . $actorName;
if ($objectType === "article") {
$articleName = $jsonData['object']['name'] ?? null;
$articleOwnerName = $jsonData['object']['ownerName'] ?? null;
$updatedOn = $jsonData['object']['modified'] ?? null;
$originalPublished = $jsonData['object']['published'] ?? null;
$update = $updatedOn !== $originalPublished;
$returnJson = [
'type' => 'Article',
'id' => $ourUrl . "/" . $articleOwnerName . "/" . $articleName,
'name' => $jsonData['object']['title'] ?? null,
'published' => $originalPublished,
'summary' => $jsonData['object']['summary'] ?? null,
'content' => $jsonData['object']['content'] ?? null,
'attributedTo' => $actorUrl,
'url' => $ourUrl . "/" . $articleOwnerName . "/" . $articleName,
'cc' => ['https://www.w3.org/ns/activitystreams#Public'],
];
if ($update) {
$returnJson['updated'] = $updatedOn;
}
if (isset($jsonData['object']['tags'])) {
if (is_array($jsonData['object']['tags'])) {
foreach ($jsonData['object']['tags'] as $tag) {
$returnJson['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
$returnJson['tags'][] = $jsonData['object']['tags'];
}
}
if (isset($jsonData['options'])) {
if (isset($jsonData['options']['informFollowers'])) {
if ($jsonData['options']['informFollowers'] === true) {
$returnJson['to'][] = $ourUrl . '/' . $actorName . '/followers';
}
}
}
} elseif ($objectType === "comment") {
$commentId = $jsonData['object']['id'] ?? null;
$articleName = $jsonData['object']['articleName'] ?? null;
$articleOwnerName = $jsonData['object']['articleOwnerName'] ?? null;
$returnJson = [
'type' => 'Note',
'id' => $ourUrl . "/" . $articleOwnerName . "/" . $articleName . "#" . $commentId,
'url' => $ourUrl . "/" . $articleOwnerName . "/" . $articleName . "#" . $commentId,
'attributedTo' => $actorUrl,
'content' => $jsonData['object']['content'] ?? null,
'summary' => $jsonData['object']['summary'] ?? null,
'published' => $jsonData['object']['published'] ?? null,
'cc' => ['https://www.w3.org/ns/activitystreams#Public'],
];
if (isset($jsonData['options'])) {
if (isset($jsonData['options']['informFollowers'])) {
if ($jsonData['options']['informFollowers'] === true) {
$returnJson['to'][] = $ourUrl . '/' . $actorName . '/followers';
}
}
}
$replyType = $jsonData['object']['inReplyTo']['type'] ?? null;
if ($replyType === "article") {
$returnJson['object']['inReplyTo'] = $ourUrl . "/" . $articleOwnerName . "/" . $articleName;
} elseif ($replyType === "comment") {
$returnJson['object']['inReplyTo'] = $ourUrl . "/" . $articleOwnerName . "/" . $articleName . "#" . $jsonData['object']['inReplyTo']['id'];
} else {
error_log("ContentNation::generateObjectJson for comment - unknown inReplyTo type: {$replyType}");
}
} elseif ($objectType === "vote") {
$votedOn = $jsonData['object']['type'] ?? null;
$articleName = $jsonData['object']['articleName'] ?? null;
$articleOwnerName = $jsonData['object']['articleOwnerName'] ?? null;
$objectId = $ourUrl . '/' . $articleOwnerName . '/' . $articleName;
if ($votedOn === "comment") {
$objectId .= '#' . $jsonData['object']['commentId'];
}
$returnJson = $objectId;
} else {
error_log("ContentNation::generateObjectJson unknown object type: {$objectType}");
return false;
}
return $returnJson;
}
/** /**
* check if the headers include a valid signature * check if the headers include a valid signature
* *