ResourceController   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 160
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 6
Bugs 1 Features 3
Metric Value
wmc 21
c 6
b 1
f 3
lcom 1
cbo 14
dl 0
loc 160
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A stringToBoolean() 0 10 3
A activeStateAction() 0 20 4
B enableStateAction() 0 25 4
B batchDeleteAction() 0 40 6
B updateStateAction() 0 35 4
1
<?php
2
3
namespace DoS\ResourceBundle\Controller;
4
5
use FOS\RestBundle\View\View;
6
use Sylius\Bundle\ResourceBundle\Controller\ResourceController as BaseResourceController;
7
use Sylius\Component\Resource\ResourceActions;
8
use Symfony\Component\HttpFoundation\RedirectResponse;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
12
use Symfony\Component\PropertyAccess\PropertyAccess;
13
14
class ResourceController extends BaseResourceController
15
{
16
    protected $activedPath = 'actived';
17
    protected $enabledPath = 'enabled';
18
    protected $stateMachineGraph = 'default';
19
20
    /**
21
     * @param $string
22
     *
23
     * @return bool
24
     */
25
    protected function stringToBoolean($string)
26
    {
27
        $string = is_string($string) ? strtolower($string) : $string;
28
29
        if (in_array($string, array(true, 1, '1', 'yes', 'true'), true)) {
30
            return true;
31
        }
32
33
        return false;
34
    }
35
36
    /**
37
     * @param Request $request
38
     * @param $state
39
     * @param null $path
40
     *
41
     * @return RedirectResponse|Response
42
     */
43
    public function activeStateAction(Request $request, $state, $path = null)
44
    {
45
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
46
        $path = $path ?: $this->activedPath;
47
        $resource = $this->findOr404($configuration);
48
        $accessor = PropertyAccess::createPropertyAccessor();
49
        $accessor->setValue($resource, $path, $this->stringToBoolean($state));
50
51
        if ($state) {
52
            // reset other to false
53
            $this->repository->bulkUpdate(array($path => false));
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Sylius\Component\Resourc...ory\RepositoryInterface as the method bulkUpdate() does only exist in the following implementations of said interface: DoS\ResourceBundle\Doctrine\ORM\EntityRepository.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
54
            $this->manager->flush();
55
        }
56
57
        if (!$configuration->isHtmlRequest()) {
58
            return $this->viewHandler->handle($configuration, View::create($resource, 204));
59
        }
60
61
        return $this->redirectHandler->redirectToReferer($configuration);
62
    }
63
64
    /**
65
     * @param Request $request
66
     * @param $state
67
     * @param null $path
68
     *
69
     * @return RedirectResponse|Response
70
     */
71
    public function enableStateAction(Request $request, $state, $path = null)
72
    {
73
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
74
75
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
76
        $resource = $this->findOr404($configuration);
77
78
        $path = $path ?: $this->enabledPath;
79
        $accessor = PropertyAccess::createPropertyAccessor();
80
        $accessor->setValue($resource, $path, $this->stringToBoolean($state));
81
82
        $resource = $this->findOr404($configuration);
83
84
        $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
85
        $this->manager->flush();
86
        $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
87
88
        if (!$configuration->isHtmlRequest()) {
89
            return $this->viewHandler->handle($configuration, View::create($resource, 204));
90
        }
91
92
        $this->flashHelper->addSuccessFlash($configuration, $state ? $path . '_enabled' : $path . '_disabled', $resource);
93
94
        return $this->redirectHandler->redirectToIndex($configuration, $resource);
95
    }
96
97
    public function batchDeleteAction(Request $request, array $ids = null)
98
    {
99
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
100
101
        $this->isGrantedOr403($configuration, ResourceActions::DELETE);
102
103
        if (null == $ids) {
104
            $ids = $request->get('ids');
105
        }
106
107
        if (is_string($ids)) {
108
            $ids = explode( ',', $ids);
109
        }
110
111
        $resources = $this->repository->findBy(array(
112
            'id' => $ids
113
        ));
114
115
        if (empty($resources)) {
116
            throw new NotFoundHttpException(
117
                sprintf(
118
                    'Requested %s does not exist with these ids: %s.',
119
                    $this->metadata->getPluralName(),
120
                    json_encode($configuration->getCriteria($ids))
121
                )
122
            );
123
        }
124
125
        foreach ($resources as $resource) {
126
            $this->manager->remove($resource);
127
        }
128
129
        $this->manager->flush();
130
131
        if (!$configuration->isHtmlRequest()) {
132
            return $this->viewHandler->handle($configuration, View::create(null, 204));
133
        }
134
135
        return $this->redirectHandler->redirectToIndex($configuration);
136
    }
137
138
    public function updateStateAction(Request $request, $transition, $graph = null)
139
    {
140
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
141
142
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
143
        $resource = $this->findOr404($configuration);
144
145
        if (null === $graph) {
146
            $graph = $this->stateMachineGraph;
147
        }
148
149
        $stateMachine = $this->get('sm.factory')->get($resource, $graph);
150
151
        if (!$stateMachine->can($transition)) {
152
            throw new NotFoundHttpException(sprintf(
153
                'The requested transition %s cannot be applied on the given %s with graph %s.',
154
                $transition,
155
                $this->metadata->getName(),
156
                $graph
157
            ));
158
        }
159
160
        $stateMachine->apply($transition);
161
162
        $this->manager->flush();
163
        $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
164
165
        if (!$configuration->isHtmlRequest()) {
166
            return $this->viewHandler->handle($configuration, View::create($resource, 204));
167
        }
168
169
        $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
170
171
        return $this->redirectHandler->redirectToResource($configuration, $resource);
172
    }
173
}
174