Completed
Push — master ( 59e7df...065c0e )
by WEBEWEB
01:51
created

dispatchDataTablesEvent()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 3
nc 2
nop 2
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\EventDispatcher\Event;
17
use Symfony\Component\HttpFoundation\JsonResponse;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\Serializer\Encoder\JsonEncoder;
21
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
22
use Symfony\Component\Serializer\Serializer;
23
use WBW\Bundle\BootstrapBundle\Controller\AbstractController;
24
use WBW\Bundle\JQuery\DataTablesBundle\API\DataTablesColumnInterface;
25
use WBW\Bundle\JQuery\DataTablesBundle\API\DataTablesWrapperInterface;
26
use WBW\Bundle\JQuery\DataTablesBundle\Event\DataTablesEvent;
27
use WBW\Bundle\JQuery\DataTablesBundle\Event\DataTablesEvents;
28
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesColumnException;
29
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesCSVExporterException;
30
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesEditorException;
31
use WBW\Bundle\JQuery\DataTablesBundle\Exception\BadDataTablesRepositoryException;
32
use WBW\Bundle\JQuery\DataTablesBundle\Exception\UnregisteredDataTablesProviderException;
33
use WBW\Bundle\JQuery\DataTablesBundle\Factory\DataTablesFactory;
34
use WBW\Bundle\JQuery\DataTablesBundle\Manager\DataTablesManager;
35
use WBW\Bundle\JQuery\DataTablesBundle\Provider\DataTablesCSVExporterInterface;
36
use WBW\Bundle\JQuery\DataTablesBundle\Provider\DataTablesEditorInterface;
37
use WBW\Bundle\JQuery\DataTablesBundle\Provider\DataTablesProviderInterface;
38
use WBW\Bundle\JQuery\DataTablesBundle\Repository\DataTablesRepositoryInterface;
39
use WBW\Library\Core\Database\PaginateHelper;
40
use WBW\Library\Core\Model\Response\ActionResponse;
41
42
/**
43
 * Abstract jQuery DataTables controller.
44
 *
45
 * @author webeweb <https://github.com/webeweb/>
46
 * @package WBW\Bundle\JQuery\DataTablesBundle\Controller
47
 * @abstract
48
 */
