EmployeesController::getRolesAction()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 3.3786

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 42
ccs 15
cts 23
cp 0.6522
crap 3.3786
rs 9.248
c 0
b 0
f 0
1
<?php
2
3
namespace App\Controller\Api;
4
5
use App\Entity\Employee;
6
use App\Entity\Performance;
7
use App\Model\Link;
8
use App\Entity\Role;
9
use App\Model\PaginationLinks;
10
use App\Model\EmployeesResponse;
11
use FOS\RestBundle\Request\ParamFetcher;
12
use FOS\RestBundle\Controller\Annotations\QueryParam;
13
use JMS\Serializer\SerializerInterface;
14
use Nelmio\ApiDocBundle\Annotation\Model;
15
use Swagger\Annotations as SWG;
16
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
17
use Symfony\Component\Routing\Annotation\Route;
18
use Symfony\Contracts\Translation\TranslatorInterface;
19
20
/**
21
 * @Route("/api/employees")
22
 */
23
class EmployeesController extends AbstractController
24
{
25
    private $translator;
26
    private $serializer;
27
28 4
    public function __construct(
29
        TranslatorInterface $translator,
30
        SerializerInterface $serializer
31
    ) {
32 4
        $this->translator = $translator;
33 4
        $this->serializer = $serializer;
34 4
    }
35
36
    /**
37
     * @Route("", name="get_employees", methods={"GET"})
38
     * @SWG\Response(
39
     *     response=200,
40
     *     description="Returns a collection of theatre employees.",
41
     *     @SWG\Schema(
42
     *         type="array",
43
     *         @SWG\Items(ref=@Model(type=EmployeesResponse::class))
44
     *     )
45
     * )
46
     * @SWG\Response(
47
     *     response=404,
48
     *     description="Returned when the entities with given limit and offset are not found",
49
     * )
50
     *
51
     * @QueryParam(name="limit", requirements="\d+", default="10", description="Count entries at one page")
52
     * @QueryParam(name="page", requirements="\d+", default="1", description="Number of page to be shown")
53
     * @QueryParam(name="locale", requirements="^[a-zA-Z]+", default="uk", description="Selects language of data you want to receive")
54
     */
55 2
    public function cgetAction(ParamFetcher $paramFetcher)
56
    {
57 2
        $em = $this->getDoctrine()->getManager();
58
59
        $employees = $em
60 2
            ->getRepository('App:Employee')
61 2
            ->findBy([], ['lastName' => 'ASC'], $paramFetcher->get('limit'), ($paramFetcher->get('page')-1) * $paramFetcher->get('limit'))
62
        ;
63
64 2
        $employeesTranslated = array();
65
66 2
        foreach ($employees as $employee) {
67 2
            $employee->setLocale($paramFetcher->get('locale'));
68
69 2
            $em->refresh($employee);
70
71 2
            if ($employee->getTranslations()) {
72 2
                $employee->unsetTranslations();
73
            }
74
75 2
            $this->translator->setLocale($paramFetcher->get('locale'));
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Contracts\Translation\TranslatorInterface as the method setLocale() does only exist in the following implementations of said interface: Symfony\Bridge\Twig\Exte...nslationExtension.php$0, Symfony\Bundle\Framework...\Translation\Translator, Symfony\Component\Transl...DataCollectorTranslator, Symfony\Component\Translation\IdentityTranslator, Symfony\Component\Translation\LoggingTranslator, Symfony\Component\Translation\Translator, Symfony\Component\Valida...l\LegacyTranslatorProxy, Symfony\Component\Valida.../ValidatorBuilder.php$0, Symfony\Contracts\Transl...st/TranslatorTest.php$0.

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...
76 2
            $employee->setPosition($this->translator->trans($employee->getPosition()));
77
78 2
            $employeesTranslated[] = $employee;
79
        }
80
81 2
        $employees = $employeesTranslated;
82
83 2
        $employeesResponse = new EmployeesResponse();
84 2
        $employeesResponse->setEmployees($employees);
85 2
        $employeesResponse->setTotalCount($this->getDoctrine()->getManager()->getRepository('App:Employee')->getCount());
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Doctrine\Persistence\ObjectRepository as the method getCount() does only exist in the following implementations of said interface: App\Repository\AbstractRepository, App\Repository\EmployeeRepository, App\Repository\HistoryRepository, App\Repository\PerformanceEventRepository, App\Repository\PerformanceRepository, App\Repository\PostRepository.

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...
86 2
        $employeesResponse->setPageCount(ceil($employeesResponse->getTotalCount() / $paramFetcher->get('limit')));
87 2
        $employeesResponse->setPage($paramFetcher->get('page'));
88
89 2
        $self = $this->generateUrl('get_employees', [
90 2
            'locale' => $paramFetcher->get('locale'),
91 2
            'limit' => $paramFetcher->get('limit'),
92 2
            'page' => $paramFetcher->get('page'),
93 2
        ], true
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
94
        );
95
96 2
        $first = $this->generateUrl('get_employees', [
97 2
            'locale' => $paramFetcher->get('locale'),
98 2
            'limit' => $paramFetcher->get('limit'),
99 2
        ], true
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
100
        );
101
102 2
        $nextPage = $paramFetcher->get('page') < $employeesResponse->getPageCount() ?
103 2
            $this->generateUrl('get_employees', [
104 2
                'locale' => $paramFetcher->get('locale'),
105 2
                'limit' => $paramFetcher->get('limit'),
106 2
                'page' => $paramFetcher->get('page')+1,
107 2
            ], true
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
108
            ) :
109 2
            'false';
110
111 2
        $previsiousPage = $paramFetcher->get('page') > 1 ?
112
            $this->generateUrl('get_employees', [
113
                'locale' => $paramFetcher->get('locale'),
114
                'limit' => $paramFetcher->get('limit'),
115
                'page' => $paramFetcher->get('page')-1,
116
            ], true
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
117
            ) :
118 2
            'false';
119
120 2
        $last = $this->generateUrl('get_employees', [
121 2
            'locale' => $paramFetcher->get('locale'),
122 2
            'limit' => $paramFetcher->get('limit'),
123 2
            'page' => $employeesResponse->getPageCount(),
124 2
        ], true
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
125
        );
126
127 2
        $links = new PaginationLinks();
128
129 2
        $employeesResponse->setLinks($links->setSelf(new Link($self)));
130 2
        $employeesResponse->setLinks($links->setFirst(new Link($first)));
131 2
        $employeesResponse->setLinks($links->setNext(new Link($nextPage)));
132 2
        $employeesResponse->setLinks($links->setPrev(new Link($previsiousPage)));
133 2
        $employeesResponse->setLinks($links->setLast(new Link($last)));
134
135 2
        return $employeesResponse;
136
    }
137
138
    /**
139
     * @Route("/{slug}", name="get_employee", methods={"GET"})
140
     * @SWG\Response(
141
     *     response=200,
142
     *     description="Returns an Employee by unique property {slug}",
143
     *     @Model(type=Employee::class)
144
     * )
145
     * @SWG\Response(
146
     *     response=404,
147
     *     description="Returns when employee by {slug} not found in database",
148
     * )
149
     *
150
     * @QueryParam(name="locale", requirements="^[a-zA-Z]+", default="uk", description="Selects language of data you want to receive")
151
     */
152 1
    public function getAction(ParamFetcher $paramFetcher, $slug)
153
    {
154 1
        $em = $this->getDoctrine()->getManager();
155
156
        /** @var Employee $employee */
157 1
        $employee = $em->getRepository('App:Employee')->findOneByslug($slug);
158
159 1
        if (!$employee) {
160 1
            throw $this->createNotFoundException('Unable to find '.$slug.' entity');
161
        }
162
163 1
        $employee->setLocale($paramFetcher->get('locale'));
164 1
        $em->refresh($employee);
165
166 1
        if ($employee->getTranslations()) {
167 1
            $employee->unsetTranslations();
168
        }
169
170 1
        $this->translator->setLocale($paramFetcher->get('locale'));
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Contracts\Translation\TranslatorInterface as the method setLocale() does only exist in the following implementations of said interface: Symfony\Bridge\Twig\Exte...nslationExtension.php$0, Symfony\Bundle\Framework...\Translation\Translator, Symfony\Component\Transl...DataCollectorTranslator, Symfony\Component\Translation\IdentityTranslator, Symfony\Component\Translation\LoggingTranslator, Symfony\Component\Translation\Translator, Symfony\Component\Valida...l\LegacyTranslatorProxy, Symfony\Component\Valida.../ValidatorBuilder.php$0, Symfony\Contracts\Transl...st/TranslatorTest.php$0.

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...
171 1
        $employee->setPosition($this->translator->trans($employee->getPosition()));
172
173 1
        return $employee;
174
    }
175
176
    /**
177
     * @Route("/{slug}/roles", name="get_employee_roles", methods={"GET"})
178
     * @SWG\Response(
179
     *     response=200,
180
     *     description="Returns employee roles by employee {slug}",
181
     *     @SWG\Schema(
182
     *         type="array",
183
     *         @SWG\Items(ref=@Model(type=Role::class))
184
     *     )
185
     * )
186
     * @SWG\Response(
187
     *     response=404,
188
     *     description="Returns when employee by {slug} not found in database",
189
     * )
190
     *
191
     * @QueryParam(name="locale", requirements="^[a-zA-Z]+", default="uk", description="Selects language of data you want to receive")
192
     */
193 1
    public function getRolesAction(ParamFetcher $paramFetcher, $slug)
194
    {
195 1
        $em = $this->getDoctrine()->getManager();
196
197
        /** @var Employee $employee */
198 1
        $employee = $em->getRepository('App:Employee')->findOneByslug($slug);
199
200 1
        if (!$employee) {
201 1
            throw $this->createNotFoundException('Unable to find '.$slug.' entity');
202
        }
203
204 1
        $employee->setLocale($paramFetcher->get('locale'));
205 1
        $em->refresh($employee);
206
207 1
        $employee->unsetTranslations();
208
209 1
        $this->translator->setLocale($paramFetcher->get('locale'));
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Contracts\Translation\TranslatorInterface as the method setLocale() does only exist in the following implementations of said interface: Symfony\Bridge\Twig\Exte...nslationExtension.php$0, Symfony\Bundle\Framework...\Translation\Translator, Symfony\Component\Transl...DataCollectorTranslator, Symfony\Component\Translation\IdentityTranslator, Symfony\Component\Translation\LoggingTranslator, Symfony\Component\Translation\Translator, Symfony\Component\Valida...l\LegacyTranslatorProxy, Symfony\Component\Valida.../ValidatorBuilder.php$0, Symfony\Contracts\Transl...st/TranslatorTest.php$0.

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...
210 1
        $employee->setPosition($this->translator->trans($employee->getPosition()));
211
212 1
        $roles = $employee->getRoles();
213
214 1
        $rolesTranslated = [];
215
216 1
        foreach ($roles as $role) {
217
            /** @var Performance $performance */
218
            $performance = $role->getPerformance();
219
220
            $role->setLocale($paramFetcher->get('locale'));
221
            $em->refresh($role);
222
            $performance->setLocale($paramFetcher->get('locale'));
223
            $em->refresh($performance);
224
225
            $role->unsetTranslations();
226
            $performance->unsetTranslations();
227
228
            $rolesTranslated[] = $role;
229
        }
230
231 1
        $roles = $rolesTranslated;
232
233 1
        return $roles;
234
    }
235
}
236