Completed
Push — master ( e6c0c9...d841f8 )
by Jeroen
35:52 queued 19:21
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 = array();
35
36
    /**
37
     * @var Field[]
38
     */
39
    private $exportFields = array();
40
41
    /**
42
     * @var ItemActionInterface[]
43
     */
44
    private $itemActions = array();
45
46
    /**
47
     * @var ListActionInterface[]
48
     */
49
    private $listActions = array();
50
51
    /**
52
     * @var BulkActionInterface[]
53
     */
54
    private $bulkActions = array();
55
56
    /**
57
     * @var AbstractType
58
     */
59
    private $type = null;
60
61
    /**
62
     * @var array
63
     */
64
    private $typeOptions = array();
65
66
    /**
67
     * @var string
68
     */
69
    private $listTemplate = 'KunstmaanAdminListBundle:Default:list.html.twig';
70
71
    /**
72
     * @var string
73
     */
74
    private $addTemplate = 'KunstmaanAdminListBundle:Default:add_or_edit.html.twig';
75
76
    /**
77
     * @var string
78
     */
79
    private $editTemplate = 'KunstmaanAdminListBundle:Default:add_or_edit.html.twig';
80
81
    /**
82
     * @var string
83
     */
84
    private $viewTemplate = 'KunstmaanAdminListBundle:Default:view.html.twig';
85
86
    /**
87
     * @var string
88
     */
89
    private $deleteTemplate = 'KunstmaanAdminListBundle:Default:delete.html.twig';
90
91
    /**
92
     * @var FilterBuilder
93
     */
94
    private $filterBuilder = null;
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 = array();
184 1
        $this->exportFields = array();
185 1
        $this->filterBuilder = null;
186 1
        $this->itemActions = array();
187 1
        $this->listActions = array();
188 1
    }
189
190
    /**
191
     * Configure the types of items you can add
192
     *
193
     * @param array $params
194
     *
195
     * @return array
196
     */
197 1
    public function getAddUrlFor(array $params = array())
198
    {
199 1
        $params = array_merge($params, $this->getExtraParameters());
200
201 1
        $friendlyName = explode('\\', $this->getEntityName());
202 1
        $friendlyName = array_pop($friendlyName);
203 1
        $re = '/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/';
204 1
        $a = preg_split($re, $friendlyName);
205 1
        $superFriendlyName = implode(' ', $a);
206
207
        return array(
208
            $superFriendlyName => array(
209 1
                'path' => $this->getPathByConvention($this::SUFFIX_ADD),
210 1
                'params' => $params,
211
            ),
212
        );
213
    }
214
215
    /**
216
     * Get the url to export the listed items
217
     *
218
     * @return array
219
     */
220 1
    public function getExportUrl()
221
    {
222 1
        $params = $this->getExtraParameters();
223
224
        return array(
225 1
            'path' => $this->getPathByConvention($this::SUFFIX_EXPORT),
226 1
            'params' => array_merge(array('_format' => 'csv'), $params),
227
        );
228
    }
229
230
    /**
231
     * Get the view url for the given $item
232
     *
233
     * @param object|array $item
234
     *
235
     * @return array
236
     */
237 1
    public function getViewUrlFor($item)
238
    {
239 1
        if (is_object($item)) {
240 1
            $id = $item->getid();
241
        } else {
242 1
            $id = $item['id'];
243
        }
244 1
        $params = ['id' => $id];
245 1
        $params = array_merge($params, $this->getExtraParameters());
246
247
        return [
248 1
            'path' => $this->getPathByConvention($this::SUFFIX_VIEW),
249 1
            'params' => $params,
250
        ];
251
    }
252
253
    /**
254
     * Return the url to list all the items
255
     *
256
     * @return array
257
     */
258 1
    public function getIndexUrl()
259
    {
260 1
        $params = $this->getExtraParameters();
261
262
        return array(
263 1
            'path' => $this->getPathByConvention(),
264 1
            'params' => $params,
265
        );
266
    }
