1 <?php
2 3 4 5 6 7 8 9 10 11 12
13 class PermissionCheckboxSetField extends FormField {
14
15 16 17 18
19 protected $hiddenPermissions = array();
20
21 22 23
24 protected $records = null;
25
26 27 28
29 protected $source = null;
30
31 32 33 34 35 36 37 38 39 40
41 function __construct($name, $title, $managedClass, $filterField, $records = null) {
42 $this->filterField = $filterField;
43 $this->managedClass = $managedClass;
44
45 if(is_a($records, 'DataObjectSet')) {
46 $this->records = $records;
47 } elseif(is_a($records, 'DataObject')) {
48 $this->records = new DataObjectSet($records);
49 } elseif($records) {
50 throw new InvalidArgumentException('$record should be either a Group record, or a DataObjectSet of Group records');
51 }
52
53
54 $this->source = Permission::get_codes(true);
55
56 parent::__construct($name, $title);
57 }
58
59 60 61
62 function setHiddenPermissions($codes) {
63 $this->hiddenPermissions = $codes;
64 }
65
66 67 68
69 function getHiddenPermissions() {
70 return $this->hiddenPermissions;
71 }
72
73 function Field() {
74 Requirements::css(SAPPHIRE_DIR . '/css/CheckboxSetField.css');
75 Requirements::javascript(SAPPHIRE_DIR . '/javascript/PermissionCheckboxSetField.js');
76
77 $uninheritedCodes = array();
78 $inheritedCodes = array();
79 $records = ($this->records) ? $this->records : new DataObjectSet();
80
81
82 if(is_object($this->form)) {
83 $record = $this->form->getRecord();
84 if(
85 $record
86 && (is_a($record, 'Group') || is_a($record, 'PermissionRole'))
87 && !$records->find('ID', $record->ID)
88 ) {
89 $records->push($record);
90 }
91 }
92
93
94 foreach($records as $record) {
95
96 $relationMethod = $this->name;
97 foreach($record->$relationMethod() as $permission) {
98 if(!isset($uninheritedCodes[$permission->Code])) $uninheritedCodes[$permission->Code] = array();
99 $uninheritedCodes[$permission->Code][] = sprintf(
100 _t('PermissionCheckboxSetField.AssignedTo', 'assigned to "%s"'),
101 $record->Title
102 );
103 }
104
105
106
107 if(is_a($record, 'Group')) {
108
109 if ($record->Roles()->Count()) {
110 foreach($record->Roles() as $role) {
111 foreach($role->Codes() as $code) {
112 if (!isset($inheritedCodes[$code->Code])) $inheritedCodes[$code->Code] = array();
113 $inheritedCodes[$code->Code][] = sprintf(
114 _t(
115 'PermissionCheckboxSetField.FromRole',
116 'inherited from role "%s"',
117 PR_MEDIUM,
118 'A permission inherited from a certain permission role'
119 ),
120 $role->Title
121 );
122 }
123 }
124 }
125
126
127 $parentGroups = $record->getAncestors();
128 if ($parentGroups) {
129 foreach ($parentGroups as $parent) {
130 if (!$parent->Roles()->Count()) continue;
131 foreach($parent->Roles() as $role) {
132 if ($role->Codes()) {
133 foreach($role->Codes() as $code) {
134 if (!isset($inheritedCodes[$code->Code])) $inheritedCodes[$code->Code] = array();
135 $inheritedCodes[$code->Code][] = sprintf(
136 _t(
137 'PermissionCheckboxSetField.FromRoleOnGroup',
138 'inherited from role "%s" on group "%s"',
139 PR_MEDIUM,
140 'A permission inherited from a role on a certain group'
141 ),
142 $role->Title,
143 $parent->Title
144 );
145 }
146 }
147 }
148 if ($parent->Permissions()->Count()) {
149 foreach($parent->Permissions() as $permission) {
150 if (!isset($inheritedCodes[$permission->Code])) $inheritedCodes[$permission->Code] = array();
151 $inheritedCodes[$permission->Code][] =
152 sprintf(
153 _t(
154 'PermissionCheckboxSetField.FromGroup',
155 'inherited from group "%s"',
156 PR_MEDIUM,
157 'A permission inherited from a certain group'
158 ),
159 $parent->Title
160 );
161 }
162 }
163 }
164 }
165 }
166 }
167
168 $odd = 0;
169 $options = '';
170 if($this->source) {
171
172 foreach($this->source as $categoryName => $permissions) {
173 $options .= "<li><h5>$categoryName</h5></li>";
174 foreach($permissions as $code => $permission) {
175 if(in_array($code, $this->hiddenPermissions)) continue;
176
177 $value = $permission['name'];
178
179 $odd = ($odd + 1) % 2;
180 $extraClass = $odd ? 'odd' : 'even';
181 $extraClass .= ' val' . str_replace(' ', '', $code);
182 $itemID = $this->id() . '_' . ereg_replace('[^a-zA-Z0-9]+', '', $code);
183 $checked = $disabled = $inheritMessage = '';
184 $checked = (isset($uninheritedCodes[$code]) || isset($inheritedCodes[$code])) ? ' checked="checked"' : '';
185 $title = $permission['help'] ? 'title="' . htmlspecialchars($permission['help']) . '" ' : '';
186
187 if (isset($inheritedCodes[$code])) {
188
189 $disabled = ' disabled="true"';
190 $inheritMessage = ' (' . join(', ', $inheritedCodes[$code]) . ')';
191 } elseif($this->records && $this->records->Count() > 1 && isset($uninheritedCodes[$code])) {
192
193
194 $inheritMessage = ' (' . join(', ', $uninheritedCodes[$code]).')';
195 }
196
197
198 if($this->readonly) $disabled = ' disabled="true"';
199
200 $inheritMessage = '<small>' . $inheritMessage . '</small>';
201 $options .= "<li class=\"$extraClass\">" .
202 "<input id=\"$itemID\"$disabled name=\"$this->name[$code]\" type=\"checkbox\" value=\"$code\"$checked class=\"checkbox\" />" .
203 "<label {$title}for=\"$itemID\">$value$inheritMessage</label>" .
204 "</li>\n";
205 }
206 }
207 }
208
209 return "<ul id=\"{$this->id()}\" class=\"optionset checkboxsetfield{$this->extraClass()}\">\n$options</ul>\n";
210 }
211
212 213 214 215 216
217 function saveInto(DataObject $record) {
218 $fieldname = $this->name;
219 $managedClass = $this->managedClass;
220
221
222 $permissions = $record->$fieldname();
223 foreach ( $permissions as $permission ) {
224 $permission->delete();
225 }
226
227 if($fieldname && $record && ($record->has_many($fieldname) || $record->many_many($fieldname))) {
228 $idList = array();
229 if($this->value) foreach($this->value as $id => $bool) {
230 if($bool) {
231 $perm = new $managedClass();
232 $perm->{$this->filterField} = $record->ID;
233 $perm->Code = $id;
234 $perm->write();
235 }
236 }
237 }
238 }
239
240 241 242
243 function performReadonlyTransformation() {
244 $readonly = new PermissionCheckboxSetField_Readonly(
245 $this->name,
246 $this->title,
247 $this->managedClass,
248 $this->filterField,
249 $this->records
250 );
251
252 return $readonly;
253 }
254
255 256 257 258 259
260 function getAssignedPermissionCodes() {
261 if(!$this->records) return false;
262
263
264
265 return $codes;
266 }
267 }
268
269 270 271 272 273 274 275
276 class PermissionCheckboxSetField_Readonly extends PermissionCheckboxSetField {
277
278 protected $readonly = true;
279
280 function saveInto($record) {
281 return false;
282 }
283 }
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-