1: <?php
2: /**
3: * Instance of a single permissioning object.
4: *
5: * Copyright 2009-2012 Horde LLC (http://www.horde.org/)
6: *
7: * See the enclosed file COPYING for license information (LGPL). If you
8: * did not receive this file, see http://www.horde.org/licenses/lgpl21.
9: *
10: * @author Chuck Hagenbuch <chuck@horde.org>
11: * @author Jan Schneider <jan@horde.org>
12: * @category Horde
13: * @package Perms
14: */
15: class Horde_Perms_Permission
16: {
17: /**
18: * TODO
19: */
20: public $data;
21:
22: /**
23: * TODO
24: */
25: public $name;
26:
27: /**
28: * Incrementing version number if cached classes change.
29: *
30: * @var integer
31: */
32: protected $_cacheVersion;
33:
34: /**
35: * Constructor.
36: *
37: * @param string $name The name of the perm.
38: * @param integer $cacheVersion The revision number of the class.
39: * @param string $type The permission type.
40: * @param array $params A hash with any parameters that the
41: * permission type needs.
42: */
43: public function __construct($name, $cacheVersion = null, $type = 'matrix',
44: $params = null)
45: {
46: $this->setName($name);
47: $this->setCacheVersion($cacheVersion);
48: $this->data['type'] = $type;
49: if (is_array($params)) {
50: $this->data['params'] = $params;
51: }
52: }
53:
54: /**
55: * Sets the revision number of the class.
56: *
57: * @param integer $cacheVersion The revision number of the class.
58: */
59: public function setCacheVersion($cacheVersion)
60: {
61: $this->_cacheVersion = $cacheVersion;
62: }
63:
64: /**
65: * Gets one of the attributes of the object, or null if it isn't defined.
66: *
67: * @param string $attribute The attribute to get.
68: *
69: * @return mixed The value of the attribute, or null.
70: */
71: public function get($attribute)
72: {
73: if (isset($this->data[$attribute])) {
74: return $this->data[$attribute];
75: }
76:
77: return ($attribute == 'type') ? 'matrix' : null;
78: }
79:
80: /**
81: * Get permission name.
82: *
83: * @return string Permission name.
84: */
85: public function getName()
86: {
87: return $this->name;
88: }
89:
90: /**
91: * Set permission name
92: *
93: * @param string $name Permission name.
94: */
95: public function setName($name)
96: {
97: $this->name = $name;
98: }
99:
100: /**
101: * Get permission details.
102: *
103: * @return array Permission details.
104: */
105: public function getData()
106: {
107: return $this->data;
108: }
109:
110: /**
111: * Set permission details.
112: *
113: * @param string $data Permission details.
114: */
115: public function setData($data)
116: {
117: $this->data = $data;
118: }
119:
120: /**
121: * Updates the permissions based on data passed in the array.
122: *
123: * @param array $perms An array containing the permissions which are to
124: * be updated.
125: */
126: public function updatePermissions($perms)
127: {
128: $type = $this->get('type');
129:
130: if ($type == 'matrix') {
131: /* Array of permission types to iterate through. */
132: $perm_types = Horde_Perms::getPermsArray();
133: }
134:
135: foreach ($perms as $perm_class => $perm_values) {
136: switch ($perm_class) {
137: case 'default':
138: case 'guest':
139: case 'creator':
140: if ($type == 'matrix') {
141: foreach ($perm_types as $val => $label) {
142: if (!empty($perm_values[$val])) {
143: $this->setPerm($perm_class, $val, false);
144: } else {
145: $this->unsetPerm($perm_class, $val, false);
146: }
147: }
148: } elseif (!empty($perm_values)) {
149: $this->setPerm($perm_class, $perm_values, false);
150: } else {
151: $this->unsetPerm($perm_class, null, false);
152: }
153: break;
154:
155: case 'u':
156: case 'g':
157: $permId = array('class' => $perm_class == 'u' ? 'users' : 'groups');
158: /* Figure out what names that are stored in this permission
159: * class have not been submitted for an update, ie. have been
160: * removed entirely. */
161: $current_names = isset($this->data[$permId['class']])
162: ? array_keys($this->data[$permId['class']])
163: : array();
164: $updated_names = array_keys($perm_values);
165: $removed_names = array_diff($current_names, $updated_names);
166:
167: /* Remove any names that have been completely unset. */
168: foreach ($removed_names as $name) {
169: unset($this->data[$permId['class']][$name]);
170: }
171:
172: /* If nothing to actually update finish with this case. */
173: if (is_null($perm_values)) {
174: continue;
175: }
176:
177: /* Loop through the names and update permissions for each. */
178: foreach ($perm_values as $name => $name_values) {
179: $permId['name'] = $name;
180:
181: if ($type == 'matrix') {
182: foreach ($perm_types as $val => $label) {
183: if (!empty($name_values[$val])) {
184: $this->setPerm($permId, $val, false);
185: } else {
186: $this->unsetPerm($permId, $val, false);
187: }
188: }
189: } elseif (!empty($name_values)) {
190: $this->setPerm($permId, $name_values, false);
191: } else {
192: $this->unsetPerm($permId, null, false);
193: }
194: }
195: break;
196: }
197: }
198: }
199:
200: /**
201: * TODO
202: */
203: public function setPerm($permId, $permission, $update = true)
204: {
205: if (is_array($permId)) {
206: if (empty($permId['name'])) {
207: return;
208: }
209: if ($this->get('type') == 'matrix' &&
210: isset($this->data[$permId['class']][$permId['name']])) {
211: $this->data[$permId['class']][$permId['name']] |= $permission;
212: } else {
213: $this->data[$permId['class']][$permId['name']] = $permission;
214: }
215: } else {
216: if ($this->get('type') == 'matrix' &&
217: isset($this->data[$permId])) {
218: $this->data[$permId] |= $permission;
219: } else {
220: $this->data[$permId] = $permission;
221: }
222: }
223:
224: if ($update) {
225: $this->save();
226: }
227: }
228:
229: /**
230: * TODO
231: */
232: public function unsetPerm($permId, $permission, $update = true)
233: {
234: if (is_array($permId)) {
235: if (empty($permId['name'])) {
236: return;
237: }
238:
239: if ($this->get('type') == 'matrix') {
240: if (isset($this->data[$permId['class']][$permId['name']])) {
241: $this->data[$permId['class']][$permId['name']] &= ~$permission;
242: if (empty($this->data[$permId['class']][$permId['name']])) {
243: unset($this->data[$permId['class']][$permId['name']]);
244: }
245: } else {
246: $update = false;
247: }
248: } else {
249: unset($this->data[$permId['class']][$permId['name']]);
250: }
251: } else {
252: if ($this->get('type') == 'matrix') {
253: if (isset($this->data[$permId])) {
254: $this->data[$permId] &= ~$permission;
255: } else {
256: $update = false;
257: }
258: } else {
259: unset($this->data[$permId]);
260: }
261: }
262:
263: if ($update) {
264: $this->save();
265: }
266: }
267:
268: /**
269: * Grants a user additional permissions to this object.
270: *
271: * @param string $uer The user to grant additional permissions
272: * to.
273: * @param integer $permission The permission (DELETE, etc.) to add.
274: * @param boolean $update Whether to automatically update the
275: * backend.
276: */
277: public function addUserPermission($user, $permission, $update = true)
278: {
279: if (empty($user)) {
280: return;
281: }
282:
283: if ($this->get('type') == 'matrix' &&
284: isset($this->data['users'][$user])) {
285: $this->data['users'][$user] |= $permission;
286: } else {
287: $this->data['users'][$user] = $permission;
288: }
289:
290: if ($update) {
291: $this->save();
292: }
293: }
294:
295: /**
296: * Grants guests additional permissions to this object.
297: *
298: * @param integer $permission The permission (DELETE, etc.) to add.
299: * @param boolean $update Whether to automatically update the
300: * backend.
301: */
302: public function addGuestPermission($permission, $update = true)
303: {
304: if ($this->get('type') == 'matrix' &&
305: isset($this->data['guest'])) {
306: $this->data['guest'] |= $permission;
307: } else {
308: $this->data['guest'] = $permission;
309: }
310:
311: if ($update) {
312: $this->save();
313: }
314: }
315:
316: /**
317: * Grants creators additional permissions to this object.
318: *
319: * @param integer $permission The permission (DELETE, etc.) to add.
320: * @param boolean $update Whether to automatically update the
321: * backend.
322: */
323: public function addCreatorPermission($permission, $update = true)
324: {
325: if ($this->get('type') == 'matrix' &&
326: isset($this->data['creator'])) {
327: $this->data['creator'] |= $permission;
328: } else {
329: $this->data['creator'] = $permission;
330: }
331:
332: if ($update) {
333: $this->save();
334: }
335: }
336:
337: /**
338: * Grants additional default permissions to this object.
339: *
340: * @param integer $permission The permission (DELETE, etc.) to add.
341: * @param boolean $update Whether to automatically update the
342: * backend.
343: */
344: public function addDefaultPermission($permission, $update = true)
345: {
346: if ($this->get('type') == 'matrix' &&
347: isset($this->data['default'])) {
348: $this->data['default'] |= $permission;
349: } else {
350: $this->data['default'] = $permission;
351: }
352:
353: if ($update) {
354: $this->save();
355: }
356: }
357:
358: /**
359: * Grants a group additional permissions to this object.
360: *
361: * @param integer $groupId The id of the group to grant additional
362: * permissions to.
363: * @param integer $permission The permission (DELETE, etc.) to add.
364: * @param boolean $update Whether to automatically update the
365: * backend.
366: */
367: public function addGroupPermission($groupId, $permission, $update = true)
368: {
369: if (empty($groupId)) {
370: return;
371: }
372:
373: if ($this->get('type') == 'matrix' &&
374: isset($this->data['groups'][$groupId])) {
375: $this->data['groups'][$groupId] |= $permission;
376: } else {
377: $this->data['groups'][$groupId] = $permission;
378: }
379:
380: if ($update) {
381: $this->save();
382: }
383: }
384:
385: /**
386: * Removes a permission that a user currently has on this object.
387: *
388: * @param string $user The user to remove the permission from.
389: * Defaults to all users.
390: * @param integer $permission The permission (DELETE, etc.) to
391: * remove. Defaults to all permissions.
392: * @param boolean $update Whether to automatically update the
393: * backend.
394: */
395: public function removeUserPermission($user = null, $permission = null,
396: $update = true)
397: {
398: if (is_null($user)) {
399: $this->data['users'] = array();
400: } else {
401: if (!isset($this->data['users'][$user])) {
402: return;
403: }
404:
405: if ($permission && $this->get('type') == 'matrix') {
406: $this->data['users'][$user] &= ~$permission;
407: if (empty($this->data['users'][$user])) {
408: unset($this->data['users'][$user]);
409: }
410: } else {
411: unset($this->data['users'][$user]);
412: }
413: }
414:
415: if ($update) {
416: $this->save();
417: }
418: }
419:
420: /**
421: * Removes a permission that guests currently have on this object.
422: *
423: * @param integer $permission The permission (DELETE, etc.) to
424: * remove. Defaults to all permissions.
425: * @param boolean $update Whether to automatically update the
426: * backend.
427: */
428: public function removeGuestPermission($permission = null, $update = true)
429: {
430: if (!isset($this->data['guest'])) {
431: return;
432: }
433:
434: if ($permission && $this->get('type') == 'matrix') {
435: $this->data['guest'] &= ~$permission;
436: } else {
437: unset($this->data['guest']);
438: }
439:
440: if ($update) {
441: $this->save();
442: }
443: }
444:
445: /**
446: * Removes a permission that creators currently have on this object.
447: *
448: * @param integer $permission The permission (DELETE, etc.) to
449: * remove. Defaults to all permissions.
450: * @param boolean $update Whether to automatically update the
451: * backend.
452: */
453: public function removeCreatorPermission($permission = null, $update = true)
454: {
455: if (!isset($this->data['creator'])) {
456: return;
457: }
458:
459: if ($permission && $this->get('type') == 'matrix') {
460: $this->data['creator'] &= ~$permission;
461: } else {
462: unset($this->data['creator']);
463: }
464:
465: if ($update) {
466: $this->save();
467: }
468: }
469:
470: /**
471: * Removes a default permission on this object.
472: *
473: * @param integer $permission The permission (DELETE, etc.) to
474: * remove. Defaults to all permissions.
475: * @param boolean $update Whether to automatically update the
476: * backend.
477: */
478: public function removeDefaultPermission($permission = null, $update = true)
479: {
480: if (!isset($this->data['default'])) {
481: return;
482: }
483:
484: if ($permission && $this->get('type') == 'matrix') {
485: $this->data['default'] &= ~$permission;
486: } else {
487: unset($this->data['default']);
488: }
489:
490: if ($update) {
491: $this->save();
492: }
493: }
494:
495: /**
496: * Removes a permission that a group currently has on this object.
497: *
498: * @param integer $groupId The id of the group to remove the
499: * permission from. Defaults to all groups.
500: * @param integer $permission The permission (DELETE, etc.) to
501: * remove. Defaults to all permissions.
502: * @param boolean $update Whether to automatically update the
503: * backend.
504: */
505: public function removeGroupPermission($groupId = null, $permission = null,
506: $update = true)
507: {
508: if (is_null($groupId)) {
509: $this->data['groups'] = array();
510: } else {
511: if (!isset($this->data['groups'][$groupId])) {
512: return;
513: }
514:
515: if ($permission && $this->get('type') == 'matrix') {
516: $this->data['groups'][$groupId] &= ~$permission;
517: if (empty($this->data['groups'][$groupId])) {
518: unset($this->data['groups'][$groupId]);
519: }
520: } else {
521: unset($this->data['groups'][$groupId]);
522: }
523: }
524:
525: if ($update) {
526: $this->save();
527: }
528: }
529:
530: /**
531: * Returns an array of all user permissions on this object.
532: *
533: * @param integer $perm List only users with this permission level.
534: * Defaults to all users.
535: *
536: * @return array All user permissions for this object, indexed by user.
537: */
538: public function getUserPermissions($perm = null)
539: {
540: if (!isset($this->data['users']) || !is_array($this->data['users'])) {
541: return array();
542: } elseif (!$perm) {
543: return $this->data['users'];
544: }
545:
546: $users = array();
547: foreach ($this->data['users'] as $user => $uperm) {
548: if ($uperm & $perm) {
549: $users[$user] = $uperm;
550: }
551: }
552:
553: return $users;
554: }
555:
556: /**
557: * Returns the guest permissions on this object.
558: *
559: * @return integer The guest permissions on this object.
560: */
561: public function getGuestPermissions()
562: {
563: return empty($this->data['guest'])
564: ? null
565: : $this->data['guest'];
566: }
567:
568: /**
569: * Returns the creator permissions on this object.
570: *
571: * @return integer The creator permissions on this object.
572: */
573: public function getCreatorPermissions()
574: {
575: return empty($this->data['creator'])
576: ? null
577: : $this->data['creator'];
578: }
579:
580: /**
581: * Returns the default permissions on this object.
582: *
583: * @return integer The default permissions on this object.
584: */
585: public function getDefaultPermissions()
586: {
587: return empty($this->data['default'])
588: ? null
589: : $this->data['default'];
590: }
591:
592: /**
593: * Returns an array of all group permissions on this object.
594: *
595: * @param integer $perm List only users with this permission level.
596: * Defaults to all users.
597: *
598: * @return array All group permissions for this object, indexed by group.
599: */
600: public function getGroupPermissions($perm = null)
601: {
602: if (!isset($this->data['groups']) ||
603: !is_array($this->data['groups'])) {
604: return array();
605: } elseif (!$perm) {
606: return $this->data['groups'];
607: }
608:
609: $groups = array();
610: foreach ($this->data['groups'] as $group => $gperm) {
611: if ($gperm & $perm) {
612: $groups[$group] = $gperm;
613: }
614: }
615:
616: return $groups;
617: }
618:
619: /**
620: * TODO
621: */
622: public function save()
623: {
624: }
625:
626: }
627: