Completed
Push — master ( d692df...4e2bc6 )
by Martin
02:30
created

AbstractRenderer::setColumns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
namespace ZfcDatagrid\Renderer;
3
4
use Doctrine\Common\Proxy\Exception\InvalidArgumentException;
5
use Zend\Cache;
6
use Zend\I18n\Translator\Translator;
7
use Zend\Mvc\MvcEvent;
8
use Zend\Paginator\Paginator;
9
use Zend\View\Model\ViewModel;
10
use ZfcDatagrid\Datagrid;
11
use ZfcDatagrid\Filter;
12
13
abstract class AbstractRenderer implements RendererInterface
14
{
15
    /**
16
     *
17
     * @var array
18
     */
19
    protected $options = [];
20
21
    /**
22
     *
23
     * @var string
24
     */
25
    protected $title;
26
27
    /**
28
     *
29
     * @var Cache\Storage\StorageInterface
30
     */
31
    protected $cache;
32
33
    /**
34
     *
35
     * @var string
36
     */
37
    protected $cacheId;
38
39
    /**
40
     *
41
     * @var Paginator
42
     */
43
    protected $paginator;
44
45
    /**
46
     * @var \ZfcDatagrid\Column\AbstractColumn[]
47
     */
48
    protected $columns = [];
49
50
    /**
51
     * @var \ZfcDataGrid\Column\Style\AbstractStyle[]
52
     */
53
    protected $rowStyles = [];
54
55
    /**
56
     * @var array
57
     */
58
    protected $sortConditions = null;
59
60
    /**
61
     * @var Filter[]
62
     */
63
    protected $filters = null;
64
65
    /**
66
     * @var integer
67
     */
68
    protected $currentPageNumber = null;
69
70
    /**
71
     *
72
     * @var array
73
     */
74
    protected $data = [];
75
76
    /**
77
     *
78
     * @var MvcEvent
79
     */
80
    protected $mvcEvent;
81
82
    /**
83
     *
84
     * @var ViewModel
85
     */
86
    protected $viewModel;
87
88
    /**
89
     *
90
     * @var string
91
     */
92
    protected $template;
93
94
    /**
95
     *
96
     * @var string
97
     */
98
    protected $templateToolbar;
99
100
    /**
101
     *
102
     * @var array
103
     */
104
    protected $toolbarTemplateVariables = [];
105
106
    /**
107
     *
108
     * @var Translator
109
     */
110
    protected $translator;
111
112
    public function setOptions(array $options)
113
    {
114
        $this->options = $options;
115
    }
116
117
    /**
118
     *
119
     * @return array
120
     */
121
    public function getOptions()
122
    {
123
        return $this->options;
124
    }
125
126
    /**
127
     *
128
     * @return array
129
     */
130
    public function getOptionsRenderer()
131
    {
132
        $options = $this->getOptions();
133
        if (isset($options['renderer'][$this->getName()])) {
134
            return $options['renderer'][$this->getName()];
135
        } else {
136
            return [];
137
        }
138
    }
139
140
    /**
141
     *
142
     * @param ViewModel $viewModel
143
     */
144
    public function setViewModel(ViewModel $viewModel)
145
    {
146
        $this->viewModel = $viewModel;
147
    }
148
149
    /**
150
     *
151
     * @return \Zend\View\Model\ViewModel
152
     */
153
    public function getViewModel()
154
    {
155
        return $this->viewModel;
156
    }
157
158
    /**
159
     * Set the view template
160
     *
161
     * @param string $name
162
     */
163
    public function setTemplate($name)
164
    {
165
        $this->template = (string) $name;
166
    }
167
168
    /**
169
     * Get the view template name
170
     *
171
     * @return string
172
     */
173
    public function getTemplate()
174
    {
175
        if (null === $this->template) {
176
            $this->template = $this->getTemplatePathDefault('layout');
177
        }
178
179
        return $this->template;
180
    }
181
182
    /**
183
     * Get the default template path (if there is no own set)
184
     *
185
     * @param  string     $type layout or toolbar
186
     * @return string
187
     * @throws \Exception
188
     */
189
    private function getTemplatePathDefault($type = 'layout')
190
    {
191
        $optionsRenderer = $this->getOptionsRenderer();
192
        if (isset($optionsRenderer['templates'][$type])) {
193
            return $optionsRenderer['templates'][$type];
194
        }
195
196
        if ('layout' === $type) {
197
            return 'zfc-datagrid/renderer/' . $this->getName() . '/' . $type;
198
        } elseif ('toolbar' === $type) {
199
            return 'zfc-datagrid/toolbar/toolbar';
200
        }
201
202
        throw new \Exception('Unknown type: "' . $type . '"');
203
    }
204
205
    /**
206
     * Set the toolbar view template name
207
     *
208
     * @param string $name
209
     */
210
    public function setToolbarTemplate($name)
211
    {
212
        $this->templateToolbar = (string) $name;
213
    }
214
215
    /**
216
     * @return string
217
     * @throws \Exception
218
     */
219
    public function getToolbarTemplate()
220
    {
221
        if (null === $this->templateToolbar) {
222
            $this->templateToolbar = $this->getTemplatePathDefault('toolbar');
223
        }
224
225
        return $this->templateToolbar;
226
    }
227
228
    /**
229
     * Set the toolbar view template variables
230
     *
231
     * @param array $variables
232
     */
233
    public function setToolbarTemplateVariables(array $variables)
234
    {
235
        $this->toolbarTemplateVariables = $variables;
236
    }
237
238
    /**
239
     * Get the toolbar template variables
240
     *
241
     * @return array
242
     */
243
    public function getToolbarTemplateVariables()
244
    {
245
        return $this->toolbarTemplateVariables;
246
    }
247
248
    /**
249
     * Paginator is here to retreive the totalItemCount, count pages, current page
250
     * NOT FOR THE ACTUAL DATA!!!!
251
     *
252
     * @param \Zend\Paginator\Paginator $paginator
253
     */
254
    public function setPaginator(Paginator $paginator)
255
    {
256
        $this->paginator = $paginator;
257
    }
258
259
    /**
260
     *
261
     * @return \Zend\Paginator\Paginator
262
     */
263
    public function getPaginator()
264
    {
265
        return $this->paginator;
266
    }
267
268
    /**
269
     * Set the columns
270
     *
271
     * @param array $columns
272
     */
273
    public function setColumns(array $columns)
274
    {
275
        $this->columns = $columns;
276
    }
277
278
    /**
279
     * Get all columns
280
     *
281
     * @return \ZfcDatagrid\Column\AbstractColumn[]
282
     */
283
    public function getColumns()
284
    {
285
        return $this->columns;
286
    }
287
288
    /**
289
     *
290
     * @param \ZfcDataGrid\Column\Style\AbstractStyle[] $rowStyles
291
     */
292
    public function setRowStyles($rowStyles = [])
293
    {
294
        $this->rowStyles = $rowStyles;
295
    }
296
297
    /**
298
     *
299
     * @return \ZfcDataGrid\Column\Style\AbstractStyle[]
300
     */
301
    public function getRowStyles()
302
    {
303
        return $this->rowStyles;
304
    }
305
306
    /**
307
     * Calculate the sum of the displayed column width to 100%
308
     *
309
     * @param array $columns
310
     */
311
    protected function calculateColumnWidthPercent(array $columns)
312
    {
313
        $widthAllColumn = 0;
314
        foreach ($columns as $column) {
315
            /* @var $column \ZfcDatagrid\Column\AbstractColumn */
316
            $widthAllColumn += $column->getWidth();
317
        }
318
319
        $widthSum = 0;
320
        // How much 1 percent columnd width is really "one" percent...
321
        $relativeOnePercent = $widthAllColumn / 100;
322
323
        foreach ($columns as $column) {
324
            $widthSum += (($column->getWidth() / $relativeOnePercent));
325
            $column->setWidth(($column->getWidth() / $relativeOnePercent));
326
        }
327
    }
328
329
    /**
330
     * The prepared data
331
     *
332
     * @param array $data
333
     */
334
    public function setData(array $data)
335
    {
336
        $this->data = $data;
337
    }
338
339
    /**
340
     *
341
     * @return array
342
     */
343
    public function getData()
344
    {
345
        return $this->data;
346
    }
347
348
    /**
349
     *
350
     * @return array
351
     */
352
    public function getCacheData()
353
    {
354
        return $this->getCache()->getItem($this->getCacheId());
355
    }
356
357
    /**
358
     *
359
     * @throws \Exception
360
     * @return array|false
361
     */
362
    private function getCacheSortConditions()
363
    {
364
        $cacheData = $this->getCacheData();
365
        if (! isset($cacheData['sortConditions'])) {
366
            return false;
367
        }
368
369
        return $cacheData['sortConditions'];
370
    }
371
372
    /**
373
     *
374
     * @throws \Exception
375
     * @return array|false
376
     */
377
    private function getCacheFilters()
378
    {
379
        $cacheData = $this->getCacheData();
380
        if (! isset($cacheData['filters'])) {
381
            return false;
382
        }
383
384
        return $cacheData['filters'];
385
    }
386
387
    /**
388
     * Not used ATM...
389
     *
390
     * @see \ZfcDatagrid\Renderer\RendererInterface::setMvcEvent()
391
     */
392
    public function setMvcEvent(MvcEvent $mvcEvent)
393
    {
394
        $this->mvcEvent = $mvcEvent;
395
    }
396
397
    /**
398
     * Not used ATM...
399
     *
400
     * @return MvcEvent
401
     */
402
    public function getMvcEvent()
403
    {
404
        return $this->mvcEvent;
405
    }
406
407
    /**
408
     *
409
     * @return \Zend\Stdlib\RequestInterface
410
     */
411
    public function getRequest()
412
    {
413
        return $this->getMvcEvent()->getRequest();
414
    }
415
416
    /**
417
     *
418
     * @param  Translator                $translator
419
     * @throws \InvalidArgumentException
420
     */
421 View Code Duplication
    public function setTranslator($translator)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
422
    {
423
        if (! $translator instanceof Translator && ! $translator instanceof \Zend\I18n\Translator\TranslatorInterface) {
424
            throw new \InvalidArgumentException('Translator must be an instanceof "Zend\I18n\Translator\Translator" or "Zend\I18n\Translator\TranslatorInterface"');
425
        }
426
427
        $this->translator = $translator;
428
    }
429
430
    /**
431
     *
432
     * @return \Zend\I18n\Translator\Translator
433
     */
434
    public function getTranslator()
435
    {
436
        return $this->translator;
437
    }
438
439
    /**
440
     * @param $string
441
     * @return string
442
     */
443
    public function translate($string)
444
    {
445
        return $this->getTranslator() ? $this->getTranslator()->translate($string) : $string;
446
    }
447
448
    /**
449
     * Set the title
450
     *
451
     * @param string $title
452
     */
453
    public function setTitle($title)
454
    {
455
        $this->title = $title;
456
    }
457
458
    /**
459
     *
460
     * @return string
461
     */
462
    public function getTitle()
463
    {
464
        return $this->title;
465
    }
466
467
    /**
468
     * @param Cache\Storage\StorageInterface $cache
469
     */
470
    public function setCache(Cache\Storage\StorageInterface $cache)
471
    {
472
        $this->cache = $cache;
473
    }
474
475
    /**
476
     *
477
     * @return Cache\Storage\StorageInterface
478
     */
479
    public function getCache()
480
    {
481
        return $this->cache;
482
    }
483
484
    /**
485
     *
486
     * @param string $cacheId
487
     */
488
    public function setCacheId($cacheId)
489
    {
490
        $this->cacheId = $cacheId;
491
    }
492
493
    /**
494
     *
495
     * @return string
496
     */
497
    public function getCacheId()
498
    {
499
        return $this->cacheId;
500
    }
501
502
    /**
503
     * Set the sort conditions explicit (e.g.
504
     * from a custom form)
505
     *
506
     * @param array $sortConditions
507
     */
508
    public function setSortConditions(array $sortConditions)
509
    {
510
        foreach ($sortConditions as $sortCondition) {
511
            if (! is_array($sortCondition)) {
512
                throw new InvalidArgumentException('Sort condition have to be an array');
513
            }
514
515
            if (! array_key_exists('column', $sortCondition)) {
516
                throw new InvalidArgumentException('Sort condition missing array key column');
517
            }
518
        }
519
520
        $this->sortConditions = $sortConditions;
521
    }
522
523
    /**
524
     *
525
     * @return array
526
     */
527 View Code Duplication
    public function getSortConditions()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
528
    {
529
        if (is_array($this->sortConditions)) {
530
            return $this->sortConditions;
531
        }
532
533
        if ($this->isExport() === true && $this->getCacheSortConditions() !== false) {
534
            // Export renderer should always retrieve the sort conditions from cache!
535
            $this->sortConditions = $this->getCacheSortConditions();
536
537
            return $this->sortConditions;
538
        }
539
540
        $this->sortConditions = $this->getSortConditionsDefault();
541
542
        return $this->sortConditions;
543
    }
544
545
    /**
546
     * Get the default sort conditions defined for the columns
547
     *
548
     * @return array
549
     */
550
    public function getSortConditionsDefault()
551
    {
552
        $sortConditions = [];
553
        foreach ($this->getColumns() as $column) {
554
            /* @var $column \ZfcDatagrid\Column\AbstractColumn */
555
            if ($column->hasSortDefault() === true) {
556
                $sortDefaults = $column->getSortDefault();
557
558
                $sortConditions[$sortDefaults['priority']] = [
559
                    'column'        => $column,
560
                    'sortDirection' => $sortDefaults['sortDirection'],
561
                ];
562
563
                $column->setSortActive($sortDefaults['sortDirection']);
564
            }
565
        }
566
567
        ksort($sortConditions);
568
569
        return $sortConditions;
570
    }
571
572
    /**
573
     * Set filters explicit (e.g.
574
     * from a custom form)
575
     *
576
     * @param array $filters
577
     */
578
    public function setFilters(array $filters)
579
    {
580
        foreach ($filters as $filter) {
581
            if (! $filter instanceof Filter) {
582
                throw new InvalidArgumentException('Filter have to be an instanceof ZfcDatagrid\Filter');
583
            }
584
        }
585
586
        $this->filters = $filters;
587
    }
588
589
    /**
590
     *
591
     * @return Filter[]
592
     */
593 View Code Duplication
    public function getFilters()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
594
    {
595
        if (is_array($this->filters)) {
596
            return $this->filters;
597
        }
598
599
        if ($this->isExport() === true && $this->getCacheFilters() !== false) {
600
            // Export renderer should always retrieve the filters from cache!
601
            $this->filters = $this->getCacheFilters();
602
603
            return $this->filters;
604
        }
605
606
        $this->filters = $this->getFiltersDefault();
607
608
        return $this->filters;
609
    }
610
611
    /**
612
     * Get the default filter conditions defined for the columns
613
     *
614
     * @return Filter[]
615
     */
616
    public function getFiltersDefault()
617
    {
618
        $filters = [];
619
620 View Code Duplication
        foreach ($this->getColumns() as $column) {
0 ignored issues
show
Duplication introduced by
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...
621
            /* @var $column \ZfcDatagrid\Column\AbstractColumn */
622
            if ($column->hasFilterDefaultValue() === true) {
623
                $filter = new Filter();
624
                $filter->setFromColumn($column, $column->getFilterDefaultValue());
625
                $filters[] = $filter;
626
627
                $column->setFilterActive($filter->getDisplayColumnValue());
628
            }
629
        }
630
631
        return $filters;
632
    }
633
634
    /**
635
     * Set the current page number
636
     *
637
     * @param integer $page
638
     */
639
    public function setCurrentPageNumber($page)
640
    {
641
        $this->currentPageNumber = (int) $page;
642
    }
643
644
    /**
645
     * Should be implemented for each renderer itself (just default)
646
     *
647
     * @return integer
648
     */
649
    public function getCurrentPageNumber()
650
    {
651
        if (null === $this->currentPageNumber) {
652
            $this->currentPageNumber = 1;
653
        }
654
655
        return (int) $this->currentPageNumber;
656
    }
657
658
    /**
659
     * Should be implemented for each renderer itself (just default)
660
     *
661
     * @return integer
662
     */
663
    public function getItemsPerPage($defaultItems = 25)
664
    {
665
        if ($this->isExport() === true) {
666
            return (int) - 1;
667
        }
668
669
        return $defaultItems;
670
    }
671
672
    /**
673
     * VERY UGLY DEPENDECY...
674
     *
675
     * @todo Refactor :-)
676
     *
677
     * @see \ZfcDatagrid\Renderer\RendererInterface::prepareViewModel()
678
     */
679
    public function prepareViewModel(Datagrid $grid)
680
    {
681
        $viewModel = $this->getViewModel();
682
683
        $viewModel->setVariable('gridId', $grid->getId());
684
        $viewModel->setVariable('title', $this->getTitle());
685
        $viewModel->setVariable('parameters', $grid->getParameters());
686
        $viewModel->setVariable('overwriteUrl', $grid->getUrl());
687
688
        $viewModel->setVariable('templateToolbar', $this->getToolbarTemplate());
689
        foreach ($this->getToolbarTemplateVariables() as $key => $value) {
690
            $viewModel->setVariable($key, $value);
691
        }
692
        $viewModel->setVariable('rendererName', $this->getName());
693
694
        $options               = $this->getOptions();
695
        $generalParameterNames = $options['generalParameterNames'];
696
        $viewModel->setVariable('generalParameterNames', $generalParameterNames);
697
698
        $viewModel->setVariable('columns', $this->getColumns());
699
700
        $viewModel->setVariable('rowStyles', $grid->getRowStyles());
701
702
        $viewModel->setVariable('paginator', $this->getPaginator());
703
        $viewModel->setVariable('data', $this->getData());
704
        $viewModel->setVariable('filters', $this->getFilters());
705
706
        $viewModel->setVariable('rowClickAction', $grid->getRowClickAction());
707
        $viewModel->setVariable('massActions', $grid->getMassActions());
708
709
        $viewModel->setVariable('isUserFilterEnabled', $grid->isUserFilterEnabled());
710
711
        /*
712
         * renderer specific parameter names
713
         */
714
        $optionsRenderer = $this->getOptionsRenderer();
715
        $viewModel->setVariable('optionsRenderer', $optionsRenderer);
716
        if ($this->isExport() === false) {
717
            $parameterNames = $optionsRenderer['parameterNames'];
718
            $viewModel->setVariable('parameterNames', $parameterNames);
719
720
            $activeParameters                                 = [];
721
            $activeParameters[$parameterNames['currentPage']] = $this->getCurrentPageNumber();
722
            {
723
                $sortColumns    = [];
724
                $sortDirections = [];
725
                foreach ($this->getSortConditions() as $sortCondition) {
726
                    $sortColumns[]    = $sortCondition['column']->getUniqueId();
727
                    $sortDirections[] = $sortCondition['sortDirection'];
728
                }
729
730
                $activeParameters[$parameterNames['sortColumns']]    = implode(',', $sortColumns);
731
                $activeParameters[$parameterNames['sortDirections']] = implode(',', $sortDirections);
732
            }
733
            $viewModel->setVariable('activeParameters', $activeParameters);
734
        }
735
736
        $viewModel->setVariable('exportRenderers', $grid->getExportRenderers());
737
    }
738
739
    /**
740
     * Return the name of the renderer
741
     * @return string
742
     */
743
    abstract public function getName();
744
745
    /**
746
     * Determine if the renderer is for export
747
     * @return boolean
748
     */
749
    abstract public function isExport();
750
751
    /**
752
     * Determin if the renderer is HTML
753
     * It can be export + html -> f.x.
754
     * printing for HTML
755
     * @return boolean
756
     */
757
    abstract public function isHtml();
758
759
    /**
760
     * Execute all...
761
     * @return ViewModel Response\Stream
762
     */
763
    abstract public function execute();
764
}
765