/
acl.php
145 lines (138 loc) · 4 KB
/
acl.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<?php
/**
* ACL behavior class.
*
* Enables objects to easily tie into an ACL system
*
* PHP versions 4 and 5
*
* CakePHP : Rapid Development Framework (http://cakephp.org)
* Copyright 2006-2010, Cake Software Foundation, Inc.
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2006-2010, Cake Software Foundation, Inc.
* @link http://cakephp.org CakePHP Project
* @package cake
* @subpackage cake.cake.libs.model.behaviors
* @since CakePHP v 1.2.0.4487
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
* ACL behavior
*
* @package cake
* @subpackage cake.cake.libs.model.behaviors
* @link http://book.cakephp.org/view/1320/ACL
*/
class AclBehavior extends ModelBehavior {
/**
* Maps ACL type options to ACL models
*
* @var array
* @access protected
*/
var $__typeMaps = array('requester' => 'Aro', 'controlled' => 'Aco', 'both' => array('Aro', 'Aco'));
/**
* Sets up the configuation for the model, and loads ACL models if they haven't been already
*
* @param mixed $config
* @return void
* @access public
*/
function setup(&$model, $config = array()) {
if (is_string($config)) {
$config = array('type' => $config);
}
$this->settings[$model->name] = array_merge(array('type' => 'controlled'), (array)$config);
$this->settings[$model->name]['type'] = strtolower($this->settings[$model->name]['type']);
$types = $this->__typeMaps[$this->settings[$model->name]['type']];
if (!class_exists('AclNode')) {
require LIBS . 'model' . DS . 'db_acl.php';
}
if (!is_array($types)) {
$types = array($types);
}
foreach($types as $type) {
if (PHP5) {
$model->{$type} = ClassRegistry::init($type);
} else {
$model->{$type} =& ClassRegistry::init($type);
}
}
if (!method_exists($model, 'parentNode')) {
trigger_error(sprintf(__('Callback parentNode() not defined in %s', true), $model->alias), E_USER_WARNING);
}
}
/**
* Retrieves the Aro/Aco node for this model
*
* @param mixed $ref
* @param string $type Only needed when Acl is set up as 'both', specify 'Aro' or 'Aco' to get the correct node
* @return array
* @access public
* @link http://book.cakephp.org/view/1322/node
*/
function node(&$model, $ref = null, $type = null) {
if (empty($type)) {
$type = $this->__typeMaps[$this->settings[$model->name]['type']];
if (is_array($type)) {
trigger_error(__('AclBehavior is setup with more then one type, please specify type parameter for node()', true), E_USER_WARNING);
return null;
}
}
if (empty($ref)) {
$ref = array('model' => $model->name, 'foreign_key' => $model->id);
}
return $model->{$type}->node($ref);
}
/**
* Creates a new ARO/ACO node bound to this record
*
* @param boolean $created True if this is a new record
* @return void
* @access public
*/
function afterSave(&$model, $created) {
$types = $this->__typeMaps[$this->settings[$model->name]['type']];
if (!is_array($types)) {
$types = array($types);
}
foreach ($types as $type) {
$parent = $model->parentNode();
if (!empty($parent)) {
$parent = $this->node($model, $parent, $type);
}
$data = array(
'parent_id' => isset($parent[0][$type]['id']) ? $parent[0][$type]['id'] : null,
'model' => $model->alias,
'foreign_key' => $model->id
);
if (!$created) {
$node = $this->node($model, null, $type);
$data['id'] = isset($node[0][$type]['id']) ? $node[0][$type]['id'] : null;
}
$model->{$type}->create();
$model->{$type}->save($data);
}
}
/**
* Destroys the ARO/ACO node bound to the deleted record
*
* @return void
* @access public
*/
function afterDelete(&$model) {
$types = $this->__typeMaps[$this->settings[$model->name]['type']];
if (!is_array($types)) {
$types = array($types);
}
foreach ($types as $type) {
$node = Set::extract($this->node($model, null, $type), "0.{$type}.id");
if (!empty($node)) {
$model->{$type}->delete($node);
}
}
}
}