activitypub-1.0.x-dev/src/Plugin/activitypub/type/Comment.php
src/Plugin/activitypub/type/Comment.php
<?php
namespace Drupal\activitypub\Plugin\activitypub\type;
use Drupal\activitypub\Entity\ActivityPubActivityInterface;
use Drupal\activitypub\Services\Type\TypePluginBase;
use Drupal\comment\CommentInterface;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeInterface;
/**
* The ActivityPub comment.
*
* @ActivityPubType(
* id = "activitypub_comment",
* label = @Translation("Comment"),
* )
*/
class Comment extends TypePluginBase {
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'comment_type' => 'comment',
'comment_body_field' => 'comment_body',
'activity_reference_field' => 'activitypub_activity',
'node_comment_field' => 'comment',
'comment_status' => TRUE,
'comment_filter_format' => 'restricted_html',
];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$default_values = $this->getConfiguration();
$filter_formats = [];
foreach (filter_formats() as $key => $format) {
$filter_formats[$key] = $format->label();
}
$form['comment_type'] = [
'#type' => 'textfield',
'#title' => $this->t('Comment type (Bundle)'),
'#default_value' => $default_values['comment_type'],
];
$form['comment_body_field'] = [
'#type' => 'textfield',
'#title' => $this->t('Comment body field'),
'#default_value' => $default_values['comment_body_field'],
];
$form['activity_reference_field'] = [
'#type' => 'textfield',
'#title' => $this->t('Activity reference field on comment'),
'#default_value' => $default_values['activity_reference_field'],
];
$form['node_comment_field'] = [
'#type' => 'textfield',
'#title' => $this->t('Activity reference field on comment'),
'#default_value' => $default_values['node_comment_field'],
];
$form['comment_status'] = [
'#type' => 'checkbox',
'#title' => $this->t('Default comment status'),
'#default_value' => $default_values['comment_status'],
];
$form['comment_filter_format'] = [
'#type' => 'select',
'#title' => $this->t('Comment filter format'),
'#options' => $filter_formats,
'#default_value' => $default_values['comment_filter_format'],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function onActivityPostSave(ActivityPubActivityInterface $activity, $update = TRUE) {
if ($activity->getType() == 'Create' && !$update && $activity->getCollection() == ActivityPubActivityInterface::INBOX && $activity->getReply()) {
// Is the inbox_reply config entity enabled or not.
/** @var \Drupal\activitypub\Entity\ActivityPubTypeInterface $activityPubType */
$activityPubType = $this->entityTypeManager->getStorage('activitypub_type')->load('inbox_reply');
if ($activityPubType && $activityPubType->isEnabled()) {
$activity->set('config_id', 'inbox_reply');
$this->activityPubProcessClient->createQueueItem($activity);
}
}
}
/**
* {@inheritdoc}
*/
public function doInboxProcess(ActivityPubActivityInterface $activity, EntityInterface $entity = NULL) {
if ($activity->getType() == 'Create' && $activity->getReply()) {
$this->handleCommentCreation($activity);
}
}
/**
* {@inheritdoc}
*/
public function onActivityDelete(ActivityPubActivityInterface $activity) {
if ($activity->getReply() && $activity->typeIsEnabled('inbox_reply')) {
try {
/** @var \Drupal\activitypub\Entity\ActivityPubTypeInterface $activityPubType */
$activityPubType = $this->entityTypeManager->getStorage('activitypub_type')->load('inbox_reply');
$configuration = $activityPubType->getPlugin()['configuration'];
$comment_storage = $this->entityTypeManager->getStorage('comment');
$comment_type = $configuration['comment_type'];
$activity_reference_field = $configuration['activity_reference_field'];
$cp = ['comment_type' => $comment_type, $activity_reference_field => $activity->id()];
foreach ($comment_storage->loadByProperties($cp) as $c) {
$c->delete();
}
}
catch (\Exception $e) {
$this->logger->error('Error deleting comment when activity is deleted: @message', ['@message' => $e->getMessage()]);
}
}
}
/**
* Handle comment creation.
*
* @param \Drupal\activitypub\Entity\ActivityPubActivityInterface $activity
*/
protected function handleCommentCreation(ActivityPubActivityInterface $activity) {
$pid = 0;
$entity = self::getEntityFromUrl($activity->getReply());
try {
$node = NULL;
// This can be a reply on a comment. Get the node to attach the comment
// there and set pid.
if ($entity instanceof CommentInterface) {
if ($entity->getCommentedEntityTypeId() == 'node') {
$pid = $entity->id();
$node = $entity->getCommentedEntity();
}
}
elseif ($entity instanceof NodeInterface) {
$node = $entity;
}
// We currently support only comments on nodes.
if ($node) {
$configuration = $this->getConfiguration();
$payload = @json_decode($activity->getPayLoad(), TRUE);
$object = $payload['object'];
$comment_type = $configuration['comment_type'];
$comment_status = (int) $configuration['comment_status'];
$comment_body_field = $configuration['comment_body_field'];
$activity_reference_field = $configuration['activity_reference_field'];
$node_comment_field_name = $configuration['node_comment_field'];
$comment_filter_format = $configuration['comment_filter_format'];
if ($node->hasField($node_comment_field_name) && $node->{$node_comment_field_name}->status == 2) {
$activity->set('entity_id', $node->id());
$activity->set('entity_type_id','node');
$subject = Unicode::truncate('Reply by ' . $payload['actor'], 50, FALSE, TRUE);
$values = [
'subject' => $subject,
'name' => Unicode::truncate($payload['actor'], 50, FALSE, TRUE),
'status' => $comment_status,
'entity_id' => $node->id(),
'entity_type' => 'node',
'pid' => $pid,
$comment_body_field => [
'value' => $object['content'],
'format' => $comment_filter_format,
],
'comment_type' => $comment_type,
'field_name' => $node_comment_field_name,
$activity_reference_field => [
'target_id' => $activity->id(),
],
];
/** @var \Drupal\comment\CommentInterface $comment */
$comment = $this->entityTypeManager->getStorage('comment')->create($values);
$comment->setCreatedTime($activity->getCreatedTime());
$comment->save();
}
}
}
catch (\Exception $e) {
$this->logger->notice('Error creating comment: @message', ['@message' => $e->getMessage()]);
}
}
}
