Completed
Push — master ( a3bf41...af2027 )
by FX
03:04
created

ProjectApiController::deleteProjectAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright (c) 2017 Francois-Xavier Soubirou.
5
 *
6
 * This file is part of ci-report.
7
 *
8
 * ci-report is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * ci-report is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with ci-report. If not, see <http://www.gnu.org/licenses/>.
20
 */
21
declare(strict_types=1);
22
23
namespace AppBundle\Controller;
24
25
use AppBundle\DTO\ProjectDTO;
26
use AppBundle\Entity\Project;
27
use AppBundle\Service\ProjectService;
28
use FOS\RestBundle\Controller\Annotations as Rest;
29
use FOS\RestBundle\View\View;
30
use Nelmio\ApiDocBundle\Annotation as Doc;
31
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
32
use Symfony\Component\HttpFoundation\Request;
33
use Symfony\Component\HttpFoundation\Response;
34
use Symfony\Component\Validator\ConstraintViolationList;
35
36
/**
37
 * Project controller class.
38
 *
39
 * @category  ci-report app
40
 *
41
 * @author    Francois-Xavier Soubirou <[email protected]>
42
 * @copyright 2017 Francois-Xavier Soubirou
43
 * @license   http://www.gnu.org/licenses/   GPLv3
44
 *
45
 * @see      https://ci-report.io
46
 *
47
 * @Rest\Route("/api")
48
 */
