Passed
Push — master ( a9f631...a3bf41 )
by FX
02:25
created

ProjectApiController::getProjectPrivateAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 2
dl 0
loc 7
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.
53
     *
54
     * @return array
55
     *
56
     * @Rest\Get("/projects")
57
     * @Rest\View(serializerGroups={"public"})
58
     *
59
     * @Doc\ApiDoc(
60
     *     section="Projects",
61
     *     description="Get the list of all projects.",
62
     *     output={
63
     *         "class"=Project::class,
64
     *         "groups"={"public"},
65
     *         "parsers"={"Nelmio\ApiDocBundle\Parser\JmsMetadataParser"}
66
     *     },
67
     *     statusCodes={
68
     *         200="Returned when successful array of public data of projects"
69
     *     }
70
     * )
71
     */
72
    public function getProjectsAction(): array
73
    {
74
        $projects = $this->getDoctrine()
75
            ->getRepository(Project::class)
76
            ->findAll();
77
78
        return $projects;
79
    }
80
81
    /**
82
     * Get public project data.
83
     *
84
     * @param Project $project Project
85
     *
86
     * @return Project
87
     *
88
     * @Rest\Get("/projects/{refid}")
89
     * @Rest\View(serializerGroups={"public"})
90
     *
91
     * @ParamConverter("project", options={"mapping": {"refid": "refid"}})
92
     *
93
     * @Doc\ApiDoc(
94
     *     section="Projects",
95
     *     description="Get public project data.",
96
     *     requirements={
97
     *         {
98
     *             "name"="refid",
99
     *             "dataType"="string",
100
     *             "requirement"="string",
101
     *             "description"="Unique short name of project defined on project creation."
102
     *         }
103
     *     },
104
     *     output= {
105
     *         "class"=Project::class,
106
     *         "groups"={"public"},
107
     *         "parsers"={"Nelmio\ApiDocBundle\Parser\JmsMetadataParser"}
108
     *     },
109
     *     statusCodes={
110
     *         200="Returned when successful",
111
     *         404="Returned when project not found"
112
     *     }
113
     * )
114
     */
115
    public function getProjectAction(Project $project): Project
116
    {
117
        return $project;
118
    }
119
120
    /**
121
     * Get private project data.
122
     *
123
     * @param Project $project Project
124
     * @param Request $request The request
125
     *
126
     * @return Project|View
127
     *
128
     * @Rest\Get("/projects/{refid}/private")
129
     * @Rest\View(serializerGroups={"private"})
130
     *
131
     * @ParamConverter("project", options={"mapping": {"refid": "refid"}})
132
     *
133
     * @Doc\ApiDoc(
134
     *     section="Projects",
135
     *     description="Get private project data.",
136
     *     headers={
137
     *         {
138
     *             "name"="X-CIR-TKN",
139
     *             "required"=true,
140
     *             "description"="Private token"
141
     *         }
142
     *     },
143
     *     requirements={
144
     *         {
145
     *             "name"="refid",
146
     *             "dataType"="string",
147
     *             "requirement"="string",
148
     *             "description"="Unique short name of project defined on project creation."
149
     *         }
150
     *     },
151
     *     output= {
152
     *         "class"=Project::class,
153
     *         "groups"={"private"},
154
     *         "parsers"={"Nelmio\ApiDocBundle\Parser\JmsMetadataParser"}
155
     *     },
156
     *     statusCodes={
157
     *         200="Returned when successful",
158
     *         401="Returned when X-CIR-TKN private token value is invalid",
159
     *         404="Returned when project not found"
160
     *     },
161
     *     tags={
162
     *         "token" = "#87ceeb"
163
     *     }
164
     * )
165
     */
166
    public function getProjectPrivateAction(Project $project, Request $request)
167
    {
168
        if ($this->isInValidToken($request, $project->getToken())) {
169
            return $this->getInvalidTokenView();
170
        }
171
172
        return $project;
173
    }
