]> git.immae.eu Git - github/wallabag/wallabag.git/blobdiff - src/Wallabag/FederationBundle/Controller/ProfileController.php
WIP
[github/wallabag/wallabag.git] / src / Wallabag / FederationBundle / Controller / ProfileController.php
diff --git a/src/Wallabag/FederationBundle/Controller/ProfileController.php b/src/Wallabag/FederationBundle/Controller/ProfileController.php
new file mode 100644 (file)
index 0000000..7e472e1
--- /dev/null
@@ -0,0 +1,425 @@
+<?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);
+    }
+
+}