Completed
Push — master ( e5e4cb...c0714e )
by WEBEWEB
01:31
created

getDataTablesSerializer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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 Doctrine\ORM\EntityNotFoundException;
15
use Doctrine\ORM\EntityRepository;
16
use Symfony\Component\HttpFoundation\JsonResponse;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\Response;
19
use Symfony\Component\Serializer\Encoder\JsonEncoder;
20
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
21
use Symfony\Component\Serializer\Serializer;
22
use WBW\Bundle\BootstrapBundle\Controller\AbstractBootstrapController;
23
use WBW\Bundle\JQuery\DataTablesBundle\API\DataTablesColumn;
24
use WBW\Bundle\JQuery\DataTablesBundle\API\DataTablesWrapper;
25
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesColumnException;
26
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesCSVExporterException;
27
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesEditorException;
28
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesRepositoryException;
29
use WBW\Bundle\JQuery\DataTablesBundle\Exception\UnregisteredDataTablesProviderException;
30
use WBW\Bundle\JQuery\DataTablesBundle\Manager\DataTablesManager;
31
use WBW\Bundle\JQuery\DataTablesBundle\Provider\DataTablesCSVExporterInterface;
32
use WBW\Bundle\JQuery\DataTablesBundle\Provider\DataTablesEditorInterface;
33
use WBW\Bundle\JQuery\DataTablesBundle\Provider\DataTablesProviderInterface;
34
use WBW\Bundle\JQuery\DataTablesBundle\Repository\DataTablesRepositoryInterface;
35
use WBW\Library\Core\Database\PaginateHelper;
36
use WBW\Library\Core\Model\Response\ActionResponse;
37
38
/**
39
 * Abstract jQuery DataTables controller.
40
 *
41
 * @author webeweb <https://github.com/webeweb/>
42
 * @package WBW\Bundle\JQuery\DataTablesBundle\Controller
43
 * @abstract
44
 */
