1: <?php
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: App::import('Model', 'App');
30: 31: 32: 33: 34: 35: 36: 37: 38:
39: class AclNode extends AppModel {
40: 41: 42: 43: 44: 45:
46: var $cacheQueries = false;
47: 48: 49: 50: 51: 52:
53: var $actsAs = array('Tree' => 'nested');
54: 55: 56: 57:
58: function __construct() {
59: $config = Configure::read('Acl.database');
60: if (isset($config)) {
61: $this->useDbConfig = $config;
62: }
63: parent::__construct();
64: }
65: 66: 67: 68: 69: 70: 71:
72: function node($ref = null) {
73: $db =& ConnectionManager::getDataSource($this->useDbConfig);
74: $type = $this->alias;
75: $result = null;
76:
77: if (!empty($this->useTable)) {
78: $table = $this->useTable;
79: } else {
80: $table = Inflector::pluralize(Inflector::underscore($type));
81: }
82:
83: if (empty($ref)) {
84: return null;
85: } elseif (is_string($ref)) {
86: $path = explode('/', $ref);
87: $start = $path[0];
88: unset($path[0]);
89:
90: $queryData = array(
91: 'conditions' => array(
92: $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft"),
93: $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght")),
94: 'fields' => array('id', 'parent_id', 'model', 'foreign_key', 'alias'),
95: 'joins' => array(array(
96: 'table' => $db->fullTableName($this),
97: 'alias' => "{$type}0",
98: 'type' => 'LEFT',
99: 'conditions' => array("{$type}0.alias" => $start)
100: )),
101: 'order' => $db->name("{$type}.lft") . ' DESC'
102: );
103:
104: foreach ($path as $i => $alias) {
105: $j = $i - 1;
106:
107: $queryData['joins'][] = array(
108: 'table' => $db->fullTableName($this),
109: 'alias' => "{$type}{$i}",
110: 'type' => 'LEFT',
111: 'conditions' => array(
112: $db->name("{$type}{$i}.lft") . ' > ' . $db->name("{$type}{$j}.lft"),
113: $db->name("{$type}{$i}.rght") . ' < ' . $db->name("{$type}{$j}.rght"),
114: $db->name("{$type}{$i}.alias") . ' = ' . $db->value($alias, 'string'),
115: $db->name("{$type}{$j}.id") . ' = ' . $db->name("{$type}{$i}.parent_id")
116: )
117: );
118:
119: $queryData['conditions'] = array('or' => array(
120: $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft") . ' AND ' . $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght"),
121: $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}{$i}.lft") . ' AND ' . $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}{$i}.rght"))
122: );
123: }
124: $result = $db->read($this, $queryData, -1);
125: $path = array_values($path);
126:
127: if (
128: !isset($result[0][$type]) ||
129: (!empty($path) && $result[0][$type]['alias'] != $path[count($path) - 1]) ||
130: (empty($path) && $result[0][$type]['alias'] != $start)
131: ) {
132: return false;
133: }
134: } elseif (is_object($ref) && is_a($ref, 'Model')) {
135: $ref = array('model' => $ref->alias, 'foreign_key' => $ref->id);
136: } elseif (is_array($ref) && !(isset($ref['model']) && isset($ref['foreign_key']))) {
137: $name = key($ref);
138:
139: if (PHP5) {
140: $model = ClassRegistry::init(array('class' => $name, 'alias' => $name));
141: } else {
142: $model =& ClassRegistry::init(array('class' => $name, 'alias' => $name));
143: }
144:
145: if (empty($model)) {
146: trigger_error("Model class '$name' not found in AclNode::node() when trying to bind {$this->alias} object", E_USER_WARNING);
147: return null;
148: }
149:
150: $tmpRef = null;
151: if (method_exists($model, 'bindNode')) {
152: $tmpRef = $model->bindNode($ref);
153: }
154: if (empty($tmpRef)) {
155: $ref = array('model' => $name, 'foreign_key' => $ref[$name][$model->primaryKey]);
156: } else {
157: if (is_string($tmpRef)) {
158: return $this->node($tmpRef);
159: }
160: $ref = $tmpRef;
161: }
162: }
163: if (is_array($ref)) {
164: if (is_array(current($ref)) && is_string(key($ref))) {
165: $name = key($ref);
166: $ref = current($ref);
167: }
168: foreach ($ref as $key => $val) {
169: if (strpos($key, $type) !== 0 && strpos($key, '.') === false) {
170: unset($ref[$key]);
171: $ref["{$type}0.{$key}"] = $val;
172: }
173: }
174: $queryData = array(
175: 'conditions' => $ref,
176: 'fields' => array('id', 'parent_id', 'model', 'foreign_key', 'alias'),
177: 'joins' => array(array(
178: 'table' => $db->fullTableName($this),
179: 'alias' => "{$type}0",
180: 'type' => 'LEFT',
181: 'conditions' => array(
182: $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft"),
183: $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght")
184: )
185: )),
186: 'order' => $db->name("{$type}.lft") . ' DESC'
187: );
188: $result = $db->read($this, $queryData, -1);
189:
190: if (!$result) {
191: trigger_error("AclNode::node() - Couldn't find {$type} node identified by \"" . print_r($ref, true) . "\"", E_USER_WARNING);
192: }
193: }
194: return $result;
195: }
196: }
197: 198: 199: 200: 201: 202:
203: class Aco extends AclNode {
204: 205: 206: 207: 208: 209:
210: var $name = 'Aco';
211: 212: 213: 214: 215: 216:
217: var $hasAndBelongsToMany = array('Aro' => array('with' => 'Permission'));
218: }
219: 220: 221: 222: 223: 224:
225: class AcoAction extends AppModel {
226: 227: 228: 229: 230: 231:
232: var $name = 'AcoAction';
233: 234: 235: 236: 237: 238:
239: var $belongsTo = array('Aco');
240: }
241: 242: 243: 244: 245: 246:
247: class Aro extends AclNode {
248: 249: 250: 251: 252: 253:
254: var $name = 'Aro';
255: 256: 257: 258: 259: 260:
261: var $hasAndBelongsToMany = array('Aco' => array('with' => 'Permission'));
262: }
263: 264: 265: 266: 267: 268:
269: class Permission extends AppModel {
270: 271: 272: 273: 274: 275:
276: var $name = 'Permission';
277: 278: 279: 280: 281: 282:
283: var $cacheQueries = false;
284: 285: 286: 287: 288: 289:
290: var $useTable = 'aros_acos';
291: 292: 293: 294: 295: 296:
297: var $belongsTo = array('Aro', 'Aco');
298: 299: 300: 301: 302: 303:
304: var $actsAs = null;
305: 306: 307: 308:
309: function __construct() {
310: $config = Configure::read('Acl.database');
311: if (!empty($config)) {
312: $this->useDbConfig = $config;
313: }
314: parent::__construct();
315: }
316: }
317: ?>