267
268
    /**
269
     * @param object $entity
270
     *
271
     * @throws InvalidArgumentException
272
     *
273
     * @return string
274
     */
275 3
    public function getAdminType($entity)
276
    {
277 3
        if (null !== $this->type) {
278 1
            return $this->type;
279
        }
280
281 2
        if (method_exists($entity, 'getAdminType')) {
282 1
            return $entity->getAdminType();
283
        }
284
285 1
        throw new InvalidArgumentException(
286
            'You need to implement the getAdminType method in '.
287 1
            get_class($this).' or '.get_class($entity)
288
        );
289
    }
290
291
    /**
292
     * @param string $type
293
     *
294
     * @return AbstractAdminListConfigurator
295
     */
296 6
    public function setAdminType($type)
297
    {
298 6
        $this->type = $type;
299
300 6
        return $this;
301
    }
302
303
    /**
304
     * @param array $typeOptions
305
     *
306
     * @return AbstractAdminListConfigurator
307
     */
308 5
    public function setAdminTypeOptions($typeOptions)
309
    {
310 5
        $this->typeOptions = $typeOptions;
311
312 5
        return $this;
313
    }
314
315
    /**
316
     * Return the default form admin type options
317
     *
318
     * @return array
319
     */
320 1
    public function getAdminTypeOptions()
321
    {
322 1
        return $this->typeOptions;
323
    }
324
325
    /**
326
     * @param object|array $item
327
     *
328
     * @return bool
329
     */
330 1
    public function canEdit($item)
331
    {
332 1
        return true;
333
    }
334
335
    /**
336
     * Configure if it's possible to delete the given $item
337
     *
338
     * @param object|array $item
339
     *
340
     * @return bool
341
     */
342 1
    public function canDelete($item)
343
    {
344 1
        return true;
345
    }
346
347
    /**
348
     * Configure if it's possible to add new items
349
     *
350
     * @return bool
351
     */
352 1
    public function canAdd()
353
    {
354 1
        return true;
355
    }
356
357 1
    public function canView($item)
358
    {
359 1
        return false;
360
    }
361
362
    /**
363
     * Configure if it's possible to add new items
364
     *
365
     * @return bool
366
     */
367 1
    public function canExport()
368
    {
369 1
        return false;
370
    }
371
372
    /**
373
     * @param string     $name     The field name
374
     * @param string     $header   The header title
375
     * @param string     $sort     Sortable column or not
376
     * @param string     $template The template
377
     * @param FieldAlias $alias    The alias
378
     *
379
     * @return AbstractAdminListConfigurator
380
     */
381 8
    public function addField($name, $header, $sort, $template = null, FieldAlias $alias = null)
382
    {
383 8
        $this->fields[] = new Field($name, $header, $sort, $template, $alias);
0 ignored issues
show
$sort is of type string, but the function expects a boolean.

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...
384
385 8
        return $this;
386
    }
387
388
    /**
389
     * @param string     $name     The field name
390
     * @param string     $header   The header title
391
     * @param string     $template The template
392
     * @param FieldAlias $alias    The alias
393
     *
394
     * @return AbstractAdminListConfigurator
395
     */
396 1
    public function addExportField($name, $header, $template = null, FieldAlias $alias = null)
397
    {
398 1
        $this->exportFields[] = new Field($name, $header, false, $template, $alias);
399
400 1
        return $this;
401
    }
402
403
    /**
404
     * @param string              $columnName The column name
405
     * @param FilterTypeInterface $type       The filter type
406
     * @param string              $filterName The name of the filter
407
     * @param array               $options    Options
408
     *
409
     * @return AbstractAdminListConfigurator
410
     */
411 5
    public function addFilter(
412
        $columnName,
413
        FilterTypeInterface $type = null,
414
        $filterName = null,
415
        array $options = array()
416
    ) {
417 5
        $this->getFilterBuilder()->add($columnName, $type, $filterName, $options);
418
419 5
        return $this;
420
    }
