Completed
Push — master ( 2e4c7e...7b5c06 )
by WEBEWEB
27:08 queued 10:25
created

getDataTablesProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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