Completed
Push — master ( 1c7520...3a85c6 )
by Rafał
09:11
created

TenantController::deleteAction()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 11
cts 11
cp 1
rs 9.488
c 0
b 0
f 0
cc 3
nc 3
nop 2
crap 3
1
<?php
2
3
/*
4
 * This file is part of the Superdesk Web Publisher Core Bundle.
5
 *
6
 * Copyright 2016 Sourcefabric z.ú. and contributors.
7
 *
8
 * For the full copyright and license information, please see the
9
 * AUTHORS and LICENSE files distributed with this source code.
10
 *
11
 * @copyright 2016 Sourcefabric z.ú
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace SWP\Bundle\CoreBundle\Controller;
16
17
use function array_key_exists;
18
use DateTime;
19
use FOS\RestBundle\Controller\FOSRestController;
20
use Nelmio\ApiDocBundle\Annotation\Operation;
21
use Nelmio\ApiDocBundle\Annotation\Model;
22
use Swagger\Annotations as SWG;
23
use SWP\Bundle\CoreBundle\Context\ScopeContextInterface;
24
use Symfony\Component\Routing\Annotation\Route;
25
use SWP\Bundle\MultiTenancyBundle\MultiTenancyEvents;
26
use SWP\Component\Common\Response\ResourcesListResponse;
27
use SWP\Component\Common\Response\ResponseContext;
28
use SWP\Component\Common\Response\SingleResourceResponse;
29
use SWP\Component\Common\Criteria\Criteria;
30
use SWP\Component\Common\Pagination\PaginationData;
31
use SWP\Bundle\CoreBundle\Form\Type\TenantType;
32
use SWP\Component\MultiTenancy\Model\TenantInterface;
33
use Symfony\Component\HttpFoundation\Request;
34
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
35
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
36
37
class TenantController extends FOSRestController
0 ignored issues
show
Deprecated Code introduced by
The class FOS\RestBundle\Controller\FOSRestController has been deprecated with message: since FOSRestBundle 2.5, use {@see AbstractFOSRestController} instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
38
{
39
    /**
40
     * List all tenants/websites.
41
     *
42
     * @Operation(
43
     *     tags={"tenant"},
44
     *     summary="List all tenants/websites",
45
     *     @SWG\Parameter(
46
     *         name="sorting",
47
     *         in="query",
48
     *         description="todo",
49
     *         required=false,
50
     *         type="string"
51
     *     ),
52
     *     @SWG\Response(
53
     *         response="200",
54
     *         description="Returned on success."
55
     *     )
56
     * )
57
     *
58
     * @Route("/api/{version}/tenants/", options={"expose"=true}, defaults={"version"="v2"}, methods={"GET"}, name="swp_api_core_list_tenants")
59
     */
60
    public function listAction(Request $request)
61
    {
62
        $tenants = $this->getTenantRepository()
63
            ->getPaginatedByCriteria(new Criteria(), $request->query->get('sorting', []), new PaginationData($request));
64
        $responseContext = new ResponseContext();
65
        $responseContext->setSerializationGroups(['Default', 'api', 'details_api']);
66
67
        return new ResourcesListResponse($tenants, $responseContext);
68
    }
69
70
    /**
71
     * Shows a single tenant/website.
72
     *
73
     * @Operation(
74
     *     tags={"tenant"},
75
     *     summary="Show single tenant/website",
76
     *     @SWG\Response(
77
     *         response="200",
78
     *         description="Returned on success.",
79
     *         @Model(type=SWP\Bundle\CoreBundle\Model\Tenant::class, groups={"api"})
80
     *     )
81
     * )
82
     *
83
     * @Route("/api/{version}/tenants/{code}", options={"expose"=true}, defaults={"version"="v2"}, methods={"GET"}, name="swp_api_core_get_tenant", requirements={"code"="[a-z0-9]+"})
84
     */
85
    public function getAction($code)
86
    {
87
        return new SingleResourceResponse($this->findOr404($code));
88
    }
