Completed
Push — master ( 91fdab...75a7b9 )
by
unknown
13:37
created

Configurator/AbstractAdminListConfigurator.php (2 issues)

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
    public function getRepositoryName()
131
    {
132
        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
    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
        if (empty($this->fields)) {
167
            $this->buildFields();
168
        }
169
    }
170
171
    /**
172
     * Build iterator (if needed)
173
     */
174
    public function buildIterator()
175
    {
176
    }
177
178
    /**
179
     * Reset all built members
180
     */
181
    public function resetBuilds()
182
    {
183
        $this->fields = array();
184
        $this->exportFields = array();
185
        $this->filterBuilder = null;
186
        $this->itemActions = array();
187
        $this->listActions = array();
188
    }
189
190
    /**
191
     * Configure the types of items you can add
192
     *
193
     * @param array $params
194
     *
195
     * @return array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use array<string,array<string,string|array>>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
196
     */
197
    public function getAddUrlFor(array $params = array())
198
    {
199
        $params = array_merge($params, $this->getExtraParameters());
200
201
        $friendlyName = explode("\\", $this->getEntityName());
202
        $friendlyName = array_pop($friendlyName);
203
        $re = '/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/';
204
        $a = preg_split($re, $friendlyName);
205
        $superFriendlyName = implode(' ', $a);
206
207
        return array(
208
            $superFriendlyName => array(
209
                'path' => $this->getPathByConvention($this::SUFFIX_ADD),
210
                'params' => $params,
211
            ),
212
        );
213
    }
214
215
    /**
216
     * Get the url to export the listed items
217
     *
218
     * @return array
219
     */
220
    public function getExportUrl()
221
    {
222
        $params = $this->getExtraParameters();
223
224
        return array(
225
            'path' => $this->getPathByConvention($this::SUFFIX_EXPORT),
226
            'params' => array_merge(array('_format' => 'csv'), $params),
227
        );
228
    }
229
230
    public function getViewUrlFor($item)
231
    {
232
        if (is_object($item)){
233
            $id = $item->getid();
234
        } else {
235
            $id = $item['id'];
236
        }
237
        $params = array('id' => $id);
238
        $params = array_merge($params, $this->getExtraParameters());
239
240
        return array(
241
            'path'   => $this->getPathByConvention($this::SUFFIX_VIEW),
242
            'params' => $params
243
        );
244
    }
245
246
    /**
247
     * Return the url to list all the items
248
     *
249
     * @return array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use array<string,string|array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
250
     */
251
    public function getIndexUrl()
252
    {
253
        $params = $this->getExtraParameters();
254
255
        return array(
256
            'path' => $this->getPathByConvention(),
257
            'params' => $params,
258
        );
259
    }
260
261
    /**
262
     * @param object $entity
263
     *
264
     * @throws InvalidArgumentException
265
     *
266
     * @return string
267
     */
268
    public function getAdminType($entity)
269
    {
270
        if (null !== $this->type) {
271
            return $this->type;
272
        }
273
274
        if (method_exists($entity, 'getAdminType')) {
275
            return $entity->getAdminType();
276
        }
277
278
        throw new InvalidArgumentException(
279
            'You need to implement the getAdminType method in '.
280
            get_class($this).' or '.get_class($entity)
281
        );
282
    }
283
284
    /**
285
     * @param string $type
286
     *
287
     * @return AbstractAdminListConfigurator
288
     */
289
    public function setAdminType($type)
290
    {
291
        $this->type = $type;
292
293
        return $this;
294
    }
295
296
    /**
297
     * @param array $typeOptions
298
     *
299
     * @return AbstractAdminListConfigurator
300
     */
301
    public function setAdminTypeOptions($typeOptions)
302
    {
303
        $this->typeOptions = $typeOptions;
304
305
        return $this;
306
    }
307
308
    /**
309
     * Return the default form admin type options
310
     *
311
     * @return array
312
     */
313
    public function getAdminTypeOptions()
314
    {
315
        return $this->typeOptions;
316
    }
317
318
    /**
319
     * @param object|array $item
320
     *
321
     * @return bool
322
     */
323
    public function canEdit($item)
324
    {
325
        return true;
326
    }
327
328
    /**
329
     * Configure if it's possible to delete the given $item
330
     *
331
     * @param object|array $item
332
     *
333
     * @return bool
334
     */
