Completed
Push — master ( 12981b...2f1b03 )
by Robbie
14s
created

GridFieldAddClassesButton   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 243
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 26.76%

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 5
dl 0
loc 243
ccs 19
cts 71
cp 0.2676
rs 10
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A setButtonName() 0 5 1
A getButtonName() 0 4 1
A getFragment() 0 4 1
A setFragment() 0 5 1
A getButtonClass() 0 4 1
A setButtonClass() 0 5 1
A getClasses() 0 4 1
A getAction() 0 4 1
A getClassesCreate() 0 13 3
A setClasses() 0 7 3
B getHTMLFragments() 0 33 4
A getActions() 0 6 1
A handleAction() 0 9 2
A handleAdd() 0 18 3
1
<?php
2
3
/**
4
 * A button which allows objects to be created with a specified classname(s)
5
 */
6
class GridFieldAddClassesButton extends Object implements GridField_HTMLProvider, GridField_ActionProvider
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
7
{
8
9
    /**
10
     * Name of fragment to insert into
11
     *
12
     * @var string
13
     */
14
    protected $targetFragment;
15
16
    /**
17
     * Button title
18
     *
19
     * @var string
20
     */
21
    protected $buttonName;
22
23
    /**
24
     * Additonal CSS classes for the button
25
     *
26
     * @var string
27
     */
28
    protected $buttonClass = null;
29
30
    /**
31
     * Class names
32
     *
33
     * @var array
34
     */
35
    protected $modelClasses = null;
36
37
    /**
38
     * @param array $classes Class or list of classes to create.
39
     * If you enter more than one class, each click of the "add" button will create one of each
40
     * @param string $targetFragment The fragment to render the button into
41
     */
42 2
    public function __construct($classes, $targetFragment = 'buttons-before-left')
43
    {
44 2
        parent::__construct();
45 2
        $this->setClasses($classes);
46 2
        $this->setFragment($targetFragment);
47 2
    }
48
49
    /**
50
     * Change the button name
51
     *
52
     * @param string $name
53
     * @return $this
54
     */
55 2
    public function setButtonName($name)
56
    {
57 2
        $this->buttonName = $name;
58 2
        return $this;
59
    }
60
61
    /**
62
     * Get the button name
63
     *
64
     * @return string
65
     */
66
    public function getButtonName()
67
    {
68
        return $this->buttonName;
69
    }
70
71
    /**
72
     * Gets the fragment name this button is rendered into.
73
     *
74
     * @return string
75
     */
76
    public function getFragment()
77
    {
78
        return $this->targetFragment;
79
    }
80
81
    /**
82
     * Sets the fragment name this button is rendered into.
83
     *
84
     * @param string $fragment
85
     * @return GridFieldAddNewInlineButton $this
86
     */
87 2
    public function setFragment($fragment)
88
    {
89 2
        $this->targetFragment = $fragment;
90 2
        return $this;
91
    }
92
93
    /**
94
     * Get extra button class
95
     *
96
     * @return string
97
     */
98
    public function getButtonClass()
99
    {
100
        return $this->buttonClass;
101
    }
102
103
    /**
104
     * Sets extra CSS classes for this button
105
     *
106
     * @param string $buttonClass
107
     * @return $this
108
     */
109 2
    public function setButtonClass($buttonClass)
110
    {
111 2
        $this->buttonClass = $buttonClass;
112 2
        return $this;
113
    }
114
115
116
    /**
117
     * Get the classes of the objects to create
118
     *
119
     * @return array
120
     */
121
    public function getClasses()
122
    {
123
        return $this->modelClasses;
124
    }
125
126
    /**
127
     * Gets the list of classes which can be created, with checks for permissions.
128
     * Will fallback to the default model class for the given DataGrid
129
     *
130
     * @param DataGrid $grid
131
     * @return array
132
     */
133
    public function getClassesCreate($grid)
134
    {
135
        // Get explicit or fallback class list
136
        $classes = $this->getClasses();
137
        if (empty($classes) && $grid) {
138
            $classes = array($grid->getModelClass());
139
        }
140
141
        // Filter out classes without permission
142
        return array_filter($classes, function ($class) {
143
            return singleton($class)->canCreate();
144
        });
145
    }
146
147
    /**
148
     * Specify the classes to create
149
     *
150
     * @param array $classes
151
     */
152 2
    public function setClasses($classes)
153
    {
154 2
        if (!is_array($classes)) {
155 2
            $classes = $classes ? array($classes) : array();
156
        }
157 2
        $this->modelClasses = $classes;
158 2
    }
159
160
    public function getHTMLFragments($grid)
161
    {
162
        // Check create permission
163
        $singleton = singleton($grid->getModelClass());
164
        if (!$singleton->canCreate()) {
165
            return array();
166
        }
167
168
        // Get button name
169
        $buttonName = $this->getButtonName();
170
        if (!$buttonName) {
171
            // provide a default button name, can be changed by calling {@link setButtonName()} on this component
172
            $objectName = $singleton->i18n_singular_name();
173
            $buttonName = _t('GridField.Add', 'Add {name}', array('name' => $objectName));
0 ignored issues
show
Documentation introduced by
array('name' => $objectName) is of type array<string,?,{"name":"?"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
174
        }
175
176
        $addAction = new GridField_FormAction(
177
            $grid,
178
            $this->getAction(),
179
            $buttonName,
180
            $this->getAction(),
181
            array()
182
        );
183
        $addAction->setAttribute('data-icon', 'add');
184
185
        if ($this->getButtonClass()) {
186
            $addAction->addExtraClass($this->getButtonClass());
187
        }
188
189
        return array(
190
            $this->targetFragment => $addAction->forTemplate()
191
        );
192
    }
193
194
    /**
195
     * {@inheritDoc}
196
     */
197
    public function getActions($gridField)
198
    {
199
        return array(
200
            $this->getAction()
201
        );
202
    }
203
204
    /**
205
     * Get the action suburl for this component
206
     *
207
     * @return string
208
     */
209
    protected function getAction()
210
    {
211
        return 'add-classes-' . strtolower(implode('-', $this->getClasses()));
212
    }
213
214
    public function handleAction(GridField $gridField, $actionName, $arguments, $data)
215
    {
216
        switch (strtolower($actionName)) {
217
            case $this->getAction():
218
                return $this->handleAdd($gridField);
219
            default:
220
                return null;
221
        }
222
    }
223
224
    /**
225
     * Handles adding a new instance of a selected class.
226
     *
227
     * @param GridField $grid
228
     * @return null
229
     */
230
    public function handleAdd($grid)
231
    {
232
        $classes = $this->getClassesCreate($grid);
0 ignored issues
show
Documentation introduced by
$grid is of type object<GridField>, but the function expects a object<DataGrid>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
233
        if (empty($classes)) {
234
            throw new SS_HTTPResponse_Exception(400);
235
        }
236
237
        // Add item to gridfield
238
        $list = $grid->getList();
239
        foreach ($classes as $class) {
240
            $item = $class::create();
241
            $item->write();
242
            $list->add($item);
243
        }
244
245
        // Should trigger a simple reload
246
        return null;
247
    }
248
}
249