89
90
    /**
91 1
     * Deletes a single tenant.
92
     *
93 1
     * @Operation(
94 1
     *     tags={"tenant"},
95
     *     summary="Delete single tenant/website",
96 1
     *     @SWG\Parameter(
97
     *         name="force",
98 1
     *         in="body",
99
     *         description="Remove tenant ignoring attached articles",
100
     *         required=false,
101
     *         @SWG\Schema(type="bool")
102
     *     ),
103
     *     @SWG\Response(
104
     *         response="204",
105
     *         description="Returned on success."
106
     *     )
107
     * )
108
     *
109
     * @Route("/api/{version}/tenants/{code}", options={"expose"=true}, defaults={"version"="v2"}, methods={"DELETE"}, name="swp_api_core_delete_tenant", requirements={"code"="[a-z0-9]+"})
110
     */
111
    public function deleteAction(Request $request, $code)
112
    {
113
        $tenantContext = $this->container->get('swp_multi_tenancy.tenant_context');
114
        $eventDispatcher = $this->container->get('event_dispatcher');
115
        $currentTenant = $tenantContext->getTenant();
116
117 6
        $repository = $this->getTenantRepository();
118
        $tenant = $this->findOr404($code);
119 6
120 6
        $forceRemove = $request->query->has('force');
121
        if (!$forceRemove) {
122 6
            $tenantContext->setTenant($tenant);
123
            $eventDispatcher->dispatch(MultiTenancyEvents::TENANTABLE_ENABLE);
124 6
            $articlesRepository = $this->get('swp.repository.article');
125
            $existingArticles = $articlesRepository->findAll();
126 5
            if (0 !== \count($existingArticles)) {
127
                throw new ConflictHttpException('This tenant have articles attached to it.');
128 5
            }
129
        }
130 5
131
        $repository->remove($tenant);
132 5
133
        $tenantContext->setTenant($currentTenant);
134 5
        $eventDispatcher->dispatch(MultiTenancyEvents::TENANTABLE_ENABLE);
135
136
        return new SingleResourceResponse(null, new ResponseContext(204));
137 1
    }
138
139
    /**
140
     * Creates a new tenant/website.
141
     *
142
     * @Operation(
143
     *     tags={"tenant"},
144
     *     summary="Create new tenant/website",
145
     *     @SWG\Parameter(
146
     *         name="body",
147
     *         in="body",
148
     *         @SWG\Schema(
149
     *             ref=@Model(type=TenantType::class)
150
     *         )
151
     *     ),
152
     *     @SWG\Response(
153
     *         response="201",
154
     *         description="Returned on success.",
155
     *         @Model(type=SWP\Bundle\CoreBundle\Model\Tenant::class, groups={"api"})
156
     *     ),
157 2
     *     @SWG\Response(
158
     *         response="400",
159 2
     *         description="Returned on failure."
160
     *     ),
161 2
     *     @SWG\Response(
162
     *         response="409",
163 2
     *         description="Returned on conflict."
164
     *     )
165 2
     * )
166
     *
167 2
     * @Route("/api/{version}/tenants/", options={"expose"=true}, defaults={"version"="v2"}, methods={"POST"}, name="swp_api_core_create_tenant")
168
     */
169 2
    public function createAction(Request $request)
170 2
    {
171
        $tenant = $this->get('swp.factory.tenant')->create();
172 2
        $tenantContext = $this->get('swp_multi_tenancy.tenant_context');
173
        $tenantObjectManager = $this->get('swp.object_manager.tenant');
174
        $form = $this->get('form.factory')->createNamed('', TenantType::class, $tenant, ['method' => $request->getMethod()]);
175
        $form->handleRequest($request);
176
177
        if ($form->isSubmitted() && $form->isValid()) {
178 3
            $this->ensureTenantDontExists($tenant->getDomainName(), $tenant->getSubdomain());
179
            if (null === $tenant->getOrganization()) {
180 3
                $organization = $tenantObjectManager->merge($tenantContext->getTenant()->getOrganization());
181
                $tenant->setOrganization($organization);
182
            }
183
            $this->getTenantRepository()->add($tenant);
184 3
185
            return new SingleResourceResponse($tenant, new ResponseContext(201));
186
        }
187 5
188
        return new SingleResourceResponse($form, new ResponseContext(400));
189 5
    }
