Issues (8)

src/Controller/DocumentApiController.php (2 issues)

Severity
1
<?php
2
3
/**
4
 * Copyright (c) 2018 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 App\Controller;
24
25
use App\DTO\ZipFileDTO;
26
use App\Entity\Campaign;
27
use App\Entity\Project;
28
use App\Entity\Suite;
29
use App\Entity\ZipFile;
30
use App\Service\DocumentStorageService;
31
use FOS\RestBundle\Controller\Annotations as Rest;
32
use FOS\RestBundle\View\View;
33
use Nelmio\ApiDocBundle\Annotation\Operation;
34
use Nelmio\ApiDocBundle\Annotation\Model;
35
use Swagger\Annotations as SWG;
36
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
37
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
38
use Symfony\Component\HttpFoundation\Request;
39
use Symfony\Component\HttpFoundation\Response;
40
41
/**
42
 * Document API controller class.
43
 *
44
 * @category  ci-report app
45
 *
46
 * @author    Francois-Xavier Soubirou <[email protected]>
47
 * @copyright 2018 Francois-Xavier Soubirou
48
 * @license   http://www.gnu.org/licenses/   GPLv3
49
 *
50
 * @see      https://www.ci-report.io
51
 *
52
 * @Rest\Route("/api")
53
 */
