Completed
Push — master ( e32091...31c526 )
by Olivier
02:31 queued 11s
created

SymfonyProfilerController::getMessages()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 0
cts 15
cp 0
rs 9.3222
c 0
b 0
f 0
cc 5
nc 4
nop 2
crap 30
1
<?php
2
3
/*
4
 * This file is part of the PHP Translation package.
5
 *
6
 * (c) PHP Translation team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Translation\Bundle\Controller;
13
14
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
15
use Symfony\Component\HttpFoundation\Request;
16
use Symfony\Component\HttpFoundation\Response;
17
use Symfony\Component\HttpKernel\Profiler\Profiler;
18
use Symfony\Component\Translation\DataCollector\TranslationDataCollector;
19
use Symfony\Component\Translation\DataCollectorTranslator;
20
use Symfony\Component\VarDumper\Cloner\Data;
21
use Translation\Bundle\Model\SfProfilerMessage;
22
use Translation\Bundle\Service\StorageService;
23
use Translation\Common\Model\MessageInterface;
24
25
/**
26
 * @author Tobias Nyholm <[email protected]>
27
 */
28
class SymfonyProfilerController extends AbstractController
29
{
30
    private $storage;
31
    private $profiler;
32
    private $isToolbarAllowEdit;
33
34
    public function __construct(StorageService $storage, Profiler $profiler, bool $isToolbarAllowEdit)
35
    {
36
        $this->storage = $storage;
37
        $this->profiler = $profiler;
38
        $this->isToolbarAllowEdit = $isToolbarAllowEdit;
39
    }
40
41
    public function editAction(Request $request, string $token): Response
42
    {
43
        if (!$this->isToolbarAllowEdit) {
44
            return new Response('You are not allowed to edit the translations.');
45
        }
46
47
        if (!$request->isXmlHttpRequest()) {
48
            return $this->redirectToRoute('_profiler', ['token' => $token]);
49
        }
50
51
        $message = $this->getMessage($request, $token);
52
53
        if ($request->isMethod('GET')) {
54
            $translation = $this->storage->syncAndFetchMessage($message->getLocale(), $message->getDomain(), $message->getKey());
55
56
            return $this->render('@Translation/SymfonyProfiler/edit.html.twig', [
57
                'message' => $translation,
58
                'key' => $request->query->get('message_id'),
59
            ]);
60
        }
61
62
        //Assert: This is a POST request
63
        $message->setTranslation($request->request->get('translation'));
64
        $this->storage->update($message->convertToMessage());
65
66
        return new Response($message->getTranslation());
67
    }
68
69
    public function syncAction(Request $request, string $token): Response
70
    {
71
        if (!$request->isXmlHttpRequest()) {
72
            return $this->redirectToRoute('_profiler', ['token' => $token]);
73
        }
74
75
        $sfMessage = $this->getMessage($request, $token);
76
        $message = $this->storage->syncAndFetchMessage($sfMessage->getLocale(), $sfMessage->getDomain(), $sfMessage->getKey());
77
78
        if (null !== $message) {
79
            return new Response($message->getTranslation());
80
        }
81
82
        return new Response('Asset not found', 404);
83
    }
84
85
    /**
86
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
87
     */
88
    public function syncAllAction(Request $request, string $token): Response
89
    {
90
        if (!$request->isXmlHttpRequest()) {
91
            return $this->redirectToRoute('_profiler', ['token' => $token]);
92
        }
93
94
        $this->storage->sync();
95
96
        return new Response('Started synchronization of all translations');
97
    }
98
99
    /**
100
     * Save the selected translation to resources.
101
     *
102
     * @author Damien Alexandre (damienalexandre)
103
     */
104
    public function createAssetsAction(Request $request, string $token): Response
105
    {
106
        if (!$request->isXmlHttpRequest()) {
107
            return $this->redirectToRoute('_profiler', ['token' => $token]);
108
        }
109
110
        $messages = $this->getSelectedMessages($request, $token);
111
        if (empty($messages)) {
112
            return new Response('No translations selected.');
113
        }
114
115
        $uploaded = [];
116
        foreach ($messages as $message) {
117
            $this->storage->create($message);
118
            $uploaded[] = $message;
119
        }
120
121
        return new Response(\sprintf('%s new assets created!', \count($uploaded)));
122
    }
123
124
    private function getMessage(Request $request, string $token): SfProfilerMessage
125
    {
126
        $this->profiler->disable();
127
128
        $messageId = $request->request->get('message_id', $request->query->get('message_id'));
129
130
        $collectorMessages = $this->getMessages($token);
131
132
        if (!isset($collectorMessages[$messageId])) {
133
            throw $this->createNotFoundException(\sprintf('No message with key "%s" was found.', $messageId));
134
        }
135
        $message = SfProfilerMessage::create($collectorMessages[$messageId]);
136
137
        if (DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK === $message->getState()) {
138
            /** @var \Symfony\Component\HttpKernel\DataCollector\RequestDataCollector */
139
            $requestCollector = $this->profiler->loadProfile($token)->getCollector('request');
140
141
            $message
142
                ->setLocale($requestCollector->getLocale())
143
                ->setTranslation(\sprintf('[%s]', $message->getTranslation()))
144
            ;
145
        }
146
147
        return $message;
148
    }
149
150
    /**
151
     * @return MessageInterface[]
152
     */
153
    protected function getSelectedMessages(Request $request, string $token): array
154
    {
155
        $this->profiler->disable();
156
157
        $selected = $request->request->get('selected');
158
        if (!$selected || 0 == \count($selected)) {
159
            return [];
160
        }
161
162
        $toSave = \array_intersect_key($this->getMessages($token), \array_flip($selected));
163
164
        $messages = [];
165
        foreach ($toSave as $data) {
166
            $messages[] = SfProfilerMessage::create($data)->convertToMessage();
167
        }
168
169
        return $messages;
170
    }
171
172
    private function getMessages(string $token, string $profileName = 'translation'): array
173
    {
174
        $profile = $this->profiler->loadProfile($token);
175
176
        if (null === $dataCollector = $profile->getCollector($profileName)) {
177
            throw $this->createNotFoundException("No collector with name \"$profileName\" was found.");
178
        }
179
        if (!$dataCollector instanceof TranslationDataCollector) {
180
            throw $this->createNotFoundException("Collector with name \"$profileName\" is not an instance of TranslationDataCollector.");
181
        }
182
183
        $messages = $dataCollector->getMessages();
184
185
        if (\class_exists(Data::class) && $messages instanceof Data) {
186
            return $messages->getValue(true);
187
        }
188
189
        return $messages;
190
    }
191
}
192