This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace SilverStripe\GridFieldAddOns; |
||
4 | |||
5 | use SilverStripe\ORM\ArrayList; |
||
6 | use SilverStripe\View\ArrayData; |
||
7 | use SilverStripe\Security\Member; |
||
8 | use SilverStripe\Security\Security; |
||
9 | use SilverStripe\View\Requirements; |
||
10 | use SilverStripe\View\ViewableData; |
||
11 | use SilverStripe\Core\Config\Config; |
||
12 | use SilverStripe\ORM\ValidationException; |
||
13 | use SilverStripe\Forms\GridField\GridField_URLHandler; |
||
14 | use SilverStripe\Forms\GridField\GridFieldDataColumns; |
||
15 | use SilverStripe\Forms\GridField\GridField_HTMLProvider; |
||
16 | use SilverStripe\Forms\GridField\GridField_ColumnProvider; |
||
17 | use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor; |
||
18 | use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor; |
||
19 | |||
20 | class GridFieldUserColumns extends ViewableData implements GridField_ColumnProvider, GridField_HTMLProvider, GridField_URLHandler |
||
21 | { |
||
22 | |||
23 | static $static_field_for_extra_columns = 'extra_summary_fields'; |
||
24 | |||
25 | protected $gridField; |
||
26 | protected $default_columns; |
||
27 | |||
28 | function init($gridField) |
||
29 | { |
||
30 | $this->gridField = $gridField; |
||
31 | } |
||
32 | |||
33 | /** |
||
34 | * This component is not providing columns but manipulating the columns provided by GridFieldDataColumns. |
||
35 | * |
||
36 | * @param GridField $gridField |
||
37 | * @param array - List reference of all column names. |
||
38 | */ |
||
39 | public function augmentColumns($gridField, &$columns) |
||
40 | { |
||
41 | |||
42 | $this->init($gridField); |
||
43 | |||
44 | Requirements::javascript('i-lateral/silverstripe-gridfield-addons:javascript/GridFieldUserColumns.js'); |
||
45 | Requirements::css('i-lateral/silverstripe-gridfield-addons:css/GridFieldUserColumns.css'); |
||
46 | |||
47 | $usercolumns = $this->currentColumns(); |
||
48 | $extracolumns = array_diff($columns, $this->availableColumns()); |
||
49 | $displaycolumns = array_values(array_unique(array_merge(array_keys($usercolumns), $extracolumns))); |
||
50 | |||
51 | $datacolumnscomponent = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class); |
||
52 | $datacolumnscomponent->setDisplayFields($usercolumns); |
||
53 | |||
54 | $columns = $displaycolumns; |
||
55 | } |
||
56 | |||
57 | function defaultColumns() |
||
58 | { |
||
59 | |||
60 | if (!$this->default_columns) { |
||
61 | if (!$this->gridField) { |
||
62 | throw new ValidationException('GridField not yet set. Do not call GridFieldUserColumns::defaultColumns() before GridFieldUserColumns::augmentColumns().'); |
||
63 | } |
||
64 | $datacolumnscomponent = $this->gridField->getConfig()->getComponentByType(GridFieldDataColumns::class); |
||
65 | $this->default_columns = $datacolumnscomponent->getDisplayFields($this->gridField); |
||
66 | } |
||
67 | |||
68 | return $this->default_columns; |
||
69 | } |
||
70 | |||
71 | function userColumns() |
||
72 | { |
||
73 | |||
74 | if (!$this->gridField) { |
||
75 | throw new ValidationException('GridField not yet set. Do not call GridFieldUserColumns::userColumns() before GridFieldUserColumns::augmentColumns().'); |
||
76 | } |
||
77 | $member = Security::getCurrentUser(); |
||
78 | if ($member->hasField('GridFieldUserColumns') && |
||
79 | $member->GridFieldUserColumns && |
||
80 | ($usercolumns = $member->getGridFieldUserColumnsFor($this->gridField->getList()->dataClass())) |
||
81 | ) { |
||
82 | return $usercolumns; |
||
83 | } |
||
84 | return false; |
||
85 | } |
||
86 | |||
87 | function currentColumns() |
||
88 | { |
||
89 | $user = $this->userColumns(); |
||
90 | return is_array($user) ? $user : $this->defaultColumns(); |
||
91 | } |
||
92 | |||
93 | function availableColumns() |
||
94 | { |
||
95 | if (!$this->gridField) { |
||
96 | throw new ValidationException('GridField not yet set. Do not call GridFieldUserColumns::userColumns() before GridFieldUserColumns::augmentColumns().'); |
||
97 | } |
||
98 | |||
99 | $class = $this->gridField->getList()->dataClass(); |
||
100 | $default = $this->defaultColumns(); |
||
101 | $user = $this->userColumns(); |
||
102 | $extra_cols = Config::inst()->get($class, self::$static_field_for_extra_columns); |
||
103 | $extra = $this->addFieldLabels($extra_cols); |
||
104 | |||
105 | $default = is_array($extra) ? array_merge($default, $extra) : $default; |
||
106 | |||
107 | return is_array($user) ? array_merge($user, $default) : $default; |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * Look for and add any needed field labels (used mostly for extra_summary_fields) |
||
112 | * and return new array |
||
113 | * |
||
114 | * @return array |
||
115 | */ |
||
116 | protected function addFieldLabels($fields) |
||
117 | { |
||
118 | $class = $this->gridField->getList()->dataClass(); |
||
119 | $obj = $class::singleton(); |
||
120 | |||
121 | // Merge associative / numeric keys |
||
122 | $return = []; |
||
123 | foreach ($fields as $key => $value) { |
||
124 | if (is_int($key)) { |
||
125 | $key = $value; |
||
126 | } |
||
127 | $return[$key] = $value; |
||
128 | } |
||
129 | |||
130 | if (!$return) { |
||
0 ignored issues
–
show
|
|||
131 | $return = array(); |
||
132 | } |
||
133 | |||
134 | // Localize fields (if possible) |
||
135 | foreach ($obj->fieldLabels(false) as $name => $label) { |
||
136 | // only attempt to localize if the label definition is the same as the field name. |
||
137 | // this will preserve any custom labels set in the summary_fields configuration |
||
138 | if (isset($return[$name]) && $name === $return[$name]) { |
||
139 | $return[$name] = $label; |
||
140 | } |
||
141 | } |
||
142 | |||
143 | return $return; |
||
144 | } |
||
145 | |||
146 | // since we're not really provide columns we're not returning anything |
||
147 | public function getColumnsHandled($gridField) |
||
148 | { |
||
149 | return array(); |
||
150 | } |
||
151 | public function getColumnMetadata($gridField, $columnName) |
||
152 | { |
||
153 | return array(); |
||
154 | } |
||
155 | public function getColumnContent($gridField, $record, $columnName) |
||
156 | { |
||
157 | return false; |
||
158 | } |
||
159 | public function getColumnAttributes($gridField, $record, $columnName) |
||
160 | { |
||
161 | return array(); |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * Returns a map where the keys are fragment names and the values are pieces of HTML to add to these fragments. |
||
166 | * |
||
167 | * Here are 4 built-in fragments: 'header', 'footer', 'before', and 'after', but components may also specify |
||
168 | * fragments of their own. |
||
169 | * |
||
170 | * To specify a new fragment, specify a new fragment by including the text "$DefineFragment(fragmentname)" in the |
||
171 | * HTML that you return. Fragment names should only contain alphanumerics, -, and _. |
||
172 | * |
||
173 | * If you attempt to return HTML for a fragment that doesn't exist, an exception will be thrown when the GridField |
||
174 | * is rendered. |
||
175 | * |
||
176 | * @return Array |
||
177 | */ |
||
178 | public function getHTMLFragments($gridField) |
||
179 | { |
||
180 | |||
181 | $gridField->getList()->dataClass(); |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
SilverStripe\ORM\SS_List as the method dataClass() does only exist in the following implementations of said interface: SilverStripe\Forms\FieldList , SilverStripe\ORM\ArrayList , SilverStripe\ORM\DataList , SilverStripe\ORM\HasManyList , SilverStripe\ORM\ManyManyList , SilverStripe\ORM\ManyManyThroughList , SilverStripe\ORM\PolymorphicHasManyList , SilverStripe\ORM\RelationList , SilverStripe\ORM\UnsavedRelationList , SilverStripe\Security\Member_GroupSet .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
182 | $buttonlabel = _t('GridFieldAddOns.ChangeColumns', "Change Columns"); |
||
183 | |||
184 | return array( |
||
185 | 'buttons-before-right' => "<a class=\"action btn h-100 btn-outline-secondary action gridfield-setup\" data-icon=\"settings\">$buttonlabel</a>", |
||
186 | ); |
||
187 | } |
||
188 | |||
189 | public function getURLHandlers($gridField) |
||
190 | { |
||
191 | return array( |
||
192 | 'usercolumnsform' => 'UserColumnsForm', |
||
193 | 'saveusercolumns' => 'saveUserColumns', |
||
194 | ); |
||
195 | } |
||
196 | |||
197 | function UserColumnsForm($gridField, $request) |
||
198 | { |
||
199 | $this->init($gridField); |
||
200 | return $this->renderWith( |
||
201 | self::class.'_Form' |
||
202 | ); |
||
203 | } |
||
204 | |||
205 | function Columns() |
||
206 | { |
||
207 | $available = $this->availableColumns(); |
||
208 | $current = $this->currentColumns(); |
||
209 | |||
210 | $columns = new ArrayList(); |
||
211 | foreach ($available as $key => $val) { |
||
212 | $selected = array_search($val, $current) !== false; |
||
213 | $columns->push(new ArrayData(array('Name' => $key, 'Title' => $val, 'Selected' => $selected))); |
||
214 | } |
||
215 | return $columns; |
||
216 | } |
||
217 | |||
218 | function saveUserColumns($gridField, $request) |
||
219 | { |
||
220 | $this->init($gridField); |
||
221 | $available = $this->availableColumns(); |
||
222 | $postcolumns = $request->postVar('columns'); |
||
223 | $newcolumns = array(); |
||
224 | if (!is_array($postcolumns)) { |
||
225 | return json_encode('bad'); |
||
226 | } |
||
227 | foreach ($postcolumns as $col) { |
||
228 | list($name, $title) = explode(':', $col); |
||
229 | if (!isset($available[$name]) || $available[$name] != $title) { |
||
230 | return json_encode(array('bad', $this->gridField->getList()->dataClass())); |
||
231 | } |
||
232 | $newcolumns[$name] = $title; |
||
233 | } |
||
234 | Security::getCurrentUser()->setGridFieldUserColumnsFor($gridField->getList()->dataClass(), $newcolumns); |
||
235 | return json_encode('good'); |
||
236 | } |
||
237 | } |
||
238 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.