54
class DocumentApiController extends AbstractApiController
55
{
56
    /**
57
     * Attach a zip archive to a suite. Example: </br>
58
     * <pre style="background:black; color:white; font-size:10px;"><code style="background:black;">
59
     * </code></pre>.
60
     *
61
     *
62
     * @param Project  $project  Project
63
     * @param Campaign $campaign Campaign
64
     * @param Suite    $suite    Suite
65
     * @param Request  $request  The request
66
     *
67
     * @return array|View
68
     *
69
     * @Rest\Post("/projects/{prefid}/campaigns/{crefid}/suites/{srefid}/doc/zip",
70
     *    requirements={"crefid" = "\d+", "srefid" = "\d+"}
71
     * )
72
     * @Rest\View(statusCode=Response::HTTP_CREATED, serializerGroups={"public"})
73
     *
74
     * @ParamConverter("project", options={"mapping": {"prefid": "refid"}})
75
     * @Entity("campaign", expr="repository.findCampaignByProjectRefidAndRefid(prefid, crefid)")
76
     * @Entity("suite", expr="repository.findSuiteByProjectRefidCampaignRefidAndRefid(prefid, crefid, srefid)")
77
     *
78
     * @Operation(
79
     *     tags={"Documents"},
80
     *     summary="Attach a zip archive to a suite.",
81
     *     description="Example: </br><pre><code>curl https://www.ci-report.io/api/projects/project-one/campaigns/1/suites/1/doc/zip -H &quot;X-CIR-TKN: 1f4ffb19e4b9-02278af07b7d-4e370a76f001&quot; -X POST -F 'zipfile=@/path/to/myfile.zip'</code></pre><p>(@ symbol is mandatory at the beginning of the file path)</p>",
82
     *     @SWG\Parameter(
83
     *         name="prefid",
84
     *         in="path",
85
     *         description="Unique short name of project defined on project creation.",
86
     *         type="string"
87
     *     ),
88
     *     @SWG\Parameter(
89
     *         name="crefid",
90
     *         in="path",
91
     *         description="Reference id of the campaign.",
92
     *         type="integer"
93
     *     ),
94
     *     @SWG\Parameter(
95
     *         name="srefid",
96
     *         in="path",
97
     *         description="Reference id of the suite.",
98
     *         type="integer"
99
     *     ),
100
     *     @SWG\Parameter(
101
     *         name="zipfile",
102
     *         in="formData",
103
     *         description="Zip file.",
104
     *         required=true,
105
     *         type="file"
106
     *     ),
107
     *     @SWG\Response(
108
     *         response="201",
109
     *         description="Returned when created",
110
     *         @Model(type=ZipFile::class, groups={"public"})
111
     *     ),
112
     *     @SWG\Response(
113
     *         response="400",
114
     *         description="Returned when a violation is raised by validation",
115
     *         @SWG\Schema(
116
     *            type="array",
117
     *            @SWG\Items(ref="#/definitions/ErrorModel")
118
     *         )
119
     *     ),
120
     *     @SWG\Response(
121
     *         response="401",
122
     *         description="Returned when X-CIR-TKN private token value is invalid",
123
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
124
     *     ),
125
     *     @SWG\Response(
126
     *         response="404",
127
     *         description="Returned when project, campaign or suite not found",
128
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
129
     *     )
130
     * )
131
     */
132
    public function postZipDocumentAction(Project $project, Campaign $campaign, Suite $suite, Request $request)
133
    {
134
        if ($this->isInvalidToken($request, $project->getToken())) {
135
            return $this->getInvalidTokenView();
136
        }
137
        if (null !== $suite->getDocumentUid()) {
0 ignored issues
show
The condition null !== $suite->getDocumentUid() is always true.
Loading history...
138
            return $this->view(
139
                array(
140
                    'code' => Response::HTTP_BAD_REQUEST,
141
                    'message' => 'A zip file already exists',
142
                ),
143
                Response::HTTP_BAD_REQUEST
144
            );
145
        }
146
        $validator = $this->get('validator');
147
        $zipFileDTO = new ZipFileDTO($request);
148
        $violations = $validator->validate($zipFileDTO);
149
        if (count($violations) > 0) {
150
            return $this->view($violations, Response::HTTP_BAD_REQUEST);
151
        }
152
        $docStoreService = $this->get(DocumentStorageService::class);
153
        $zipFile = $docStoreService->storeZip(
154
            $project,
155
            $campaign,
156
            $zipFileDTO->getZipfile()
157
        );
158
        $suite->setDocumentUid($zipFile->getFileName());
159
        $this->getDoctrine()->getManager()->flush();
160
161
        return $zipFile;
162
    }
163
164
    /**
165
     * Delete a zip archive from a suite.
166
     *
167
     * @param Project  $project  Project
168
     * @param Campaign $campaign Campaign
169
     * @param Suite    $suite    Suite to delete
170
     * @param Request  $request  The request
171
     *
172
     * @return void|View
173
     *
174
     * @Rest\Delete(
175
     *    "/projects/{prefid}/campaigns/{crefid}/suites/{srefid}/doc/zip",
176
     *    requirements={"crefid" = "\d+", "srefid" = "\d+"}
177
     * )
178
     * @Rest\View(statusCode=Response::HTTP_NO_CONTENT)
179
     *
180
     * @ParamConverter("project", options={"mapping": {"prefid": "refid"}})
181
     * @Entity("campaign", expr="repository.findCampaignByProjectRefidAndRefid(prefid, crefid)")
182
     * @Entity("suite", expr="repository.findSuiteByProjectRefidCampaignRefidAndRefid(prefid, crefid, srefid)")
183
     *
184
     * @Operation(
185
     *     tags={"Documents"},
186
     *     summary="Delete a zip archive from a suite.",
187
     *     description="Example: </br><pre><code>curl https://www.ci-report.io/api/projects/project-one/campaigns/1/suites/1/doc/zip -H &quot;X-CIR-TKN: 1f4ffb19e4b9-02278af07b7d-4e370a76f001&quot; -X DELETE</code></pre>",
188
     *     @SWG\Parameter(
189
     *         name="prefid",
190
     *         in="path",
191
     *         description="Unique short name of project defined on project creation.",
192
     *         type="string"
193
     *     ),
194
     *     @SWG\Parameter(
195
     *         name="crefid",
196
     *         in="path",
197
     *         description="Reference id of the campaign.",
198
     *         type="integer"
199
     *     ),
200
     *     @SWG\Parameter(
201
     *         name="srefid",
202
     *         in="path",
203
     *         description="Reference id of the suite.",
204
     *         type="integer"
205
     *     ),
206
     *     @SWG\Response(
207
     *         response="204",
208
     *         description="Returned when successful"
209
     *     ),
210
     *     @SWG\Response(
211
     *         response="401",
212
     *         description="Returned when X-CIR-TKN private token value is invalid",
213
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
214
     *     ),
215
     *     @SWG\Response(
216
     *         response="404",
217
     *         description="Returned when suite not found",
218
     *         @SWG\Schema(ref="#/definitions/ErrorModel")
219
     *     )
220
     * )
221
     */
222
    public function deleteZipDocumentAction(Project $project, Campaign $campaign, Suite $suite, Request $request)
223
    {
224
        if ($this->isInvalidToken($request, $project->getToken())) {
225
            return $this->getInvalidTokenView();
226
        }
227
        $documentUid = $suite->getDocumentUid();
228
229
        if (null !== $documentUid) {
0 ignored issues
show
The condition null !== $documentUid is always true.
Loading history...
230
            $suite->setDocumentUid(null);
231
            $this->getDoctrine()->getManager()->flush();
232
233
            $docStoreService = $this->get(DocumentStorageService::class);
234
            $docStoreService->remove(
235
                $project,
236
                $campaign,
237
                $documentUid
238
            );
239
        }
240
    }
241
}
242