activitypub-1.0.x-dev/src/Services/ActivityPubUtility.php

src/Services/ActivityPubUtility.php
<?php

namespace Drupal\activitypub\Services;

use ActivityPhp\Server;
use Drupal\activitypub\Entity\ActivityPubActivityInterface;
use Drupal\activitypub\Entity\ActivityPubActorInterface;
use Drupal\activitypub\Event\VisibilityOptionsEvent;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileUrlGeneratorInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\file\Entity\File;
use Drupal\media\MediaInterface;
use Drupal\user\UserInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

class ActivityPubUtility implements ActivityPubUtilityInterface {

  Use StringTranslationTrait;

  /**
   * The image style storage.
   *
   * @var \Drupal\image\ImageStyleStorageInterface
   */
  protected $imageStyleStorage;

  /**
   * The actor storage.
   *
   * @var \Drupal\activitypub\Entity\Storage\ActivityPubActorStorageInterface
   */
  protected $actorStorage;

  /**
   * The activitypub storage.
   *
   * @var \Drupal\activitypub\Entity\Storage\ActivityPubActivityStorageInterface
   */
  protected $activityStorage;

  /**
   * The request stack
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack $requestStack
   */
  protected $requestStack;

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The file url generator.
   *
   * @var \Drupal\Core\File\FileUrlGeneratorInterface
   */
  protected $fileUrlGenerator;

  /**
   * The event dispatcher.
   *
   * @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface
   */
  protected $eventDispatcher;

  /**
   * The ActivityPub signature service.
   *
   * @var \Drupal\activitypub\Services\ActivityPubSignatureInterface
   */
  protected $activityPubSignature;

  /**
   * ActivityPubUtility constructor
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\activitypub\Services\ActivityPubSignatureInterface $activitypub_signature
   *   The ActivityPub Signature service.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator
   *   The file url generator.
   * @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $event_dispatcher
   *   The event dispatcher service.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, ActivityPubSignatureInterface $activitypub_signature, RequestStack $request_stack, ConfigFactoryInterface $config_factory, FileUrlGeneratorInterface $file_url_generator, EventDispatcherInterface $event_dispatcher) {
    $this->imageStyleStorage = $entity_type_manager->getStorage('image_style');
    $this->actorStorage = $entity_type_manager->getStorage('activitypub_actor');
    $this->activityStorage = $entity_type_manager->getStorage('activitypub_activity');
    $this->activityPubSignature = $activitypub_signature;
    $this->requestStack = $request_stack;
    $this->configFactory = $config_factory;
    $this->fileUrlGenerator = $file_url_generator;
    $this->eventDispatcher = $event_dispatcher;
  }

  /**
   * {@inheritdoc}
   */
  public function getActivityPubName(ActivityPubActorInterface $actor) {
    return $actor->getName() . '@' . $this->requestStack->getCurrentRequest()->getHost();
  }

  /**
   * {@inheritdoc}
   */
  public function getActivityPubID(ActivityPubActorInterface $actor) {
    return $this->requestStack->getCurrentRequest()->getSchemeAndHttpHost() . $this->requestStack->getCurrentRequest()->getBasePath() . '/user/' . $actor->getOwnerId() . '/activitypub/' . $actor->getName();
  }

  /**
   * {@inheritdoc}
   */
  public function getActivityPubUserImage(UserInterface $user, string $type = 'avatar') {
    $image_url = NULL;
    $config = $this->configFactory->get('activitypub.settings');
    $image_user_field = $config->get($type . '_user_field');
    /** @var \Drupal\file\FileInterface $image */
    if ($image = $this->getUserImage($user, $image_user_field)) {

      /** @var \Drupal\image\ImageStyleInterface $image_style */
      $image_style = $this->imageStyleStorage->load($config->get($type . '_user_style'));
      $image_url = $image_style->buildUrl($image->getFileUri());
    }
    elseif ($type == 'avatar') {
      $avatar_path = $config->get('avatar_default_path');
      if ($avatar_path == 'assets/avatar.png') {
        $avatar_path = \Drupal::service('extension.list.module')->getPath('activitypub') . '/' . $avatar_path;
      }
      $image_url = $this->fileUrlGenerator->generateAbsoluteString($avatar_path);
    }

    return $image_url;
  }

