|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace AppBundle\Controller; |
|
4
|
|
|
|
|
5
|
|
|
use AppBundle\Entity\Tip; |
|
6
|
|
|
use AppBundle\Form\Type\TipType; |
|
7
|
|
|
use FOS\RestBundle\Controller\Annotations as FOSRest; |
|
8
|
|
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration as Sensio; |
|
9
|
|
|
use Nelmio\ApiDocBundle\Annotation as Nelmio; |
|
10
|
|
|
use Symfony\Component\HttpFoundation\Request; |
|
11
|
|
|
use Symfony\Component\HttpFoundation\Response; |
|
12
|
|
|
|
|
13
|
|
|
/** |
|
14
|
|
|
* Class TipController |
|
15
|
|
|
* |
|
16
|
|
|
* @package AppBundle\Controller |
|
17
|
|
|
* |
|
18
|
|
|
* @FOSRest\NamePrefix("api_") |
|
19
|
|
|
*/ |
|
20
|
|
|
class TipController extends AbstractRestController |
|
21
|
|
|
{ |
|
22
|
|
|
/** |
|
23
|
|
|
* Returns a tip by given id. |
|
24
|
|
|
* |
|
25
|
|
|
* @param Tip $tip |
|
26
|
|
|
* |
|
27
|
|
|
* @Nelmio\ApiDoc( |
|
28
|
|
|
* resource=true, |
|
29
|
|
|
* section="Tip", |
|
30
|
|
|
* description="Get tip by id.", |
|
31
|
|
|
* requirements={ |
|
32
|
|
|
* { |
|
33
|
|
|
* "name"="tip", |
|
34
|
|
|
* "dataType"="integer", |
|
35
|
|
|
* "requirement"="id", |
|
36
|
|
|
* "description"="Id of tip" |
|
37
|
|
|
* }, |
|
38
|
|
|
* { |
|
39
|
|
|
* "name"="_format", |
|
40
|
|
|
* "dataType"="string", |
|
41
|
|
|
* "requirement"="json|xml", |
|
42
|
|
|
* "pattern"="json", |
|
43
|
|
|
* "description"="Format" |
|
44
|
|
|
* } |
|
45
|
|
|
* } |
|
46
|
|
|
* ) |
|
47
|
|
|
* |
|
48
|
|
|
* @Sensio\ParamConverter("tip", class="AppBundle:Tip") |
|
49
|
|
|
* |
|
50
|
|
|
* @return Response |
|
51
|
|
|
*/ |
|
52
|
2 |
|
public function getAction(Tip $tip) |
|
53
|
|
|
{ |
|
54
|
2 |
|
return $this->handleView($this->view($tip)); |
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
|
|
/** |
|
58
|
|
|
* Returns a collection of tips |
|
59
|
|
|
* |
|
60
|
|
|
* @param Request $request |
|
61
|
|
|
* |
|
62
|
|
|
* @Nelmio\ApiDoc( |
|
63
|
|
|
* section="Tip", |
|
64
|
|
|
* description="Get tips", |
|
65
|
|
|
* requirements={ |
|
66
|
|
|
* { |
|
67
|
|
|
* "name"="_format", |
|
68
|
|
|
* "dataType"="string", |
|
69
|
|
|
* "requirement"="json|xml", |
|
70
|
|
|
* "pattern"="json", |
|
71
|
|
|
* "description"="Format" |
|
72
|
|
|
* } |
|
73
|
|
|
* } |
|
74
|
|
|
* ) |
|
75
|
|
|
* |
|
76
|
|
|
* @FOSRest\QueryParam(name="page", nullable=true, requirements="\d+", description="page number of |
|
77
|
|
|
* pagination (optional)") |
|
78
|
|
|
* @FOSRest\QueryParam(name="limit", nullable=true, requirements="\d+", description="number of entries |
|
79
|
|
|
* per page (optional)") |
|
80
|
|
|
* |
|
81
|
|
|
* @return Response |
|
82
|
|
|
*/ |
|
83
|
1 |
|
public function cgetAction(Request $request) |
|
84
|
|
|
{ |
|
85
|
1 |
|
$em = $this->getDoctrine()->getManager(); |
|
86
|
1 |
|
$queryBuilder = $em->getRepository('AppBundle:Tip')->createQueryBuilder('t'); |
|
87
|
|
|
|
|
88
|
1 |
|
$representation = $this->createRepresentation($request, $queryBuilder); |
|
89
|
1 |
|
$content = $this->get('serializer')->serialize($representation, $request->getRequestFormat()); |
|
90
|
|
|
|
|
91
|
1 |
|
return new Response($content, Response::HTTP_OK, ['Content-Type' => 'application/hal+json']); |
|
92
|
|
|
} |
|
93
|
|
|
|
|
94
|
|
|
/** |
|
95
|
|
|
* @param Request $request |
|
96
|
|
|
* |
|
97
|
|
|
* @NELMIO\ApiDoc( |
|
98
|
|
|
* section = "Tip", |
|
99
|
|
|
* description="Create a new tip", |
|
100
|
|
|
* statusCodes = { |
|
101
|
|
|
* 200 = "Returned when successful", |
|
102
|
|
|
* 400 = "Returned when request are not correct", |
|
103
|
|
|
* 403 = "Returned when the user is not authorized to create an tip", |
|
104
|
|
|
* 500 = "Returned when internal error" |
|
105
|
|
|
* } |
|
106
|
|
|
* ) |
|
107
|
|
|
* |
|
108
|
|
|
* @return Response |
|
109
|
|
|
* |
|
110
|
|
|
*/ |
|
111
|
1 |
|
public function newAction(Request $request) |
|
112
|
|
|
{ |
|
113
|
1 |
|
return $this->handleRequestAction($request, new Tip()); |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
/** |
|
117
|
|
|
* @param Request $request |
|
118
|
|
|
* |
|
119
|
|
|
* @FOSRest\Post("/tips") |
|
120
|
|
|
* |
|
121
|
|
|
* @NELMIO\ApiDoc( |
|
122
|
|
|
* section = "Tip", |
|
123
|
|
|
* description="Create a new tip", |
|
124
|
|
|
* input = "AppBundle\Form\PageType", |
|
125
|
|
|
* statusCodes = { |
|
126
|
|
|
* 200 = "Returned when successful", |
|
127
|
|
|
* 400 = "Returned when request are not correct", |
|
128
|
|
|
* 403 = "Returned when the user is not authorized to create an tip", |
|
129
|
|
|
* 500 = "Returned when internal error" |
|
130
|
|
|
* } |
|
131
|
|
|
* ) |
|
132
|
|
|
* |
|
133
|
|
|
* @return Response |
|
134
|
|
|
*/ |
|
135
|
2 |
|
public function createAction(Request $request) |
|
136
|
|
|
{ |
|
137
|
2 |
|
return $this->handleRequestAction($request, new Tip()); |
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
/** |
|
141
|
|
|
* @param Request $request |
|
142
|
|
|
* @param Tip $tip |
|
143
|
|
|
* |
|
144
|
|
|
* @FOSRest\Post |
|
145
|
|
|
* |
|
146
|
|
|
* @NELMIO\ApiDoc( |
|
147
|
|
|
* section = "Tip", |
|
148
|
|
|
* description="Update a tip by id.", |
|
149
|
|
|
* input = "AppBundle\Form\PageType", |
|
150
|
|
|
* statusCodes = { |
|
151
|
|
|
* 200 = "Returned when successful", |
|
152
|
|
|
* 400 = "Returned when request are not correct", |
|
153
|
|
|
* 403 = "Returned when the user is not authorized to create an tip", |
|
154
|
|
|
* 500 = "Returned when internal error" |
|
155
|
|
|
* } |
|
156
|
|
|
* ) |
|
157
|
|
|
* |
|
158
|
|
|
* @Sensio\ParamConverter("tip", class="AppBundle:Tip") |
|
159
|
|
|
* |
|
160
|
|
|
* @return Response |
|
161
|
|
|
*/ |
|
162
|
1 |
|
public function updateAction(Request $request, Tip $tip) |
|
163
|
|
|
{ |
|
164
|
1 |
|
return $this->handleRequestAction($request, $tip); |
|
165
|
|
|
} |
|
166
|
|
|
|
|
167
|
|
|
/** |
|
168
|
|
|
* @param Tip $tip |
|
169
|
|
|
* |
|
170
|
|
|
* @Sensio\ParamConverter("tip", class="AppBundle:Tip") |
|
171
|
|
|
* |
|
172
|
|
|
* @return Response |
|
173
|
|
|
*/ |
|
174
|
1 |
|
public function deleteAction(Tip $tip) |
|
175
|
|
|
{ |
|
176
|
1 |
|
$em = $this->getDoctrine()->getManager(); |
|
177
|
1 |
|
$em->remove($tip); |
|
178
|
1 |
|
$em->flush(); |
|
179
|
1 |
|
} |
|
180
|
|
|
|
|
181
|
|
|
/** |
|
182
|
|
|
* @FOSRest\NoRoute() |
|
183
|
|
|
* |
|
184
|
|
|
* @param Request $request |
|
185
|
|
|
* @param Tip $tip |
|
186
|
|
|
* |
|
187
|
|
|
* @return Response |
|
188
|
|
|
*/ |
|
189
|
4 |
|
private function handleRequestAction(Request $request, Tip $tip) |
|
190
|
|
|
{ |
|
191
|
4 |
|
$form = $this->createForm(TipType::class, $tip); |
|
192
|
4 |
|
$form->handleRequest($request); |
|
193
|
|
|
|
|
194
|
4 |
|
if (true === $form->isSubmitted() && $form->isValid()) { |
|
195
|
2 |
|
$em = $this->getDoctrine()->getManager(); |
|
196
|
2 |
|
$em->persist($tip); |
|
197
|
2 |
|
$em->flush(); |
|
198
|
|
|
|
|
199
|
2 |
|
$response = new Response($this->get('serializer')->serialize($tip, $request->getRequestFormat())); |
|
200
|
2 |
|
$response->headers->set('Location', $this->generateUrl('api_get_tip', ['tip' => $tip->getId()])); |
|
201
|
|
|
|
|
202
|
2 |
|
return $response; |
|
203
|
|
|
} |
|
204
|
|
|
|
|
205
|
2 |
|
return $this->view($form, 400); |
|
|
|
|
|
|
206
|
|
|
} |
|
207
|
|
|
} |
|
208
|
|
|
|
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.