Completed
Push — master ( 6d6774...64f3ed )
by Jeroen
11:23 queued 05:13
created

Controller/TranslatorController.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\TranslatorBundle\Controller;
4
5
use Doctrine\ORM\EntityManager;
6
use Kunstmaan\AdminBundle\FlashMessages\FlashTypes;
7
use Kunstmaan\AdminListBundle\AdminList\AdminList;
8
use Kunstmaan\AdminListBundle\AdminList\Configurator\AbstractAdminListConfigurator;
9
use Kunstmaan\AdminListBundle\Controller\AdminListController;
10
use Kunstmaan\TranslatorBundle\AdminList\TranslationAdminListConfigurator;
11
use Kunstmaan\TranslatorBundle\Entity\Translation;
12
use Kunstmaan\TranslatorBundle\Form\TranslationAdminType;
13
use Kunstmaan\TranslatorBundle\Form\TranslationsFileUploadType;
14
use Symfony\Component\Routing\Annotation\Route;
15
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
16
use Symfony\Component\Form\FormBuilderInterface;
17
use Symfony\Component\Form\FormError;
18
use Symfony\Component\HttpFoundation\JsonResponse;
19
use Symfony\Component\HttpFoundation\RedirectResponse;
20
use Symfony\Component\HttpFoundation\Request;
21
use Symfony\Component\HttpFoundation\Response;
22
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
23
use Symfony\Component\Translation\TranslatorInterface;
24
25
class TranslatorController extends AdminListController
26
{
27
    /**
28
     * @var AbstractAdminListConfigurator
29
     */
30
    private $adminListConfigurator;
31
32
    /**
33
     * @Route("/", name="KunstmaanTranslatorBundle_settings_translations")
34
     * @Template("@KunstmaanTranslator/Translator/list.html.twig")
35
     *
36
     * @param \Symfony\Component\HttpFoundation\Request $request
37
     *
38
     * @return array
39
     */
40
    public function indexAction(Request $request)
41
    {
42
        $configurator = $this->getAdminListConfigurator();
43
44
        /* @var AdminList $adminList */
45
        $adminList = $this->container->get('kunstmaan_adminlist.factory')->createList($configurator);
46
        $adminList->bindRequest($request);
47
48
        $cacheFresh = $this->container->get('kunstmaan_translator.service.translator.cache_validator')->isCacheFresh();
49
        $debugMode = $this->container->getParameter('kuma_translator.debug') === true;
50
51
        if (!$cacheFresh && !$debugMode) {
52
            $this->addFlash(
53
                FlashTypes::INFO,
54
                $this->container->get('translator')->trans('settings.translator.not_live_warning')
55
            );
56
        }
57
58
        return [
59
            'adminlist' => $adminList,
60
            'adminlistconfigurator' => $configurator,
61
        ];
62
    }
63
64
    /**
65
     * @param Request $request
66
     * @param string  $keyword
67
     * @param string  $domain
68
     * @param string  $locale
69
     *
70
     * @return array|RedirectResponse
71
     *
72
     * @throws \Doctrine\ORM\OptimisticLockException
73
     *
74
     * @Route("/add", name="KunstmaanTranslatorBundle_settings_translations_add", methods={"GET", "POST"})
75
     * @Template("@KunstmaanTranslator/Translator/addTranslation.html.twig")
76
     */
77
    public function addAction(Request $request, $keyword = '', $domain = '', $locale = '')
78
    {
79
        /* @var EntityManager $em */
80
        $em = $this->getDoctrine()->getManager();
81
        $configurator = $this->getAdminListConfigurator();
82
        $translator = $this->container->get('translator');
83
84
        $translation = new \Kunstmaan\TranslatorBundle\Model\Translation();
85
        $managedLocales = $this->container->getParameter('kuma_translator.managed_locales');
86
        foreach ($managedLocales as $managedLocale) {
87
            $translation->addText($managedLocale, '');
88
        }
89
90
        $form = $this->createForm(TranslationAdminType::class, $translation, ['csrf_token_id' => 'add']);
91
        if ($request->getMethod() === Request::METHOD_POST) {
92
            $form->handleRequest($request);
93
94
            // Fetch form data
95
            $data = $form->getData();
96
            if (!$em->getRepository('KunstmaanTranslatorBundle:Translation')->isUnique($data)) {
97
                $error = new FormError($translator->trans('translator.translation_not_unique'));
98
                $form->get('domain')->addError($error);
99
                $form->get('keyword')->addError($error);
100
            }
101
102 View Code Duplication
            if ($form->isSubmitted() && $form->isValid()) {
103
                // Create translation
104
                $em->getRepository('KunstmaanTranslatorBundle:Translation')->createTranslations($data);
105
                $em->flush();
106
107
                $this->addFlash(
108
                    FlashTypes::SUCCESS,
109
                    $this->container->get('translator')->trans('settings.translator.succesful_added')
110
                );
111
112
                $indexUrl = $configurator->getIndexUrl();
113
114
                return new RedirectResponse($this->generateUrl(
115
                    $indexUrl['path'],
116
                    isset($indexUrl['params']) ? $indexUrl['params'] : []
117
                ));
118
            }
119
        }
120
121
        return [
122
            'form' => $form->createView(),
123
            'adminlistconfigurator' => $configurator,
124
        ];
125
    }
126
127
    /**
128
     * The edit action
129
     *
130
     * @Route("/{id}/edit", requirements={"id" = "\d+"}, name="KunstmaanTranslatorBundle_settings_translations_edit", methods={"GET", "POST"})
131
     * @Template("@KunstmaanTranslator/Translator/editTranslation.html.twig")
132
     *
133
     * @param \Symfony\Component\HttpFoundation\Request $request
134
     * @param $id
135
     *
136
     * @throws \InvalidArgumentException
137
     *
138
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
139
     */
140
    public function editAction(Request $request, $id)
141
    {
142
        $em = $this->getDoctrine()->getManager();
143
        $configurator = $this->getAdminListConfigurator();
144
145
        $translations = $em->getRepository('KunstmaanTranslatorBundle:Translation')->findBy(['translationId' => $id]);
146
        if (\count($translations) < 1) {
147
            throw new \InvalidArgumentException('No existing translations found for this id');
148
        }
149
150
        $translation = new \Kunstmaan\TranslatorBundle\Model\Translation();
151
        $translation->setDomain($translations[0]->getDomain());
152
        $translation->setKeyword($translations[0]->getKeyword());
153
        $locales = $this->container->getParameter('kuma_translator.managed_locales');
154
        foreach ($locales as $locale) {
155
            $found = false;
156
            foreach ($translations as $t) {
157
                if ($locale == $t->getLocale()) {
158
                    $translation->addText($locale, $t->getText(), $t->getId());
159
                    $found = true;
160
                }
161
            }
162
            if (!$found) {
163
                $translation->addText($locale, '');
164
            }
165
        }
166
167
        $form = $this->createForm(TranslationAdminType::class, $translation, ['intention' => 'edit']);
168
169
        if ($request->getMethod() === Request::METHOD_POST) {
170
            $form->handleRequest($request);
171
172 View Code Duplication
            if ($form->isSubmitted() && $form->isValid()) {
173
                // Update translations
174
                $em->getRepository('KunstmaanTranslatorBundle:Translation')->updateTranslations($translation, $id);
0 ignored issues
show
It seems like you code against a concrete implementation and not the interface Doctrine\Persistence\ObjectRepository as the method updateTranslations() does only exist in the following implementations of said interface: Kunstmaan\TranslatorBund...y\TranslationRepository.

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...
175
                $em->flush();
176
177
                $this->addFlash(
178
                    FlashTypes::SUCCESS,
179
                    $this->container->get('translator')->trans('settings.translator.succesful_edited')
180
                );
181
182
                $indexUrl = $configurator->getIndexUrl();
183
184
                return new RedirectResponse($this->generateUrl(
185
                    $indexUrl['path'],
186
                    isset($indexUrl['params']) ? $indexUrl['params'] : []
187
                ));
188
            }
189
        }
190
191
        return [
192
            'form' => $form->createView(),
193
            'translation' => $translation,
194
            'adminlistconfigurator' => $configurator,
195
        ];
196
    }
197
198
    /**
199
     * @Route("upload", name="KunstmaanTranslatorBundle_settings_translations_upload", methods={"GET", "POST"})
200
     * @Template("@KunstmaanTranslator/Translator/addTranslation.html.twig")
201
     *
202
     * @param Request $request
203
     *
204
     * @return array
205
     */
206
    public function uploadFileAction(Request $request)
207
    {
208
        /** @var FormBuilderInterface $uploadForm */
209
        $form = $this->createForm(TranslationsFileUploadType::class);
210
        $configurator = $this->getAdminListConfigurator();
211
212
        if (Request::METHOD_POST === $request->getMethod()) {
213
            $form->handleRequest($request);
214
            if ($form->isSubmitted() && $form->isValid()) {
215
                $locales = $this->getParameter('kuma_translator.managed_locales');
216
                $data = $form->getData();
217
                $file = $data['file'];
218
                $force = $data['force'];
219
                $imported = $this->container->get('kunstmaan_translator.service.importer.importer')->importFromSpreadsheet($file, $locales, $force);
220
                $this->addFlash(FlashTypes::SUCCESS, sprintf('Translation imported: %d', $imported));
221
            }
222
        }
223
224
        return [
225
            'form' => $form->createView(),
226
            'adminlistconfigurator' => $configurator,
227
        ];
228
    }
229
230
    /**
231
     * The export action
232
     *
233
     * @param string $_format
234
     *
235
     * @Route("/export.{_format}", requirements={"_format" = "csv|ods|xlsx"}, name="KunstmaanTranslatorBundle_settings_translations_export", methods={"GET", "POST"})
236
     *
237
     * @return array
238
     */
239
    public function exportAction(Request $request, $_format)
240
    {
241
        return parent::doExportAction($this->getAdminListConfigurator(), $_format, $request);
242
    }
243
244
    /**
245
     * @param $domain
246
     * @param $locale
247
     * @param $keyword
248
     *
249
     * @return RedirectResponse
250
     */
251
    public function editSearchAction($domain, $locale, $keyword)
252
    {
253
        $configurator = $this->getAdminListConfigurator();
254
        $em = $this->getDoctrine()->getManager();
255
        $translation = $em->getRepository('KunstmaanTranslatorBundle:Translation')->findOneBy(
256
            ['domain' => $domain, 'keyword' => $keyword, 'locale' => $locale]
257
        );
258
259
        if ($translation === null) {
260
            $addUrl = $configurator->getAddUrlFor(
261
                ['domain' => $domain, 'keyword' => $keyword, 'locale' => $locale]
262
            );
263
264
            return new RedirectResponse($this->generateUrl($addUrl['path'], $addUrl['params']));
265
        }
266
267
        $editUrl = $configurator->getEditUrlFor(['id' => $translation->getId()]);
268
269
        return new RedirectResponse($this->generateUrl($editUrl['path'], $editUrl['params']));
270
    }
271
272
    /**
273
     * @param $id
274
     *
275
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
276
     *
277
     * @throws NotFoundHttpException
278
     *
279
     * @Route("/{id}/delete", requirements={"id" = "\d+"}, name="KunstmaanTranslatorBundle_settings_translations_delete", methods={"GET", "POST"})
280
     */
281
    public function deleteAction(Request $request, $id)
282
    {
283
        /* @var EntityManager $em */
284
        $em = $this->getDoctrine()->getManager();
285
286
        $indexUrl = $this->getAdminListConfigurator()->getIndexUrl();
287
        if ($request->isMethod('POST')) {
288
            $em->getRepository('KunstmaanTranslatorBundle:Translation')->removeTranslations($id);
289
        }
290
291
        return new RedirectResponse($this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : []));
292
    }
