Completed
Push — master ( 694bec...006cd9 )
by Jan
04:25
created

BaseAdminController::_edit()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 17
nc 4
nop 3
dl 0
loc 31
rs 8.8333
c 1
b 0
f 0
1
<?php
2
/**
3
 *
4
 * part-db version 0.1
5
 * Copyright (C) 2005 Christoph Lechner
6
 * http://www.cl-projects.de/
7
 *
8
 * part-db version 0.2+
9
 * Copyright (C) 2009 K. Jacobs and others (see authors.php)
10
 * http://code.google.com/p/part-db/
11
 *
12
 * Part-DB Version 0.4+
13
 * Copyright (C) 2016 - 2019 Jan Böhmer
14
 * https://github.com/jbtronics
15
 *
16
 * This program is free software; you can redistribute it and/or
17
 * modify it under the terms of the GNU General Public License
18
 * as published by the Free Software Foundation; either version 2
19
 * of the License, or (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU General Public License
27
 * along with this program; if not, write to the Free Software
28
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
29
 *
30
 */
31
32
namespace App\Controller\AdminPages;
33
34
use App\Entity\Base\NamedDBElement;
35
use App\Entity\Base\StructuralDBElement;
36
use App\Entity\UserSystem\User;
37
use App\Form\AdminPages\ImportType;
38
use App\Form\AdminPages\MassCreationForm;
39
use App\Services\EntityExporter;
40
use App\Services\EntityImporter;
41
use App\Services\StructuralElementRecursionHelper;
42
use Doctrine\ORM\EntityManagerInterface;
43
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
44
use Symfony\Component\HttpFoundation\File\UploadedFile;
45
use Symfony\Component\HttpFoundation\Request;
46
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
47
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
48
use Symfony\Component\Security\Core\Tests\Encoder\PasswordEncoder;
49
use Symfony\Component\Validator\ConstraintViolationList;
50
use Symfony\Contracts\Translation\TranslatorInterface;
51
52
abstract class BaseAdminController extends AbstractController
53
{
54
55
    protected $entity_class = '';
56
    protected $form_class = '';
57
    protected $twig_template = '';
58
    protected $route_base = '';
59
60
61
    protected $passwordEncoder;
62
    protected $translator;
63
64
    public function __construct(TranslatorInterface $translator, UserPasswordEncoderInterface $passwordEncoder)
65
    {
66
        if ($this->entity_class === '' || $this->form_class === '' || $this->twig_template === '' || $this->route_base === '') {
0 ignored issues
show
introduced by
The condition $this->form_class === '' is always false.
Loading history...
introduced by
The condition $this->route_base === '' is always false.
Loading history...
introduced by
The condition $this->twig_template === '' is always false.
Loading history...
67
            throw new \InvalidArgumentException('You have to override the $entity_class, $form_class, $route_base and $twig_template value in your subclasss!');
68
        }
69
70
        $this->translator = $translator;
71
        $this->passwordEncoder = $passwordEncoder;
72
    }
73
74
    protected function _edit(NamedDBElement $entity, Request $request, EntityManagerInterface $em)
75
    {
76
77
        $this->denyAccessUnlessGranted('read', $entity);
78
79
        $form = $this->createForm($this->form_class, $entity);
0 ignored issues
show
Bug introduced by
$this->form_class of type mixed is incompatible with the type string expected by parameter $type of Symfony\Bundle\Framework...ontroller::createForm(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

79
        $form = $this->createForm(/** @scrutinizer ignore-type */ $this->form_class, $entity);
Loading history...
80
81
        $form->handleRequest($request);
82
        if ($form->isSubmitted() && $form->isValid()) {
83
            //Check if we editing a user and if we need to change the password of it
84
            if ($entity instanceof User && !empty($form['new_password']->getData())) {
85
                $password = $this->passwordEncoder->encodePassword($entity, $form['new_password']->getData());
86
                $entity->setPassword($password);
87
                //By default the user must change the password afterwards
88
                $entity->setNeedPwChange(true);
89
            }
90
91
            $em->persist($entity);
92
            $em->flush();
93
            $this->addFlash('success', $this->translator->trans('entity.edit_flash'));
94
95
            //Rebuild form, so it is based on the updated data. Important for the parent field!
96
            //We can not use dynamic form events here, because the parent entity list is build from database!
97
            $form = $this->createForm($this->form_class, $entity);
98
        } elseif ($form->isSubmitted() && ! $form->isValid()) {
99
            $this->addFlash('error', $this->translator->trans('entity.edit_flash.invalid'));
100
        }
101
102
        return $this->render($this->twig_template, [
0 ignored issues
show
Bug introduced by
$this->twig_template of type mixed is incompatible with the type string expected by parameter $view of Symfony\Bundle\Framework...actController::render(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

102
        return $this->render(/** @scrutinizer ignore-type */ $this->twig_template, [
Loading history...
103
            'entity' => $entity,
104
            'form' => $form->createView()
105
        ]);
106
    }
107
108
    protected function _new(Request $request, EntityManagerInterface $em, EntityImporter $importer)
109
    {
110
        /** @var StructuralDBElement $new_entity */
111
        $new_entity = new $this->entity_class();
112
113
        $this->denyAccessUnlessGranted('read', $new_entity);
114
115
        //Basic edit form
116
        $form = $this->createForm($this->form_class, $new_entity);
0 ignored issues
show
Bug introduced by
$this->form_class of type mixed is incompatible with the type string expected by parameter $type of Symfony\Bundle\Framework...ontroller::createForm(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

116
        $form = $this->createForm(/** @scrutinizer ignore-type */ $this->form_class, $new_entity);
Loading history...
117
118
        $form->handleRequest($request);
119
120
        if ($form->isSubmitted() && $form->isValid()) {
121
            if ($new_entity instanceof User && !empty($form['new_password']->getData())) {
0 ignored issues
show
introduced by
$new_entity is never a sub-type of App\Entity\UserSystem\User.
Loading history...
122
                $password = $this->passwordEncoder->encodePassword($new_entity, $form['new_password']->getData());
123
                $new_entity->setPassword($password);
124
                //By default the user must change the password afterwards
125
                $new_entity->setNeedPwChange(true);
126
            }
127
            $em->persist($new_entity);
128
            $em->flush();
129
            $this->addFlash('success', $this->translator->trans('entity.created_flash'));
130
131
            return $this->redirectToRoute($this->route_base . '_edit', ['id' => $new_entity->getID()]);
0 ignored issues
show
Bug introduced by
Are you sure $this->route_base of type mixed can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

131
            return $this->redirectToRoute(/** @scrutinizer ignore-type */ $this->route_base . '_edit', ['id' => $new_entity->getID()]);
Loading history...
132
        }
133
134
        if ($form->isSubmitted() && ! $form->isValid()) {
135
            $this->addFlash('error', $this->translator->trans('entity.created_flash.invalid'));
136
        }
137
138
        //Import form
139
        $import_form = $this->createForm(ImportType::class, ['entity_class' => $this->entity_class]);
140
        $import_form->handleRequest($request);
141
142
        if ($import_form->isSubmitted() && $import_form->isValid()) {
143
            /** @var UploadedFile $file */
144
            $file = $import_form['file']->getData();
145
            $data = $import_form->getData();
146
147
            $options = array('parent' => $data['parent'], 'preserve_children' => $data['preserve_children'],
148
                'format' => $data['format'], 'csv_separator' => $data['csv_separator']);
149
150
            $errors = $importer->fileToDBEntities($file, $this->entity_class, $options);
0 ignored issues
show
Bug introduced by
$this->entity_class of type mixed is incompatible with the type string expected by parameter $class_name of App\Services\EntityImporter::fileToDBEntities(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

150
            $errors = $importer->fileToDBEntities($file, /** @scrutinizer ignore-type */ $this->entity_class, $options);
Loading history...
151
152
            foreach ($errors as $name => $error) {
153
                /** @var $error ConstraintViolationList */
154
                $this->addFlash('error', $name . ':' . $error);
155
            }
156
        }
157
158
        //Mass creation form
159
        $mass_creation_form = $this->createForm(MassCreationForm::class, ['entity_class' => $this->entity_class]);
160
        $mass_creation_form->handleRequest($request);
161
162
        if ($mass_creation_form->isSubmitted() && $mass_creation_form->isValid()) {
163
            $data = $mass_creation_form->getData();
164
165
            dump($data);
166
167
            //Create entries based on input
168
            $errors = $importer->massCreation($data['lines'], $this->entity_class, $data['parent']);
0 ignored issues
show
Bug introduced by
$this->entity_class of type mixed is incompatible with the type string expected by parameter $class_name of App\Services\EntityImporter::massCreation(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

168
            $errors = $importer->massCreation($data['lines'], /** @scrutinizer ignore-type */ $this->entity_class, $data['parent']);
Loading history...
169
170
            //Show errors to user:
171
            foreach ($errors as $name => $error) {
172
                /** @var $error ConstraintViolationList */
173
                $this->addFlash('error', $name . ':' . $error);
174
            }
175
        }
176
177
        return $this->render($this->twig_template, [
0 ignored issues
show
Bug introduced by
$this->twig_template of type mixed is incompatible with the type string expected by parameter $view of Symfony\Bundle\Framework...actController::render(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

177
        return $this->render(/** @scrutinizer ignore-type */ $this->twig_template, [
Loading history...
178
            'entity' => $new_entity,
179
            'form' => $form->createView(),
180
            'import_form' => $import_form->createView(),
181
            'mass_creation_form' => $mass_creation_form->createView()
182
        ]);
183
    }
184
185
    protected function _delete(Request $request, NamedDBElement $entity, StructuralElementRecursionHelper $recursionHelper)
186
    {
187
        $this->denyAccessUnlessGranted('delete', $entity);
188
189
        if ($this->isCsrfTokenValid('delete'.$entity->getId(), $request->request->get('_token'))) {
190
            $entityManager = $this->getDoctrine()->getManager();
191
192
            //Check if we need to remove recursively
193
            if ($entity instanceof StructuralDBElement && $request->get('delete_recursive', false)) {
194
                $recursionHelper->delete($entity, false);
195
            } else {
196
                if ($entity instanceof StructuralDBElement) {
197
                    $parent = $entity->getParent();
198
199
                    //Move all sub entities to the current parent
200
                    foreach ($entity->getSubelements() as $subelement) {
201
                        $subelement->setParent($parent);
202
                        $entityManager->persist($subelement);
203
                    }
204
                }
205
206
                //Remove current element
207
                $entityManager->remove($entity);
208
            }
209
210
            //Flush changes
211
            $entityManager->flush();
212
213
            $this->addFlash('success', 'attachment_type.deleted');
214
        }
215
216
        return $this->redirectToRoute($this->route_base .  '_new');
0 ignored issues
show
Bug introduced by
Are you sure $this->route_base of type mixed can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

216
        return $this->redirectToRoute(/** @scrutinizer ignore-type */ $this->route_base .  '_new');
Loading history...
217
    }
218
219
    protected function _exportAll(EntityManagerInterface $em, EntityExporter $exporter, Request $request)
220
    {
221
        $entity = new $this->entity_class();
222
223
        $this->denyAccessUnlessGranted('read', $entity);
224
225
        $entities = $em->getRepository($this->entity_class)->findAll();
0 ignored issues
show
Bug introduced by
$this->entity_class of type mixed is incompatible with the type string expected by parameter $className of Doctrine\Common\Persiste...anager::getRepository(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

225
        $entities = $em->getRepository(/** @scrutinizer ignore-type */ $this->entity_class)->findAll();
Loading history...
226
227
        return $exporter->exportEntityFromRequest($entities,$request);
228
    }
229
230
    protected function _exportEntity(NamedDBElement $entity, EntityExporter $exporter, Request $request)
231
    {
232
        $this->denyAccessUnlessGranted('read', $entity);
233
234
        return $exporter->exportEntityFromRequest($entity, $request);
235
    }
236
}