421
422
    /**
423
     * @return int
424
     */
425 3
    public function getLimit()
426
    {
427 3
        return 10;
428
    }
429
430
    /**
431
     * @return array
432
     */
433 1
    public function getSortFields()
434
    {
435 1
        $array = array();
436 1
        foreach ($this->getFields() as $field) {
437 1
            if ($field->isSortable()) {
438 1
                $array[] = $field->getName();
439
            }
440
        }
441
442 1
        return $array;
443
    }
444
445
    /**
446
     * @return Field[]
447
     */
448 9
    public function getFields()
449
    {
450 9
        return $this->fields;
451
    }
452
453
    /**
454
     * @return Field[]
455
     */
456 2
    public function getExportFields()
457
    {
458 2
        if (empty($this->exportFields)) {
459 1
            return $this->fields;
460
        } else {
461 1
            return $this->exportFields;
462
        }
463
    }
464
465
    /**
466
     * @param string   $label          The label, only used when the template equals null
467
     * @param callable $routeGenerator The generator used to generate the url of an item, when generating the item will
468
     *                                 be provided
469
     * @param string   $icon           The icon, only used when the template equals null
470
     * @param string   $template       The template, when not specified the label is shown
471
     *
472
     * @return AbstractAdminListConfigurator
473
     */
474 1
    public function addSimpleItemAction($label, $routeGenerator, $icon, $template = null)
475
    {
476 1
        return $this->addItemAction(new SimpleItemAction($routeGenerator, $icon, $label, $template));
477
    }
478
479
    /**
480
     * @param ItemActionInterface $itemAction
481
     *
482
     * @return AbstractAdminListConfigurator
483
     */
484 4
    public function addItemAction(ItemActionInterface $itemAction)
485
    {
486 4
        $this->itemActions[] = $itemAction;
487
488 4
        return $this;
489
    }
490
491
    /**
492
     * @return bool
493
     */
494 1
    public function hasItemActions()
495
    {
496 1
        return !empty($this->itemActions);
497
    }
498
499
    /**
500
     * @return ItemActionInterface[]
501
     */
502 3
    public function getItemActions()
503
    {
504 3
        return $this->itemActions;
505
    }
506
507
    /**
508
     * @param ListActionInterface $listAction
509
     *
510
     * @return AdminListConfiguratorInterface
511
     */
512 1
    public function addListAction(ListActionInterface $listAction)
513
    {
514 1
        $this->listActions[] = $listAction;
515
516 1
        return $this;
517
    }
518
519
    /**
520
     * @return bool
521
     */
522 1
    public function hasListActions()
523
    {
524 1
        return !empty($this->listActions);
525
    }
526
527
    /**
528
     * @return ListActionInterface[]
529
     */
530 1
    public function getListActions()
531
    {
532 1
        return $this->listActions;
533
    }
534
535
    /**
536
     * @param BulkActionInterface $bulkAction
537
     *
538
     * @return AdminListConfiguratorInterface
539
     */
540 1
    public function addBulkAction(BulkActionInterface $bulkAction)
541
    {
542 1
        $this->bulkActions[] = $bulkAction;
543
544 1
        return $this;
545
    }
546
547
    /**
548
     * @return bool
549
     */
550 1
    public function hasBulkActions()
551
    {
552 1
        return !empty($this->bulkActions);
553
    }
554
555
    /**
556
     * @return BulkActionInterface[]
557
     */
558 1
    public function getBulkActions()
559
    {
560 1
        return $this->bulkActions;
561
    }
562
563
    /**
564
     * @return string
565
     */
566 2
    public function getListTemplate()
567
    {
568 2
        return $this->listTemplate;
569
    }
570
571
    /**
572
     * @param string $template
573
     *
574
     * @return AdminListConfiguratorInterface
575
     */
576 1
    public function setListTemplate($template)
577
    {
578 1
        $this->listTemplate = $template;
579
580 1
        return $this;
581
    }
