php-plug-web3/src/Lemmy/Comment.php
Snider 79d206009c feat: extract Web3 providers from app/Plug/Web3
Bluesky, Farcaster, Lemmy, Mastodon, Nostr, Threads
providers with Core\Plug\Web3 namespace alignment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 17:28:07 +00:00

139 lines
4.2 KiB
PHP

<?php
declare(strict_types=1);
namespace Core\Plug\Web3\Lemmy;
use Core\Plug\Concern\BuildsResponse;
use Core\Plug\Concern\ManagesTokens;
use Core\Plug\Concern\UsesHttp;
use Core\Plug\Contract\Commentable;
use Core\Plug\Response;
/**
* Lemmy comment publishing.
*/
class Comment implements Commentable
{
use BuildsResponse;
use ManagesTokens;
use UsesHttp;
private string $instanceUrl = '';
/**
* Set the instance URL.
*/
public function forInstance(string $instanceUrl): self
{
$this->instanceUrl = rtrim($instanceUrl, '/');
return $this;
}
/**
* Create a comment on a post.
*
* @param string $text Comment content (markdown)
* @param string $postId Post ID to comment on
* @param array $params Optional: parent_id for replies, language_id
*/
public function comment(string $text, string $postId, array $params = []): Response
{
if (! $this->instanceUrl) {
return $this->error('Instance URL is required');
}
$commentData = [
'content' => $text,
'post_id' => (int) $postId,
];
// Handle reply to existing comment
if (isset($params['parent_id'])) {
$commentData['parent_id'] = (int) $params['parent_id'];
}
// Language
if (isset($params['language_id'])) {
$commentData['language_id'] = $params['language_id'];
}
$response = $this->http()
->withHeaders(['Authorization' => 'Bearer '.$this->accessToken()])
->post($this->instanceUrl.'/api/v3/comment', $commentData);
return $this->fromHttp($response, fn ($data) => [
'id' => $data['comment_view']['comment']['id'],
'content' => $data['comment_view']['comment']['content'],
'post_id' => $data['comment_view']['comment']['post_id'],
'ap_id' => $data['comment_view']['comment']['ap_id'],
'published' => $data['comment_view']['comment']['published'],
]);
}
/**
* Get comments for a post.
*/
public function getComments(int $postId, array $params = []): Response
{
if (! $this->instanceUrl) {
return $this->error('Instance URL is required');
}
$response = $this->http()
->withHeaders($this->authHeaders())
->get($this->instanceUrl.'/api/v3/comment/list', [
'post_id' => $postId,
'sort' => $params['sort'] ?? 'Hot', // Hot, Top, New, Old
'limit' => $params['limit'] ?? 50,
'page' => $params['page'] ?? 1,
'max_depth' => $params['max_depth'] ?? 8,
]);
return $this->fromHttp($response, fn ($data) => [
'comments' => array_map(fn ($item) => [
'id' => $item['comment']['id'],
'content' => $item['comment']['content'],
'path' => $item['comment']['path'],
'author' => $item['creator']['name'],
'upvotes' => $item['counts']['upvotes'] ?? 0,
'downvotes' => $item['counts']['downvotes'] ?? 0,
'published' => $item['comment']['published'],
], $data['comments'] ?? []),
]);
}
/**
* Edit a comment.
*/
public function edit(int $commentId, string $content): Response
{
if (! $this->instanceUrl) {
return $this->error('Instance URL is required');
}
$response = $this->http()
->withHeaders(['Authorization' => 'Bearer '.$this->accessToken()])
->put($this->instanceUrl.'/api/v3/comment', [
'comment_id' => $commentId,
'content' => $content,
]);
return $this->fromHttp($response, fn ($data) => [
'id' => $data['comment_view']['comment']['id'],
'content' => $data['comment_view']['comment']['content'],
'updated' => $data['comment_view']['comment']['updated'] ?? null,
]);
}
/**
* Get auth headers if token is available.
*/
protected function authHeaders(): array
{
$token = $this->accessToken();
return $token ? ['Authorization' => 'Bearer '.$token] : [];
}
}