<?php
namespace Wallabag\FederationBundle\Controller;
use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Pagerfanta;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\FederationBundle\Entity\Account;
use Wallabag\FederationBundle\Federation\CloudId;
class ProfileController extends Controller
{
/**
* @Route("/profile/@{user}", name="user-profile")
* @ParamConverter("user", class="WallabagFederationBundle:Account", options={
* "repository_method" = "findOneByUsername"})
*
* @param Request $request
* @param Account $user
* @return JsonResponse|Response
*/
public function getUserProfile(Request $request, Account $user)
{
if (in_array('application/ld+json; profile="https://www.w3.org/ns/activitystreams', $request->getAcceptableContentTypes(), true)) {
$data = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Person',
'id' => CloudId::getCloudIdFromAccount($user, $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL))->getDisplayId(),
'following' => $this->generateUrl('following', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL),
'followers' => $this->generateUrl('followers', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL),
//'liked' => $this->generateUrl('recommended', ['user' => $user], UrlGeneratorInterface::ABSOLUTE_URL),
'inbox' => $this->generateUrl('user-inbox', ['user' => $user], UrlGeneratorInterface::ABSOLUTE_URL),
'outbox' => $this->generateUrl('user-outbox', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL),
'preferredUsername' => $user->getUser()->getName(),
'name' => $user->getUsername(),
//'oauthAuthorizationEndpoint' => $this->generateUrl('fos_oauth_server_authorize', [], UrlGeneratorInterface::ABSOLUTE_URL),
'oauthTokenEndpoint' => $this->generateUrl('fos_oauth_server_token', [], UrlGeneratorInterface::ABSOLUTE_URL),
//'publicInbox' => $this->generateUrl('public_inbox', [], UrlGeneratorInterface::ABSOLUTE_URL),
];
return new JsonResponse($data);
}
return $this->render(
'WallabagFederationBundle:User:profile.html.twig', [
'user' => $user,
'registration_enabled' => $this->getParameter('wallabag_user.registration_enabled'),
]
);
}
/**
* @Route("/profile/@{user}/followings/{page}", name="following", defaults={"page" : 0})
* @ParamConverter("user", class="WallabagFederationBundle:Account", options={
* "repository_method" = "findOneByUsername"})
*
* @param Request $request
* @param Account $user
* @param int $page
* @return JsonResponse|Response
*/
public function getUsersFollowing(Request $request, Account $user, $page = 0)
{
$qb = $this->getDoctrine()->getRepository('WallabagFederationBundle:Account')->getBuilderForFollowingsByAccount($user->getId());
$pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false);
$following = new Pagerfanta($pagerAdapter);
$totalFollowing = $following->getNbResults();
$activityStream = in_array('application/ld+json; profile="https://www.w3.org/ns/activitystreams', $request->getAcceptableContentTypes(), true);
if ($page === 0 && $activityStream) {
/** Home page */
$dataPrez = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'summary' => $user->getUsername() . " followings'",
'type' => 'Collection',
'id' => $this->generateUrl('following', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL),
'totalItems' => $totalFollowing,
'first' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'First page of ' . $user->getUsername() . ' followings'
],
'last' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => $following->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Last page of ' . $user->getUsername() . ' followings'
]
];
return new JsonResponse($dataPrez);
//}
}
$following->setMaxPerPage(30);
$following->setCurrentPage($page);
if (!$activityStream) {
return $this->render('WallabagFederationBundle:User:followers.html.twig', [
'users' => $following,
'user' => $user,
'registration_enabled' => $this->getParameter('wallabag_user.registration_enabled'),
]);
}
$items = [];
foreach ($following->getCurrentPageResults() as $follow) {
/** @var Account $follow */
/** Items in the page */
$items[] = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Person',
'name' => $follow->getUsername(),
'id' => CloudId::getCloudIdFromAccount($follow),
];
}
$data = [
'summary' => 'Page ' . $page . ' of ' . $user->getUsername() . ' followers',
'partOf' => $this->generateUrl('following', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL),
'type' => 'OrderedCollectionPage',
'startIndex' => ($page - 1) * 30,
'orderedItems' => $items,
'first' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'First page of ' . $user->getUsername() . ' followings'
],
'last' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => $following->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Last page of ' . $user->getUsername() . ' followings'
],
];
/** Previous page */
if ($page > 1) {
$data['prev'] = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => $page - 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Previous page of ' . $user->getUsername() . ' followings'
];
}
/** Next page */
if ($page < $following->getNbPages()) {
$data['next'] = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => $page + 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Next page of ' . $user->getUsername() . ' followings'
];
}
return new JsonResponse($data);
}
/**
* @Route("/profile/@{user}/followers/{page}", name="followers", defaults={"page" : 0})
* @ParamConverter("user", class="WallabagFederationBundle:Account", options={
* "repository_method" = "findOneByUsername"})
*
* @param Request $request
* @param Account $user
* @return JsonResponse
*/
public function getUsersFollowers(Request $request, Account $user, $page)
{
$qb = $this->getDoctrine()->getRepository('WallabagFederationBundle:Account')->getBuilderForFollowersByAccount($user->getId());
$pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false);
$followers = new Pagerfanta($pagerAdapter);
$totalFollowers = $followers->getNbResults();
$activityStream = in_array('application/ld+json; profile="https://www.w3.org/ns/activitystreams', $request->getAcceptableContentTypes(), true);
if ($page === 0 && $activityStream) {
/** Home page */
$dataPrez = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'summary' => $user->getUsername() . " followers'",
'type' => 'Collection',
'id' => $this->generateUrl('followers', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL),
'totalItems' => $totalFollowers,
'first' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'First page of ' . $user->getUsername() . ' followers'
],
'last' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => $followers->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Last page of ' . $user->getUsername() . ' followers'
]
];
return new JsonResponse($dataPrez);
}
$followers->setMaxPerPage(30);
if (!$activityStream && $page === 0) {
$followers->setCurrentPage(1);
} else {
$followers->setCurrentPage($page);
}
if (!$activityStream) {
return $this->render('WallabagFederationBundle:User:followers.html.twig', [
'users' => $followers,
'user' => $user,
'registration_enabled' => $this->getParameter('wallabag_user.registration_enabled'),
]);
}
$items = [];
foreach ($followers->getCurrentPageResults() as $follow) {
/** @var Account $follow */
/** Items in the page */
$items[] = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Person',
'name' => $follow->getUsername(),
'id' => CloudId::getCloudIdFromAccount($follow)->getDisplayId(),
];
}
$data = [
'summary' => 'Page ' . $page . ' of ' . $user->getUsername() . ' followers',
'partOf' => $this->generateUrl('followers', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL),
'type' => 'OrderedCollectionPage',
'startIndex' => ($page - 1) * 30,
'orderedItems' => $items,
'first' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'First page of ' . $user->getUsername() . ' followers'
],
'last' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => $followers->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Last page of ' . $user->getUsername() . ' followers'
],
];
/** Previous page */
if ($page > 1) {
$data['prev'] = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => $page - 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Previous page of ' . $user->getUsername() . ' followers'
];
}
/** Next page */
if ($page < $followers->getNbPages()) {
$data['next'] = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => $page + 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Next page of ' . $user->getUsername() . ' followers'
];
}
return new JsonResponse($data);
}
/**
* @Route("/profile/@{userToFollow}/follow", name="follow-user")
* @ParamConverter("userToFollow", class="WallabagFederationBundle:Account", options={
* "repository_method" = "findOneByUsername"})
* @param Account $userToFollow
*/
public function followAccountAction(Account $userToFollow)
{
// if we're on our own instance
if ($this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
/** @var Account $userAccount */
$userAccount = $this->getUser()->getAccount();
if ($userToFollow === $userAccount) {
$this->createAccessDeniedException("You can't follow yourself");
}
$em = $this->getDoctrine()->getManager();
$userAccount->addFollowing($userToFollow);
$userToFollow->addFollower($userAccount);
$em->persist($userAccount);
$em->persist($userToFollow);
$em->flush();
} else {
// ask cloud id and redirect to instance
}
}
/**
* @Route("/profile/@{user}/recommendations", name="user-recommendations", defaults={"page" : 0})
* @ParamConverter("user", class="WallabagFederationBundle:Account", options={
* "repository_method" = "findOneByUsername"})
*
* @param Request $request
* @param Account $user
* @param int $page
* @return JsonResponse|Response
*/
public function getUsersRecommendationsAction(Request $request, Account $user, $page = 0)
{
$qb = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry')->getBuilderForRecommendationsByUser($user->getUser()->getId());
$pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false);
$recommendations = new Pagerfanta($pagerAdapter);
$totalRecommendations = $recommendations->getNbResults();
$activityStream = in_array('application/ld+json; profile="https://www.w3.org/ns/activitystreams', $request->getAcceptableContentTypes(), true);
if ($page === 0 && $activityStream) {
$dataPrez = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'summary' => $user->getUsername() . " recommendations'",
'type' => 'Collection',
'id' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL),
'totalItems' => $totalRecommendations,
'first' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'First page of ' . $user->getUsername() . ' followers'
],
'last' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => $recommendations->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Last page of ' . $user->getUsername() . ' followers'
]
];
return new JsonResponse($dataPrez);
}
$recommendations->setMaxPerPage(30);
if (!$activityStream && $page === 0) {
$recommendations->setCurrentPage(1);
} else {
$recommendations->setCurrentPage($page);
}
if (!$activityStream) {
return $this->render('WallabagFederationBundle:User:recommendations.html.twig', [
'recommendations' => $recommendations,
'registration_enabled' => $this->getParameter('wallabag_user.registration_enabled'),
]);
}
$items = [];
foreach ($recommendations->getCurrentPageResults() as $recommendation) {
$items[] = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Person',
'name' => $recommendation->getTitle(),
'id' => $recommendation->getUrl(),
];
}
$data = [
'summary' => 'Page ' . $page . ' of ' . $user->getUsername() . ' recommendations',
'partOf' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL),
'type' => 'OrderedCollectionPage',
'startIndex' => ($page - 1) * 30,
'orderedItems' => $items,
'first' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'First page of ' . $user->getUsername() . ' recommendations'
],
'last' => [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => $recommendations->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Last page of ' . $user->getUsername() . ' recommendations'
],
];
if ($page > 1) {
$data['prev'] = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => $page - 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Previous page of ' . $user->getUsername() . ' recommendations'
];
}
if ($page < $recommendations->getNbPages()) {
$data['next'] = [
'@context' => 'https://www.w3.org/ns/activitystreams',
'type' => 'Link',
'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => $page + 1], UrlGeneratorInterface::ABSOLUTE_URL),
'name' => 'Next page of ' . $user->getUsername() . ' recommendations'
];
}
return new JsonResponse($data);
}
}