582
583
    /**
584
     * @param array|object $item       The item
585
     * @param string       $columnName The column name
586
     *
587
     * @return mixed
588
     */
589 2
    public function getValue($item, $columnName)
590
    {
591 2
        if (is_array($item)) {
592 2
            if (isset($item[$columnName])) {
593 2
                return $item[$columnName];
594
            } else {
595 1
                return '';
596
            }
597
        }
598
599 1
        $accessor = PropertyAccess::createPropertyAccessor();
600
601 1
        if ($accessor->isReadable($item, $columnName)) {
602 1
            $result = $accessor->getValue($item, $columnName);
603
        } else {
604 1
            return sprintf('undefined function [get/is/has]%s()', $columnName);
605
        }
606
607 1
        return $result;
608
    }
609
610
    /**
611
     * @param array|object $item       The item
612
     * @param string       $columnName The column name
613
     *
614
     * @return string
615
     */
616 1
    public function getStringValue($item, $columnName)
617
    {
618 1
        $result = $this->getValue($item, $columnName);
619 1
        if (is_bool($result)) {
620 1
            return $result ? 'true' : 'false';
621
        }
622 1
        if ($result instanceof \DateTimeInterface) {
623 1
            return $result->format('Y-m-d H:i:s');
624
        } else {
625 1
            if ($result instanceof PersistentCollection) {
626 1
                $results = [];
627
                /* @var Object $entry */
628 1
                foreach ($result as $entry) {
629 1
                    $results[] = $entry->getName();
630
                }
631 1
                if (empty($results)) {
632 1
                    return '';
633
                }
634
635 1
                return implode(', ', $results);
636
            } else {
637 1
                if (is_array($result)) {
638 1
                    return implode(', ', $result);
639
                } else {
640 1
                    return $result;
641
                }
642
            }
643
        }
644
    }
645
646
    /**
647
     * @return string
648
     */
649 1
    public function getAddTemplate()
650
    {
651 1
        return $this->addTemplate;
652
    }
653
654
    /**
655
     * @param string $template
656
     *
657
     * @return AdminListConfiguratorInterface
658
     */
659 1
    public function setAddTemplate($template)
660
    {
661 1
        $this->addTemplate = $template;
662
663 1
        return $this;
664
    }
665
666
    /**
667
     * @return string
668
     */
669 1
    public function getViewTemplate()
670
    {
671 1
        return $this->viewTemplate;
672
    }
673
674
    /**
675
     * @param string $template
676
     *
677
     * @return AdminListConfiguratorInterface
678
     */
679 1
    public function setViewTemplate($template)
680
    {
681 1
        $this->viewTemplate = $template;
682
683 1
        return $this;
684
    }
685
686
    /**
687
     * @return string
688
     */
689 1
    public function getEditTemplate()
690
    {
691 1
        return $this->editTemplate;
692
    }
693
694
    /**
695
     * @param string $template
696
     *
697
     * @return AdminListConfiguratorInterface
698
     */
699 1
    public function setEditTemplate($template)
700
    {
701 1
        $this->editTemplate = $template;
702
703 1
        return $this;
704
    }
705
706
    /**
707
     * @return string
708
     */
709 1
    public function getDeleteTemplate()
710
    {
711 1
        return $this->deleteTemplate;
712
    }
713
714
    /**
715
     * @param string $template
716
     *
717
     * @return AdminListConfiguratorInterface
718
     */
719 1
    public function setDeleteTemplate($template)
720
    {
721 1
        $this->deleteTemplate = $template;
722
723 1
        return $this;
724
    }
725
726
    /**
727
     * You can override this method to do some custom things you need to do when adding an entity
728
     *
729
     * @param object $entity
730
     *
731
     * @return mixed
732
     */
733 1
    public function decorateNewEntity($entity)
734
    {
735 1
        return $entity;
736
    }
737
738
    /**
739
     * @return FilterBuilder
740
     */
