activitypub-1.0.x-dev/src/Plugin/activitypub/type/DynamicTypes.php
src/Plugin/activitypub/type/DynamicTypes.php
<?php
namespace Drupal\activitypub\Plugin\activitypub\type;
use Drupal\activitypub\Entity\ActivityPubActivityInterface;
use Drupal\activitypub\Services\Type\TypePluginBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
/**
* The ActivityPub core types.
*
* @ActivityPubType(
* id = "activitypub_dynamic_types",
* label = @Translation("Public message")
* )
*/
class DynamicTypes extends TypePluginBase {
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'target_entity_type_id' => 'node',
'target_bundle' => '',
'object' => '',
'field_mapping' => []
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function calculateDependencies() {
$dependencies = [];
$configuration = $this->getConfiguration();
if (!empty($configuration['target_entity_type_id'])) {
$dependencies['module'] = [$configuration['target_entity_type_id']];
}
if (!empty($configuration['target_entity_type_id']) && !empty($configuration['target_bundle'])) {
$dependencies['config'] = [$configuration['target_entity_type_id'] . '.type.' . $configuration['target_bundle']];
}
return $dependencies;
}
/**
* {@inheritdoc}
*/
public function getActivities() {
return [
'Create', 'Like', 'Announce',
];
}
/**
* {@inheritdoc}
*/
public function getObjects() {
return [
'Article', 'Note',
];
}
/**
* {@inheritdoc}
*/
public function getProperties($object) {
return [
'published' => 'Date',
'name' => 'Title',
'content' => 'Content',
'summary' => 'Summary',
'object' => ['label' => 'Like/Announce/Follow target', 'description' => 'This field contains the URL of the object to like/announce/follow.'],
'inReplyTo' => ['label' => 'Reply link', 'description' => 'This field contains the URL to the original post you are replying to.'],
// 'attachment' was originally reserved for 'images' only, but attachments
// can also contain other media types.
'attachment' => ['label' => 'Image attachment', 'property' => 'attachment'],
'attachment_2' => ['label' => 'Video attachment', 'property' => 'attachment'],
'attachment_3' => ['label' => 'Audio attachment', 'property' => 'attachment'],
];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$default_mapping = [];
$default_value = $this->getConfiguration()['field_mapping'];
foreach ($default_value as $v) {
$default_mapping[$v['property']] = $v['field_name'];
}
// Get bundle fields.
$bundle_fields = ['' => $this->t('- Select -')];
$field_definitions = $this->entityFieldManager->getFieldDefinitions($this->getConfiguration()['target_entity_type_id'], $this->getConfiguration()['target_bundle']);
foreach ($field_definitions as $field_definition) {
$bundle_fields[$field_definition->getFieldStorageDefinition()
->getName()] = $field_definition->getName();
}
$form['field_mapping'] = [
'#type' => 'container',
];
$properties = $this->getProperties($this->getConfiguration()['object']);
foreach ($properties as $property => $info) {
$description = '';
$label = is_array($info) ? $info['label'] : $info;
if (is_array($info) && !empty($info['description'])) {
$description = $info['description'];
}
$form['field_mapping'][] = [
'property' => [
'#type' => 'value',
'#value' => $property,
],
'field_name' => [
'#type' => 'select',
'#title' => $this->t('Property: @property', ['@property' => $label]),
'#options' => $bundle_fields,
'#default_value' => $default_mapping[$property] ?? '',
'#description' => $description,
],
];
}
return $form;
}
/**
* {@inheritdoc}
*/
public function build(ActivityPubActivityInterface $activity, EntityInterface $entity = NULL) {
$object = [
'type' => $this->getConfiguration()['object'],
'id' => $this->renderEntityUrl($entity),
'attributedTo' => $activity->getActor(),
];
foreach ($this->getConfiguration()['field_mapping'] as $mapping) {
if (!empty($mapping['field_name'])) {
if ($entity->hasField($mapping['field_name']) && ($value = $entity->get($mapping['field_name'])->getValue())) {
$field_type = $entity->get($mapping['field_name'])->getFieldDefinition()->getType();
$property = $mapping['property'];
// 'attachment' was originally reserved for 'images' only, but
// attachments can also contain other media types like video and
// audio.
if (str_contains($property, 'attachment_')) {
$property = 'attachment';
}
if ($v = $this->getValue($property, $value, $field_type)) {
if (!isset($object[$property])) {
$object[$property] = $v;
}
else {
$object[$property] = array_merge($v, $object[$property]);
}
}
}
}
}
$to = $cc = $mention = [];
$this->buildAudience($to, $cc, $mention, $activity);
$object['to'] = $to;
$object['cc'] = $cc;
// Create.
if ($this->getConfiguration()['activity'] == 'Create') {
$return = [
'type' => $this->getConfiguration()['activity'],
'id' => $this->renderEntityUrl($activity),
'actor' => $activity->getActor(),
'to' => $to,
'cc' => $cc,
'object' => $object
];
if (!empty($mention)) {
$return['object']['tag'] = [(object) $mention];
}
}
else {
$return = [
'type' => $this->getConfiguration()['activity'],
'id' => $this->renderEntityUrl($activity),
'actor' => $activity->getActor(),
'to' => $to,
'cc' => $cc,
'object' => $object['object']
];
}
return $return;
}
}