293
294
    /**
295
     * @param $adminListConfigurator
296
     */
297
    public function setAdminListConfigurator($adminListConfigurator)
298
    {
299
        $this->adminListConfigurator = $adminListConfigurator;
300
    }
301
302
    /**
303
     * @return AbstractAdminListConfigurator
304
     */
305
    public function getAdminListConfigurator()
306
    {
307
        $locales = $this->container->getParameter('kuma_translator.managed_locales');
308
309
        if (!isset($this->adminListConfigurator)) {
310
            $this->adminListConfigurator = new TranslationAdminListConfigurator($this->getDoctrine()->getConnection(), $locales);
311
        }
312
313
        return $this->adminListConfigurator;
314
    }
315
316
    /**
317
     * @param Request $request
318
     *
319
     * @return JsonResponse|Response
320
     *
321
     * @Route("/inline-edit", name="KunstmaanTranslatorBundle_settings_translations_inline_edit", methods={"POST"})
322
     */
323
    public function inlineEditAction(Request $request)
324
    {
325
        $values = $request->request->all();
326
327
        $adminListConfigurator = $this->getAdminListConfigurator();
328
        if (!$adminListConfigurator->canEditInline($values)) {
329
            throw $this->createAccessDeniedException('Not allowed to edit this translation');
330
        }
331
332
        $id = isset($values['pk']) ? (int) $values['pk'] : 0;
333
        $em = $this->getDoctrine()->getManager();
334
        /**
335
         * @var TranslatorInterface
336
         */
337
        $translator = $this->container->get('translator');
338
339
        try {
340
            if ($id !== 0) {
341
                // Find existing translation
342
                $translation = $em->getRepository('KunstmaanTranslatorBundle:Translation')->find($id);
343
344
                if (\is_null($translation)) {
345
                    return new Response($translator->trans('translator.translator.invalid_translation'), 500);
346
                }
347
            } else {
348
                // Create new translation
349
                $translation = new Translation();
350
                $translation->setDomain($values['domain']);
351
                $translation->setKeyword($values['keyword']);
352
                $translation->setLocale($values['locale']);
353
                $translation->setTranslationId($values['translationId']);
354
            }
355
            $translation->setText($values['value']);
356
            $em->persist($translation);
357
            $em->flush();
358
359
            return new JsonResponse([
360
                'success' => true,
361
                'uid' => $translation->getId(),
362
            ], 200);
363
        } catch (\Exception $e) {
364
            return new Response($translator->trans('translator.translator.fatal_error_occurred'), 500);
365
        }
366
    }
367
}
368