45
abstract class AbstractDataTablesController extends AbstractBootstrapController {
46
47
    /**
48
     * Build a response.
49
     *
50
     * @param Request $request The request.
51
     * @param string $name The provider name.
52
     * @param array $output The output.
53
     * @return Response Returns the response.
54
     */
55
    protected function buildDataTablesResponse(Request $request, $name, ActionResponse $output) {
56
57
        // Determines if the request is an XML HTTP request.
58
        if (true === $request->isXmlHttpRequest()) {
59
60
            // Return the response.
61
            return new JsonResponse($output);
62
        }
63
64
        // Notify the user.
65
        switch ($output->getStatus()) {
66
67
            case 200:
68
                $this->notifySuccess($output->getNotify());
69
                break;
70
71
            case 404:
72
                $this->notifyDanger($output->getNotify());
73
                break;
74
75
            case 500:
76
                $this->notifyWarning($output->getNotify());
77
                break;
78
        }
79
80
        // Return the response.
81
        return $this->redirectToRoute("jquery_datatables_index", ["name" => $name]);
82
    }
83
84
    /**
85
     * Export callback.
86
     *
87
     * @param DataTablesProviderInterface $dtProvider The provider.
88
     * @param DataTablesRepositoryInterface $repository The repository.
89
     * @param DataTablesCSVExporterInterface $dtExporter The exporter.
90
     * @return void
91
     */
92
    protected function exportCallback(DataTablesProviderInterface $dtProvider, DataTablesRepositoryInterface $repository, DataTablesCSVExporterInterface $dtExporter) {
93
94
        // Get the entities manager.
95
        $em = $this->getDoctrine()->getManager();
96
97
        // Open the file.
98
        $stream = fopen("php://output", "w+");
99
100
        // Export the columns.
101
        fputcsv($stream, $dtExporter->exportColumns(), ";");
102
103
        // Paginates.
104
        $total = $repository->dataTablesCountExported($dtProvider);
105
        $pages = PaginateHelper::getPagesCount($total, DataTablesRepositoryInterface::REPOSITORY_LIMIT);
106
107
        // Handle each page.
108
        for ($i = 0; $i < $pages; ++$i) {
109
110
            // Get the offset and limit.
111
            list($offset, $limit) = PaginateHelper::getPageOffsetAndLimit($i, DataTablesRepositoryInterface::REPOSITORY_LIMIT, $total);
112
113
            // Get the export query with offset and limit.
114
            $result = $repository->dataTablesExportAll($dtProvider)
115
                ->setFirstResult($offset)
116
                ->setMaxResults($limit)
117
                ->getQuery()
118
                ->iterate();
119
120
            // Handle each entity.
121
            while (false !== ($row = $result->next())) {
122
123
                // Export the entity.
124
                fputcsv($stream, $dtExporter->exportRow($row[0]), ";");
125
126
                // Detach the entity to avoid memory consumption.
127
                $em->detach($row[0]);
128
            }
129
        }
130
        // Close the file.
131
        fclose($stream);
132
    }
133
134
    /**
135
     * Get a column.
136
     *
137
     * @param DataTableProviderInterface $dtProvider The provider.
138
     * @param string $data The data.
139
     * @return DataTablesColumn Returns the column.
140
     * @throws BadDataTablesColumnException Throws a bad column exception.
141
     */
142
    protected function getDataTablesColumn(DataTablesProviderInterface $dtProvider, $data) {
143
144
        // Get the column.
145
        $dtColumn = $this->getDataTablesWrapper($dtProvider)->getColumn($data);
146
147
        // Log a debug trace.
148
        $this->getLogger()->debug(sprintf("DataTables controller search for a column with name \"%s\"", $data));
149
150
        // Check the column.
151
        if (null === $dtColumn) {
152
            throw new BadDataTablesColumnException($data);
153
        }
154
155
        // Log a debug trace.
156
        $this->getLogger()->debug(sprintf("DataTables controller found a column with name \"%s\"", $data));
157
158
        // Return the column.
159
        return $dtColumn;
160
    }
161
162
    /**
163
     * Get a CSV exporter.
164
     *
165
     * @param DataTablesProviderInterface $dtProvider The provider.
166
     * @return DataTablesCSVExporterInterface Returns the CSV exporter.
167
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
168
     * @throws BadDataTablesCSVExporterException Throws a bad CSV exporter exception.
169
     */
170
    protected function getDataTablesCSVExporter(DataTablesProviderInterface $dtProvider) {
171
172
        // Get the provider.
173
        $dtExporter = $dtProvider->getCSVExporter();
174
175
        // Log a debug trace.
176
        $this->getLogger()->debug(sprintf("DataTables controller search for a CSV exporter with name \"%s\"", $dtProvider->getName()));
177
178
        // Check the CSV exporter.
179
        if (false === ($dtExporter instanceOf DataTablesCSVExporterInterface)) {
180
            throw new BadDataTablesCSVExporterException(null !== $dtExporter ? $dtExporter : "null");
0 ignored issues
show
Documentation introduced by
null !== $dtExporter ? $dtExporter : 'null' is of type string, but the function expects a object.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
181
        }
182
183
        // Log a debug trace.
184
        $this->getLogger()->debug(sprintf("DataTables controller found a CSV exporter with name \"%s\"", $dtProvider->getName()));
185
186
        // Return the exporter.
187
        return $dtExporter;
188
    }
189
190
    /**
191
     * Get an editor.
192
     *
193
     * @param DataTablesProviderInterface $dtProvider The provider.
194
     * @return DataTablesEditorInterface Returns the editor.
195
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
196
     * @throws BadDataTablesEditorException Throws a bad editor exception.
197
     */
198
    protected function getDataTablesEditor(DataTablesProviderInterface $dtProvider) {
199
200
        // Get the editor.
201
        $dtEditor = $dtProvider->getEditor();
202
203
        // Log a debug trace.
204
        $this->getLogger()->debug(sprintf("DataTables controller search for an editor with name \"%s\"", $dtProvider->getName()));
205
206
        // Check the CSV exporter.
207
        if (false === ($dtEditor instanceOf DataTablesEditorInterface)) {
208
            throw new BadDataTablesEditorException(null !== $dtEditor ? $dtEditor : "null");
0 ignored issues
show
Documentation introduced by
null !== $dtEditor ? $dtEditor : 'null' is of type string, but the function expects a object.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
209
        }
210
211
        // Log a debug trace.
212
        $this->getLogger()->debug(sprintf("DataTables controller found an editor with name \"%s\"", $dtProvider->getName()));
213
214
        // Return the exporter.
215
        return $dtEditor;
216
    }
217
218
    /**
219
     * Get an entity by id.
220
     *
221
     * @param DataTablesProviderInterface $dtProvider The provider.
222
     * @param integer $id The entity id.
223
     * @return object Returns the entity.
224
     * @throws BadDataTablesRepositoryException Throws a bad repository exception.
225
     * @throws EntityNotFoundException Throws an Entity not found exception.
226
     */
227
    protected function getDataTablesEntityById(DataTablesProviderInterface $dtProvider, $id) {
228
229
        // Get the repository.
230
        $repository = $this->getDataTablesRepository($dtProvider);
231
232
        // Log a debug trace.
233
        $this->getLogger()->debug(sprintf("DataTables controller search for an entity [%s]", $id));
234
235
        // Find and check the entity.
236
        $entity = $repository->find($id);
237
        if (null === $entity) {
238
            throw EntityNotFoundException::fromClassNameAndIdentifier($dtProvider->getEntity(), [$id]);
239
        }
240
241
        // Log a debug trace.
242
        $this->getLogger()->debug(sprintf("DataTables controller found an entity [%s]", $id));
243
244
        // Return the entity.
245
        return $entity;
246
    }
247
248
    /**
249
     * Get the provider.
250
     *
251
     * @param string $name The provider name.
252
     * @return DataTablesProviderInterface Returns the provider.
253
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
254
     */
255
    protected function getDataTablesProvider($name) {
256
257
        // Log a debug trace.
258
        $this->getLogger()->debug(sprintf("DataTables controller search for a provider with name \"%s\"", $name));
259
260
        // Get the provider.
261
        $dtProvider = $this->get(DataTablesManager::SERVICE_NAME)->getProvider($name);
262
263
        // Log a debug trace.
264
        $this->getLogger()->debug(sprintf("DataTables controller found a provider with name \"%s\"", $name));
265
266
        // Return the provider.
267
        return $dtProvider;
268
    }
269
270
    /**
271
     * Get a repository.
272
     *
273
     * @param DataTablesProviderInterface $dtProvider The provider.
274
     * @return EntityRepository Returns the repository.
275
     * @throws BadDataTablesRepositoryException Throws a bad repository exception.
276
     */
277
    protected function getDataTablesRepository(DataTablesProviderInterface $dtProvider) {
278
279
        // Log a debug trace.
280
        $this->getLogger()->debug(sprintf("DataTables controller search for a repository with name \"%s\"", $dtProvider->getName()));
281
282
        // Get the entities manager.
283
        $em = $this->getDoctrine()->getManager();
284
285
        // Get and check the entities repository.
286
        $repository = $em->getRepository($dtProvider->getEntity());
287
        if (false === ($repository instanceOf DataTablesRepositoryInterface)) {
288
            throw new BadDataTablesRepositoryException($repository);
289
        }
290
291
        // Return the repository.
292
        return $repository;
293
    }
294
295
    /**
296
     * Get a serializer.
297
     *
298
     * @return Serializer Returns the serializer.
299
     */
300
    protected function getDataTablesSerializer() {
301
        return new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
302
    }
303
304
    /**
305
     * Get a wrapper.
306
     *
307
     * @param DataTablesProviderInterface $dtProvider The provider.
308
     * @return DataTablesWrapper Returns the wrapper.
309
     */
310
    protected function getDataTablesWrapper(DataTablesProviderInterface $dtProvider) {
311
312
        // Initialize the URL.
313
        $url = $this->getRouter()->generate("jquery_datatables_index", ["name" => $dtProvider->getName()]);
314
315
        // Initialize the wrapper.
316
        $dtWrapper = new DataTablesWrapper($dtProvider->getMethod(), $url, $dtProvider->getName());
317
        $dtWrapper->getMapping()->setPrefix($dtProvider->getPrefix());
318
319
        // Handle each column.
320
        foreach ($dtProvider->getColumns() as $dtColumn) {
321
322
            // Log a debug trace.
323
            $this->getLogger()->debug(sprintf("DataTables provider add a column \"%s\"", $dtColumn->getData()));
324
325
            // Add.
326
            $dtWrapper->addColumn($dtColumn);
327
        }
328
329
        // Set the options.
330
        if (null !== $dtProvider->getOptions()) {
331
            $dtWrapper->setOptions($dtProvider->getOptions());
332
        }
333
334
        // Return the wrapper.
335
        return $dtWrapper;
336
    }
337
338
    /**
339
     * Get the notification.
340
     *
341
     * @param string $id The notification id.
342
     * @return string Returns the notification.
343
     */
344
    protected function getNotification($id) {
345
        return $this->getTranslator()->trans($id, [], "JQueryDataTablesBundle");
346
    }
347
348
    /**
349
     * Prepare an action response.
350
     *
351
     * @param int $status The status.
352
     * @param string $notify The notify.
353
     * @return ActionResponse Returns the action response.
354
     */
355
    protected function prepareActionResponse($status, $notify) {
356
357
        // Initialize the action response.
358
        $response = new ActionResponse();
359
        $response->setStatus($status);
360
        $response->setNotify($this->getNotification($notify));
361
362
        // Return the action response.
363
        return $response;
364
    }
365
366
}
367