  /**
   * Get the file entity for a given user field which can be a file or media
   * field.
   *
   * @param \Drupal\user\UserInterface $user
   *   The user.
   * @param string $image_user_field
   *   The field name.
   *
   * @return \Drupal\file\Entity\File|null
   */
  private function getUserImage(UserInterface $user, string $image_user_field): ?File {
    $image = NULL;
    if (!empty($image_user_field) &&
      $user->hasField($image_user_field) &&
      ($image = $user->get($image_user_field)->entity)) {
      if ($image instanceof MediaInterface) {
        $fid = $image->getSource()->getSourceFieldValue($image);
        $image = File::load($fid);
      }
    }
    return $image;
  }

  /**
   * {@inheritdoc}
   */
  public function getServer(array $config = []) {
    $config += [
      'cache' => [
        'ttl' => activitypub_cache_ttl(),
        'stream' => activitypub_cache_path()
      ],
      'logger'   => [
        'driver' => '\Psr\Log\NullLogger'
      ],
    ];

    // Override for tests.
    if ($test_prefix = drupal_valid_test_ua()) {
      $config['cache'] = ['enabled' => FALSE];
      $config['http']['agent'] = drupal_generate_test_ua($test_prefix);
    }

    $config['instance']['types'] = 'ignore';
    return new Server($config);
  }

  /**
   * {@inheritdoc}
   */
  public function alterNodeInfo(array &$data) {
    $data['protocols'] = ['activitypub'];
    $data['usage']['users']['total'] = $this->actorStorage->getActorCount(['status' => 1]);
    $data['usage']['localPosts'] = $this->activityStorage->getActivityCount(['collection' => ['outbox', 'liked'], 'status' => 1, 'visibility' => ActivityPubActivityInterface::VISIBILITY_PUBLIC]);
  }

  /**
   * {@inheritdoc}
   */
  public function onEntityDelete(EntityInterface $entity) {
    if ($entity instanceof ContentEntityInterface && !($entity instanceof ActivityPubActivityInterface)) {
      if ($entity instanceof UserInterface) {
        $actors = $this->actorStorage->loadByProperties(['uid' => $entity->id()]);
        $this->actorStorage->delete($actors);
      }
      elseif ($entity instanceof ActivityPubActorInterface) {
        $this->activityPubSignature->deleteKeys($entity->getName());
        $activities = $this->activityStorage->loadByProperties(['uid' => $entity->getOwnerId()]);
        $this->activityStorage->delete($activities);
      }
      elseif (method_exists($entity, 'getOwnerId')) {
        // Find a single activity for this entity.
        $conditions = [
          'uid' => $entity->getOwnerId() ,
          'entity_id' => $entity->id(),
          'entity_type_id' => $entity->getEntityTypeId(),
          'collection' => ActivityPubActivityInterface::OUTBOX
        ];
        $activities = $this->activityStorage->loadByProperties($conditions);
        if (count($activities) == 1) {
          /** @var \Drupal\activitypub\Entity\ActivityPubActivityInterface $activity */
          $activity = array_shift($activities);
          $activity->onEntityDelete($entity);
          $activity->delete();
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getVisibilityOptions() {
    $options = [
      ActivityPubActivityInterface::VISIBILITY_PUBLIC => $this->t('Public'),
      ActivityPubActivityInterface::VISIBILITY_FOLLOWERS => $this->t('Followers'),
      ActivityPubActivityInterface::VISIBILITY_UNLISTED => $this->t('Unlisted'),
      ActivityPubActivityInterface::VISIBILITY_PRIVATE => $this->t('Private'),
    ];

    $event = new VisibilityOptionsEvent($options);
    $this->eventDispatcher->dispatch($event, VisibilityOptionsEvent::ADD_OPTIONS);
    return $event->getVisibilityOptions();
  }

  /**
   * {@inheritdoc}
   */
  public function getOutboxIgnoreTypes() {
    return ['Follow', 'Undo', 'Delete'];
  }

  /**
   * {@inheritdoc}
   */
  public function getTimelineTypes() {
    return ['Create', 'Like', 'Announce'];
  }

  /**
   * {@inheritdoc}
   */
  public function getNotificationTypes() {
    return ['Like', 'Announce', 'Follow', 'Create'];
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc