Completed
Push — master ( 3d485f...407dff )
by Paweł
66:49
created

ContainerService::linkUnlinkWidget()   C

Complexity

Conditions 12
Paths 13

Size

Total Lines 41
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 156

Importance

Changes 0
Metric Value
dl 0
loc 41
ccs 0
cts 5
cp 0
rs 5.1612
c 0
b 0
f 0
cc 12
eloc 25
nc 13
nop 3
crap 156

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the Superdesk Web Publisher Template Engine Bundle.
5
 *
6
 * Copyright 2015 Sourcefabric z.u. 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 2015 Sourcefabric z.ú
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace SWP\Bundle\TemplatesSystemBundle\Service;
16
17
use Doctrine\ORM\EntityManagerInterface;
18
use SWP\Bundle\TemplatesSystemBundle\Factory\ContainerDataFactoryInterface;
19
use SWP\Component\TemplatesSystem\Gimme\Model\ContainerDataInterface;
20
use SWP\Component\TemplatesSystem\Gimme\Model\ContainerInterface;
21
use SWP\Component\Common\Event\HttpCacheEvent;
22
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
23
use Symfony\Component\DependencyInjection\ContainerInterface as ServiceContainerInterface;
24
use Symfony\Component\HttpFoundation\Request;
25
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
26
27
/**
28
 * Class ContainerService.
29
 */
30
class ContainerService implements ContainerServiceInterface
31
{
32
    /**
33
     * @var ServiceContainerInterface
34
     */
35
    protected $serviceContainer;
36
37
    /**
38
     * @var EntityManagerInterface
39
     */
40
    protected $entityManager;
41
42
    /**
43
     * @var EventDispatcherInterface
44
     */
45
    protected $eventDispatcher;
46 99
47
    /**
48 99
     * ContainerService constructor.
49 99
     *
50 99
     * @param EntityManagerInterface    $entityManager
51 99
     * @param EventDispatcherInterface  $eventDispatcher
52 99
     * @param ServiceContainerInterface $serviceContainer
53 99
     */
54
    public function __construct(
55
        EntityManagerInterface $entityManager,
56
        EventDispatcherInterface $eventDispatcher,
57
        ServiceContainerInterface $serviceContainer
58
    ) {
59
        $this->entityManager = $entityManager;
60
        $this->eventDispatcher = $eventDispatcher;
61
        $this->serviceContainer = $serviceContainer;
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function createContainer($name, array $parameters = [], ContainerInterface $container = null): ContainerInterface
68
    {
69
        if (null === $container) {
70
            /** @var ContainerInterface $containerEntity */
71
            $container = $this->serviceContainer->get('swp.factory.container')->create();
72
        }
73
74
        $containerDataFactory = $this->serviceContainer->get('swp.factory.container_data');
75
        $container->setName($name);
76
        foreach ($parameters as $key => $value) {
77
            switch ($key) {
78
                case 'cssClass':
79
                    $container->setCssClass($value);
80
                    break;
81
                case 'styles':
82
                    $container->setStyles($value);
83
                    break;
84
                case 'visible':
85
                    $container->setVisible($value);
86
                    break;
87
                case 'data':
88 View Code Duplication
                    foreach ($value as $dataKey => $dataValue) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
89
                        /** @var ContainerDataInterface $containerData */
90
                        $containerData = $containerDataFactory->create($dataKey, $dataValue);
91
                        $containerData->setContainer($container);
92
                        $this->entityManager->persist($containerData);
93
                        $container->addData($containerData);
94
                    }
95
            }
96
        }
97
        $this->entityManager->persist($container);
98
        $this->entityManager->flush();
99
100
        $this->eventDispatcher
101
            ->dispatch(HttpCacheEvent::EVENT_NAME, new HttpCacheEvent($container));
102
103
        return $container;
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    public function updateContainer(ContainerInterface $container, array $extraData): ContainerInterface
110
    {
111
        /** @var ContainerDataFactoryInterface $containerDataFactory */
112
        $containerDataFactory = $this->serviceContainer->get('swp.factory.container_data');
113
        if (!empty($extraData) && is_array($extraData)) {
114
            // Remove old containerData's
115
            foreach ($container->getData() as $containerData) {
116
                $this->entityManager->remove($containerData);
117
            }
118
119
            // Apply new containerData's
120 View Code Duplication
            foreach ($extraData as $key => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
121
                /** @var ContainerDataInterface $containerData */
122
                $containerData = $containerDataFactory->create($key, $value);
123
                $containerData->setContainer($container);
124
                $this->entityManager->persist($containerData);
125
                $container->addData($containerData);
126
            }
127
        }
128
129
        $this->entityManager->flush();
130
        $this->entityManager->refresh($container);
131
132
        return $container;
133
    }
134
135
    /**
136
     * @param mixed              $object
137
     * @param ContainerInterface $container
138
     * @param Request            $request
139
     *
140
     * @throws \Exception
141
     */
142
    public function linkUnlinkWidget($object, ContainerInterface $container, Request $request)
143
    {
144
        $containerWidget = $this->serviceContainer->get('swp.repository.container_widget')
145
            ->findOneBy([
146
                'widget' => $object,
147
                'container' => $container,
148
            ]);
149
150
        if ($request->getMethod() === 'LINK') {
151
            $position = false;
152
            if (count($notConvertedLinks = self::getNotConvertedLinks($request)) > 0) {
153
                foreach ($notConvertedLinks as $link) {
154
                    if (isset($link['resourceType']) && $link['resourceType'] == 'widget-position') {
155
                        $position = $link['resource'];
156
                    }
157
                }
158
            }
159
160
            if ($position === false && $containerWidget) {
161
                throw new ConflictHttpException('WidgetModel is already linked to container');
162
            }
163
164
            if (!$containerWidget) {
165
                $containerWidget = $this->serviceContainer->get('swp.factory.container_widget')->create($container, $object);
166
                $this->entityManager->persist($containerWidget);
167
            }
168
169
            if ($position !== false) {
170
                $containerWidget->setPosition($position);
171
            }
172
            $container->addWidget($containerWidget);
173
            $this->entityManager->flush();
174
        } elseif ($request->getMethod() === 'UNLINK') {
175
            if (!$container->getWidgets()->contains($containerWidget)) {
176
                throw new ConflictHttpException('WidgetModel is not linked to container');
177
            }
178
            $this->entityManager->remove($containerWidget);
179
        }
180
181
        return $container;
182
    }
183
184
    /**
185
     * @param Request $request
186
     *
187
     * @return array
188
     */
189
    public static function getNotConvertedLinks($request)
190
    {
191
        $links = [];
192
        foreach ($request->attributes->get('links') as $idx => $link) {
193
            if (is_string($link)) {
194
                $linkParams = explode(';', trim($link));
195
                $resourceType = null;
196 View Code Duplication
                if (count($linkParams) > 1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
197
                    $resourceType = trim(preg_replace('/<|>/', '', $linkParams[1]));
198
                    $resourceType = str_replace('"', '', str_replace('rel=', '', $resourceType));
199
                }
200
                $resource = array_shift($linkParams);
201
                $resource = preg_replace('/<|>/', '', $resource);
202
203
                $links[] = [
204
                    'resource' => $resource,
205
                    'resourceType' => $resourceType,
206
                ];
207
            }
208
        }
209
210
        return $links;
211
    }
212
}
213