Passed
Push — master ( 0208b2...1155ca )
by Robbie
09:03
created

GridFieldDeleteAction::getRemoveRelation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Forms\GridField;
4
5
use SilverStripe\ORM\DataObject;
6
use SilverStripe\ORM\ValidationException;
7
8
/**
9
 * This class is a {@link GridField} component that adds a delete action for
10
 * objects.
11
 *
12
 * This component also supports unlinking a relation instead of deleting the
13
 * object.
14
 *
15
 * Use the {@link $removeRelation} property set in the constructor.
16
 *
17
 * <code>
18
 * $action = new GridFieldDeleteAction(); // delete objects permanently
19
 *
20
 * // removes the relation to object instead of deleting
21
 * $action = new GridFieldDeleteAction(true);
22
 * </code>
23
 */
24
class GridFieldDeleteAction implements GridField_ColumnProvider, GridField_ActionProvider, GridField_ActionMenuItem
25
{
26
27
    /**
28
     * If this is set to true, this {@link GridField_ActionProvider} will
29
     * remove the object from the list, instead of deleting.
30
     *
31
     * In the case of a has one, has many or many many list it will uncouple
32
     * the item from the list.
33
     *
34
     * @var boolean
35
     */
36
    protected $removeRelation = false;
37
38
    /**
39
     *
40
     * @param boolean $removeRelation - true if removing the item from the list, but not deleting it
41
     */
42
    public function __construct($removeRelation = false)
43
    {
44
        $this->setRemoveRelation($removeRelation);
45
    }
46
47
    /**
48
     * @inheritdoc
49
     */
50
    public function getTitle($gridField, $record, $columnName)
51
    {
52
        $field = $this->getRemoveAction($gridField, $record, $columnName);
53
54
        if ($field) {
55
            return $field->getAttribute('title');
56
        }
57
58
        return _t(__CLASS__ . '.Delete', "Delete");
59
    }
60
61
    /**
62
     * @inheritdoc
63
     */
64
    public function getGroup($gridField, $record, $columnName)
65
    {
66
        return GridField_ActionMenuItem::DEFAULT_GROUP;
67
    }
68
69
    /**
70
     *
71
     * @param GridField $gridField
72
     * @param DataObject $record
73
     * @param string $columnName
74
     * @return string|null the attribles for the action
75
     */
76
    public function getExtraData($gridField, $record, $columnName)
77
    {
78
79
        $field = $this->getRemoveAction($gridField, $record, $columnName);
80
81
        if ($field) {
82
            return $field->getAttributes();
83
        }
84
85
        return null;
86
    }
87
88
    /**
89
     * Add a column 'Delete'
90
     *
91
     * @param GridField $gridField
92
     * @param array $columns
93
     */
94
    public function augmentColumns($gridField, &$columns)
95
    {
96
        if (!in_array('Actions', $columns)) {
97
            $columns[] = 'Actions';
98
        }
99
    }
100
101
    /**
102
     * Return any special attributes that will be used for FormField::create_tag()
103
     *
104
     * @param GridField $gridField
105
     * @param DataObject $record
106
     * @param string $columnName
107
     * @return array
108
     */
109
    public function getColumnAttributes($gridField, $record, $columnName)
110
    {
111
        return ['class' => 'grid-field__col-compact'];
112
    }
113
114
    /**
115
     * Add the title
116
     *
117
     * @param GridField $gridField
118
     * @param string $columnName
119
     * @return array
120
     */
121
    public function getColumnMetadata($gridField, $columnName)
122
    {
123
        if ($columnName == 'Actions') {
124
            return ['title' => ''];
125
        }
126
    }
127
128
    /**
129
     * Which columns are handled by this component
130
     *
131
     * @param GridField $gridField
132
     * @return array
133
     */
134
    public function getColumnsHandled($gridField)
135
    {
136
        return ['Actions'];
137
    }
138
139
    /**
140
     * Which GridField actions are this component handling
141
     *
142
     * @param GridField $gridField
143
     * @return array
144
     */
145
    public function getActions($gridField)
146
    {
147
        return ['deleterecord', 'unlinkrelation'];
148
    }
149
150
    /**
151
     *
152
     * @param GridField $gridField
153
     * @param DataObject $record
154
     * @param string $columnName
155
     * @return string|null the HTML for the column
156
     */
157
    public function getColumnContent($gridField, $record, $columnName)
158
    {
159
        $field = $this->getRemoveAction($gridField, $record, $columnName);
160
161
        if ($field) {
162
            return $field->Field();
163
        }
164
165
        return null;
166
    }
167
168
    /**
169
     * Handle the actions and apply any changes to the GridField
170
     *
171
     * @param GridField $gridField
172
     * @param string $actionName
173
     * @param array $arguments
174
     * @param array $data Form data
175
     * @throws ValidationException
176
     */
177
    public function handleAction(GridField $gridField, $actionName, $arguments, $data)
178
    {
179
        if ($actionName == 'deleterecord' || $actionName == 'unlinkrelation') {
180
            /** @var DataObject $item */
181
            $item = $gridField->getList()->byID($arguments['RecordID']);
0 ignored issues
show
Bug introduced by
The method byID() does not exist on SilverStripe\ORM\SS_List. It seems like you code against a sub-type of said class. However, the method does not exist in SilverStripe\ORM\Sortable or SilverStripe\ORM\Limitable. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

181
            $item = $gridField->getList()->/** @scrutinizer ignore-call */ byID($arguments['RecordID']);
Loading history...
182
            if (!$item) {
0 ignored issues
show
introduced by
$item is of type SilverStripe\ORM\DataObject, thus it always evaluated to true. If $item can have other possible types, add them to src/Forms/GridField/GridFieldDeleteAction.php:180
Loading history...
183
                return;
184
            }
185
186
            if ($actionName == 'deleterecord') {
187
                if (!$item->canDelete()) {
188
                    throw new ValidationException(
189
                        _t(__CLASS__ . '.DeletePermissionsFailure', "No delete permissions")
190
                    );
191
                }
192
193
                $item->delete();
194
            } else {
195
                if (!$item->canEdit()) {
196
                    throw new ValidationException(
197
                        _t(__CLASS__ . '.EditPermissionsFailure', "No permission to unlink record")
198
                    );
199
                }
200
201
                $gridField->getList()->remove($item);
202
            }
203
        }
204
    }
205
206
    /**
207
     *
208
     * @param GridField $gridField
209
     * @param DataObject $record
210
     * @param string $columnName
211
     * @return GridField_FormAction|null
212
     */
213
    private function getRemoveAction($gridField, $record, $columnName)
0 ignored issues
show
Unused Code introduced by
The parameter $columnName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

213
    private function getRemoveAction($gridField, $record, /** @scrutinizer ignore-unused */ $columnName)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
214
    {
215
        if ($this->getRemoveRelation()) {
216
            if (!$record->canEdit()) {
217
                return null;
218
            }
219
            $title = _t(__CLASS__ . '.UnlinkRelation', "Unlink");
220
221
            $field = GridField_FormAction::create(
222
                $gridField,
223
                'UnlinkRelation' . $record->ID,
224
                false,
225
                "unlinkrelation",
226
                ['RecordID' => $record->ID]
227
            )
228
                ->addExtraClass(
229
                    'btn btn--no-text btn--icon-md font-icon-link-broken grid-field__icon-action '
230
                    . 'gridfield-button-unlink action-menu--handled'
231
                )
232
                ->setAttribute('classNames', 'gridfield-button-unlink font-icon-link-broken')
233
                ->setDescription($title)
234
                ->setAttribute('aria-label', $title);
235
        } else {
236
            if (!$record->canDelete()) {
237
                return null;
238
            }
239
            $title = _t(__CLASS__ . '.Delete', "Delete");
240
241
            $field = GridField_FormAction::create(
242
                $gridField,
243
                'DeleteRecord' . $record->ID,
244
                false,
245
                "deleterecord",
246
                ['RecordID' => $record->ID]
247
            )
248
                ->addExtraClass(
249
                    'gridfield-button-delete btn--icon-md font-icon-trash-bin btn--no-text '
250
                    . 'grid-field__icon-action action-menu--handled'
251
                )
252
                ->setAttribute('classNames', 'gridfield-button-delete font-icon-trash')
253
                ->setDescription($title)
254
                ->setAttribute('aria-label', $title);
255
        }
256
257
        return $field;
258
    }
259
260
    /**
261
     * Get whether to remove or delete the relation
262
     *
263
     * @return bool
264
     */
265
    public function getRemoveRelation()
266
    {
267
        return $this->removeRelation;
268
    }
269
270
    /**
271
     * Set whether to remove or delete the relation
272
     * @param bool $removeRelation
273
     * @return $this
274
     */
275
    public function setRemoveRelation($removeRelation)
276
    {
277
        $this->removeRelation = (bool) $removeRelation;
278
        return $this;
279
    }
280
}
281