174
175
    /**
176
     * Create a project. Private token is sent by email.
177
     *
178
     * @param Project                 $project    Project to create
179
     * @param ConstraintViolationList $violations List of violations
180
     *
181
     * @return Project|View
182
     *
183
     * @Rest\Post("/projects")
184
     * @Rest\View(statusCode=Response::HTTP_CREATED, serializerGroups={"private"})
185
     *
186
     * @ParamConverter("project", converter="fos_rest.request_body", options={ "validator"={"groups"={"input", "unique"}} } )
187
     *
188
     * @Doc\ApiDoc(
189
     *     section="Projects",
190
     *     description="Create a project. Private data are sent by mail.",
191
     *     input= { "class"=ProjectDTO::class },
192
     *     output= {
193
     *         "class"=Project::class,
194
     *         "groups"={"private"},
195
     *         "parsers"={"Nelmio\ApiDocBundle\Parser\JmsMetadataParser"}
196
     *     },
197
     *     statusCodes={
198
     *         201="Returned when created",
199
     *         400="Returned when a violation is raised by validation"
200
     *     }
201
     * )
202
     */
203
    public function postProjectsAction(Project $project, ConstraintViolationList $violations)
204
    {
205
        if (count($violations) > 0) {
206
            return $this->view($violations, Response::HTTP_BAD_REQUEST);
207
        }
208
        $projectService = $this->get(ProjectService::class);
209
        $projectService->setSlugAndToken($project);
210
211
        $em = $this->getDoctrine()->getManager();
212
        $em->persist($project);
213
        $em->flush();
214
215
        $projectService->sendRegistrationEmail($project);
216
217
        return $project;
218
    }
219
220
    /**
221
     * Update a project.
222
     *
223
     * @param Project $projectDTO Project containing values to update
224
     * @param Project $projectDB  Project to update
225
     * @param Request $request    The request
226
     *
227
     * @return Project|View
228
     *
229
     * @Rest\Put("/projects/{refid}")
230
     * @Rest\View(serializerGroups={"private"})
231
     *
232
     * @ParamConverter("projectDB", options={"mapping": {"refid": "refid"}})
233
     * @ParamConverter("projectDTO", converter="fos_rest.request_body")
234
     *
235
     * @Doc\ApiDoc(
236
     *     section="Projects",
237
     *     description="Update a project.",
238
     *     headers={
239
     *         {
240
     *             "name"="X-CIR-TKN",
241
     *             "required"=true,
242
     *             "description"="Private token"
243
     *         }
244
     *     },
245
     *     requirements={
246
     *         {
247
     *             "name"="ref_id",
248
     *             "dataType"="string",
249
     *             "requirement"="string",
250
     *             "description"="Unique short name of project defined on project creation."
251
     *         }
252
     *     },
253
     *     input= { "class"=ProjectDTO::class },
254
     *     output= {
255
     *         "class"=Project::class,
256
     *         "groups"={"private"},
257
     *         "parsers"={"Nelmio\ApiDocBundle\Parser\JmsMetadataParser"}
258
     *     },
259
     *     statusCodes={
260
     *         200="Returned when successful",
261
     *         400="Returned when a violation is raised by validation",
262
     *         401="Returned when X-CIR-TKN private token value is invalid",
263
     *         404="Returned when project not found"
264
     *     },
265
     *     tags={
266
     *         "token" = "#87ceeb"
267
     *     }
268
     * )
269
     */
270
    public function putProjectsAction(ProjectDTO $projectDTO, Project $projectDB, Request $request)
271
    {
272
        if ($this->isInValidToken($request, $projectDB->getToken())) {
273
            return $this->getInvalidTokenView();
274
        }
275
276
        $validator = $this->get('validator');
277
        $violationsDTO = $validator->validate($projectDTO);
278
279
        if (count($violationsDTO) > 0) {
280
            return $this->view($violationsDTO, Response::HTTP_BAD_REQUEST);
281
        }
282
        $projectDB->setFromDTO($projectDTO);
283
284
        // Check for unique name.
285
        $violationsDB = $validator->validate($projectDB, null, array('input', 'unique'));
286
        if (count($violationsDB) > 0) {
287
            return $this->view($violationsDB, Response::HTTP_BAD_REQUEST);
288
        }
289
        $this->getDoctrine()->getManager()->flush();
290
291
        return $projectDB;
292
    }
293
}
294