activitypub-1.0.x-dev/src/Controller/FollowController.php
src/Controller/FollowController.php
<?php
namespace Drupal\activitypub\Controller;
use Drupal\activitypub\Entity\ActivityPubActivityInterface;
use Drupal\activitypub\Entity\ActivitypubActorInterface;
use Drupal\Core\Url;
use Drupal\user\UserInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
class FollowController extends BaseController {
/**
* Followers routing callback.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Drupal\user\UserInterface $user
* @param \Drupal\activitypub\Entity\ActivitypubActorInterface $activitypub_actor
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
*/
public function followers(Request $request, UserInterface $user, ActivitypubActorInterface $activitypub_actor) {
return $this->get($request, $user, $activitypub_actor, ActivityPubActivityInterface::FOLLOWERS);
}
/**
* Following routing callback.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Drupal\user\UserInterface $user
* @param \Drupal\activitypub\Entity\ActivitypubActorInterface $activitypub_actor
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
*/
public function following(Request $request, UserInterface $user, ActivitypubActorInterface $activitypub_actor) {
return $this->get($request, $user, $activitypub_actor, ActivityPubActivityInterface::FOLLOWING);
}
/**
* Helper function to get followers or following collection.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Drupal\user\UserInterface $user
* @param \Drupal\activitypub\Entity\ActivitypubActorInterface $activitypub_actor
* @param $type
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
*/
protected function get(Request $request, UserInterface $user, ActivitypubActorInterface $activitypub_actor, $type) {
$status = 400;
$data = NULL;
try {
$page = $request->get('page');
if (!isset($page)) {
$data = $this->getCollectionInfo($user, $activitypub_actor, $type);
}
else {
$data = $this->getCollectionItems($user, $activitypub_actor, $page, $type);
}
$status = 200;
}
catch (\Exception $e) {
$this->getLogger('activitypub')->notice('Follow error (@type): @message', ['@type' => $type, '@message' => $e->getMessage()]);
}
return new JsonResponse($data, $status);
}
/**
* Get collection info.
*
* @param \Drupal\user\UserInterface $user
* @param \Drupal\activitypub\Entity\ActivitypubActorInterface $activitypub_actor
* @param $type
*
* @return array
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function getCollectionInfo(UserInterface $user, ActivitypubActorInterface $activitypub_actor, $type) {
/** @var \Drupal\activitypub\Entity\Storage\ActivityPubActivityStorageInterface $storage */
$storage = $this->entityTypeManager()->getStorage('activitypub_activity');
$url = Url::fromRoute('activitypub.user.self', ['user' => $activitypub_actor->getOwnerId(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE])->toString();
$conditions = ['type' => 'Follow'];
$conditions['status'] = 1;
if ($type == ActivityPubActivityInterface::FOLLOWERS) {
$conditions['object'] = $url;
$conditions['collection'] = ActivityPubActivityInterface::INBOX;
}
else {
$conditions['actor'] = $url;
$conditions['collection'] = ActivityPubActivityInterface::OUTBOX;
}
$total = $storage->getActivityCount($conditions);
return [
'@context' => ActivityPubActivityInterface::CONTEXT_URL,
'type' => 'OrderedCollection',
'id' => Url::fromRoute('activitypub.' . $type, ['user' => $user->id(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE])->toString(),
'first' => Url::fromRoute('activitypub.' . $type, ['user' => $user->id(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE, 'query' => ['page' => 0]])->toString(),
'totalItems' => $total,
];
}
/**
* Get collection items.
*
* @param \Drupal\user\UserInterface $user
* @param \Drupal\activitypub\Entity\ActivitypubActorInterface $activitypub_actor
* @param int $page
* @param $type
*
* @return array
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function getCollectionItems(UserInterface $user, ActivitypubActorInterface $activitypub_actor, int $page, $type) {
$data = [
'@context' => ActivityPubActivityInterface::CONTEXT_URL,
'type' => 'OrderedCollectionPage',
'partOf' => Url::fromRoute('activitypub.' . $type, ['user' => $user->id(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE])->toString(),
'id' => Url::fromRoute('activitypub.' . $type, ['user' => $user->id(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE, 'query' => ['page' => $page]])->toString(),
];
$items = [];
$conditions = ['type' => 'Follow', 'status' => 1];
$url = Url::fromRoute('activitypub.user.self', ['user' => $activitypub_actor->getOwnerId(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE])->toString();
if ($type == ActivityPubActivityInterface::FOLLOWERS) {
/** @var \Drupal\activitypub\Entity\ActivityPubActivityInterface[] $activities */
$conditions['object'] = $url;
$conditions['collection'] = ActivityPubActivityInterface::INBOX;
}
else {
$conditions['actor'] = $url;
$conditions['collection'] = ActivityPubActivityInterface::OUTBOX;
}
/** @var \Drupal\activitypub\Entity\Storage\ActivityPubActivityStorageInterface $storage */
$storage = $this->entityTypeManager()->getStorage('activitypub_activity');
$activities = $storage->getActivities($conditions, [['id', 'DESC']], 20);
foreach ($activities as $activity) {
$items[] = $type == ActivityPubActivityInterface::FOLLOWERS ? $activity->getActor() : $activity->getObject();
}
$pager = $this->pagerManager->getPager();
$pager_total = $pager->getTotalPages();
if (isset($pager_total) && is_numeric($pager_total)) {
$page++;
if ($pager_total > $page) {
$data['next'] = Url::fromRoute('activitypub.' . $type, ['user' => $user->id(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE, 'query' => ['page' => $page]])->toString();
}
}
$data['totalItems'] = (int)$pager->getTotalItems();
$data['orderedItems'] = $items;
return $data;
}
}
