activitypub-1.0.x-dev/src/Form/ActivitypubInteractForm.php

src/Form/ActivitypubInteractForm.php
<?php

namespace Drupal\activitypub\Form;

use Drupal\activitypub\Services\ActivityPubUtilityInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;

/**
 * The ActivityPub content interaction form.
 */
class ActivitypubInteractForm extends FormBase {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The ActivityPub utility service.
   *
   * @var \Drupal\activitypub\Services\ActivityPubUtilityInterface
   */
  protected $activityPubUtility;

  /**
   * FollowForm constructor.
   *
   * @param \Drupal\activitypub\Services\ActivityPubUtilityInterface $activitypub_utility
   *   The ActivityPub utility service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(ActivityPubUtilityInterface $activitypub_utility, EntityTypeManagerInterface $entity_type_manager) {
    $this->activityPubUtility = $activitypub_utility;
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('activitypub.utility'),
      $container->get('entity_type.manager')
      );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'activitypub_interact_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, EntityInterface $node = NULL, $interact_type = NULL) {
    $actorStorage = $this->entityTypeManager->getStorage('activitypub_actor');
    $actor = $actorStorage->loadActorByEntityIdAndType($node->getOwnerId(), 'person');
    $url = $node->toUrl('canonical', ['absolute' => TRUE])->toString();

    if ($actor) {
      $entity_type = $node->getEntityType()->id();
      $view_builder = $this->entityTypeManager->getViewBuilder($entity_type);
      $entity_storage = $this->entityTypeManager->getstorage($entity_type);
      $node_build = $view_builder->view($node, 'teaser');
      $form['content'] = $node_build;
      $form['handle'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Username'),
        '#placeholder' => $this->t('Enter your username@domain to interact from'),
        '#description' => $this->t('<strong>Why is this step necessary?</strong> <code>%domain</code> might not be the server where you are registered, so we need to redirect you to your home server first.<br/><small>You can interact with me from Mastodon or any other similar application that uses ActivityPub. If you prefer, you can try to search this status ( %url ) from your instance and interact there.</small>', ["%domain" => \Drupal::request()->getHost(), "%url" => $url]),
        '#required' => TRUE,
      ];
      $form['status'] = [
        '#type' => 'hidden',
        '#title' => $this->t('Link title'),
        '#value' => $url,
      ];

      $form['follow'] = [
        '#type' => 'submit',
        '#value' => $this->t('Proceed to %interact', ["%interact" => $interact_type]),
      ];
    }
    else {
      $form['info'] = ['#markup' => $this->t('No ActivityPub actor found')];
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $endpoint = '';
    $handle = $form_state->getValue('handle');
    try {
      $webfinger = $this->activityPubUtility->getServer()->actor($handle)->webfinger();
      $links = $webfinger->getLinks();
      foreach ($links as $link) {
        if ($link['rel'] == 'http://ostatus.org/schema/1.0/subscribe') {
          $endpoint = $link['template'];
        }
      }
    }
    catch (\Exception $e) {
      $this->logger('activitypub')->error('Error getting subscribe endpoint: @message', ['@message' => $e->getMessage()]);
    }
    if (empty($endpoint)) {
      $form_state->setErrorByName('handle', $this->t('Could not find your subscription endpoint.'));
    }
    else {
      $form_state->setValue('endpoint', $endpoint);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $handle = $form_state->getValue('handle');
    $endpoint = $form_state->getValue('endpoint');
    $status = $form_state->getValue('status');
    $redirect = str_replace('{uri}', $status, $endpoint);
    $response = new TrustedRedirectResponse($redirect);
    $form_state->setResponse($response);
  }

  /**
   * Checks access to interact with content.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   Run access checks for this account.
   * @param \Drupal\Core\Entity\EntityInterface $node
   *   The entity that the interaction is for.
   * @param string $interact_type
   *   The wanted interaction.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function access(AccountInterface $account, EntityInterface $node = NULL, $interact_type = NULL) {
    $activitypub_type_query = $this->entityTypeManager->getStorage('activitypub_type')->getQuery()->accessCheck();
    $activitypub_type_query
      ->condition('status', 1)
      ->condition('plugin.configuration.target_entity_type_id', $node->getEntityType()->id())
      ->condition('plugin.configuration.target_bundle', $node->bundle());
    $enabled_activitypub_types = $activitypub_type_query->execute();

    return AccessResult::allowedIf($enabled_activitypub_types);
  }

  /**
   * Cook the title to interact with content.
   *
   * @param \Drupal\Core\Entity\EntityInterface $node
   *   The entity that the interaction is for.
   * @param string $interact_type
   *   The wanted interaction.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function title(EntityInterface $node = NULL, $interact_type = NULL) {
    switch ($interact_type) {
      case "favourite":
        $title = $this->t("Mark %node as favourite", ["%node" => $node->label()]);
        break;

      case "announce":
        $title = $this->t("Announce %node", ["%node" => $node->label()]);
        break;

      default:
        $title = $this->t("Interact with %node", ["%node" => $node->label()]);
    }
    return $title;
  }

}

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

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