Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
created

Configurator/AbstractAdminListConfigurator.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\AdminListBundle\AdminList\Configurator;
4
5
use Doctrine\ORM\PersistentCollection;
6
use InvalidArgumentException;
7
use Kunstmaan\AdminListBundle\AdminList\BulkAction\BulkActionInterface;
8
use Kunstmaan\AdminListBundle\AdminList\Field;
9
use Kunstmaan\AdminListBundle\AdminList\FieldAlias;
10
use Kunstmaan\AdminListBundle\AdminList\FilterBuilder;
11
use Kunstmaan\AdminListBundle\AdminList\FilterType\FilterTypeInterface;
12
use Kunstmaan\AdminListBundle\AdminList\ItemAction\ItemActionInterface;
13
use Kunstmaan\AdminListBundle\AdminList\ItemAction\SimpleItemAction;
14
use Kunstmaan\AdminListBundle\AdminList\ListAction\ListActionInterface;
15
use Symfony\Component\Form\AbstractType;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\PropertyAccess\PropertyAccess;
18
19
/**
20
 * Abstract admin list configurator, this implements the most common functionality from the
21
 * AdminListConfiguratorInterface and ExportListConfiguratorInterface
22
 */
23
abstract class AbstractAdminListConfigurator implements AdminListConfiguratorInterface, ExportListConfiguratorInterface
24
{
25
    const SUFFIX_ADD = 'add';
26
    const SUFFIX_EDIT = 'edit';
27
    const SUFFIX_EXPORT = 'export';
28
    const SUFFIX_DELETE = 'delete';
29
    const SUFFIX_VIEW = 'view';
30
31
    /**
32
     * @var Field[]
33
     */
34
    private $fields = [];
35
36
    /**
37
     * @var Field[]
38
     */
39
    private $exportFields = [];
40
41
    /**
42
     * @var ItemActionInterface[]
43
     */
44
    private $itemActions = [];
45
46
    /**
47
     * @var ListActionInterface[]
48
     */
49
    private $listActions = [];
50
51
    /**
52
     * @var BulkActionInterface[]
53
     */
54
    private $bulkActions = [];
55
56
    /**
57
     * @var AbstractType
58
     */
59
    private $type;
60
61
    /**
62
     * @var array
63
     */
64
    private $typeOptions = [];
65
66
    /**
67
     * @var string
68
     */
69
    private $listTemplate = '@KunstmaanAdminList/Default/list.html.twig';
70
71
    /**
72
     * @var string
73
     */
74
    private $addTemplate = '@KunstmaanAdminList/Default/add_or_edit.html.twig';
75
76
    /**
77
     * @var string
78
     */
79
    private $editTemplate = '@KunstmaanAdminList/Default/add_or_edit.html.twig';
80
81
    /**
82
     * @var string
83
     */
84
    private $viewTemplate = '@KunstmaanAdminList/Default/view.html.twig';
85
86
    /**
87
     * @var string
88
     */
89
    private $deleteTemplate = '@KunstmaanAdminList/Default/delete.html.twig';
90
91
    /**
92
     * @var FilterBuilder
93
     */
94
    private $filterBuilder;
95
96
    /**
97
     * @var int
98
     */
99
    protected $page = 1;
100
101
    /**
102
     * @var string
103
     */
104
    protected $orderBy = '';
105
106
    /**
107
     * @var string
108
     */
109
    protected $orderDirection = '';
110
111
    /**
112
     * Return current bundle name.
113
     *
114
     * @return string
115
     */
116
    abstract public function getBundleName();
117
118
    /**
119
     * Return current entity name.
120
     *
121
     * @return string
122
     */
123
    abstract public function getEntityName();
124
125
    /**
126
     * Return default repository name.
127
     *
128
     * @return string
129
     */
130 8
    public function getRepositoryName()
131
    {
132 8
        return sprintf('%s:%s', $this->getBundleName(), $this->getEntityName());
133
    }
134
135
    /**
136
     * Configure the fields you can filter on
137
     */
138
    public function buildFilters()
139
    {
140
    }
141
142
    /**
143
     * Configure the actions for each line
144
     */
145
    public function buildItemActions()
146
    {
147
    }
148
149
    /**
150
     * Configure the actions that can be executed on the whole list
151
     */
152
    public function buildListActions()
153
    {
154
    }
155
156
    /**
157
     * Configure the export fields
158
     */
159 1
    public function buildExportFields()
160
    {
161
        /*
162
         * This is only here to prevent a BC break!!!
163
         *
164
         * Just override this function if you want to set your own fields...
165
         */
166 1
        if (empty($this->fields)) {
167 1
            $this->buildFields();
168
        }
169 1
    }
170
171
    /**
172
     * Build iterator (if needed)
173
     */
174
    public function buildIterator()
175
    {
176
    }
177
178
    /**
179
     * Reset all built members
180
     */
181 1
    public function resetBuilds()
182
    {
183 1
        $this->fields = [];
184 1
        $this->exportFields = [];
185 1
        $this->filterBuilder = null;
186 1
        $this->itemActions = [];
187 1
        $this->listActions = [];
188 1
    }
189
190
    /**
191
     * Configure the types of items you can add
192
     *
193
     * @return array
194
     */
195 1
    public function getAddUrlFor(array $params = [])
196
    {
197 1
        $params = array_merge($params, $this->getExtraParameters());
198
199 1
        $friendlyName = explode('\\', $this->getEntityName());
200 1
        $friendlyName = array_pop($friendlyName);
201 1
        $re = '/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/';
202 1
        $a = preg_split($re, $friendlyName);
203 1
        $superFriendlyName = implode(' ', $a);
204
205
        return [
206
            $superFriendlyName => [
207 1
                'path' => $this->getPathByConvention($this::SUFFIX_ADD),
208 1
                'params' => $params,
209
            ],
210
        ];
211
    }
212
213
    /**
214
     * Get the url to export the listed items
215
     *
216
     * @return array
217
     */
218 1
    public function getExportUrl()
219
    {
220 1
        $params = $this->getExtraParameters();
221
222
        return [
223 1
            'path' => $this->getPathByConvention($this::SUFFIX_EXPORT),
224 1
            'params' => array_merge(['_format' => 'csv'], $params),
225
        ];
226
    }
227
228
    /**
229
     * Get the view url for the given $item
230
     *
231
     * @param object|array $item
232
     *
233
     * @return array
234
     */
235 1
    public function getViewUrlFor($item)
236
    {
237 1
        if (\is_object($item)) {
238 1
            $id = $item->getid();
239
        } else {
240 1
            $id = $item['id'];
241
        }
242 1
        $params = ['id' => $id];
243 1
        $params = array_merge($params, $this->getExtraParameters());
244
245
        return [
246 1
            'path' => $this->getPathByConvention($this::SUFFIX_VIEW),
247 1
            'params' => $params,
248
        ];
249
    }
250
251
    /**
252
     * Return the url to list all the items
253
     *
254
     * @return array
255
     */
256 1
    public function getIndexUrl()
257
    {
258 1
        $params = $this->getExtraParameters();
259
260
        return [
261 1
            'path' => $this->getPathByConvention(),
262 1
            'params' => $params,
263
        ];
264
    }
265
266
    /**
267
     * @param object $entity
268
     *
269
     * @throws InvalidArgumentException
270
     *
271
     * @return string
272
     */
273 3
    public function getAdminType($entity)
274
    {
275 3
        if (null !== $this->type) {
276 1
            return $this->type;
277
        }
278
279 2
        if (method_exists($entity, 'getAdminType')) {
280 1
            return $entity->getAdminType();
281
        }
282
283 1
        throw new InvalidArgumentException('You need to implement the getAdminType method in ' . \get_class($this) . ' or ' . \get_class($entity));
284
    }
285
286
    /**
287
     * @param string $type
288
     *
289
     * @return AbstractAdminListConfigurator
290
     */
291 6
    public function setAdminType($type)
292
    {
293 6
        $this->type = $type;
294
295 6
        return $this;
296
    }
297
298
    /**
299
     * @param array $typeOptions
300
     *
301
     * @return AbstractAdminListConfigurator
302
     */
303 5
    public function setAdminTypeOptions($typeOptions)
304
    {
305 5
        $this->typeOptions = $typeOptions;
306
307 5
        return $this;
308
    }
309
310
    /**
311
     * Return the default form admin type options
312
     *
313
     * @return array
314
     */
315 1
    public function getAdminTypeOptions()
316
    {
317 1
        return $this->typeOptions;
318
    }
319
320
    /**
321
     * @param object|array $item
322
     *
323
     * @return bool
324
     */
325 1
    public function canEdit($item)
326
    {
327 1
        return true;
328
    }
329
330
    /**
331
     * Configure if it's possible to delete the given $item
332
     *
333
     * @param object|array $item
334
     *
335
     * @return bool
336
     */
337 1
    public function canDelete($item)
338
    {
339 1
        return true;
340
    }
341
342
    /**
343
     * Configure if it's possible to add new items
344
     *
345
     * @return bool
346
     */
347 1
    public function canAdd()
348
    {
349 1
        return true;
350
    }
351
352 1
    public function canView($item)
353
    {
354 1
        return false;
355
    }
356
357
    /**
358
     * Configure if it's possible to add new items
359
     *
360
     * @return bool
361
     */
362 1
    public function canExport()
363
    {
364 1
        return false;
365
    }
366
367
    /**
368
     * @param string     $name     The field name
369
     * @param string     $header   The header title
370
     * @param bool       $sort     Sortable column or not
371
     * @param string     $template The template
372
     * @param FieldAlias $alias    The alias
373
     *
374
     * @return AbstractAdminListConfigurator
375
     */
376 8
    public function addField($name, $header, $sort, $template = null, FieldAlias $alias = null)
377
    {
378 8
        $this->fields[] = new Field($name, $header, $sort, $template, $alias);
379
380 8
        return $this;
381
    }
382
383
    /**
384
     * @param string     $name     The field name
385
     * @param string     $header   The header title
386
     * @param string     $template The template
387
     * @param FieldAlias $alias    The alias
388
     *
389
     * @return AbstractAdminListConfigurator
390
     */
391 1
    public function addExportField($name, $header, $template = null, FieldAlias $alias = null)
392
    {
393 1
        $this->exportFields[] = new Field($name, $header, false, $template, $alias);
394
395 1
        return $this;
396
    }
397
398
    /**
399
     * @param string              $columnName The column name
400
     * @param FilterTypeInterface $type       The filter type
401
     * @param string              $filterName The name of the filter
402
     * @param array               $options    Options
403
     *
404
     * @return AbstractAdminListConfigurator
405
     */
406 5
    public function addFilter(
407
        $columnName,
408
        FilterTypeInterface $type = null,
409
        $filterName = null,
410
        array $options = []
411
    ) {
412 5
        $this->getFilterBuilder()->add($columnName, $type, $filterName, $options);
413
414 5
        return $this;
415
    }
416
417
    /**
418
     * @return int
419
     */
420 3
    public function getLimit()
421
    {
422 3
        return 10;
423
    }
424
425
    /**
426
     * @return array
427
     */
428 1
    public function getSortFields()
429
    {
430 1
        $array = [];
431 1
        foreach ($this->getFields() as $field) {
432 1
            if ($field->isSortable()) {
433 1
                $array[] = $field->getName();
434
            }
435
        }
436
437 1
        return $array;
438
    }
439
440
    /**
441
     * @return Field[]
442
     */
443 9
    public function getFields()
444
    {
445 9
        return $this->fields;
446
    }
447
448
    /**
449
     * @return Field[]
450
     */
451 2
    public function getExportFields()
452
    {
453 2
        if (empty($this->exportFields)) {
454 1
            return $this->fields;
455
        }
456
457 1
        return $this->exportFields;
458
    }
459
460
    /**
461
     * @param string   $label          The label, only used when the template equals null
462
     * @param callable $routeGenerator The generator used to generate the url of an item, when generating the item will
463
     *                                 be provided
464
     * @param string   $icon           The icon, only used when the template equals null
465
     * @param string   $template       The template, when not specified the label is shown
466
     *
467
     * @return AbstractAdminListConfigurator
468
     */
469 1
    public function addSimpleItemAction($label, $routeGenerator, $icon, $template = null)
470
    {
471 1
        return $this->addItemAction(new SimpleItemAction($routeGenerator, $icon, $label, $template));
472
    }
473
474
    /**
475
     * @return AbstractAdminListConfigurator
476
     */
477 4
    public function addItemAction(ItemActionInterface $itemAction)
478
    {
479 4
        $this->itemActions[] = $itemAction;
480
481 4
        return $this;
482
    }
483
484
    /**
485
     * @return bool
486
     */
487 1
    public function hasItemActions()
488
    {
489 1
        return !empty($this->itemActions);
490
    }
491
492
    /**
493
     * @return ItemActionInterface[]
494
     */
495 3
    public function getItemActions()
496
    {
497 3
        return $this->itemActions;
498
    }
499
500
    /**
501
     * @return AdminListConfiguratorInterface
502
     */
503 1
    public function addListAction(ListActionInterface $listAction)
504
    {
505 1
        $this->listActions[] = $listAction;
506
507 1
        return $this;
508
    }
509
510
    /**
511
     * @return bool
512
     */
513 1
    public function hasListActions()
514
    {
515 1
        return !empty($this->listActions);
516
    }
517
518
    /**
519
     * @return ListActionInterface[]
520
     */
521 1
    public function getListActions()
522
    {
523 1
        return $this->listActions;
524
    }
525
526
    /**
527
     * @return AdminListConfiguratorInterface
528
     */
529 1
    public function addBulkAction(BulkActionInterface $bulkAction)
530
    {
531 1
        $this->bulkActions[] = $bulkAction;
532
533 1
        return $this;
534
    }
535
536
    /**
537
     * @return bool
538
     */
539 1
    public function hasBulkActions()
540
    {
541 1
        return !empty($this->bulkActions);
542
    }
543
544
    /**
545
     * @return BulkActionInterface[]
546
     */
547 1
    public function getBulkActions()
548
    {
549 1
        return $this->bulkActions;
550
    }
551
552
    /**
553
     * @return string
554
     */
555 2
    public function getListTemplate()
556
    {
557 2
        return $this->listTemplate;
558
    }
559
560
    /**
561
     * @param string $template
562
     *
563
     * @return AdminListConfiguratorInterface
564
     */
565 1
    public function setListTemplate($template)
566
    {
567 1
        $this->listTemplate = $template;
568
569 1
        return $this;
570
    }
571
572
    /**
573
     * @param array|object $item       The item
574
     * @param string       $columnName The column name
575
     *
576
     * @return mixed
577
     */
578 2
    public function getValue($item, $columnName)
579
    {
580 2
        if (\is_array($item)) {
581 2
            if (isset($item[$columnName])) {
582 2
                return $item[$columnName];
583
            }
584
585 1
            return '';
586
        }
587
588 1
        $accessor = PropertyAccess::createPropertyAccessor();
589
590 1
        if ($accessor->isReadable($item, $columnName)) {
591 1
            $result = $accessor->getValue($item, $columnName);
592
        } else {
593 1
            return sprintf('undefined function [get/is/has]%s()', $columnName);
594
        }
595
596 1
        return $result;
597
    }
598
599
    /**
600
     * @param array|object $item       The item
601
     * @param string       $columnName The column name
602
     *
603
     * @return string
604
     */
605 1
    public function getStringValue($item, $columnName)
606
    {
607 1
        $result = $this->getValue($item, $columnName);
608 1
        if (\is_bool($result)) {
609 1
            return $result ? 'true' : 'false';
610
        }
611 1
        if ($result instanceof \DateTimeInterface) {
612 1
            return $result->format('Y-m-d H:i:s');
613
        }
614
615 1
        if ($result instanceof PersistentCollection) {
616 1
            $results = [];
617
            /* @var Object $entry */
618 1
            foreach ($result as $entry) {
619 1
                $results[] = $entry->getName();
620
            }
621 1
            if (empty($results)) {
622 1
                return '';
623
            }
624
625 1
            return implode(', ', $results);
626
        }
627
628 1
        if (is_array($result)) {
629 1
            return implode(', ', $result);
630
        }
631
632 1
        return $result;
633
    }
634
635
    /**
636
     * @return string
637
     */
638 1
    public function getAddTemplate()
639
    {
640 1
        return $this->addTemplate;
641
    }
642
643
    /**
644
     * @param string $template
645
     *
646
     * @return AdminListConfiguratorInterface
647
     */
648 1
    public function setAddTemplate($template)
649
    {
650 1
        $this->addTemplate = $template;
651
652 1
        return $this;
653
    }
654
655
    /**
656
     * @return string
657
     */
658 1
    public function getViewTemplate()
659
    {
660 1
        return $this->viewTemplate;
661
    }
662
663
    /**
664
     * @param string $template
665
     *
666
     * @return AdminListConfiguratorInterface
667
     */
668 1
    public function setViewTemplate($template)
669
    {
670 1
        $this->viewTemplate = $template;
671
672 1
        return $this;
673
    }
674
675
    /**
676
     * @return string
677
     */
678 1
    public function getEditTemplate()
679
    {
680 1
        return $this->editTemplate;
681
    }
682
683
    /**
684
     * @param string $template
685
     *
686
     * @return AdminListConfiguratorInterface
687
     */
688 1
    public function setEditTemplate($template)
689
    {
690 1
        $this->editTemplate = $template;
691
692 1
        return $this;
693
    }
694
695
    /**
696
     * @return string
697
     */
698 1
    public function getDeleteTemplate()
699
    {
700 1
        return $this->deleteTemplate;
701
    }
702
703
    /**
704
     * @param string $template
705
     *
706
     * @return AdminListConfiguratorInterface
707
     */
708 1
    public function setDeleteTemplate($template)
709
    {
710 1
        $this->deleteTemplate = $template;
711
712 1
        return $this;
713
    }
714
715
    /**
716
     * You can override this method to do some custom things you need to do when adding an entity
717
     *
718
     * @param object $entity
719
     *
720
     * @return mixed
721
     */
722 1
    public function decorateNewEntity($entity)
723
    {
724 1
        return $entity;
725
    }
726
727
    /**
728
     * @return FilterBuilder
729
     */
730 10
    public function getFilterBuilder()
731
    {
732 10
        if (\is_null($this->filterBuilder)) {
733 9
            $this->filterBuilder = new FilterBuilder();
734
        }
735
736 10
        return $this->filterBuilder;
737
    }
738
739
    /**
740
     * @return AbstractAdminListConfigurator
741
     */
742 2
    public function setFilterBuilder(FilterBuilder $filterBuilder)
743
    {
744 2
        $this->filterBuilder = $filterBuilder;
745
746 2
        return $this;
747
    }
748
749
    /**
750
     * Bind current request.
751
     */
752 4
    public function bindRequest(Request $request)
753
    {
754 4
        $query = $request->query;
755 4
        $session = $request->getSession();
756
757 4
        $adminListName = 'listconfig_' . $request->get('_route');
758
759 4
        $this->page = $request->query->getInt('page', 1);
760
        // Allow alphanumeric, _ & . in order by parameter!
761 4
        $this->orderBy = preg_replace('/[^[a-zA-Z0-9\_\.]]/', '', $request->query->get('orderBy', ''));
762 4
        $this->orderDirection = $request->query->getAlpha('orderDirection');
763
764
        // there is a session and the filter param is not set
765 4 View Code Duplication
        if ($session->has($adminListName) && !$query->has('filter')) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
766 3
            $adminListSessionData = $request->getSession()->get($adminListName);
767 3
            if (!$query->has('page')) {
768 1
                $this->page = $adminListSessionData['page'];
769
            }
770
771 3
            if (!$query->has('orderBy')) {
772 3
                $this->orderBy = $adminListSessionData['orderBy'];
773
            }
774
775 3
            if (!$query->has('orderDirection')) {
776 3
                $this->orderDirection = $adminListSessionData['orderDirection'];
777
            }
778
        }
779
780
        // save current parameters
781 4
        $session->set(
782 4
            $adminListName,
783
            [
784 4
                'page' => $this->page,
785 4
                'orderBy' => $this->orderBy,
786 4
                'orderDirection' => $this->orderDirection,
787
            ]
788
        );
789
790 4
        $this->getFilterBuilder()->bindRequest($request);
791 4
    }