190 1
191
    /**
192
     * Updates a single tenant.
193 5
     *
194
     * @Operation(
195
     *     tags={"tenant"},
196 5
     *     summary="Update single tenant",
197
     *     @SWG\Parameter(
198 5
     *         name="body",
199 4
     *         in="body",
200 4
     *         description="",
201
     *         required=true,
202 4
     *         @SWG\Schema(ref=@Model(type=TenantType::class))
203
     *     ),
204
     *     @SWG\Response(
205
     *         response="200",
206 4
     *         description="Returned on success.",
207
     *         @Model(type=SWP\Bundle\CoreBundle\Model\Tenant::class, groups={"api"})
208
     *     ),
209 5
     *     @SWG\Response(
210
     *         response="400",
211
     *         description="Returned on failure."
212 6
     *     ),
213
     *     @SWG\Response(
214 6
     *         response="404",
215
     *         description="Returned when not found."
216
     *     ),
217
     *     @SWG\Response(
218
     *         response="409",
219
     *         description="Returned on conflict."
220
     *     )
221
     * )
222
     *
223
     * @Route("/api/{version}/tenants/{code}", options={"expose"=true}, defaults={"version"="v2"}, methods={"PATCH"}, name="swp_api_core_update_tenant", requirements={"code"="[a-z0-9]+"})
224
     */
225
    public function updateAction(Request $request, $code)
226
    {
227
        $tenant = $this->findOr404($code);
228
        $form = $this->get('form.factory')->createNamed('', TenantType::class, $tenant, ['method' => $request->getMethod()]);
229
        $form->handleRequest($request);
230
231
        if ($form->isSubmitted() && $form->isValid()) {
232
            $formData = $request->request->all();
233
            $tenant->setUpdatedAt(new DateTime('now'));
234
            $this->get('swp.object_manager.tenant')->flush();
235
236
            $tenantContext = $this->get('swp_multi_tenancy.tenant_context');
237
            $tenantContext->setTenant($tenant);
238
239
            $settingsManager = $this->get('swp_settings.manager.settings');
240
241
            if (array_key_exists('fbiaEnabled', $formData)) {
242
                $settingsManager->set('fbia_enabled', (bool) $formData['fbiaEnabled'], ScopeContextInterface::SCOPE_TENANT, $tenant);
243
            }
244
            if (array_key_exists('paywallEnabled', $formData)) {
245
                $settingsManager->set('paywall_enabled', (bool) $formData['paywallEnabled'], ScopeContextInterface::SCOPE_TENANT, $tenant);
246
            }
247
            if (array_key_exists('defaultLanguage', $formData)) {
248
                $settingsManager->set('default_language', $formData['defaultLanguage'], ScopeContextInterface::SCOPE_TENANT, $tenant);
249
            }
250
251
            return new SingleResourceResponse($tenant);
252
        }
253
254
        return new SingleResourceResponse($form, new ResponseContext(400));
255
    }
256
257
    /**
258
     * @param string $code
259
     *
260
     * @throws NotFoundHttpException
261
     *
262
     * @return mixed|TenantInterface|null
263
     */
264
    private function findOr404($code)
265
    {
266
        if (null === $tenant = $this->getTenantRepository()->findOneByCode($code)) {
267
            throw $this->createNotFoundException(sprintf('Tenant with code "%s" was not found.', $code));
268
        }
269
270
        return $tenant;
271
    }
272
273
    /**
274
     * @param string      $domain
275
     * @param string|null $subdomain
276
     *
277
     * @return mixed|TenantInterface|null
278
     */
279
    private function ensureTenantDontExists(string $domain, string $subdomain = null)
280
    {
281
        if (null !== $tenant = $this->getTenantRepository()->findOneBySubdomainAndDomain($subdomain, $domain)) {
282
            throw new ConflictHttpException('Tenant for this host already exists.');
283
        }
284
285
        return $tenant;
286
    }
287
288
    /**
289
     * @return object|\SWP\Bundle\MultiTenancyBundle\Doctrine\ORM\TenantRepository
290
     */
291
    private function getTenantRepository()
292
    {
293
        return $this->get('swp.repository.tenant');
294
    }
295
}
296