335
    public function canDelete($item)
336
    {
337
        return true;
338
    }
339
340
    /**
341
     * Configure if it's possible to add new items
342
     *
343
     * @return bool
344
     */
345
    public function canAdd()
346
    {
347
        return true;
348
    }
349
350
    public function canView($item)
351
    {
352
        return false;
353
    }
354
355
    /**
356
     * Configure if it's possible to add new items
357
     *
358
     * @return bool
359
     */
360
    public function canExport()
361
    {
362
        return false;
363
    }
364
365
    /**
366
     * @param string $name The field name
367
     * @param string $header The header title
368
     * @param string $sort Sortable column or not
369
     * @param string $template The template
370
     * @param FieldAlias $alias The alias
371
     *
372
     * @return AbstractAdminListConfigurator
373
     */
374
    public function addField($name, $header, $sort, $template = null, FieldAlias $alias = null)
375
    {
376
        $this->fields[] = new Field($name, $header, $sort, $template, $alias);
377
378
        return $this;
379
    }
380
381
    /**
382
     * @param string $name The field name
383
     * @param string $header The header title
384
     * @param string $template The template
385
     * @param FieldAlias $alias The alias
386
     *
387
     * @return AbstractAdminListConfigurator
388
     */
389
    public function addExportField($name, $header, $template = null, FieldAlias $alias = null)
390
    {
391
        $this->exportFields[] = new Field($name, $header, false, $template, $alias);
392
393
        return $this;
394
    }
395
396
    /**
397
     * @param string $columnName The column name
398
     * @param FilterTypeInterface $type The filter type
399
     * @param string $filterName The name of the filter
400
     * @param array $options Options
401
     *
402
     * @return AbstractAdminListConfigurator
403
     */
404
    public function addFilter(
405
        $columnName,
406
        FilterTypeInterface $type = null,
407
        $filterName = null,
408
        array $options = array()
409
    ) {
410
        $this->getFilterBuilder()->add($columnName, $type, $filterName, $options);
411
412
        return $this;
413
    }
414
415
    /**
416
     * @return int
417
     */
418
    public function getLimit()
419
    {
420
        return 10;
421
    }
422
423
    /**
424
     * @return array
425
     */
426
    public function getSortFields()
427
    {
428
        $array = array();
429
        foreach ($this->getFields() as $field) {
430
            if ($field->isSortable()) {
431
                $array[] = $field->getName();
432
            }
433
        }
434
435
        return $array;
436
    }
437
438
    /**
439
     * @return Field[]
440
     */
441
    public function getFields()
442
    {
443
        return $this->fields;
444
    }
445
446
    /**
447
     * @return Field[]
448
     */
449
    public function getExportFields()
450
    {
451
        if (empty($this->exportFields)) {
452
            return $this->fields;
453
        } else {
454
            return $this->exportFields;
455
        }
456
    }
457
458
    /**
459
     * @param string $label The label, only used when the template equals null
460
     * @param callable $routeGenerator The generator used to generate the url of an item, when generating the item will
461
     *                                 be provided
462
     * @param string $icon The icon, only used when the template equals null
463
     * @param string $template The template, when not specified the label is shown
464
     *
465
     * @return AbstractAdminListConfigurator
466
     */
467
    public function addSimpleItemAction($label, $routeGenerator, $icon, $template = null)
468
    {
469
        return $this->addItemAction(new SimpleItemAction($routeGenerator, $icon, $label, $template));
470
    }
471
472
    /**
473
     * @param ItemActionInterface $itemAction
474
     *
475
     * @return AbstractAdminListConfigurator
476
     */
477
    public function addItemAction(ItemActionInterface $itemAction)
478
    {
479
        $this->itemActions[] = $itemAction;
480
481
        return $this;
482
    }
483
484
    /**
485
     * @return bool
486
     */
487
    public function hasItemActions()
488
    {
489
        return !empty($this->itemActions);
490
    }
491
492
    /**
493
     * @return ItemActionInterface[]
494
     */
495
    public function getItemActions()
496
    {
497
        return $this->itemActions;
498
    }
499
500
    /**
501
     * @param ListActionInterface $listAction
502
     *
503
     * @return AdminListConfiguratorInterface
504
     */
505
    public function addListAction(ListActionInterface $listAction)
506
    {
507
        $this->listActions[] = $listAction;
508
509
        return $this;
510
    }