741 10
    public function getFilterBuilder()
742
    {
743 10
        if (is_null($this->filterBuilder)) {
744 9
            $this->filterBuilder = new FilterBuilder();
745
        }
746
747 10
        return $this->filterBuilder;
748
    }
749
750
    /**
751
     * @param FilterBuilder $filterBuilder
752
     *
753
     * @return AbstractAdminListConfigurator
754
     */
755 2
    public function setFilterBuilder(FilterBuilder $filterBuilder)
756
    {
757 2
        $this->filterBuilder = $filterBuilder;
758
759 2
        return $this;
760
    }
761
762
    /**
763
     * Bind current request.
764
     *
765
     * @param Request $request
766
     */
767 4
    public function bindRequest(Request $request)
768
    {
769 4
        $query = $request->query;
770 4
        $session = $request->getSession();
771
772 4
        $adminListName = 'listconfig_'.$request->get('_route');
773
774 4
        $this->page = $request->query->getInt('page', 1);
775
        // Allow alphanumeric, _ & . in order by parameter!
776 4
        $this->orderBy = preg_replace('/[^[a-zA-Z0-9\_\.]]/', '', $request->query->get('orderBy', ''));
777 4
        $this->orderDirection = $request->query->getAlpha('orderDirection', '');
778
779
        // there is a session and the filter param is not set
780 4 View Code Duplication
        if ($session->has($adminListName) && !$query->has('filter')) {
781 3
            $adminListSessionData = $request->getSession()->get($adminListName);
782 3
            if (!$query->has('page')) {
783 1
                $this->page = $adminListSessionData['page'];
784
            }
785
786 3
            if (!$query->has('orderBy')) {
787 3
                $this->orderBy = $adminListSessionData['orderBy'];
788
            }
789
790 3
            if (!$query->has('orderDirection')) {
791 3
                $this->orderDirection = $adminListSessionData['orderDirection'];
792
            }
793
        }
794
795
        // save current parameters
796 4
        $session->set(
797 4
            $adminListName,
798
            array(
799 4
                'page' => $this->page,
800 4
                'orderBy' => $this->orderBy,
801 4
                'orderDirection' => $this->orderDirection,
802
            )
803
        );
804
805 4
        $this->getFilterBuilder()->bindRequest($request);
806 4
    }
807
808
    /**
809
     * Return current page.
810
     *
811
     * @return int
812
     */
813 3
    public function getPage()
814
    {
815 3
        return $this->page;
816
    }
817
818
    /**
819
     * Return current sorting column.
820
     *
821
     * @return string
822
     */
823 1
    public function getOrderBy()
824
    {
825 1
        return $this->orderBy;
826
    }
827
828
    /**
829
     * Return current sorting direction.
830
     *
831
     * @return string
832
     */
833 1
    public function getOrderDirection()
834
    {
835 1
        return $this->orderDirection;
836
    }
837
838
    /**
839
     * @param string $suffix
840
     *
841
     * @return string
842
     */
843 9
    public function getPathByConvention($suffix = null)
844
    {
845 9
        $entityName = strtolower($this->getEntityName());
846 9
        $entityName = str_replace('\\', '_', $entityName);
847 9
        if (empty($suffix)) {
848 1
            return sprintf('%s_admin_%s', strtolower($this->getBundleName()), $entityName);
849
        }
850
851 8
        return sprintf('%s_admin_%s_%s', strtolower($this->getBundleName()), $entityName, $suffix);
852
    }
853
854
    /**
855
     * Get controller path.
856
     *
857
     * @return string
858
     */
859 1
    public function getControllerPath()
860
    {
861 1
        return sprintf('%s:%s', $this->getBundleName(), $this->getEntityName());
862
    }
863
864
    /**
865
     * Return extra parameters for use in list actions.
866
     *
867
     * @return array
868
     */
869 9
    public function getExtraParameters()
870
    {
871 9
        return array();
872
    }
873
}
874