Completed
Push — master ( eab2a6...645cff )
by Jeroen
30s queued 13s
created

Controller/TranslatorController.php (3 issues)

Labels
Severity

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)) {
0 ignored issues
show
It seems like you code against a concrete implementation and not the interface Doctrine\Persistence\ObjectRepository as the method isUnique() 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...
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);
0 ignored issues
show
It seems like you code against a concrete implementation and not the interface Doctrine\Persistence\ObjectRepository as the method createTranslations() 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...
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);
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);
0 ignored issues
show
It seems like you code against a concrete implementation and not the interface Doctrine\Persistence\ObjectRepository as the method removeTranslations() 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...
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