511
512
    /**
513
     * @return bool
514
     */
515
    public function hasListActions()
516
    {
517
        return !empty($this->listActions);
518
    }
519
520
    /**
521
     * @return ListActionInterface[]
522
     */
523
    public function getListActions()
524
    {
525
        return $this->listActions;
526
    }
527
528
    /**
529
     * @param BulkActionInterface $bulkAction
530
     *
531
     * @return AdminListConfiguratorInterface
532
     */
533
    public function addBulkAction(BulkActionInterface $bulkAction)
534
    {
535
        $this->bulkActions[] = $bulkAction;
536
537
        return $this;
538
    }
539
540
    /**
541
     * @return bool
542
     */
543
    public function hasBulkActions()
544
    {
545
        return !empty($this->bulkActions);
546
    }
547
548
    /**
549
     * @return BulkActionInterface[]
550
     */
551
    public function getBulkActions()
552
    {
553
        return $this->bulkActions;
554
    }
555
556
    /**
557
     * @return string
558
     */
559
    public function getListTemplate()
560
    {
561
        return $this->listTemplate;
562
    }
563
564
    /**
565
     * @param string $template
566
     *
567
     * @return AdminListConfiguratorInterface
568
     */
569
    public function setListTemplate($template)
570
    {
571
        $this->listTemplate = $template;
572
573
        return $this;
574
    }
575
576
    /**
577
     * @param array|object $item The item
578
     * @param string $columnName The column name
579
     *
580
     * @return mixed
581
     */
582
    public function getValue($item, $columnName)
583
    {
584
        if (is_array($item)) {
585
            if (isset($item[$columnName])) {
586
                return $item[$columnName];
587
            } else {
588
                return '';
589
            }
590
        }
591
592
        $accessor = PropertyAccess::createPropertyAccessor();
593
594
        if ($accessor->isReadable($item, $columnName)) {
595
            $result = $accessor->getValue($item, $columnName);
596
        } else {
597
            return sprintf('undefined function [get/is/has]%s()', $columnName);
598
        }
599
600
        return $result;
601
    }
602
603
    /**
604
     * @param array|object $item The item
605
     * @param string $columnName The column name
606
     *
607
     * @return string
608
     */
609
    public function getStringValue($item, $columnName)
610
    {
611
        $result = $this->getValue($item, $columnName);
612
        if (is_bool($result)) {
613
            return $result ? 'true' : 'false';
614
        }
615
        if ($result instanceof \DateTime) {
616
            return $result->format('Y-m-d H:i:s');
617
        } else {
618
            if ($result instanceof PersistentCollection) {
619
                $results = [];
620
                /* @var Object $entry */
621
                foreach ($result as $entry) {
622
                    $results[] = $entry->getName();
623
                }
624
                if (empty($results)) {
625
                    return "";
626
                }
627
628
                return implode(', ', $results);
629
            } else {
630
                if (is_array($result)) {
631
                    return implode(', ', $result);
632
                } else {
633
                    return $result;
634
                }
635
            }
636
        }
637
    }
638
639
    /**
640
     * @return string
641
     */
642
    public function getAddTemplate()
643
    {
644
        return $this->addTemplate;
645
    }
646
647
    /**
648
     * @param string $template
649
     *
650
     * @return AdminListConfiguratorInterface
651
     */
652
    public function setAddTemplate($template)
653
    {
654
        $this->addTemplate = $template;
655
656
        return $this;
657
    }
658
659
    /**
660
     * @return string
661
     */
662
    public function getViewTemplate()
663
    {
664
        return $this->viewTemplate;
665
    }
666
667
    /**
668
     * @param string $template
669
     *
670
     * @return AdminListConfiguratorInterface
671
     */
672
    public function setViewTemplate($template)
673
    {
674
        $this->viewTemplate = $template;
675
676
        return $this;
677
    }
678
679
    /**
680
     * @return string
681
     */
682
    public function getEditTemplate()
683
    {
684
        return $this->editTemplate;
685
    }
686
687
    /**
688
     * @param string $template
689
     *
690
     * @return AdminListConfiguratorInterface
691
     */
692
    public function setEditTemplate($template)
693
    {
694
        $this->editTemplate = $template;
695
696
        return $this;
697
    }
698
699
    /**
700
     * @return string
701
     */
702
    public function getDeleteTemplate()