792
793
    /**
794
     * Return current page.
795
     *
796
     * @return int
797
     */
798 3
    public function getPage()
799
    {
800 3
        return $this->page;
801
    }
802
803
    /**
804
     * Return current sorting column.
805
     *
806
     * @return string
807
     */
808 1
    public function getOrderBy()
809
    {
810 1
        return $this->orderBy;
811
    }
812
813
    /**
814
     * Return current sorting direction.
815
     *
816
     * @return string
817
     */
818 1
    public function getOrderDirection()
819
    {
820 1
        return $this->orderDirection;
821
    }
822
823
    /**
824
     * @param string $suffix
825
     *
826
     * @return string
827
     */
828 9
    public function getPathByConvention($suffix = null)
829
    {
830 9
        $entityName = strtolower($this->getEntityName());
831 9
        $entityName = str_replace('\\', '_', $entityName);
832 9
        if (empty($suffix)) {
833 1
            return sprintf('%s_admin_%s', strtolower($this->getBundleName()), $entityName);
834
        }
835
836 8
        return sprintf('%s_admin_%s_%s', strtolower($this->getBundleName()), $entityName, $suffix);
837
    }
838
839
    /**
840
     * Get controller path.
841
     *
842
     * @return string
843
     */
844 1
    public function getControllerPath()
845
    {
846 1
        return sprintf('%s:%s', $this->getBundleName(), $this->getEntityName());
847
    }
848
849
    /**
850
     * Return extra parameters for use in list actions.
851
     *
852
     * @return array
853
     */
854 9
    public function getExtraParameters()
855
    {
856 9
        return [];
857
    }
858
}
859