Passed
Push — int-types ( 949579...4b2be5 )
by Sam
05:58
created

GridFieldLazyLoader   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 66
rs 10
c 0
b 0
f 0
wmc 11

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getHTMLFragments() 0 6 2
A isInTabSet() 0 10 4
A getManipulatedData() 0 13 3
A isLazy() 0 5 2
1
<?php
2
3
namespace SilverStripe\Forms\GridField;
4
5
use SilverStripe\Forms\FormField;
6
use SilverStripe\Forms\TabSet;
7
use SilverStripe\ORM\ArrayList;
8
use SilverStripe\ORM\Filterable;
9
use SilverStripe\ORM\SS_List;
10
11
/**
12
 * GridFieldLazyLoader alters the {@link GridField} behavior to delay rendering of rows until the tab containing the
13
 * GridField is selected by the user.
14
 *
15
 * @see GridField
16
 */
17
class GridFieldLazyLoader implements GridField_DataManipulator, GridField_HTMLProvider
18
{
19
20
    /**
21
     * Empty $datalist if the current request should be lazy loadable.
22
     *
23
     * @param GridField $gridField
24
     * @param SS_List $dataList
25
     * @return SS_List
26
     */
27
    public function getManipulatedData(GridField $gridField, SS_List $dataList)
28
    {
29
        // If we are lazy loading an empty the list
30
        if ($this->isLazy($gridField)) {
31
            if ($dataList instanceof Filterable) {
32
                // If our original list can be filtered, filter out all results.
33
                $dataList = $dataList->byIDs([-1]);
34
            } else {
35
                // If not, create an empty list instead.
36
                $dataList = ArrayList::create([]);
37
            }
38
        }
39
        return $dataList;
40
    }
41
42
    /**
43
     * Apply an appropriate CSS class to `$gridField` based on whatever the current request is lazy loadable or not.
44
     *
45
     * @param GridField $gridField
46
     * @return array
47
     */
48
    public function getHTMLFragments($gridField)
49
    {
50
        $gridField->addExtraClass($this->isLazy($gridField) ?
51
            'grid-field--lazy-loadable' :
52
            'grid-field--lazy-loaded');
53
        return [];
54
    }
55
56
    /**
57
     * Detect if the current request should include results.
58
     * @param GridField $gridField
59
     * @return bool
60
     */
61
    private function isLazy(GridField $gridField)
62
    {
63
        return
64
            $gridField->getRequest()->getHeader('X-Pjax') !== 'CurrentField' &&
65
            $this->isInTabSet($gridField);
66
    }
67
68
    /**
69
     * Recursively check if $field is inside a TabSet.
70
     * @param FormField $field
71
     * @return bool
72
     */
73
    private function isInTabSet(FormField $field)
74
    {
75
        $list = $field->getContainerFieldList();
76
        if ($list && $containerField = $list->getContainerField()) {
77
            // Classes that extends TabSet might not have the expected JS to lazy load.
78
            return get_class($containerField) === TabSet::class
79
                ?: $this->isInTabSet($containerField);
80
        }
81
82
        return false;
83
    }
84
}
85