aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag/ApiBundle
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag/ApiBundle')
-rw-r--r--src/Wallabag/ApiBundle/Controller/EntryRestController.php99
-rw-r--r--src/Wallabag/ApiBundle/Controller/UserRestController.php139
-rw-r--r--src/Wallabag/ApiBundle/Resources/config/routing_rest.yml5
3 files changed, 205 insertions, 38 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
index 31bb67fd..93c8157e 100644
--- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
@@ -231,7 +231,6 @@ class EntryRestController extends WallabagRestController
231 $this->validateAuthentication(); 231 $this->validateAuthentication();
232 232
233 $urls = json_decode($request->query->get('urls', [])); 233 $urls = json_decode($request->query->get('urls', []));
234 $results = [];
235 234
236 $limit = $this->container->getParameter('wallabag_core.api_limit_mass_actions'); 235 $limit = $this->container->getParameter('wallabag_core.api_limit_mass_actions');
237 236
@@ -239,32 +238,34 @@ class EntryRestController extends WallabagRestController
239 throw new HttpException(400, 'API limit reached'); 238 throw new HttpException(400, 'API limit reached');
240 } 239 }
241 240
241 $results = [];
242 if (empty($urls)) {
243 return $this->sendResponse($results);
244 }
245
242 // handle multiple urls 246 // handle multiple urls
243 if (!empty($urls)) { 247 foreach ($urls as $key => $url) {
244 foreach ($urls as $key => $url) { 248 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId(
245 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId( 249 $url,
246 $url, 250 $this->getUser()->getId()
247 $this->getUser()->getId() 251 );
248 );
249
250 $results[$key]['url'] = $url;
251
252 if (false === $entry) {
253 $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
254 new Entry($this->getUser()),
255 $url
256 );
257 }
258 252
259 $em = $this->getDoctrine()->getManager(); 253 $results[$key]['url'] = $url;
260 $em->persist($entry);
261 $em->flush();
262 254
263 $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; 255 if (false === $entry) {
256 $entry = new Entry($this->getUser());
264 257
265 // entry saved, dispatch event about it! 258 $this->get('wallabag_core.content_proxy')->updateEntry($entry, $url);
266 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
267 } 259 }
260
261 $em = $this->getDoctrine()->getManager();
262 $em->persist($entry);
263 $em->flush();
264
265 $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false;
266
267 // entry saved, dispatch event about it!
268 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
268 } 269 }
269 270
270 return $this->sendResponse($results); 271 return $this->sendResponse($results);
@@ -273,6 +274,9 @@ class EntryRestController extends WallabagRestController
273 /** 274 /**
274 * Create an entry. 275 * Create an entry.
275 * 276 *
277 * If you want to provide the HTML content (which means wallabag won't fetch it from the url), you must provide `content`, `title` & `url` fields **non-empty**.
278 * Otherwise, content will be fetched as normal from the url and values will be overwritten.
279 *
276 * @ApiDoc( 280 * @ApiDoc(
277 * parameters={ 281 * parameters={
278 * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."}, 282 * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
@@ -280,6 +284,11 @@ class EntryRestController extends WallabagRestController
280 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, 284 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
281 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"}, 285 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"},
282 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"}, 286 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"},
287 * {"name"="content", "dataType"="string", "required"=false, "description"="Content of the entry"},
288 * {"name"="language", "dataType"="string", "required"=false, "description"="Language of the entry"},
289 * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"},
290 * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"},
291 * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"},
283 * } 292 * }
284 * ) 293 * )
285 * 294 *
@@ -291,32 +300,46 @@ class EntryRestController extends WallabagRestController
291 300
292 $url = $request->request->get('url'); 301 $url = $request->request->get('url');
293 $title = $request->request->get('title'); 302 $title = $request->request->get('title');
303 $tags = $request->request->get('tags', []);
294 $isArchived = $request->request->get('archive'); 304 $isArchived = $request->request->get('archive');
295 $isStarred = $request->request->get('starred'); 305 $isStarred = $request->request->get('starred');
306 $content = $request->request->get('content');
307 $language = $request->request->get('language');
308 $picture = $request->request->get('preview_picture');
309 $publishedAt = $request->request->get('published_at');
310 $authors = $request->request->get('authors', '');
296 311
297 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId()); 312 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
298 313
299 if (false === $entry) { 314 if (false === $entry) {
300 $entry = new Entry($this->getUser()); 315 $entry = new Entry($this->getUser());
301 try {
302 $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
303 $entry,
304 $url
305 );
306 } catch (\Exception $e) {
307 $this->get('logger')->error('Error while saving an entry', [
308 'exception' => $e,
309 'entry' => $entry,
310 ]);
311 $entry->setUrl($url);
312 }
313 } 316 }
314 317
315 if (!is_null($title)) { 318 try {
316 $entry->setTitle($title); 319 $this->get('wallabag_core.content_proxy')->updateEntry(
320 $entry,
321 $url,
322 [
323 'title' => $title,
324 'html' => $content,
325 'url' => $url,
326 'language' => $language,
327 'date' => $publishedAt,
328 // faking the preview picture
329 'open_graph' => [
330 'og_image' => $picture,
331 ],
332 'authors' => explode(',', $authors),
333 ]
334 );
335 } catch (\Exception $e) {
336 $this->get('logger')->error('Error while saving an entry', [
337 'exception' => $e,
338 'entry' => $entry,
339 ]);
340 $entry->setUrl($url);
317 } 341 }
318 342
319 $tags = $request->request->get('tags', '');
320 if (!empty($tags)) { 343 if (!empty($tags)) {
321 $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags); 344 $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags);
322 } 345 }
@@ -406,7 +429,7 @@ class EntryRestController extends WallabagRestController
406 $this->validateUserAccess($entry->getUser()->getId()); 429 $this->validateUserAccess($entry->getUser()->getId());
407 430
408 try { 431 try {
409 $entry = $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl()); 432 $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl());
410 } catch (\Exception $e) { 433 } catch (\Exception $e) {
411 $this->get('logger')->error('Error while saving an entry', [ 434 $this->get('logger')->error('Error while saving an entry', [
412 'exception' => $e, 435 'exception' => $e,
diff --git a/src/Wallabag/ApiBundle/Controller/UserRestController.php b/src/Wallabag/ApiBundle/Controller/UserRestController.php
new file mode 100644
index 00000000..a1b78e3f
--- /dev/null
+++ b/src/Wallabag/ApiBundle/Controller/UserRestController.php
@@ -0,0 +1,139 @@
1<?php
2
3namespace Wallabag\ApiBundle\Controller;
4
5use FOS\UserBundle\Event\UserEvent;
6use FOS\UserBundle\FOSUserEvents;
7use JMS\Serializer\SerializationContext;
8use Nelmio\ApiDocBundle\Annotation\ApiDoc;
9use Symfony\Component\HttpFoundation\Request;
10use Symfony\Component\HttpFoundation\JsonResponse;
11use Wallabag\UserBundle\Entity\User;
12
13class UserRestController extends WallabagRestController
14{
15 /**
16 * Retrieve current logged in user informations.
17 *
18 * @ApiDoc()
19 *
20 * @return JsonResponse
21 */
22 public function getUserAction()
23 {
24 $this->validateAuthentication();
25
26 return $this->sendUser($this->getUser());
27 }
28
29 /**
30 * Register an user.
31 *
32 * @ApiDoc(
33 * requirements={
34 * {"name"="username", "dataType"="string", "required"=true, "description"="The user's username"},
35 * {"name"="password", "dataType"="string", "required"=true, "description"="The user's password"},
36 * {"name"="email", "dataType"="string", "required"=true, "description"="The user's email"}
37 * }
38 * )
39 *
40 * @todo Make this method (or the whole API) accessible only through https
41 *
42 * @return JsonResponse
43 */
44 public function putUserAction(Request $request)
45 {
46 if (!$this->container->getParameter('fosuser_registration')) {
47 $json = $this->get('serializer')->serialize(['error' => "Server doesn't allow registrations"], 'json');
48
49 return (new JsonResponse())->setJson($json)->setStatusCode(403);
50 }
51
52 $userManager = $this->get('fos_user.user_manager');
53 $user = $userManager->createUser();
54 // enable created user by default
55 $user->setEnabled(true);
56
57 $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user, [
58 'csrf_protection' => false,
59 ]);
60
61 // simulate form submission
62 $form->submit([
63 'username' => $request->request->get('username'),
64 'plainPassword' => [
65 'first' => $request->request->get('password'),
66 'second' => $request->request->get('password'),
67 ],
68 'email' => $request->request->get('email'),
69 ]);
70
71 if ($form->isSubmitted() && false === $form->isValid()) {
72 $view = $this->view($form, 400);
73 $view->setFormat('json');
74
75 // handle errors in a more beautiful way than the default view
76 $data = json_decode($this->handleView($view)->getContent(), true)['children'];
77 $errors = [];
78
79 if (isset($data['username']['errors'])) {
80 $errors['username'] = $this->translateErrors($data['username']['errors']);
81 }
82
83 if (isset($data['email']['errors'])) {
84 $errors['email'] = $this->translateErrors($data['email']['errors']);
85 }
86
87 if (isset($data['plainPassword']['children']['first']['errors'])) {
88 $errors['password'] = $this->translateErrors($data['plainPassword']['children']['first']['errors']);
89 }
90
91 $json = $this->get('serializer')->serialize(['error' => $errors], 'json');
92
93 return (new JsonResponse())->setJson($json)->setStatusCode(400);
94 }
95
96 $userManager->updateUser($user);
97
98 // dispatch a created event so the associated config will be created
99 $event = new UserEvent($user, $request);
100 $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event);
101
102 return $this->sendUser($user);
103 }
104
105 /**
106 * Send user response.
107 *
108 * @param User $user
109 *
110 * @return JsonResponse
111 */
112 private function sendUser(User $user)
113 {
114 $json = $this->get('serializer')->serialize(
115 $user,
116 'json',
117 SerializationContext::create()->setGroups(['user_api'])
118 );
119
120 return (new JsonResponse())->setJson($json);
121 }
122
123 /**
124 * Translate errors message.
125 *
126 * @param array $errors
127 *
128 * @return array
129 */
130 private function translateErrors($errors)
131 {
132 $translatedErrors = [];
133 foreach ($errors as $error) {
134 $translatedErrors[] = $this->get('translator')->trans($error);
135 }
136
137 return $translatedErrors;
138 }
139}
diff --git a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
index 57d37f4b..c0283e71 100644
--- a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
+++ b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
@@ -17,3 +17,8 @@ misc:
17 type: rest 17 type: rest
18 resource: "WallabagApiBundle:WallabagRest" 18 resource: "WallabagApiBundle:WallabagRest"
19 name_prefix: api_ 19 name_prefix: api_
20
21user:
22 type: rest
23 resource: "WallabagApiBundle:UserRest"
24 name_prefix: api_