49
abstract class AbstractDataTablesController extends AbstractController {
50
51
    /**
52
     * Build a response.
53
     *
54
     * @param Request $request The request.
55
     * @param string $name The provider name.
56
     * @param ActionResponse $output The output.
57
     * @return Response Returns the response.
58
     */
59
    protected function buildDataTablesResponse(Request $request, $name, ActionResponse $output) {
60
61
        // Determines if the request is an XML HTTP request.
62
        if (true === $request->isXmlHttpRequest()) {
63
64
            // Return the response.
65
            return new JsonResponse($output);
66
        }
67
68
        // Notify the user.
69
        switch ($output->getStatus()) {
70
71
            case 200:
72
                $this->notifySuccess($output->getNotify());
73
                break;
74
75
            case 404:
76
                $this->notifyDanger($output->getNotify());
77
                break;
78
79
            case 500:
80
                $this->notifyWarning($output->getNotify());
81
                break;
82
        }
83
84
        // Return the response.
85
        return $this->redirectToRoute("jquery_datatables_index", ["name" => $name]);
86
    }
87
88
    /**
89
     * Dispatch an event.
90
     *
91
     * @param string $eventName The event name.
92
     * @param array $entities The entities.
93
     * @return Event Returns the event in case of succes, null otherwise.
94
     */
95
    protected function dispatchDataTablesEvent($eventName, array $entities) {
96
97
        // Get and check the event dispatcher.
98
        $eventDispatcher = $this->getEventDispatcher();
99
        if (null !== $eventDispatcher && false === $eventDispatcher->hasListeners($eventName)) {
100
            return null;
101
        }
102
103
        // Dispatch the event.
104
        return $eventDispatcher->dispatch($eventName, new DataTablesEvent($eventName, $entities));
105
    }
106
107
    /**
108
     * Export callback.
109
     *
110
     * @param DataTablesProviderInterface $dtProvider The provider.
111
     * @param DataTablesRepositoryInterface $repository The repository.
112
     * @param DataTablesCSVExporterInterface $dtExporter The exporter.
113
     * @return void
114
     */
115
    protected function exportCallback(DataTablesProviderInterface $dtProvider, DataTablesRepositoryInterface $repository, DataTablesCSVExporterInterface $dtExporter) {
116
117
        // Get the entities manager.
118
        $em = $this->getDoctrine()->getManager();
119
120
        // Open the file.
121
        $stream = fopen("php://output", "w+");
122
123
        // Export the columns.
124
        fputcsv($stream, $dtExporter->exportColumns(), ";");
125
126
        // Paginates.
127
        $total = $repository->dataTablesCountExported($dtProvider);
128
        $pages = PaginateHelper::getPagesCount($total, DataTablesRepositoryInterface::REPOSITORY_LIMIT);
129
130
        // Handle each page.
131
        for ($i = 0; $i < $pages; ++$i) {
132
133
            // Get the offset and limit.
134
            list($offset, $limit) = PaginateHelper::getPageOffsetAndLimit($i, DataTablesRepositoryInterface::REPOSITORY_LIMIT, $total);
135
136
            // Get the export query with offset and limit.
137
            $result = $repository->dataTablesExportAll($dtProvider)
138
                ->setFirstResult($offset)
139
                ->setMaxResults($limit)
140
                ->getQuery()
141
                ->iterate();
142
143
            // Handle each entity.
144
            while (false !== ($row = $result->next())) {
145
146
                // Dispatch an event.
147
                $this->dispatchDataTablesEvent(DataTablesEvents::DATATABLES_PRE_EXPORT, [$row[0]]);
148
149
                // Export the entity.
150
                fputcsv($stream, $dtExporter->exportRow($row[0]), ";");
151
152
                // Detach the entity to avoid memory consumption.
153
                $em->detach($row[0]);
154
155
                // Dispatch an event.
156
                $this->dispatchDataTablesEvent(DataTablesEvents::DATATABLES_PRE_EXPORT, [$row[0]]);
157
            }
158
        }
159
160
        // Close the file.
161
        fclose($stream);
162
    }
163
164
    /**
165
     * Get a column.
166
     *
167
     * @param DataTablesProviderInterface $dtProvider The provider.
168
     * @param string $data The data.
169
     * @return DataTablesColumnInterface Returns the column.
170
     * @throws BadDataTablesColumnException Throws a bad column exception.
171
     */
172
    protected function getDataTablesColumn(DataTablesProviderInterface $dtProvider, $data) {
173
174
        // Get the column.
175
        $dtColumn = $this->getDataTablesWrapper($dtProvider)->getColumn($data);
176
177
        // Log a debug trace.
178
        $this->getLogger()->debug(sprintf("DataTables controller search for a column with name \"%s\"", $data));
179
180
        // Check the column.
181
        if (null === $dtColumn) {
182
            throw new BadDataTablesColumnException($data);
183
        }
184
185
        // Log a debug trace.
186
        $this->getLogger()->debug(sprintf("DataTables controller found a column with name \"%s\"", $data));
187
188
        // Return the column.
189
        return $dtColumn;
190
    }
191
192
    /**
193
     * Get a CSV exporter.
194
     *
195
     * @param DataTablesProviderInterface $dtProvider The provider.
196
     * @return DataTablesCSVExporterInterface Returns the CSV exporter.
197
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
198
     * @throws BadDataTablesCSVExporterException Throws a bad CSV exporter exception.
199
     */
200
    protected function getDataTablesCSVExporter(DataTablesProviderInterface $dtProvider) {
201
202
        // Get the provider.
203
        $dtExporter = $dtProvider->getCSVExporter();
204
205
        // Log a debug trace.
206
        $this->getLogger()->debug(sprintf("DataTables controller search for a CSV exporter with name \"%s\"", $dtProvider->getName()));
207
208
        // Check the CSV exporter.
209
        if (false === ($dtExporter instanceOf DataTablesCSVExporterInterface)) {
210
            throw new BadDataTablesCSVExporterException($dtExporter);
211
        }
212
213
        // Log a debug trace.
214
        $this->getLogger()->debug(sprintf("DataTables controller found a CSV exporter with name \"%s\"", $dtProvider->getName()));
215
216
        // Return the exporter.
217
        return $dtExporter;
218
    }
219
220
    /**
221
     * Get an editor.
222
     *
223
     * @param DataTablesProviderInterface $dtProvider The provider.
224
     * @return DataTablesEditorInterface Returns the editor.
225
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
226
     * @throws BadDataTablesEditorException Throws a bad editor exception.
227
     */
228
    protected function getDataTablesEditor(DataTablesProviderInterface $dtProvider) {
229
230
        // Get the editor.
231
        $dtEditor = $dtProvider->getEditor();
232
233
        // Log a debug trace.
234
        $this->getLogger()->debug(sprintf("DataTables controller search for an editor with name \"%s\"", $dtProvider->getName()));
235
236
        // Check the CSV exporter.
237
        if (false === ($dtEditor instanceOf DataTablesEditorInterface)) {
238
            throw new BadDataTablesEditorException($dtEditor);
239
        }
240
241
        // Log a debug trace.
242
        $this->getLogger()->debug(sprintf("DataTables controller found an editor with name \"%s\"", $dtProvider->getName()));
243
244
        // Return the exporter.
245
        return $dtEditor;
246
    }
247
248
    /**
249
     * Get an entity by id.
250
     *
251
     * @param DataTablesProviderInterface $dtProvider The provider.
252
     * @param int $id The entity id.
253
     * @return object Returns the entity.
254
     * @throws BadDataTablesRepositoryException Throws a bad repository exception.
255
     * @throws EntityNotFoundException Throws an Entity not found exception.
256
     */
257
    protected function getDataTablesEntityById(DataTablesProviderInterface $dtProvider, $id) {
258
259
        // Get the repository.
260
        $repository = $this->getDataTablesRepository($dtProvider);
261
262
        // Log a debug trace.
263
        $this->getLogger()->debug(sprintf("DataTables controller search for an entity [%s]", $id));
264
265
        // Find and check the entity.
266
        $entity = $repository->find($id);
267
        if (null === $entity) {
268
            throw EntityNotFoundException::fromClassNameAndIdentifier($dtProvider->getEntity(), [$id]);
269
        }
270
271
        // Log a debug trace.
272
        $this->getLogger()->debug(sprintf("DataTables controller found an entity [%s]", $id));
273
274
        // Return the entity.
275
        return $entity;
276
    }
277
278
    /**
279
     * Get the manager.
280
     *
281
     * @return DataTablesManager Returns the manager.
282
     */
283
    protected function getDataTablesManager() {
284
        return $this->get(DataTablesManager::SERVICE_NAME);
285
    }
286
287
    /**
288
     * Get the provider.
289
     *
290
     * @param string $name The provider name.
291
     * @return DataTablesProviderInterface Returns the provider.
292
     * @throws UnregisteredDataTablesProviderException Throws an unregistered provider exception.
293
     */
294
    protected function getDataTablesProvider($name) {
295
296
        // Log a debug trace.
297
        $this->getLogger()->debug(sprintf("DataTables controller search for a provider with name \"%s\"", $name));
298
299
        // Get the provider.
300
        $dtProvider = $this->getDataTablesManager()->getProvider($name);
301
302
        // Log a debug trace.
303
        $this->getLogger()->debug(sprintf("DataTables controller found a provider with name \"%s\"", $name));
304
305
        // Return the provider.
306
        return $dtProvider;
307
    }
308
309
    /**
310
     * Get a repository.
311
     *
312
     * @param DataTablesProviderInterface $dtProvider The provider.
313
     * @return EntityRepository Returns the repository.
314
     * @throws BadDataTablesRepositoryException Throws a bad repository exception.
315
     */
316
    protected function getDataTablesRepository(DataTablesProviderInterface $dtProvider) {
317
318
        // Log a debug trace.
319
        $this->getLogger()->debug(sprintf("DataTables controller search for a repository with name \"%s\"", $dtProvider->getName()));
320
321
        // Get the entities manager.
322
        $em = $this->getDoctrine()->getManager();
323
324
        // Get and check the entities repository.
325
        $repository = $em->getRepository($dtProvider->getEntity());
326
        if (false === ($repository instanceOf DataTablesRepositoryInterface)) {
327
            throw new BadDataTablesRepositoryException($repository);
328
        }
329
330
        // Return the repository.
331
        return $repository;
332
    }
333
334
    /**
335
     * Get a serializer.
336
     *
337
     * @return Serializer Returns the serializer.
338
     */
339
    protected function getDataTablesSerializer() {
340
        return new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
341
    }
342
343
    /**
344
     * Get a wrapper.
345
     *
346
     * @param DataTablesProviderInterface $dtProvider The provider.
347
     * @return DataTablesWrapperInterface Returns the wrapper.
348
     */
349
    protected function getDataTablesWrapper(DataTablesProviderInterface $dtProvider) {
350
351
        // Initialize the URL.
352
        $url = $this->getRouter()->generate("jquery_datatables_index", ["name" => $dtProvider->getName()]);
353
354
        // Initialize the wrapper.
355
        $dtWrapper = DataTablesFactory::newWrapper($url, $dtProvider);
356
357
        // Handle each column.
358
        foreach ($dtProvider->getColumns() as $dtColumn) {
359
360
            // Log a debug trace.
361
            $this->getLogger()->debug(sprintf("DataTables provider add a column \"%s\"", $dtColumn->getData()));
362
363
            // Add the column.
364
            $dtWrapper->addColumn($dtColumn);
365
        }
366
367
        // Set the options.
368
        if (null !== $dtProvider->getOptions()) {
369
            $dtWrapper->setOptions($dtProvider->getOptions());
370
        }
371
372
        // Return the wrapper.
373
        return $dtWrapper;
374
    }
375
376
    /**
377
     * Get the notification.
378
     *
379
     * @param string $id The notification id.
380
     * @return string Returns the notification.
381
     */
382
    protected function getNotification($id) {
383
        return $this->getTranslator()->trans($id, [], "JQueryDataTablesBundle");
384
    }
385
386
    /**
387
     * Prepare an action response.
388
     *
389
     * @param int $status The status.
390
     * @param string $notify The notify.
391
     * @return ActionResponse Returns the action response.
392
     */
393
    protected function prepareActionResponse($status, $notify) {
394
395
        // Initialize the action response.
396
        $response = new ActionResponse();
397
        $response->setStatus($status);
398
        $response->setNotify($this->getNotification($notify));
399
400
        // Return the action response.
401
        return $response;
402
    }
403
404
}
405