Passed
Push — master ( 6bc222...ffd20d )
by WEBEWEB
14:18
created

DataTablesController::editAction()   A

Complexity

Conditions 3
Paths 19

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 17
dl 0
loc 31
c 2
b 0
f 0
rs 9.7
cc 3
nc 19
nop 5
1
<?php
2
3
/*
4
 * This file is part of the jquery-datatables-bundle package.
5
 *
6
 * (c) 2018 WEBEWEB
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 WBW\Bundle\JQuery\DataTablesBundle\Controller;
13
14
use DateTime;
15
use Doctrine\ORM\EntityNotFoundException;
16
use Symfony\Component\HttpFoundation\JsonResponse;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\Response;
19
use Symfony\Component\HttpFoundation\StreamedResponse;
20
use Throwable;
21
use WBW\Bundle\JQuery\DataTablesBundle\Event\DataTablesEvent;
22
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesColumnException;
23
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesCSVExporterException;
24
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesEditorException;
25
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesRepositoryException;
26
use WBW\Bundle\JQuery\DataTablesBundle\Exception\UnregisteredDataTablesProviderException;
27
use WBW\Bundle\JQuery\DataTablesBundle\Factory\DataTablesFactory;
28
use WBW\Bundle\JQuery\DataTablesBundle\Helper\DataTablesEntityHelper;
29
use WBW\Bundle\JQuery\DataTablesBundle\Helper\DataTablesExportHelper;
30
use WBW\Bundle\JQuery\DataTablesBundle\Helper\DataTablesWrapperHelper;
31
use WBW\Bundle\JQuery\DataTablesBundle\Model\DataTablesEnumerator;
32
use WBW\Bundle\JQuery\DataTablesBundle\Model\DataTablesLoop;
33
use WBW\Library\Types\Helper\BooleanHelper;
34
35
/**
36
 * DataTables controller.
37
 *
38
 * @author webeweb <https://github.com/webeweb>
39
 * @package WBW\Bundle\JQuery\DataTablesBundle\Controller
40
 */