49
class ProjectApiController extends AbstractApiController
50
{
51
    /**
52
     * Get list of projects. Example: </br>
53
     * <pre style="background:black; color:white; font-size:10px;"><code style="background:black;">curl https://www.ci-report.io/api/projects -X GET
54
     * </code></pre>.
55
     *
56
     * @return array
57
     *
58
     * @Rest\Get("/projects")
59
     * @Rest\View(serializerGroups={"public"})
60
     *
61
     * @Doc\ApiDoc(
62
     *     section="Projects",
63
     *     description="Get the list of all projects.",
64
     *     output={
65
     *         "class"=Project::class,
66
     *         "groups"={"public"},
67
     *         "parsers"={"Nelmio\ApiDocBundle\Parser\JmsMetadataParser"}
68
     *     },
69
     *     statusCodes={
70
     *         200="Returned when successful array of public data of projects"
71
     *     }
72
     * )
73
     */
74
    public function getProjectsAction(): array
75
    {
76
        $projects = $this->getDoctrine()
77
            ->getRepository(Project::class)
78
            ->findAll();
79
80
        return $projects;
81
    }
82
83
    /**
84
     * Get public project data. Example: </br>
85
     * <pre style="background:black; color:white; font-size:10px;"><code style="background:black;">curl https://www.ci-report.io/api/projects/project-one -X GET
86
     * </code></pre>.
87
     *
88
     * @param Project $project Project
89
     *
90
     * @return Project
91
     *
92
     * @Rest\Get("/projects/{refid}")
93
     * @Rest\View(serializerGroups={"public"})
94
     *
95
     * @ParamConverter("project", options={"mapping": {"refid": "refid"}})
96
     *
97
     * @Doc\ApiDoc(
98
     *     section="Projects",
99
     *     description="Get public project data.",
100
     *     requirements={
101
     *         {
102
     *             "name"="refid",
103
     *             "dataType"="string",
104
     *             "requirement"="string",
105
     *             "description"="Unique short name of project defined on project creation."
106
     *         }
107
     *     },
108
     *     output= {
109
     *         "class"=Project::class,
110
     *         "groups"={"public"},
111
     *         "parsers"={"Nelmio\ApiDocBundle\Parser\JmsMetadataParser"}
112
     *     },
113
     *     statusCodes={
114
     *         200="Returned when successful",
115
     *         404="Returned when project not found"
116
     *     }
117
     * )
118
     */
119
    public function getProjectAction(Project $project): Project
120
    {
121
        return $project;
122
    }
123
124
    /**
125
     * Get private project data. Example: </br>
126
     * <pre style="background:black; color:white; font-size:10px;"><code style="background:black;">curl https://www.ci-report.io/api/projects/project-one/private -H "X-CIR-TKN: 1f4ffb19e4b9-02278af07b7d-4e370a76f001" -X GET
127
     * </code></pre>.
128
     *
129
     * @param Project $project Project
130
     * @param Request $request The request
131
     *
132
     * @return Project|View
133
     *
134
     * @Rest\Get("/projects/{refid}/private")
135
     * @Rest\View(serializerGroups={"private"})
136
     *
137
     * @ParamConverter("project", options={"mapping": {"refid": "refid"}})
138
     *
139
     * @Doc\ApiDoc(
140
     *     section="Projects",
141
     *     description="Get private project data.",
142
     *     headers={
143
     *         {
144
     *             "name"="X-CIR-TKN",
145
     *             "required"=true,
146
     *             "description"="Private token"
147
     *         }
148
     *     },
149
     *     requirements={
150
     *         {
151
     *             "name"="refid",
152
     *             "dataType"="string",
153
     *             "requirement"="string",
154
     *             "description"="Unique short name of project defined on project creation."
155
     *         }
156
     *     },
157
     *     output= {
158
     *         "class"=Project::class,
159
     *         "groups"={"private"},
160
     *         "parsers"={"Nelmio\ApiDocBundle\Parser\JmsMetadataParser"}
161
     *     },
162
     *     statusCodes={
163
     *         200="Returned when successful",
164
     *         401="Returned when X-CIR-TKN private token value is invalid",
165
     *         404="Returned when project not found"
166
     *     },
167
     *     tags={
168
     *         "token" = "#87ceeb"
169
     *     }
170
     * )
171
     */
172
    public function getProjectPrivateAction(Project $project, Request $request)
173
    {
174
        if ($this->isInvalidToken($request, $project->getToken())) {
175
            return $this->getInvalidTokenView();
176
        }
177
178
        return $project;
179
    }
180
181
    /**
182
     * Create a project. Private token is sent by email. Example: </br>
183
     * <pre style="background:black; color:white; font-size:10px;"><code style="background:black;">curl https://www.ci-report.io/api/projects -H "Content-Type: application/json" -X POST --data '{"name":"Project To Add", "warning":80, "success":95, "email":"[email protected]"}'
184
     * </code></pre>.
185
     *
186
     * @param Project                 $project    Project to create
187
     * @param ConstraintViolationList $violations List of violations
188
     *
189
     * @return Project|View
190
     *
191
     * @Rest\Post("/projects")
192
     * @Rest\View(statusCode=Response::HTTP_CREATED, serializerGroups={"private"})
193
     *
194
     * @ParamConverter("project", converter="fos_rest.request_body", options={ "validator"={"groups"={"input", "unique"}} } )
195
     *
196
     * @Doc\ApiDoc(
197
     *     section="Projects",
198
     *     description="Create a project. Private data are sent by mail.",
199
     *     headers={
200
     *         {
201
     *             "name"="Content-Type",
202
     *             "required"=true,
203
     *             "description"="Type of content: application/json"
204
     *         }
205
     *     },
206
     *     input= { "class"=ProjectDTO::class },
207
     *     output= {
208
     *         "class"=Project::class,
209
     *         "groups"={"private"},
210
     *         "parsers"={"Nelmio\ApiDocBundle\Parser\JmsMetadataParser"}
211
     *     },
212
     *     statusCodes={
213
     *         201="Returned when created",
214
     *         400="Returned when a violation is raised by validation"
215
     *     }
216
     * )
217
     */
218
    public function postProjectAction(Project $project, ConstraintViolationList $violations)
219
    {
220
        if (count($violations) > 0) {
221
            return $this->view($violations, Response::HTTP_BAD_REQUEST);
222
        }
223
        $projectService = $this->get(ProjectService::class);
224
        $projectService->setSlugAndToken($project);
225
226
        $em = $this->getDoctrine()->getManager();
227
        $em->persist($project);
228
        $em->flush();
229
230
        $projectService->sendRegistrationEmail($project);
231
232
        return $project;
233
    }
234
235
    /**
236
     * Update a project. Example: </br>
237
     * <pre style="background:black; color:white; font-size:10px;"><code style="background:black;">curl https://www.ci-report.io/api/projects/project-one -H "Content-Type: application/json" -H "X-CIR-TKN: 1f4ffb19e4b9-02278af07b7d-4e370a76f001" -X PUT --data '{"name":"Project To Update", "warning":85, "success":90, "email":"[email protected]"}'
238
     * </code></pre>.
239
     *
240
     * @param Project $projectDTO Project containing values to update
241
     * @param Project $projectDB  Project to update
242
     * @param Request $request    The request
243
     *
244
     * @return Project|View
245
     *
246
     * @Rest\Put("/projects/{refid}")
247
     * @Rest\View(serializerGroups={"private"})
248
     *
249
     * @ParamConverter("projectDB", options={"mapping": {"refid": "refid"}})
250
     * @ParamConverter("projectDTO", converter="fos_rest.request_body")
251
     *
252
     * @Doc\ApiDoc(
253
     *     section="Projects",
254
     *     description="Update a project.",
255
     *     headers={
256
     *         {
257
     *             "name"="Content-Type",
258
     *             "required"=true,
259
     *             "description"="Type of content: application/json"
260
     *         },
261
     *         {
262
     *             "name"="X-CIR-TKN",
263
     *             "required"=true,
264
     *             "description"="Private token"
265
     *         }
266
     *     },
267
     *     requirements={
268
     *         {
269
     *             "name"="refid",
270
     *             "dataType"="string",
271
     *             "requirement"="string",
272
     *             "description"="Unique short name of project defined on project creation."
273
     *         }
274
     *     },
275
     *     input= { "class"=ProjectDTO::class },
276
     *     output= {
277
     *         "class"=Project::class,
278
     *         "groups"={"private"},
279
     *         "parsers"={"Nelmio\ApiDocBundle\Parser\JmsMetadataParser"}
280
     *     },
281
     *     statusCodes={
282
     *         200="Returned when successful",
283
     *         400="Returned when a violation is raised by validation",
284
     *         401="Returned when X-CIR-TKN private token value is invalid",
285
     *         404="Returned when project not found"
286
     *     },
287
     *     tags={
288
     *         "token" = "#87ceeb"
289
     *     }
290
     * )
291
     */
292
    public function putProjectAction(ProjectDTO $projectDTO, Project $projectDB, Request $request)
293
    {
294
        if ($this->isInvalidToken($request, $projectDB->getToken())) {
295
            return $this->getInvalidTokenView();
296
        }
297
298
        $validator = $this->get('validator');
299
        $violationsDTO = $validator->validate($projectDTO);
300
301
        if (count($violationsDTO) > 0) {
302
            return $this->view($violationsDTO, Response::HTTP_BAD_REQUEST);
303
        }
304
        $projectDB->setFromDTO($projectDTO);
305
306
        // Check for unique name.
307
        $violationsDB = $validator->validate($projectDB, null, array('input', 'unique'));
308
        if (count($violationsDB) > 0) {
309
            return $this->view($violationsDB, Response::HTTP_BAD_REQUEST);
310
        }
311
        $this->getDoctrine()->getManager()->flush();
312
313
        return $projectDB;
314
    }
315
316
    /**
317
     * Delete a project. Example: </br>
318
     * <pre style="background:black; color:white; font-size:10px;"><code style="background:black;">curl https://www.ci-report.io/api/projects/project-one -H "X-CIR-TKN: 1f4ffb19e4b9-02278af07b7d-4e370a76f001" -X DELETE
319
     * </code></pre>.
320
     *
321
     * @param Project $project Project
322
     * @param Request $request The request
323
     *
324
     * @return void|View
325
     *
326
     * @Rest\Delete("/projects/{refid}")
327
     * @Rest\View(statusCode=Response::HTTP_NO_CONTENT)
328
     *
329
     * @ParamConverter("project", options={"mapping": {"refid": "refid"}})
330
     *
331
     * @Doc\ApiDoc(
332
     *     section="Projects",
333
     *     description="Delete a project.",
334
     *     headers={
335
     *         {
336
     *             "name"="X-CIR-TKN",
337
     *             "required"=true,
338
     *             "description"="Private token"
339
     *         }
340
     *     },
341
     *     requirements={
342
     *         {
343
     *             "name"="refid",
344
     *             "dataType"="string",
345
     *             "requirement"="string",
346
     *             "description"="Unique short name of project defined on project creation."
347
     *         }
348
     *     },
349
     *     statusCodes={
350
     *         204="Returned when successful",
351
     *         401="Returned when X-CIR-TKN private token value is invalid",
352
     *         404="Returned when project not found"
353
     *     },
354
     *     tags={
355
     *         "token" = "#87ceeb"
356
     *     }
357
     * )
358
     */
359
    public function deleteProjectAction(Project $project, Request $request)
360
    {
361
        if ($this->isInvalidToken($request, $project->getToken())) {
362
            return $this->getInvalidTokenView();
363
        }
364
        $em = $this->getDoctrine()->getManager();
365
        $em->remove($project);
366
        $em->flush();
367
    }
368
}
369