Completed
Push — master ( af42de...cc6223 )
by Florian
17s queued 11s
created

BaseFormController::handleDeleteFormInternal()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 24
rs 9.7998
c 0
b 0
f 0
cc 2
nc 1
nop 6
1
<?php
2
3
/*
4
 * This file is part of the feedback project.
5
 *
6
 * (c) Florian Moser <[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 App\Controller\Base;
13
14
use App\Entity\Base\BaseEntity;
15
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
16
use Symfony\Component\Form\FormInterface;
17
use Symfony\Component\HttpFoundation\Request;
18
19
class BaseFormController extends BaseDoctrineController
20
{
21
    /**
22
     * @param callable $onValidCallable with $form ass an argument
23
     *
24
     * @return FormInterface
25
     */
26
    protected function handleForm(FormInterface $form, Request $request, $onValidCallable)
27
    {
28
        $form->handleRequest($request);
29
30
        if ($form->isSubmitted()) {
31
            if ($form->isValid()) {
32
                return $onValidCallable($form);
33
            }
34
35
            $this->displayError(
36
                $this->getTranslator()->trans('form.error.validation_failed', [], 'framework')
37
            );
38
        }
39
40
        return $form;
41
    }
42
43
    /**
44
     * creates a "create" form.
45
     *
46
     * @param callable|null $beforeCreateCallable
47
     *
48
     * @return FormInterface
49
     */
50
    protected function handleCreateForm(Request $request, BaseEntity $defaultEntity, $beforeCreateCallable = null)
51
    {
52
        //translate messages
53
        $translator = $this->getTranslator();
54
        $buttonLabel = $translator->trans('form.submit_buttons.create', [], 'framework');
55
        $successfulText = $translator->trans('form.successful.created', [], 'framework');
56
57
        $formType = $this->classToFormType(\get_class($defaultEntity));
58
        $startEntity = clone $defaultEntity;
59
60
        //create persist callable
61
        $myOnSuccessCallable = function ($form) use ($defaultEntity, $beforeCreateCallable, $successfulText, $formType, $startEntity, $buttonLabel) {
62
            $manager = $this->getDoctrine()->getManager();
63
64
            if (!\is_callable($beforeCreateCallable) || false !== $beforeCreateCallable($manager)) {
65
                $manager->persist($defaultEntity);
66
                $manager->flush();
67
                $this->displaySuccess($successfulText);
68
69
                //recreate form so values are not filled out already
70
                return $this->createForm($formType, $startEntity)
71
                    ->add('submit', SubmitType::class, ['label' => $buttonLabel, 'translation_domain' => false]);
72
            }
73
74
            return $form;
75
        };
76
77
        //handle the form
78
        return $this->handleForm(
79
            $this->createForm($formType, $defaultEntity)
80
                ->add('submit', SubmitType::class, ['label' => $buttonLabel, 'translation_domain' => false]),
81
            $request,
82
            $myOnSuccessCallable
83
        );
84
    }
85
86
    /**
87
     * creates a "create" form.
88
     *
89
     * @param callable|null $beforeUpdateCallable
90
     *
91
     * @return FormInterface
92
     */
93
    protected function handleUpdateForm(Request $request, BaseEntity $entity, $beforeUpdateCallable = null)
94
    {
95
        //translate messages
96
        $translator = $this->getTranslator();
97
        $buttonLabel = $translator->trans('form.submit_buttons.update', [], 'framework');
98
        $successfulText = $translator->trans('form.successful.updated', [], 'framework');
99
100
        //create persist callable
101
        $myOnSuccessCallable = function ($form) use ($entity, $beforeUpdateCallable, $successfulText) {
102
            $manager = $this->getDoctrine()->getManager();
103
104
            if (!\is_callable($beforeUpdateCallable) || false !== $beforeUpdateCallable($manager)) {
105
                $manager->persist($entity);
106
                $manager->flush();
107
                $this->displaySuccess($successfulText);
108
            }
109
110
            return $form;
111
        };
112
113
        //handle the form
114
        return $this->handleForm(
115
            $this->createForm($this->classToFormType(\get_class($entity)), $entity)
116
                ->add('submit', SubmitType::class, ['label' => $buttonLabel, 'translation_domain' => false]),
117
            $request,
118
            $myOnSuccessCallable
119
        );
120
    }
121
122
    /**
123
     * creates a "create" form.
124
     *
125
     * @param callable $beforeDeleteCallable called after successful submit, before entity is deleted. return true to continue removal
126
     *
127
     * @return FormInterface
128
     */
129
    protected function handleDeleteForm(Request $request, BaseEntity $entity, $beforeDeleteCallable = null)
130
    {
131
        $translator = $this->getTranslator();
132
133
        return $this->handleDeleteFormInternal(
134
            $request,
135
            $entity,
136
            $this->classToFormType(\get_class($entity), 'Delete', false),
137
            $translator->trans('form.submit_buttons.delete', [], 'framework'),
138
            $translator->trans('form.successful.deleted', [], 'framework'),
139
            $beforeDeleteCallable ??
140
            function () {
141
                return true;
142
            }
143
        );
144
    }
145
146
    /**
147
     * persist the entity to the database if submitted successfully.
148
     *
149
     * @param string $formType namespace of form type to use
150
     * @param string $buttonLabel label of button
151
     * @param string $successText content of text displayed if successful
152
     * @param callable $beforeDeleteCallable called after successful submit, before entity is deleted. return true to continue removal
153
     *
154
     * @return FormInterface the constructed form
155
     */
156
    private function handleDeleteFormInternal(Request $request, BaseEntity $entity, $formType, $buttonLabel, $successText, $beforeDeleteCallable)
157
    {
158
        $myOnSuccessCallable = function ($form) use ($entity, $successText, $beforeDeleteCallable) {
159
            $manager = $this->getDoctrine()->getManager();
160
161
            if (false !== $beforeDeleteCallable($entity, $manager)) {
162
                $manager->remove($entity);
163
                $manager->flush();
164
                $this->displaySuccess($successText);
165
166
                return null;
167
            }
168
169
            return $form;
170
        };
171
172
        $myForm = $this->handleForm(
173
            $this->createForm($formType, $entity)
174
                ->add('submit', SubmitType::class, ['label' => $buttonLabel, 'translation_domain' => false]),
175
            $request,
176
            $myOnSuccessCallable
177
        );
178
179
        return $myForm;
180
    }
181
182
    /**
183
     * produces App\Form\MyClassName\MyClassNameType from App\Entity\MyClassName
184
     * if $isDeleteType is true then the delete form is returned.
185
     *
186
     * @param string $classWithNamespace
187
     * @param string $prepend is prepended to class name
188
     * @param bool $repeatClass
189
     *
190
     * @return string
191
     */
192
    private function classToFormType($classWithNamespace, $prepend = '', $repeatClass = true)
193
    {
194
        $className = mb_substr($classWithNamespace, mb_strrpos($classWithNamespace, '\\') + 1);
195
196
        return 'App\\Form\\' . $className . '\\' . $prepend . ($repeatClass ? $className : '') . 'Type';
197
    }
198
}
199