activitypub-1.0.x-dev/src/Controller/OutboxController.php
src/Controller/OutboxController.php
<?php
namespace Drupal\activitypub\Controller;
use Drupal\activitypub\Entity\ActivityPubActivityInterface;
use Drupal\activitypub\Entity\ActivitypubActorInterface;
use Drupal\Core\Cache\CacheableJsonResponse;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Url;
use Drupal\user\UserInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
class OutboxController extends BaseController {
/**
* Outbox 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 outbox(Request $request, UserInterface $user, ActivitypubActorInterface $activitypub_actor) {
$status = 400;
$data = NULL;
$metadata = new CacheableMetadata();
try {
$metadata->addCacheContexts(['url.query_args:page']);
$metadata->addCacheTags(['user:' . $user->id()]);
$page = $request->get('page');
if (!isset($page)) {
$data = $this->getCollectionInfo($user, $activitypub_actor, $metadata);
}
else {
$data = $this->getCollectionItems($user, $activitypub_actor, $page, $metadata);
}
$status = 200;
}
catch (\Exception $e) {
$this->getLogger('activitypub')->notice('Outbox error: @message', ['@message' => $e->getMessage()]);
}
if ($status == 200) {
$response = new CacheableJsonResponse($data);
$response->addCacheableDependency($metadata);
return $response;
}
else {
return new JsonResponse($data, $status);
}
}
/**
* Get collection info.
*
* @param \Drupal\user\UserInterface $user
* @param \Drupal\activitypub\Entity\ActivitypubActorInterface $activitypub_actor
* @param \Drupal\Core\Cache\CacheableMetadata $metadata
*
* @return array
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function getCollectionInfo(UserInterface $user, ActivitypubActorInterface $activitypub_actor, CacheableMetadata $metadata) {
/** @var \Drupal\activitypub\Entity\Storage\ActivityPubActivityStorageInterface $storage */
$storage = $this->entityTypeManager()->getStorage('activitypub_activity');
$conditions = ['uid' => $user->id(), 'status' => 1, 'visibility' => ActivityPubActivityInterface::VISIBILITY_PUBLIC, 'collection' => 'outbox', '!type' => $this->activityPubUtility->getOutboxIgnoreTypes()];
$id = Url::fromRoute('activitypub.outbox', ['user' => $user->id(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE])->toString(TRUE);
$metadata->addCacheableDependency($id);
$first = Url::fromRoute('activitypub.outbox', ['user' => $user->id(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE, 'query' => ['page' => 0]])->toString(TRUE);
$metadata->addCacheableDependency($first);
return [
'@context' => ActivityPubActivityInterface::CONTEXT_URL,
'type' => 'OrderedCollection',
'id' => $id->getGeneratedUrl(),
'first' => $first->getGeneratedUrl(),
'totalItems' => $storage->getActivityCount($conditions),
];
}
/**
* Get collection items.
*
* @param \Drupal\user\UserInterface $user
* @param \Drupal\activitypub\Entity\ActivitypubActorInterface $activitypub_actor
* @param int $page
* @param \Drupal\Core\Cache\CacheableMetadata $metadata
*
* @return array
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
protected function getCollectionItems(UserInterface $user, ActivitypubActorInterface $activitypub_actor, int $page, CacheableMetadata $metadata) {
$partOf = Url::fromRoute('activitypub.outbox', ['user' => $user->id(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE])->toString(TRUE);
$metadata->addCacheableDependency($partOf);
$id = Url::fromRoute('activitypub.outbox', ['user' => $user->id(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE, 'query' => ['page' => $page]])->toString(TRUE);
$metadata->addCacheableDependency($id);
$data = [
'@context' => ActivityPubActivityInterface::CONTEXT_URL,
'type' => 'OrderedCollectionPage',
'partOf' => $partOf->getGeneratedUrl(),
'id' => $id->getGeneratedUrl(),
];
$items = [];
/** @var \Drupal\activitypub\Entity\ActivityPubActivityInterface[] $activities */
$storage = $this->entityTypeManager()->getStorage('activitypub_activity');
$conditions = [
'uid' => $user->id(),
'status' => 1,
'visibility' => ActivityPubActivityInterface::VISIBILITY_PUBLIC,
'collection' => 'outbox',
'!type' => $this->activityPubUtility->getOutboxIgnoreTypes(),
];
$activities = $storage->getActivities($conditions, [['id', 'DESC']], 20);
foreach ($activities as $activity) {
$items[] = $activity->buildActivity();
}
$pager = $this->pagerManager->getPager();
$pager_total = $pager->getTotalPages();
if (isset($pager_total) && is_numeric($pager_total)) {
$page++;
if ($pager_total > $page) {
$nextPage = Url::fromRoute('activitypub.outbox', ['user' => $user->id(), 'activitypub_actor' => $activitypub_actor->getName()], ['absolute' => TRUE, 'query' => ['page' => $page]])->toString(TRUE);
$metadata->addCacheableDependency($nextPage);
$data['next'] = $nextPage->getGeneratedUrl();
}
}
$data['orderedItems'] = $items;
$data['totalItems'] = (int) $pager->getTotalItems();
return $data;
}
}
