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.php52
-rw-r--r--src/Wallabag/ApiBundle/Controller/UserRestController.php139
-rw-r--r--src/Wallabag/ApiBundle/Resources/config/routing_rest.yml5
3 files changed, 181 insertions, 15 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
index 31bb67fd..c3ba1858 100644
--- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
@@ -273,6 +273,9 @@ class EntryRestController extends WallabagRestController
273 /** 273 /**
274 * Create an entry. 274 * Create an entry.
275 * 275 *
276 * 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**.
277 * Otherwise, content will be fetched as normal from the url and values will be overwritten.
278 *
276 * @ApiDoc( 279 * @ApiDoc(
277 * parameters={ 280 * parameters={
278 * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."}, 281 * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
@@ -280,6 +283,11 @@ class EntryRestController extends WallabagRestController
280 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, 283 * {"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"}, 284 * {"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"}, 285 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"},
286 * {"name"="content", "dataType"="string", "required"=false, "description"="Content of the entry"},
287 * {"name"="language", "dataType"="string", "required"=false, "description"="Language of the entry"},
288 * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"},
289 * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"},
290 * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"},
283 * } 291 * }
284 * ) 292 * )
285 * 293 *
@@ -291,32 +299,46 @@ class EntryRestController extends WallabagRestController
291 299
292 $url = $request->request->get('url'); 300 $url = $request->request->get('url');
293 $title = $request->request->get('title'); 301 $title = $request->request->get('title');
302 $tags = $request->request->get('tags', []);
294 $isArchived = $request->request->get('archive'); 303 $isArchived = $request->request->get('archive');
295 $isStarred = $request->request->get('starred'); 304 $isStarred = $request->request->get('starred');
305 $content = $request->request->get('content');
306 $language = $request->request->get('language');
307 $picture = $request->request->get('preview_picture');
308 $publishedAt = $request->request->get('published_at');
309 $authors = $request->request->get('authors', '');
296 310
297 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId()); 311 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
298 312
299 if (false === $entry) { 313 if (false === $entry) {
300 $entry = new Entry($this->getUser()); 314 $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 } 315 }
314 316
315 if (!is_null($title)) { 317 try {
316 $entry->setTitle($title); 318 $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
319 $entry,
320 $url,
321 [
322 'title' => $title,
323 'html' => $content,
324 'url' => $url,
325 'language' => $language,
326 'date' => $publishedAt,
327 // faking the preview picture
328 'open_graph' => [
329 'og_image' => $picture,
330 ],
331 'authors' => explode(',', $authors),
332 ]
333 );
334 } catch (\Exception $e) {
335 $this->get('logger')->error('Error while saving an entry', [
336 'exception' => $e,
337 'entry' => $entry,
338 ]);
339 $entry->setUrl($url);
317 } 340 }
318 341
319 $tags = $request->request->get('tags', '');
320 if (!empty($tags)) { 342 if (!empty($tags)) {
321 $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags); 343 $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags);
322 } 344 }
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_