Completed
Push — master ( d15cf4...5163a0 )
by Valentyn
06:05
created

BaseController   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 90.24%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 4
dl 0
loc 90
ccs 37
cts 41
cp 0.9024
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A response() 0 9 2
A appendRolesToContextGroups() 0 18 4
B translateEntities() 0 25 5
A getEntityTranslation() 0 5 1
A getUserPreferredLocale() 0 16 4
1
<?php
2
declare(strict_types=1);
3
4
namespace App\Controller;
5
6
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
7
use JMS\Serializer\SerializationContext;
8
use Symfony\Component\HttpFoundation\JsonResponse;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\RequestStack;
11
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
12
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
13
use Symfony\Component\Serializer\SerializerInterface;
14
15
/**
16
 * Class BaseController
17
 * @package App\Controller
18
 */
19
abstract class BaseController extends Controller implements ControllerInterface
20
{
21
    protected $serializer;
22
    protected $normalizer;
23
    protected $currentRequest;
24
25 25
    public function __construct(NormalizerInterface $normalizer, RequestStack $requestStack)
26
    {
27 25
        $this->normalizer = $normalizer;
28 25
        $this->currentRequest = $requestStack->getCurrentRequest();
29 25
    }
30
31 13
    protected function response($data, int $status = 200, array $headers = array(), array $context = array())
32
    {
33 13
        $contextWithRoles = $this->appendRolesToContextGroups($context);
34
35 13
        $response = $this->normalizer->normalize($data, null, $contextWithRoles);
36 13
        $response = $this->translateEntities(is_array($response) ? $response : [$response]);
37
38 13
        return $this->json($response, $status, $headers, $context);
39
    }
40
41 13
    private function appendRolesToContextGroups(?array $context): array
42
    {
43 13
        if ($this->getUser() === null) return $context;
44
45 5
        if ($context === null) {
46
            return [
47
                'groups' => $this->getUser()->getRoles(),
48
            ];
49
        }
50
51 5
        if (isset($context['groups'])) {
52 5
            $context['groups'] = array_merge($context['groups'], $this->getUser()->getRoles());
53
        } else {
54
            $context['groups'] = $this->getUser()->getRoles();
55
        }
56
57 5
        return $context;
58
    }
59
60 13
    protected function translateEntities(array $data, $recursive = true): array
61
    {
62 13
        $translatedData = [];
63
64 13
        foreach ($data as $key => $value) {
65 13
            if ($key === 'translations') {
66 8
                $translatedData = array_merge($translatedData, $this->getEntityTranslation($value));
67
68 8
                if ($recursive === true) {
69 8
                    continue;
70
                } else {
71
                    break;
72
                }
73
            }
74
75 13
            if (is_array($value)) {
76 13
                $data[$key] = $this->translateEntities($value, $recursive);
77
            }
78
        }
79
80 13
        unset($data['translations']);
81 13
        $data = array_merge($data, $translatedData);
82
83 13
        return $data;
84
    }
85
86 8
    private function getEntityTranslation(array $translations)
87
    {
88 8
        $userLocale = $this->getUserPreferredLocale(array_keys($translations));
89 8
        return $translations[$userLocale];
90
    }
91
92 8
    private function getUserPreferredLocale(array $locales = [])
93
    {
94 8
        if (!isset($locales[0])) {
95
            // there's no translations for this entity
96
            throw new NotFoundHttpException();
97
        }
98
99 8
        $preferredLocale = $this->currentRequest->getPreferredLanguage($locales);
100
101 8
        $locale = $this->currentRequest->getLocale(); // can be set by query param (?language=ru) or by symfony
102 8
        if ($locale !== $this->currentRequest->getDefaultLocale() && in_array($locale, $locales) === true) {
103 1
            $preferredLocale = $locale;
104
        }
105
106 8
        return $preferredLocale;
107
    }
108
}