Completed
Push — master ( 4ee163...3aefa6 )
by Mohamed
02:49
created

HasOneSelectorField   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 188
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 5

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 13
lcom 2
cbo 5
dl 0
loc 188
ccs 46
cts 46
cp 1
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A setEmptyString() 0 6 1
A setDataClass() 0 6 1
A getDataClass() 0 4 1
A getRecord() 0 4 1
A setOwner() 0 6 1
A getOwner() 0 4 1
A getList() 0 8 1
A getManipulatedList() 0 8 1
A getOptionalTableBody() 0 12 2
A __construct() 0 26 1
A setRecord() 0 8 2
1
<?php
2
3
/**
4
 * Class HasOneSelectorField provides CMS field to manage selecting/adding/editing object within
5
 * has_one relation of the current object being edited
6
 */
7
class HasOneSelectorField extends GridField
8
{
9
    /**
10
     * Name of the list data class
11
     *
12
     * @var string
13
     */
14
    protected $dataClass;
15
16
    /**
17
     * Instance of data object that contains the has one relation
18
     *
19
     * @var DataObject
20
     */
21
    protected $owner;
22
23
    /**
24
     * Text to display when no record selected
25
     *
26
     * @var string
27
     */
28
    protected $emptyString = 'No item selected';
29
30
    /**
31
     * HasOneSelectorField constructor.
32
     * @param string      $name
33
     * @param string|null $title
34
     * @param DataObject  $owner
35
     * @param string      $dataClass
36
     */
37 3
    public function __construct($name, $title = null, DataObject $owner, $dataClass = DataObject::class)
38
    {
39
        // Include styles
40 3
        Requirements::css('hasoneselector/client/styles/hasoneselector.css');
41
42
        // Initiate grid field configuration based on relation editor
43 3
        $config = GridFieldConfig_RelationEditor::create();
44 3
        $config->removeComponentsByType('GridFieldToolbarHeader');
45 3
        $config->removeComponentsByType('GridFieldSortableHeader');
46 3
        $config->removeComponentsByType('GridFieldFilterHeader');
47 3
        $config->removeComponentsByType('GridFieldPageCount');
48 3
        $config->removeComponentsByType('GridFieldPaginator');
49
50
        // Set the data class of the list
51 3
        $this->setDataClass($dataClass);
52
        // Set the owner data object that contains the has one relation
53 3
        $this->setOwner($owner);
54
55
        // Instance of data list that manages the grid field data
56 3
        $dataList = HasOneSelectorDataList::create($this);
57
58
        // Set empty string based on the data class
59 3
        $this->setEmptyString(sprintf('No %s selected', strtolower(singleton($dataClass)->singular_name())));
60
61 3
        parent::__construct($name . 'ID', $title, $dataList, $config);
62 3
    }
63
64
    /**
65
     * Set empty string when no record selected
66
     *
67
     * @param  string $string
68
     * @return $this
69
     */
70 3
    public function setEmptyString($string)
71
    {
72 3
        $this->emptyString = $string;
73
74 3
        return $this;
75
    }
76
77
    /**
78
     * set the name of the data class for current list
79
     *
80
     * @param  string $class
81
     * @return $this
82
     */
83 3
    public function setDataClass($class)
84
    {
85 3
        $this->dataClass = $class;
86
87 3
        return $this;
88
    }
89
90
    /**
91
     * Get the name of the data class for current list
92
     *
93
     * @return string
94
     */
95 3
    public function getDataClass()
96
    {
97 3
        return $this->dataClass;
98
    }
99
100
    /**
101
     * Get the record of the has one relation for current owner object
102
     *
103
     * @return DataObject|null
104
     * @throws Exception
105
     */
106 3
    public function getRecord()
107
    {
108 3
        return $this->getOwner()->{rtrim($this->getName(), 'ID')}();
109
    }
110
111
    /**
112
     * Set the record of the has one relation for current owner object
113
     *
114
     * @param  DataObject|null     $object
115
     * @return void
116
     * @throws ValidationException
117
     */
118 1
    public function setRecord($object)
119
    {
120 1
        $owner      = $this->getOwner();
121 1
        $recordName = $this->getName();
122
123 1
        $owner->{$recordName} = is_null($object) ? 0 : $object->ID;
124 1
        $owner->write();
125 1
    }
126
127
    /**
128
     * Set instance of data object that has the has one relation
129
     *
130
     * @param  DataObject $owner
131
     * @return $this
132
     */
133 3
    public function setOwner(DataObject $owner)
134
    {
135 3
        $this->owner = $owner;
136
137 3
        return $this;
138
    }
139
140
    /**
141
     * Get instance of data object that has the has one relation
142
     *
143
     * @return DataObject
144
     */
145 3
    public function getOwner()
146
    {
147 3
        return $this->owner;
148
    }
149
150
    /**
151
     * Get the data source.
152
     *
153
     * @return SS_List
154
     */
155 3
    public function getList()
156
    {
157
        // Get current record ID
158 3
        $id = (int) $this->getOwner()->{$this->getName()};
159
160
        // Filter current list to display current record (has one) value
161 3
        return $this->list->filter('ID', $id);
162
    }
163
164
    /**
165
     * Get the data source after applying every {@link GridField_DataManipulator} to it.
166
     *
167
     * @return SS_List
168
     */
169 3
    public function getManipulatedList()
170
    {
171
        // Call manipulation from parent class to update current record (has one)
172 3
        parent::getManipulatedList();
173
174
        // Get list of data based on new record
175 3
        return $this->getList();
176
    }
177
178
    /**
179
     * @param  array  $content
180
     * @return string
181
     */
182 2
    protected function getOptionalTableBody(array $content)
183
    {
184
        // Text used by grid field for no items
185 2
        $noItemsText = _t('GridField.NoItemsFound', 'No items found');
186
187
        // If we have no items text in the body, then replace the text with customised string
188 2
        if (strpos($content['body'], $noItemsText) !== false) {
189 2
            $content['body'] = str_replace($noItemsText, $this->emptyString, $content['body']);
190
        }
191
192 2
        return parent::getOptionalTableBody($content);
193
    }
194
}
195