41
class DataTablesController extends AbstractController {
42
43
    /**
44
     * Service name.
45
     *
46
     * @var string
47
     */
48
    const SERVICE_NAME = "wbw.jquery.datatables.controller.datatables";
49
50
    /**
51
     * Delete an existing entity.
52
     *
53
     * @param Request $request The request.
54
     * @param string $name The provider name.
55
     * @param string $id The entity id.
56
     * @return Response Returns the response.
57
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
58
     */
59
    public function deleteAction(Request $request, string $name, string $id): Response {
60
61
        $dtProvider = $this->getDataTablesProvider($name);
62
63
        try {
64
65
            $entity = $this->getDataTablesEntityById($dtProvider, $id);
66
67
            $this->dispatchDataTablesEvent(DataTablesEvent::PRE_DELETE, [$entity], $dtProvider);
68
69
            $em = $this->getDoctrine()->getManager();
0 ignored issues
show
Deprecated Code introduced by
The function Symfony\Bundle\Framework...ntroller::getDoctrine() has been deprecated: since Symfony 5.4, inject an instance of ManagerRegistry in your controller instead ( Ignorable by Annotation )

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

69
            $em = /** @scrutinizer ignore-deprecated */ $this->getDoctrine()->getManager();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
70
            $em->remove($entity);
71
            $em->flush();
72
73
            $this->dispatchDataTablesEvent(DataTablesEvent::POST_DELETE, [$entity], $dtProvider);
74
75
            $output = $this->prepareActionResponse(200, "controller.datatables.delete.success");
76
        } catch (Throwable $ex) {
77
78
            $output = $this->handleDataTablesException($ex, "controller.datatables.delete");
79
        }
80
81
        return $this->buildDataTablesResponse($request, $name, $output);
82
    }
83
84
    /**
85
     * Edit an existing entity.
86
     *
87
     * @param Request $request The request.
88
     * @param string $name The provider name
89
     * @param string $id The entity id.
90
     * @param string $data The data.
91
     * @param mixed $value The value
92
     * @return Response Returns the response.
93
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
94
     * @throws BadDataTablesEditorException Throws a bad editor exception.
95
     * @throws BadDataTablesColumnException Throws a bad column exception.
96
     */
97
    public function editAction(Request $request, string $name, string $id, string $data, $value): Response {
98
99
        $dtProvider = $this->getDataTablesProvider($name);
100
        $dtEditor   = $this->getDataTablesEditor($dtProvider);
101
        $dtColumn   = $this->getDataTablesColumn($dtProvider, $data);
102
103
        try {
104
105
            $entity = $this->getDataTablesEntityById($dtProvider, $id);
106
107
            if (true === $request->isMethod("POST")) {
108
                $value = $request->request->get("value");
109
            }
110
111
            $this->dispatchDataTablesEvent(DataTablesEvent::PRE_EDIT, [$entity], $dtProvider);
112
113
            $dtEditor->editColumn($dtColumn, $entity, $value);
114
115
            $em = $this->getDoctrine()->getManager();
0 ignored issues
show
Deprecated Code introduced by
The function Symfony\Bundle\Framework...ntroller::getDoctrine() has been deprecated: since Symfony 5.4, inject an instance of ManagerRegistry in your controller instead ( Ignorable by Annotation )

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

115
            $em = /** @scrutinizer ignore-deprecated */ $this->getDoctrine()->getManager();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
116
            $em->persist($entity);
117
            $em->flush();
118
119
            $this->dispatchDataTablesEvent(DataTablesEvent::POST_EDIT, [$entity], $dtProvider);
120
121
            $output = $this->prepareActionResponse(200, "controller.datatables.edit.success");
122
        } catch (Throwable $ex) {
123
124
            $output = $this->handleDataTablesException($ex, "controller.datatables.edit");
125
        }
126
127
        return new JsonResponse($output);
128
    }
129
130
    /**
131
     * Export all entities.
132
     *
133
     * @param Request $request The request.
134
     * @param string $name The provider name.
135
     * @return Response Returns the response.
136
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
137
     * @throws BadDataTablesCSVExporterException Throws a bad CSV exporter exception.
138
     * @throws BadDataTablesRepositoryException Throws a bad repository exception.
139
     */
140
    public function exportAction(Request $request, string $name): Response {
141
142
        $windows = DataTablesExportHelper::isWindows($request);
143
144
        $dtProvider = $this->getDataTablesProvider($name);
145
        $dtExporter = $this->getDataTablesCSVExporter($dtProvider);
146
        $repository = $this->getDataTablesRepository($dtProvider);
147
148
        $filename = (new DateTime())->format("Y.m.d-H.i.s") . "-" . $dtProvider->getName() . ".csv";
149
        $charset  = true === $windows ? "iso-8859-1" : "utf-8";
150
151
        $response = new StreamedResponse();
152
        $response->headers->set("Content-Disposition", 'attachment; filename="' . $filename . '"');
153
        $response->headers->set("Content-Type", "text/csv; charset=" . $charset);
154
        $response->setCallback(function() use ($dtProvider, $repository, $dtExporter, $windows) {
155
            $this->exportDataTablesCallback($dtProvider, $repository, $dtExporter, $windows);
156
        });
157
        $response->setStatusCode(200);
158
159
        return $response;
160
    }
161
162
    /**
163
     * Lists all entities.
164
     *
165
     * @param Request $request The request.
166
     * @param string $name The provider name.
167
     * @return Response Returns the response.
168
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
169
     * @throws BadDataTablesRepositoryException Throws a bad repository exception.
170
     */
171
    public function indexAction(Request $request, string $name): Response {
172
173
        if (false === $request->isXmlHttpRequest()) {
174
            return $this->renderAction($name);
175
        }
176
177
        $dtProvider = $this->getDataTablesProvider($name);
178
        $repository = $this->getDataTablesRepository($dtProvider);
179
180
        $dtWrapper = $this->getDataTablesWrapper($dtProvider);
181
        DataTablesFactory::parseWrapper($dtWrapper, $request);
182
183
        $dtRecords = $repository->dataTablesCountTotal($dtWrapper);
184
185
        $dtWrapper->getResponse()->setRecordsTotal($dtRecords);
186
        $dtWrapper->getResponse()->setRecordsFiltered($dtRecords);
187
188
        if (true === DataTablesWrapperHelper::hasSearch($dtWrapper)) {
189
            $dtWrapper->getResponse()->setRecordsFiltered($repository->dataTablesCountFiltered($dtWrapper));
190
        }
191
192
        $entities = $repository->dataTablesFindAll($dtWrapper);
193
194
        $this->dispatchDataTablesEvent(DataTablesEvent::PRE_INDEX, $entities, $dtProvider);
195
196
        $dtLoop = new DataTablesLoop($entities);
197
198
        foreach ($entities as $entity) {
199
200
            $dtWrapper->getResponse()->addRow();
201
202
            // Render each row.
203
            foreach (DataTablesEnumerator::enumRows() as $dtRow) {
204
                $dtWrapper->getResponse()->setRow($dtRow, $dtProvider->renderRow($dtRow, $entity, $dtLoop->getIndex0()));
205
            }
206
207
            // Render each column.
208
            foreach ($dtWrapper->getColumns() as $dtColumn) {
209
                $dtWrapper->getResponse()->setRow($dtColumn->getData(), $dtProvider->renderColumn($dtColumn, $entity));
0 ignored issues
show
Bug introduced by
It seems like $dtColumn->getData() can also be of type null; however, parameter $data of WBW\Bundle\JQuery\DataTa...onseInterface::setRow() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

209
                $dtWrapper->getResponse()->setRow(/** @scrutinizer ignore-type */ $dtColumn->getData(), $dtProvider->renderColumn($dtColumn, $entity));
Loading history...
210
            }
211
212
            $dtLoop->next();
213
        }
214
215
        $this->dispatchDataTablesEvent(DataTablesEvent::POST_INDEX, $entities, $dtProvider);
216
217
        return new JsonResponse($dtWrapper->getResponse());
218
    }
219
220
    /**
221
     * Options of a DataTables.
222
     *
223
     * @param string $name The provider name.
224
     * @return Response Returns a response.
225
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
226
     */
227
    public function optionsAction(string $name): Response {
228
229
        $dtProvider = $this->getDataTablesProvider($name);
230
        $dtWrapper  = $this->getDataTablesWrapper($dtProvider);
231
        $dtOptions  = DataTablesWrapperHelper::getOptions($dtWrapper);
232
233
        return new JsonResponse($dtOptions);
234
    }
235
236
    /**
237
     * Render a DataTables.
238
     *
239
     * @param string $name The provider name.
240
     * @param string|null $alone Alone ?
241
     * @return Response Returns the response.
242
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
243
     */
244
    public function renderAction(string $name, string $alone = null): Response {
245
246
        $dtProvider = $this->getDataTablesProvider($name);
247
        $dtWrapper  = $this->getDataTablesWrapper($dtProvider);
248
249
        $dtView = $dtProvider->getView();
250
        if (null === $dtProvider->getView()) {
251
            $dtView = "@WBWJQueryDataTables/datatables/index.html.twig";
252
        }
253
        if (true === BooleanHelper::parseString($alone)) {
254
            $dtView = "@WBWJQueryDataTables/datatables/render.html.twig";
255
        }
256
257
        return $this->render($dtView, [
0 ignored issues
show
Bug introduced by
It seems like $dtView can also be of type null; however, parameter $view of Symfony\Bundle\Framework...actController::render() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

257
        return $this->render(/** @scrutinizer ignore-type */ $dtView, [
Loading history...
258
            "dtWrapper" => $dtWrapper,
259
        ]);
260
    }
261
262
    /**
263
     * Serialize an existing entity.
264
     *
265
     * @param string $name The provider name.
266
     * @param string $id The entity id.
267
     * @return Response Returns the response.
268
     * @throws BadDataTablesRepositoryException Throws a bad repository exception.
269
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
270
     */
271
    public function serializeAction(string $name, string $id): Response {
272
273
        $dtProvider = $this->getDataTablesProvider($name);
274
275
        $entity = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $entity is dead and can be removed.
Loading history...
276
277
        try {
278
279
            $entity = $this->getDataTablesEntityById($dtProvider, $id);
280
281
            $this->dispatchDataTablesEvent(DataTablesEvent::PRE_SERIALIZE, [$entity], $dtProvider);
282
        } catch (EntityNotFoundException $ex) {
283
            $this->logInfo($ex->getMessage());
284
        }
285
286
        $data = DataTablesEntityHelper::jsonSerialize($entity);
287
288
        return new Response($data, 200, ["Content-type" => "application/json"]);
289
    }
290
291
    /**
292
     * Show an existing entity.
293
     *
294
     * @param string $name The provider name.
295
     * @param string $id The entity id.
296
     * @return Response Returns the response.
297
     * @throws BadDataTablesRepositoryException Throws a bad repository exception.
298
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
299
     * @deprecated since 3.9.0 use {@see WBW\Bundle\JQuery\DataTablesBundle\Controller\DataTablesController::serializeAction()} instead.
300
     */
301
    public function showAction(string $name, string $id): Response {
302
303
        $format = "The %s::showAction() is deprecated: use %s::serializeAction() instead";
304
        $myself = get_class($this);
305
306
        $this->getLogger()->warning(sprintf($format, $myself, $myself));
307
308
        return $this->serializeAction($name, $id);
309
    }
310
}
311