703
    {
704
        return $this->deleteTemplate;
705
    }
706
707
    /**
708
     * @param string $template
709
     *
710
     * @return AdminListConfiguratorInterface
711
     */
712
    public function setDeleteTemplate($template)
713
    {
714
        $this->deleteTemplate = $template;
715
716
        return $this;
717
    }
718
719
    /**
720
     * You can override this method to do some custom things you need to do when adding an entity
721
     *
722
     * @param object $entity
723
     *
724
     * @return mixed
725
     */
726
    public function decorateNewEntity($entity)
727
    {
728
        return $entity;
729
    }
730
731
    /**
732
     * @return FilterBuilder
733
     */
734
    public function getFilterBuilder()
735
    {
736
        if (is_null($this->filterBuilder)) {
737
            $this->filterBuilder = new FilterBuilder();
738
        }
739
740
        return $this->filterBuilder;
741
    }
742
743
    /**
744
     * @param FilterBuilder $filterBuilder
745
     *
746
     * @return AbstractAdminListConfigurator
747
     */
748
    public function setFilterBuilder(FilterBuilder $filterBuilder)
749
    {
750
        $this->filterBuilder = $filterBuilder;
751
752
        return $this;
753
    }
754
755
    /**
756
     * Bind current request.
757
     *
758
     * @param Request $request
759
     */
760
    public function bindRequest(Request $request)
761
    {
762
        $query = $request->query;
763
        $session = $request->getSession();
764
765
        $adminListName = 'listconfig_'.$request->get('_route');
766
767
        $this->page = $request->query->getInt('page', 1);
768
        // Allow alphanumeric, _ & . in order by parameter!
769
        $this->orderBy = preg_replace('/[^[a-zA-Z0-9\_\.]]/', '', $request->query->get('orderBy', ''));
770
        $this->orderDirection = $request->query->getAlpha('orderDirection', '');
771
772
        // there is a session and the filter param is not set
773 View Code Duplication
        if ($session->has($adminListName) && !$query->has('filter')) {
774
            $adminListSessionData = $request->getSession()->get($adminListName);
775
            if (!$query->has('page')) {
776
                $this->page = $adminListSessionData['page'];
777
            }
778
779
            if (!$query->has('orderBy')) {
780
                $this->orderBy = $adminListSessionData['orderBy'];
781
            }
782
783
            if (!$query->has('orderDirection')) {
784
                $this->orderDirection = $adminListSessionData['orderDirection'];
785
            }
786
        }
787
788
        // save current parameters
789
        $session->set(
790
            $adminListName,
791
            array(
792
                'page' => $this->page,
793
                'orderBy' => $this->orderBy,
794
                'orderDirection' => $this->orderDirection,
795
            )
796
        );
797
798
799
        $this->getFilterBuilder()->bindRequest($request);
800
    }
801
802
    /**
803
     * Return current page.
804
     *
805
     * @return int
806
     */
807
    public function getPage()
808
    {
809
        return $this->page;
810
    }
811
812
    /**
813
     * Return current sorting column.
814
     *
815
     * @return string
816
     */
817
    public function getOrderBy()
818
    {
819
        return $this->orderBy;
820
    }
821
822
    /**
823
     * Return current sorting direction.
824
     *
825
     * @return string
826
     */
827
    public function getOrderDirection()
828
    {
829
        return $this->orderDirection;
830
    }
831
832
    /**
833
     * @param string $suffix
834
     *
835
     * @return string
836
     */
837
    public function getPathByConvention($suffix = null)
838
    {
839
        $entityName = strtolower($this->getEntityName());
840
        $entityName = str_replace('\\', '_', $entityName);
841
        if (empty($suffix)) {
842
            return sprintf('%s_admin_%s', strtolower($this->getBundleName()), $entityName);
843
        }
844
845
        return sprintf('%s_admin_%s_%s', strtolower($this->getBundleName()), $entityName, $suffix);
846
    }
847
848
    /**
849
     * Get controller path.
850
     *
851
     * @return string
852
     */
853
    public function getControllerPath()
854
    {
855
        return sprintf('%s:%s', $this->getBundleName(), $this->getEntityName());
856
    }
857
858
    /**
859
     * Return extra parameters for use in list actions.
860
     *
861
     * @return array
862
     */
863
    public function getExtraParameters()
864
    {
865
        return array();
866
    }
867
}
868