|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* This file is part of the Sonata Project package. |
|
5
|
|
|
* |
|
6
|
|
|
* (c) Thomas Rabaix <[email protected]> |
|
7
|
|
|
* |
|
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
|
9
|
|
|
* file that was distributed with this source code. |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
namespace Sonata\NewsBundle\Controller\Api; |
|
13
|
|
|
|
|
14
|
|
|
use Application\Sonata\NewsBundle\Entity\Post; |
|
15
|
|
|
use FOS\RestBundle\Controller\Annotations\QueryParam; |
|
16
|
|
|
use FOS\RestBundle\Controller\Annotations\Route; |
|
17
|
|
|
use FOS\RestBundle\Controller\Annotations\View; |
|
18
|
|
|
use FOS\RestBundle\Request\ParamFetcherInterface; |
|
19
|
|
|
use JMS\Serializer\SerializationContext; |
|
20
|
|
|
use Nelmio\ApiDocBundle\Annotation\ApiDoc; |
|
21
|
|
|
use Sonata\DatagridBundle\Pager\PagerInterface; |
|
22
|
|
|
use Sonata\FormatterBundle\Formatter\Pool as FormatterPool; |
|
23
|
|
|
use Sonata\NewsBundle\Mailer\MailerInterface; |
|
24
|
|
|
use Sonata\NewsBundle\Model\Comment; |
|
25
|
|
|
use Sonata\NewsBundle\Model\CommentManagerInterface; |
|
26
|
|
|
use Sonata\NewsBundle\Model\PostManagerInterface; |
|
27
|
|
|
use Symfony\Component\Form\FormFactoryInterface; |
|
28
|
|
|
use Symfony\Component\Form\FormInterface; |
|
29
|
|
|
use Symfony\Component\HttpFoundation\Request; |
|
30
|
|
|
use Symfony\Component\HttpKernel\Exception\HttpException; |
|
31
|
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; |
|
32
|
|
|
|
|
33
|
|
|
/** |
|
34
|
|
|
* Class PostController. |
|
35
|
|
|
* |
|
36
|
|
|
* |
|
37
|
|
|
* @author Hugo Briand <[email protected]> |
|
38
|
|
|
*/ |
|
39
|
|
|
class PostController |
|
40
|
|
|
{ |
|
41
|
|
|
/** |
|
42
|
|
|
* @var PostManagerInterface |
|
43
|
|
|
*/ |
|
44
|
|
|
protected $postManager; |
|
45
|
|
|
|
|
46
|
|
|
/** |
|
47
|
|
|
* @var CommentManagerInterface |
|
48
|
|
|
*/ |
|
49
|
|
|
protected $commentManager; |
|
50
|
|
|
|
|
51
|
|
|
/** |
|
52
|
|
|
* @var MailerInterface |
|
53
|
|
|
*/ |
|
54
|
|
|
protected $mailer; |
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* @var FormFactoryInterface |
|
58
|
|
|
*/ |
|
59
|
|
|
protected $formFactory; |
|
60
|
|
|
|
|
61
|
|
|
/** |
|
62
|
|
|
* @var FormatterPool |
|
63
|
|
|
*/ |
|
64
|
|
|
protected $formatterPool; |
|
65
|
|
|
|
|
66
|
|
|
/** |
|
67
|
|
|
* Constructor. |
|
68
|
|
|
* |
|
69
|
|
|
* @param PostManagerInterface $postManager |
|
70
|
|
|
* @param CommentManagerInterface $commentManager |
|
71
|
|
|
* @param MailerInterface $mailer |
|
72
|
|
|
* @param FormFactoryInterface $formFactory |
|
73
|
|
|
* @param FormatterPool $formatterPool |
|
74
|
|
|
*/ |
|
75
|
|
|
public function __construct(PostManagerInterface $postManager, CommentManagerInterface $commentManager, MailerInterface $mailer, FormFactoryInterface $formFactory, FormatterPool $formatterPool) |
|
76
|
|
|
{ |
|
77
|
|
|
$this->postManager = $postManager; |
|
78
|
|
|
$this->commentManager = $commentManager; |
|
79
|
|
|
$this->mailer = $mailer; |
|
80
|
|
|
$this->formFactory = $formFactory; |
|
81
|
|
|
$this->formatterPool = $formatterPool; |
|
82
|
|
|
} |
|
83
|
|
|
|
|
84
|
|
|
/** |
|
85
|
|
|
* Retrieves the list of posts (paginated) based on criteria. |
|
86
|
|
|
* |
|
87
|
|
|
* @ApiDoc( |
|
88
|
|
|
* resource=true, |
|
89
|
|
|
* output={"class"="Sonata\DatagridBundle\Pager\PagerInterface", "groups"={"sonata_api_read"}} |
|
90
|
|
|
* ) |
|
91
|
|
|
* |
|
92
|
|
|
* @QueryParam(name="page", requirements="\d+", default="1", description="Page for posts list pagination") |
|
93
|
|
|
* @QueryParam(name="count", requirements="\d+", default="10", description="Number of posts by page") |
|
94
|
|
|
* @QueryParam(name="enabled", requirements="0|1", nullable=true, strict=true, description="Enabled/Disabled posts filter") |
|
95
|
|
|
* @QueryParam(name="dateQuery", requirements=">|<|=", default=">", description="Date filter orientation (>, < or =)") |
|
96
|
|
|
* @QueryParam(name="dateValue", requirements="[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-2][0-9]:[0-5][0-9]:[0-5][0-9]([+-][0-9]{2}(:)?[0-9]{2})?", nullable=true, strict=true, description="Date filter value") |
|
97
|
|
|
* @QueryParam(name="tag", requirements="\S+", nullable=true, strict=true, description="Tag name filter") |
|
98
|
|
|
* @QueryParam(name="author", requirements="\S+", nullable=true, strict=true, description="Author filter") |
|
99
|
|
|
* @QueryParam(name="mode", requirements="public|admin", default="public", description="'public' mode filters posts having enabled tags and author") |
|
100
|
|
|
* |
|
101
|
|
|
* @View(serializerGroups="sonata_api_read", serializerEnableMaxDepthChecks=true) |
|
102
|
|
|
* |
|
103
|
|
|
* @Route(requirements={"_format"="json|xml"}) |
|
104
|
|
|
* |
|
105
|
|
|
* @param ParamFetcherInterface $paramFetcher |
|
106
|
|
|
* |
|
107
|
|
|
* @return PagerInterface |
|
108
|
|
|
*/ |
|
109
|
|
|
public function getPostsAction(ParamFetcherInterface $paramFetcher) |
|
110
|
|
|
{ |
|
111
|
|
|
$page = $paramFetcher->get('page'); |
|
112
|
|
|
$count = $paramFetcher->get('count'); |
|
113
|
|
|
|
|
114
|
|
|
$pager = $this->postManager->getPager($this->filterCriteria($paramFetcher), $page, $count); |
|
115
|
|
|
|
|
116
|
|
|
return $pager; |
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
/** |
|
120
|
|
|
* Retrieves a specific post. |
|
121
|
|
|
* |
|
122
|
|
|
* @ApiDoc( |
|
123
|
|
|
* requirements={ |
|
124
|
|
|
* {"name"="id", "dataType"="integer", "requirement"="\d+", "description"="post id"} |
|
125
|
|
|
* }, |
|
126
|
|
|
* output={"class"="sonata_news_api_form_post", "groups"={"sonata_api_read"}}, |
|
127
|
|
|
* statusCodes={ |
|
128
|
|
|
* 200="Returned when successful", |
|
129
|
|
|
* 404="Returned when post is not found" |
|
130
|
|
|
* } |
|
131
|
|
|
* ) |
|
132
|
|
|
* |
|
133
|
|
|
* @View(serializerGroups="sonata_api_read", serializerEnableMaxDepthChecks=true) |
|
134
|
|
|
* |
|
135
|
|
|
* @Route(requirements={"_format"="json|xml"}) |
|
136
|
|
|
* |
|
137
|
|
|
* @param int $id A post identifier |
|
138
|
|
|
* |
|
139
|
|
|
* @return Post |
|
140
|
|
|
*/ |
|
141
|
|
|
public function getPostAction($id) |
|
142
|
|
|
{ |
|
143
|
|
|
return $this->getPost($id); |
|
144
|
|
|
} |
|
145
|
|
|
|
|
146
|
|
|
/** |
|
147
|
|
|
* Adds a post. |
|
148
|
|
|
* |
|
149
|
|
|
* @ApiDoc( |
|
150
|
|
|
* input={"class"="sonata_news_api_form_post", "name"="", "groups"={"sonata_api_write"}}, |
|
151
|
|
|
* output={"class"="sonata_news_api_form_post", "groups"={"sonata_api_read"}}, |
|
152
|
|
|
* statusCodes={ |
|
153
|
|
|
* 200="Returned when successful", |
|
154
|
|
|
* 400="Returned when an error has occurred while post creation", |
|
155
|
|
|
* } |
|
156
|
|
|
* ) |
|
157
|
|
|
* |
|
158
|
|
|
* @Route(requirements={"_format"="json|xml"}) |
|
159
|
|
|
* |
|
160
|
|
|
* @param Request $request A Symfony request |
|
161
|
|
|
* |
|
162
|
|
|
* @return Post |
|
163
|
|
|
* |
|
164
|
|
|
* @throws NotFoundHttpException |
|
165
|
|
|
*/ |
|
166
|
|
|
public function postPostAction(Request $request) |
|
167
|
|
|
{ |
|
168
|
|
|
return $this->handleWritePost($request); |
|
169
|
|
|
} |
|
170
|
|
|
|
|
171
|
|
|
/** |
|
172
|
|
|
* Updates a post. |
|
173
|
|
|
* |
|
174
|
|
|
* @ApiDoc( |
|
175
|
|
|
* requirements={ |
|
176
|
|
|
* {"name"="id", "dataType"="integer", "requirement"="\d+", "description"="post identifier"} |
|
177
|
|
|
* }, |
|
178
|
|
|
* input={"class"="sonata_news_api_form_post", "name"="", "groups"={"sonata_api_write"}}, |
|
179
|
|
|
* output={"class"="sonata_news_api_form_post", "groups"={"sonata_api_read"}}, |
|
180
|
|
|
* statusCodes={ |
|
181
|
|
|
* 200="Returned when successful", |
|
182
|
|
|
* 400="Returned when an error has occurred while post update", |
|
183
|
|
|
* 404="Returned when unable to find post" |
|
184
|
|
|
* } |
|
185
|
|
|
* ) |
|
186
|
|
|
* |
|
187
|
|
|
* @Route(requirements={"_format"="json|xml"}) |
|
188
|
|
|
* |
|
189
|
|
|
* @param int $id A Post identifier |
|
190
|
|
|
* @param Request $request A Symfony request |
|
191
|
|
|
* |
|
192
|
|
|
* @return Post |
|
193
|
|
|
* |
|
194
|
|
|
* @throws NotFoundHttpException |
|
195
|
|
|
*/ |
|
196
|
|
|
public function putPostAction($id, Request $request) |
|
197
|
|
|
{ |
|
198
|
|
|
return $this->handleWritePost($request, $id); |
|
199
|
|
|
} |
|
200
|
|
|
|
|
201
|
|
|
/** |
|
202
|
|
|
* Deletes a post. |
|
203
|
|
|
* |
|
204
|
|
|
* @ApiDoc( |
|
205
|
|
|
* requirements={ |
|
206
|
|
|
* {"name"="id", "dataType"="integer", "requirement"="\d+", "description"="post identifier"} |
|
207
|
|
|
* }, |
|
208
|
|
|
* statusCodes={ |
|
209
|
|
|
* 200="Returned when post is successfully deleted", |
|
210
|
|
|
* 400="Returned when an error has occurred while post deletion", |
|
211
|
|
|
* 404="Returned when unable to find post" |
|
212
|
|
|
* } |
|
213
|
|
|
* ) |
|
214
|
|
|
* |
|
215
|
|
|
* @Route(requirements={"_format"="json|xml"}) |
|
216
|
|
|
* |
|
217
|
|
|
* @param int $id A Post identifier |
|
218
|
|
|
* |
|
219
|
|
|
* @return View |
|
220
|
|
|
* |
|
221
|
|
|
* @throws NotFoundHttpException |
|
222
|
|
|
*/ |
|
223
|
|
|
public function deletePostAction($id) |
|
224
|
|
|
{ |
|
225
|
|
|
$post = $this->getPost($id); |
|
226
|
|
|
|
|
227
|
|
|
try { |
|
228
|
|
|
$this->postManager->delete($post); |
|
229
|
|
|
} catch (\Exception $e) { |
|
230
|
|
|
return \FOS\RestBundle\View\View::create(array('error' => $e->getMessage()), 400); |
|
231
|
|
|
} |
|
232
|
|
|
|
|
233
|
|
|
return array('deleted' => true); |
|
|
|
|
|
|
234
|
|
|
} |
|
235
|
|
|
|
|
236
|
|
|
/** |
|
237
|
|
|
* Retrieves the comments of specified post. |
|
238
|
|
|
* |
|
239
|
|
|
* @ApiDoc( |
|
240
|
|
|
* requirements={ |
|
241
|
|
|
* {"name"="id", "dataType"="integer", "requirement"="\d+", "description"="Post id"} |
|
242
|
|
|
* }, |
|
243
|
|
|
* output={"class"="Sonata\DatagridBundle\Pager\PagerInterface", "groups"={"sonata_api_read"}}, |
|
244
|
|
|
* statusCodes={ |
|
245
|
|
|
* 200="Returned when successful", |
|
246
|
|
|
* 404="Returned when post is not found" |
|
247
|
|
|
* } |
|
248
|
|
|
* ) |
|
249
|
|
|
* |
|
250
|
|
|
* @QueryParam(name="page", requirements="\d+", default="1", description="Page for comments list pagination") |
|
251
|
|
|
* @QueryParam(name="count", requirements="\d+", default="10", description="Number of comments by page") |
|
252
|
|
|
* |
|
253
|
|
|
* @Route(requirements={"_format"="json|xml"}) |
|
254
|
|
|
* |
|
255
|
|
|
* @View(serializerGroups="sonata_api_read", serializerEnableMaxDepthChecks=true) |
|
256
|
|
|
* |
|
257
|
|
|
* @param int $id A post identifier |
|
258
|
|
|
* @param ParamFetcherInterface $paramFetcher |
|
259
|
|
|
* |
|
260
|
|
|
* @return PagerInterface |
|
261
|
|
|
*/ |
|
262
|
|
|
public function getPostCommentsAction($id, ParamFetcherInterface $paramFetcher) |
|
263
|
|
|
{ |
|
264
|
|
|
$post = $this->getPost($id); |
|
265
|
|
|
|
|
266
|
|
|
$page = $paramFetcher->get('page'); |
|
267
|
|
|
$count = $paramFetcher->get('count'); |
|
268
|
|
|
|
|
269
|
|
|
$criteria = $this->filterCriteria($paramFetcher); |
|
270
|
|
|
$criteria['postId'] = $post->getId(); |
|
271
|
|
|
|
|
272
|
|
|
/** @var PagerInterface $pager */ |
|
273
|
|
|
$pager = $this->commentManager->getPager($criteria, $page, $count); |
|
274
|
|
|
|
|
275
|
|
|
return $pager; |
|
276
|
|
|
} |
|
277
|
|
|
|
|
278
|
|
|
/** |
|
279
|
|
|
* Adds a comment to a post. |
|
280
|
|
|
* |
|
281
|
|
|
* @ApiDoc( |
|
282
|
|
|
* requirements={ |
|
283
|
|
|
* {"name"="id", "dataType"="integer", "requirement"="\d+", "description"="post id"} |
|
284
|
|
|
* }, |
|
285
|
|
|
* input={"class"="sonata_news_api_form_comment", "name"="", "groups"={"sonata_api_write"}}, |
|
286
|
|
|
* output={"class"="Sonata\NewsBundle\Model\Comment", "groups"={"sonata_api_read"}}, |
|
287
|
|
|
* statusCodes={ |
|
288
|
|
|
* 200="Returned when successful", |
|
289
|
|
|
* 400="Returned when an error has occurred while comment creation", |
|
290
|
|
|
* 403="Returned when commenting is not enabled on the related post", |
|
291
|
|
|
* 404="Returned when post is not found" |
|
292
|
|
|
* } |
|
293
|
|
|
* ) |
|
294
|
|
|
* |
|
295
|
|
|
* @Route(requirements={"_format"="json|xml"}) |
|
296
|
|
|
* |
|
297
|
|
|
* @param int $id A post identifier |
|
298
|
|
|
* @param Request $request |
|
299
|
|
|
* |
|
300
|
|
|
* @return Comment|FormInterface |
|
301
|
|
|
* |
|
302
|
|
|
* @throws HttpException |
|
303
|
|
|
*/ |
|
304
|
|
|
public function postPostCommentsAction($id, Request $request) |
|
305
|
|
|
{ |
|
306
|
|
|
$post = $this->getPost($id); |
|
307
|
|
|
|
|
308
|
|
|
if (!$post->isCommentable()) { |
|
309
|
|
|
throw new HttpException(403, sprintf('Post (%d) not commentable', $id)); |
|
310
|
|
|
} |
|
311
|
|
|
|
|
312
|
|
|
$comment = $this->commentManager->create(); |
|
313
|
|
|
$comment->setPost($post); |
|
314
|
|
|
|
|
315
|
|
|
$form = $this->formFactory->createNamed(null, 'sonata_news_api_form_comment', $comment, array('csrf_protection' => false)); |
|
316
|
|
|
$form->bind($request); |
|
317
|
|
|
|
|
318
|
|
|
if ($form->isValid()) { |
|
319
|
|
|
$comment = $form->getData(); |
|
320
|
|
|
$comment->setPost($post); |
|
321
|
|
|
|
|
322
|
|
|
if (!$comment->getStatus()) { |
|
323
|
|
|
$comment->setStatus($post->getCommentsDefaultStatus()); |
|
324
|
|
|
} |
|
325
|
|
|
|
|
326
|
|
|
$this->commentManager->save($comment); |
|
327
|
|
|
$this->mailer->sendCommentNotification($comment); |
|
328
|
|
|
|
|
329
|
|
|
$view = \FOS\RestBundle\View\View::create($comment); |
|
330
|
|
|
$serializationContext = SerializationContext::create(); |
|
331
|
|
|
$serializationContext->setGroups(array('sonata_api_read')); |
|
332
|
|
|
$serializationContext->enableMaxDepthChecks(); |
|
333
|
|
|
$view->setSerializationContext($serializationContext); |
|
334
|
|
|
|
|
335
|
|
|
return $view; |
|
336
|
|
|
} |
|
337
|
|
|
|
|
338
|
|
|
return $form; |
|
339
|
|
|
} |
|
340
|
|
|
|
|
341
|
|
|
/** |
|
342
|
|
|
* Updates a comment. |
|
343
|
|
|
* |
|
344
|
|
|
* @ApiDoc( |
|
345
|
|
|
* requirements={ |
|
346
|
|
|
* {"name"="postId", "dataType"="integer", "requirement"="\d+", "description"="post identifier"}, |
|
347
|
|
|
* {"name"="commentId", "dataType"="integer", "requirement"="\d+", "description"="comment identifier"} |
|
348
|
|
|
* }, |
|
349
|
|
|
* input={"class"="sonata_news_api_form_comment", "name"="", "groups"={"sonata_api_write"}}, |
|
350
|
|
|
* output={"class"="Sonata\NewsBundle\Model\Comment", "groups"={"sonata_api_read"}}, |
|
351
|
|
|
* statusCodes={ |
|
352
|
|
|
* 200="Returned when successful", |
|
353
|
|
|
* 400="Returned when an error has occurred while comment update", |
|
354
|
|
|
* 404="Returned when unable to find comment" |
|
355
|
|
|
* } |
|
356
|
|
|
* ) |
|
357
|
|
|
* |
|
358
|
|
|
* @Route(requirements={"_format"="json|xml"}) |
|
359
|
|
|
* |
|
360
|
|
|
* @param int $postId A post identifier |
|
361
|
|
|
* @param int $commentId A comment identifier |
|
362
|
|
|
* @param Request $request A Symfony request |
|
363
|
|
|
* |
|
364
|
|
|
* @return Comment |
|
365
|
|
|
* |
|
366
|
|
|
* @throws NotFoundHttpException |
|
367
|
|
|
* @throws HttpException |
|
368
|
|
|
*/ |
|
369
|
|
|
public function putPostCommentsAction($postId, $commentId, Request $request) |
|
370
|
|
|
{ |
|
371
|
|
|
$post = $this->getPost($postId); |
|
372
|
|
|
|
|
373
|
|
|
if (!$post->isCommentable()) { |
|
374
|
|
|
throw new HttpException(403, sprintf('Post (%d) not commentable', $postId)); |
|
375
|
|
|
} |
|
376
|
|
|
|
|
377
|
|
|
$comment = $this->commentManager->find($commentId); |
|
378
|
|
|
|
|
379
|
|
|
if (null === $comment) { |
|
380
|
|
|
throw new NotFoundHttpException(sprintf('Comment (%d) not found', $commentId)); |
|
381
|
|
|
} |
|
382
|
|
|
|
|
383
|
|
|
$comment->setPost($post); |
|
384
|
|
|
|
|
385
|
|
|
$form = $this->formFactory->createNamed(null, 'sonata_news_api_form_comment', $comment, array( |
|
386
|
|
|
'csrf_protection' => false, |
|
387
|
|
|
)); |
|
388
|
|
|
|
|
389
|
|
|
$form->bind($request); |
|
390
|
|
|
|
|
391
|
|
|
if ($form->isValid()) { |
|
392
|
|
|
$comment = $form->getData(); |
|
393
|
|
|
$this->commentManager->save($comment); |
|
394
|
|
|
|
|
395
|
|
|
$view = \FOS\RestBundle\View\View::create($comment); |
|
396
|
|
|
$serializationContext = SerializationContext::create(); |
|
397
|
|
|
$serializationContext->setGroups(array('sonata_api_read')); |
|
398
|
|
|
$serializationContext->enableMaxDepthChecks(); |
|
399
|
|
|
$view->setSerializationContext($serializationContext); |
|
400
|
|
|
|
|
401
|
|
|
return $view; |
|
402
|
|
|
} |
|
403
|
|
|
|
|
404
|
|
|
return $form; |
|
405
|
|
|
} |
|
406
|
|
|
|
|
407
|
|
|
/** |
|
408
|
|
|
* Filters criteria from $paramFetcher to be compatible with the Pager criteria. |
|
409
|
|
|
* |
|
410
|
|
|
* @param ParamFetcherInterface $paramFetcher |
|
411
|
|
|
* |
|
412
|
|
|
* @return array The filtered criteria |
|
413
|
|
|
*/ |
|
414
|
|
|
protected function filterCriteria(ParamFetcherInterface $paramFetcher) |
|
415
|
|
|
{ |
|
416
|
|
|
$criteria = $paramFetcher->all(); |
|
417
|
|
|
|
|
418
|
|
|
unset($criteria['page'], $criteria['count']); |
|
419
|
|
|
|
|
420
|
|
|
foreach ($criteria as $key => $value) { |
|
421
|
|
|
if (null === $value) { |
|
422
|
|
|
unset($criteria[$key]); |
|
423
|
|
|
} |
|
424
|
|
|
} |
|
425
|
|
|
|
|
426
|
|
|
if (array_key_exists('dateValue', $criteria)) { |
|
427
|
|
|
$date = new \DateTime($criteria['dateValue']); |
|
428
|
|
|
$criteria['date'] = array( |
|
429
|
|
|
'query' => sprintf('p.publicationDateStart %s :dateValue', $criteria['dateQuery']), |
|
430
|
|
|
'params' => array('dateValue' => $date), |
|
431
|
|
|
); |
|
432
|
|
|
unset($criteria['dateValue'], $criteria['dateQuery']); |
|
433
|
|
|
} else { |
|
434
|
|
|
unset($criteria['dateQuery']); |
|
435
|
|
|
} |
|
436
|
|
|
|
|
437
|
|
|
return $criteria; |
|
438
|
|
|
} |
|
439
|
|
|
|
|
440
|
|
|
/** |
|
441
|
|
|
* Retrieves post with id $id or throws an exception if it doesn't exist. |
|
442
|
|
|
* |
|
443
|
|
|
* @param int $id A Post identifier |
|
444
|
|
|
* |
|
445
|
|
|
* @return Post |
|
446
|
|
|
* |
|
447
|
|
|
* @throws NotFoundHttpException |
|
448
|
|
|
*/ |
|
449
|
|
|
protected function getPost($id) |
|
450
|
|
|
{ |
|
451
|
|
|
$post = $this->postManager->find($id); |
|
452
|
|
|
|
|
453
|
|
|
if (null === $post) { |
|
454
|
|
|
throw new NotFoundHttpException(sprintf('Post (%d) not found', $id)); |
|
455
|
|
|
} |
|
456
|
|
|
|
|
457
|
|
|
return $post; |
|
458
|
|
|
} |
|
459
|
|
|
|
|
460
|
|
|
/** |
|
461
|
|
|
* Write a post, this method is used by both POST and PUT action methods. |
|
462
|
|
|
* |
|
463
|
|
|
* @param Request $request Symfony request |
|
464
|
|
|
* @param int|null $id A post identifier |
|
465
|
|
|
* |
|
466
|
|
|
* @return FormInterface |
|
467
|
|
|
*/ |
|
468
|
|
|
protected function handleWritePost($request, $id = null) |
|
469
|
|
|
{ |
|
470
|
|
|
$post = $id ? $this->getPost($id) : null; |
|
471
|
|
|
|
|
472
|
|
|
$form = $this->formFactory->createNamed(null, 'sonata_news_api_form_post', $post, array( |
|
473
|
|
|
'csrf_protection' => false, |
|
474
|
|
|
)); |
|
475
|
|
|
|
|
476
|
|
|
$form->bind($request); |
|
477
|
|
|
|
|
478
|
|
|
if ($form->isValid()) { |
|
479
|
|
|
$post = $form->getData(); |
|
480
|
|
|
$post->setContent($this->formatterPool->transform($post->getContentFormatter(), $post->getRawContent())); |
|
481
|
|
|
$this->postManager->save($post); |
|
482
|
|
|
|
|
483
|
|
|
$view = \FOS\RestBundle\View\View::create($post); |
|
484
|
|
|
$serializationContext = SerializationContext::create(); |
|
485
|
|
|
$serializationContext->setGroups(array('sonata_api_read')); |
|
486
|
|
|
$serializationContext->enableMaxDepthChecks(); |
|
487
|
|
|
$view->setSerializationContext($serializationContext); |
|
488
|
|
|
|
|
489
|
|
|
return $view; |
|
|
|
|
|
|
490
|
|
|
} |
|
491
|
|
|
|
|
492
|
|
|
return $form; |
|
493
|
|
|
} |
|
494
|
|
|
} |
|
495
|
|
|
|
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.