Passed
Push — develop ( 441564...de4ae5 )
by BENARD
12:43
created

ArticleLocaleSubscriber::getPreferredLocale()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 16
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ProjetNormandie\ArticleBundle\EventSubscriber;
6
7
use ApiPlatform\Symfony\EventListener\EventPriorities;
8
use ProjetNormandie\ArticleBundle\Entity\Article;
9
use ProjetNormandie\ArticleBundle\Service\LocaleResolver;
10
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpKernel\Event\ViewEvent;
13
use Symfony\Component\HttpKernel\KernelEvents;
14
15
/**
16
 * Event subscriber that sets the current locale on Article entities
17
 * based on the HTTP_ACCEPT_LANGUAGE header
18
 */
19
class ArticleLocaleSubscriber implements EventSubscriberInterface
20
{
21
    public function __construct(private readonly LocaleResolver $localeResolver)
22
    {
23
    }
24
25
26
    /**
27
     * {@inheritdoc}
28
     */
29
    public static function getSubscribedEvents(): array
30
    {
31
        return [
32
            // This event is triggered right before the serialization process
33
            KernelEvents::VIEW => ['setLocale', EventPriorities::PRE_SERIALIZE],
34
        ];
35
    }
36
37
    /**
38
     * Set the appropriate locale on Article entities based on HTTP_ACCEPT_LANGUAGE
39
     *
40
     * @param ViewEvent $event The event
41
     */
42
    public function setLocale(ViewEvent $event): void
43
    {
44
        $request = $event->getRequest();
45
        $result = $event->getControllerResult();
46
47
        // Only process GET requests targeting Article entities
48
        if (!$this->shouldProcess($request, $result)) {
49
            return;
50
        }
51
52
        // Get preferred locale from HTTP_ACCEPT_LANGUAGE header
53
        $locale = $this->localeResolver->getPreferredLocale($request);
54
55
        // Set locale on one or more Article entities
56
        $this->applyLocaleToResult($result, $locale);
57
    }
58
59
    /**
60
     * Determine if this request should be processed
61
     *
62
     * @param Request $request The HTTP request
63
     * @param mixed $result The controller result
64
     * @return bool Whether the request should be processed
65
     */
66
    private function shouldProcess(Request $request, $result): bool
67
    {
68
        // Only process GET requests
69
        if (!in_array($request->getMethod(), ['GET'])) {
70
            return false;
71
        }
72
73
        // Process single Article
74
        if ($result instanceof Article) {
75
            return true;
76
        }
77
78
        // Process collections containing Articles
79
        if (is_array($result) || $result instanceof \Traversable) {
80
            foreach ($result as $item) {
81
                if ($item instanceof Article) {
82
                    return true;
83
                }
84
            }
85
        }
86
87
        return false;
88
    }
89
90
    /**
91
     * Apply the preferred locale to Article entities in the result
92
     *
93
     * @param mixed $result The controller result
94
     * @param string $locale The preferred locale
95
     */
96
    private function applyLocaleToResult($result, string $locale): void
97
    {
98
        // Single Article
99
        if ($result instanceof Article) {
100
            $result->setCurrentLocale($locale);
101
            return;
102
        }
103
104
        // Collection of Articles
105
        if (is_array($result) || $result instanceof \Traversable) {
106
            foreach ($result as $item) {
107
                if ($item instanceof Article) {
108
                    $item->setCurrentLocale($locale);
109
                }
110
            }
111
        }
112
    }
113
}
114