]>
Commit | Line | Data |
---|---|---|
bf6c0346 TC |
1 | <?php |
2 | ||
3 | namespace Wallabag\FederationBundle\Controller; | |
4 | ||
5 | use Pagerfanta\Adapter\DoctrineORMAdapter; | |
6 | use Pagerfanta\Pagerfanta; | |
7 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; | |
8 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | |
9 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; | |
10 | use Symfony\Component\HttpFoundation\JsonResponse; | |
11 | use Symfony\Component\HttpFoundation\Request; | |
12 | use Symfony\Component\HttpFoundation\Response; | |
13 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |
14 | use Wallabag\CoreBundle\Entity\Entry; | |
15 | use Wallabag\FederationBundle\Entity\Account; | |
16 | use Wallabag\FederationBundle\Federation\CloudId; | |
17 | ||
18 | class ProfileController extends Controller | |
19 | { | |
20 | /** | |
21 | * @Route("/profile/@{user}", name="user-profile") | |
22 | * @ParamConverter("user", class="WallabagFederationBundle:Account", options={ | |
23 | * "repository_method" = "findOneByUsername"}) | |
24 | * | |
25 | * @param Request $request | |
26 | * @param Account $user | |
27 | * @return JsonResponse|Response | |
28 | */ | |
29 | public function getUserProfile(Request $request, Account $user) | |
30 | { | |
31 | if (in_array('application/ld+json; profile="https://www.w3.org/ns/activitystreams', $request->getAcceptableContentTypes(), true)) { | |
32 | $data = [ | |
33 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
34 | 'type' => 'Person', | |
35 | 'id' => CloudId::getCloudIdFromAccount($user, $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL))->getDisplayId(), | |
36 | 'following' => $this->generateUrl('following', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL), | |
37 | 'followers' => $this->generateUrl('followers', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL), | |
38 | //'liked' => $this->generateUrl('recommended', ['user' => $user], UrlGeneratorInterface::ABSOLUTE_URL), | |
39 | 'inbox' => $this->generateUrl('user-inbox', ['user' => $user], UrlGeneratorInterface::ABSOLUTE_URL), | |
40 | 'outbox' => $this->generateUrl('user-outbox', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL), | |
41 | 'preferredUsername' => $user->getUser()->getName(), | |
42 | 'name' => $user->getUsername(), | |
43 | //'oauthAuthorizationEndpoint' => $this->generateUrl('fos_oauth_server_authorize', [], UrlGeneratorInterface::ABSOLUTE_URL), | |
44 | 'oauthTokenEndpoint' => $this->generateUrl('fos_oauth_server_token', [], UrlGeneratorInterface::ABSOLUTE_URL), | |
45 | //'publicInbox' => $this->generateUrl('public_inbox', [], UrlGeneratorInterface::ABSOLUTE_URL), | |
46 | ]; | |
47 | return new JsonResponse($data); | |
48 | } | |
49 | return $this->render( | |
50 | 'WallabagFederationBundle:User:profile.html.twig', [ | |
51 | 'user' => $user, | |
52 | 'registration_enabled' => $this->getParameter('wallabag_user.registration_enabled'), | |
53 | ] | |
54 | ); | |
55 | } | |
56 | ||
57 | /** | |
58 | * @Route("/profile/@{user}/followings/{page}", name="following", defaults={"page" : 0}) | |
59 | * @ParamConverter("user", class="WallabagFederationBundle:Account", options={ | |
60 | * "repository_method" = "findOneByUsername"}) | |
61 | * | |
62 | * @param Request $request | |
63 | * @param Account $user | |
64 | * @param int $page | |
65 | * @return JsonResponse|Response | |
66 | */ | |
67 | public function getUsersFollowing(Request $request, Account $user, $page = 0) | |
68 | { | |
69 | $qb = $this->getDoctrine()->getRepository('WallabagFederationBundle:Account')->getBuilderForFollowingsByAccount($user->getId()); | |
70 | ||
71 | $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false); | |
72 | ||
73 | $following = new Pagerfanta($pagerAdapter); | |
74 | $totalFollowing = $following->getNbResults(); | |
75 | ||
76 | $activityStream = in_array('application/ld+json; profile="https://www.w3.org/ns/activitystreams', $request->getAcceptableContentTypes(), true); | |
77 | ||
78 | if ($page === 0 && $activityStream) { | |
79 | /** Home page */ | |
80 | $dataPrez = [ | |
81 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
82 | 'summary' => $user->getUsername() . " followings'", | |
83 | 'type' => 'Collection', | |
84 | 'id' => $this->generateUrl('following', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL), | |
85 | 'totalItems' => $totalFollowing, | |
86 | 'first' => [ | |
87 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
88 | 'type' => 'Link', | |
89 | 'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
90 | 'name' => 'First page of ' . $user->getUsername() . ' followings' | |
91 | ], | |
92 | 'last' => [ | |
93 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
94 | 'type' => 'Link', | |
95 | 'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => $following->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL), | |
96 | 'name' => 'Last page of ' . $user->getUsername() . ' followings' | |
97 | ] | |
98 | ]; | |
99 | return new JsonResponse($dataPrez); | |
100 | //} | |
101 | } | |
102 | ||
103 | $following->setMaxPerPage(30); | |
104 | $following->setCurrentPage($page); | |
105 | ||
106 | if (!$activityStream) { | |
107 | return $this->render('WallabagFederationBundle:User:followers.html.twig', [ | |
108 | 'users' => $following, | |
109 | 'user' => $user, | |
110 | 'registration_enabled' => $this->getParameter('wallabag_user.registration_enabled'), | |
111 | ]); | |
112 | } | |
113 | ||
114 | $items = []; | |
115 | ||
116 | foreach ($following->getCurrentPageResults() as $follow) { | |
117 | /** @var Account $follow */ | |
118 | /** Items in the page */ | |
119 | $items[] = [ | |
120 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
121 | 'type' => 'Person', | |
122 | 'name' => $follow->getUsername(), | |
123 | 'id' => CloudId::getCloudIdFromAccount($follow), | |
124 | ]; | |
125 | } | |
126 | ||
127 | $data = [ | |
128 | 'summary' => 'Page ' . $page . ' of ' . $user->getUsername() . ' followers', | |
129 | 'partOf' => $this->generateUrl('following', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL), | |
130 | 'type' => 'OrderedCollectionPage', | |
131 | 'startIndex' => ($page - 1) * 30, | |
132 | 'orderedItems' => $items, | |
133 | 'first' => [ | |
134 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
135 | 'type' => 'Link', | |
136 | 'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
137 | 'name' => 'First page of ' . $user->getUsername() . ' followings' | |
138 | ], | |
139 | 'last' => [ | |
140 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
141 | 'type' => 'Link', | |
142 | 'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => $following->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL), | |
143 | 'name' => 'Last page of ' . $user->getUsername() . ' followings' | |
144 | ], | |
145 | ]; | |
146 | ||
147 | /** Previous page */ | |
148 | if ($page > 1) { | |
149 | $data['prev'] = [ | |
150 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
151 | 'type' => 'Link', | |
152 | 'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => $page - 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
153 | 'name' => 'Previous page of ' . $user->getUsername() . ' followings' | |
154 | ]; | |
155 | } | |
156 | ||
157 | /** Next page */ | |
158 | if ($page < $following->getNbPages()) { | |
159 | $data['next'] = [ | |
160 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
161 | 'type' => 'Link', | |
162 | 'href' => $this->generateUrl('following', ['user' => $user->getUsername(), 'page' => $page + 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
163 | 'name' => 'Next page of ' . $user->getUsername() . ' followings' | |
164 | ]; | |
165 | } | |
166 | ||
167 | return new JsonResponse($data); | |
168 | } | |
169 | ||
170 | /** | |
171 | * @Route("/profile/@{user}/followers/{page}", name="followers", defaults={"page" : 0}) | |
172 | * @ParamConverter("user", class="WallabagFederationBundle:Account", options={ | |
173 | * "repository_method" = "findOneByUsername"}) | |
174 | * | |
175 | * @param Request $request | |
176 | * @param Account $user | |
177 | * @return JsonResponse | |
178 | */ | |
179 | public function getUsersFollowers(Request $request, Account $user, $page) | |
180 | { | |
181 | $qb = $this->getDoctrine()->getRepository('WallabagFederationBundle:Account')->getBuilderForFollowersByAccount($user->getId()); | |
182 | ||
183 | $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false); | |
184 | ||
185 | $followers = new Pagerfanta($pagerAdapter); | |
186 | $totalFollowers = $followers->getNbResults(); | |
187 | ||
188 | $activityStream = in_array('application/ld+json; profile="https://www.w3.org/ns/activitystreams', $request->getAcceptableContentTypes(), true); | |
189 | ||
190 | if ($page === 0 && $activityStream) { | |
191 | /** Home page */ | |
192 | $dataPrez = [ | |
193 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
194 | 'summary' => $user->getUsername() . " followers'", | |
195 | 'type' => 'Collection', | |
196 | 'id' => $this->generateUrl('followers', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL), | |
197 | 'totalItems' => $totalFollowers, | |
198 | 'first' => [ | |
199 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
200 | 'type' => 'Link', | |
201 | 'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
202 | 'name' => 'First page of ' . $user->getUsername() . ' followers' | |
203 | ], | |
204 | 'last' => [ | |
205 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
206 | 'type' => 'Link', | |
207 | 'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => $followers->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL), | |
208 | 'name' => 'Last page of ' . $user->getUsername() . ' followers' | |
209 | ] | |
210 | ]; | |
211 | return new JsonResponse($dataPrez); | |
212 | } | |
213 | ||
214 | $followers->setMaxPerPage(30); | |
215 | if (!$activityStream && $page === 0) { | |
216 | $followers->setCurrentPage(1); | |
217 | } else { | |
218 | $followers->setCurrentPage($page); | |
219 | } | |
220 | ||
221 | if (!$activityStream) { | |
222 | return $this->render('WallabagFederationBundle:User:followers.html.twig', [ | |
223 | 'users' => $followers, | |
224 | 'user' => $user, | |
225 | 'registration_enabled' => $this->getParameter('wallabag_user.registration_enabled'), | |
226 | ]); | |
227 | } | |
228 | ||
229 | $items = []; | |
230 | ||
231 | foreach ($followers->getCurrentPageResults() as $follow) { | |
232 | /** @var Account $follow */ | |
233 | /** Items in the page */ | |
234 | $items[] = [ | |
235 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
236 | 'type' => 'Person', | |
237 | 'name' => $follow->getUsername(), | |
238 | 'id' => CloudId::getCloudIdFromAccount($follow)->getDisplayId(), | |
239 | ]; | |
240 | } | |
241 | $data = [ | |
242 | 'summary' => 'Page ' . $page . ' of ' . $user->getUsername() . ' followers', | |
243 | 'partOf' => $this->generateUrl('followers', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL), | |
244 | 'type' => 'OrderedCollectionPage', | |
245 | 'startIndex' => ($page - 1) * 30, | |
246 | 'orderedItems' => $items, | |
247 | 'first' => [ | |
248 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
249 | 'type' => 'Link', | |
250 | 'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
251 | 'name' => 'First page of ' . $user->getUsername() . ' followers' | |
252 | ], | |
253 | 'last' => [ | |
254 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
255 | 'type' => 'Link', | |
256 | 'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => $followers->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL), | |
257 | 'name' => 'Last page of ' . $user->getUsername() . ' followers' | |
258 | ], | |
259 | ]; | |
260 | ||
261 | /** Previous page */ | |
262 | if ($page > 1) { | |
263 | $data['prev'] = [ | |
264 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
265 | 'type' => 'Link', | |
266 | 'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => $page - 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
267 | 'name' => 'Previous page of ' . $user->getUsername() . ' followers' | |
268 | ]; | |
269 | } | |
270 | ||
271 | /** Next page */ | |
272 | if ($page < $followers->getNbPages()) { | |
273 | $data['next'] = [ | |
274 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
275 | 'type' => 'Link', | |
276 | 'href' => $this->generateUrl('followers', ['user' => $user->getUsername(), 'page' => $page + 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
277 | 'name' => 'Next page of ' . $user->getUsername() . ' followers' | |
278 | ]; | |
279 | } | |
280 | ||
281 | return new JsonResponse($data); | |
282 | } | |
283 | ||
284 | /** | |
285 | * @Route("/profile/@{userToFollow}/follow", name="follow-user") | |
286 | * @ParamConverter("userToFollow", class="WallabagFederationBundle:Account", options={ | |
287 | * "repository_method" = "findOneByUsername"}) | |
288 | * @param Account $userToFollow | |
289 | */ | |
290 | public function followAccountAction(Account $userToFollow) | |
291 | { | |
292 | // if we're on our own instance | |
293 | if ($this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) { | |
294 | ||
295 | /** @var Account $userAccount */ | |
296 | $userAccount = $this->getUser()->getAccount(); | |
297 | ||
298 | if ($userToFollow === $userAccount) { | |
299 | $this->createAccessDeniedException("You can't follow yourself"); | |
300 | } | |
301 | ||
302 | $em = $this->getDoctrine()->getManager(); | |
303 | ||
304 | $userAccount->addFollowing($userToFollow); | |
305 | $userToFollow->addFollower($userAccount); | |
306 | ||
307 | $em->persist($userAccount); | |
308 | $em->persist($userToFollow); | |
309 | ||
310 | $em->flush(); | |
311 | } else { | |
312 | // ask cloud id and redirect to instance | |
313 | } | |
314 | } | |
315 | ||
316 | /** | |
317 | * @Route("/profile/@{user}/recommendations", name="user-recommendations", defaults={"page" : 0}) | |
318 | * @ParamConverter("user", class="WallabagFederationBundle:Account", options={ | |
319 | * "repository_method" = "findOneByUsername"}) | |
320 | * | |
321 | * @param Request $request | |
322 | * @param Account $user | |
323 | * @param int $page | |
324 | * @return JsonResponse|Response | |
325 | */ | |
326 | public function getUsersRecommendationsAction(Request $request, Account $user, $page = 0) | |
327 | { | |
328 | $qb = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry')->getBuilderForRecommendationsByUser($user->getUser()->getId()); | |
329 | ||
330 | $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false); | |
331 | ||
332 | $recommendations = new Pagerfanta($pagerAdapter); | |
333 | $totalRecommendations = $recommendations->getNbResults(); | |
334 | ||
335 | $activityStream = in_array('application/ld+json; profile="https://www.w3.org/ns/activitystreams', $request->getAcceptableContentTypes(), true); | |
336 | ||
337 | if ($page === 0 && $activityStream) { | |
338 | $dataPrez = [ | |
339 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
340 | 'summary' => $user->getUsername() . " recommendations'", | |
341 | 'type' => 'Collection', | |
342 | 'id' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL), | |
343 | 'totalItems' => $totalRecommendations, | |
344 | 'first' => [ | |
345 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
346 | 'type' => 'Link', | |
347 | 'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
348 | 'name' => 'First page of ' . $user->getUsername() . ' followers' | |
349 | ], | |
350 | 'last' => [ | |
351 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
352 | 'type' => 'Link', | |
353 | 'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => $recommendations->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL), | |
354 | 'name' => 'Last page of ' . $user->getUsername() . ' followers' | |
355 | ] | |
356 | ]; | |
357 | return new JsonResponse($dataPrez); | |
358 | } | |
359 | ||
360 | $recommendations->setMaxPerPage(30); | |
361 | if (!$activityStream && $page === 0) { | |
362 | $recommendations->setCurrentPage(1); | |
363 | } else { | |
364 | $recommendations->setCurrentPage($page); | |
365 | } | |
366 | ||
367 | if (!$activityStream) { | |
368 | return $this->render('WallabagFederationBundle:User:recommendations.html.twig', [ | |
369 | 'recommendations' => $recommendations, | |
370 | 'registration_enabled' => $this->getParameter('wallabag_user.registration_enabled'), | |
371 | ]); | |
372 | } | |
373 | ||
374 | $items = []; | |
375 | ||
376 | foreach ($recommendations->getCurrentPageResults() as $recommendation) { | |
377 | $items[] = [ | |
378 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
379 | 'type' => 'Person', | |
380 | 'name' => $recommendation->getTitle(), | |
381 | 'id' => $recommendation->getUrl(), | |
382 | ]; | |
383 | } | |
384 | $data = [ | |
385 | 'summary' => 'Page ' . $page . ' of ' . $user->getUsername() . ' recommendations', | |
386 | 'partOf' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername()], UrlGeneratorInterface::ABSOLUTE_URL), | |
387 | 'type' => 'OrderedCollectionPage', | |
388 | 'startIndex' => ($page - 1) * 30, | |
389 | 'orderedItems' => $items, | |
390 | 'first' => [ | |
391 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
392 | 'type' => 'Link', | |
393 | 'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
394 | 'name' => 'First page of ' . $user->getUsername() . ' recommendations' | |
395 | ], | |
396 | 'last' => [ | |
397 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
398 | 'type' => 'Link', | |
399 | 'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => $recommendations->getNbPages()], UrlGeneratorInterface::ABSOLUTE_URL), | |
400 | 'name' => 'Last page of ' . $user->getUsername() . ' recommendations' | |
401 | ], | |
402 | ]; | |
403 | ||
404 | if ($page > 1) { | |
405 | $data['prev'] = [ | |
406 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
407 | 'type' => 'Link', | |
408 | 'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => $page - 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
409 | 'name' => 'Previous page of ' . $user->getUsername() . ' recommendations' | |
410 | ]; | |
411 | } | |
412 | ||
413 | if ($page < $recommendations->getNbPages()) { | |
414 | $data['next'] = [ | |
415 | '@context' => 'https://www.w3.org/ns/activitystreams', | |
416 | 'type' => 'Link', | |
417 | 'href' => $this->generateUrl('user-recommendations', ['user' => $user->getUsername(), 'page' => $page + 1], UrlGeneratorInterface::ABSOLUTE_URL), | |
418 | 'name' => 'Next page of ' . $user->getUsername() . ' recommendations' | |
419 | ]; | |
420 | } | |
421 | ||
422 | return new JsonResponse($data); | |
423 | } | |
424 | ||
425 | } |