source: Dev/branches/cakephp/cake/libs/model/db_acl.php @ 126

Last change on this file since 126 was 126, checked in by fpvanagthoven, 14 years ago

Cakephp branch.

File size: 7.5 KB
Line 
1<?php
2/**
3 * This is core configuration file.
4 *
5 * Use it to configure core behaviour ofCake.
6 *
7 * PHP versions 4 and 5
8 *
9 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
10 * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
11 *
12 * Licensed under The MIT License
13 * Redistributions of files must retain the above copyright notice.
14 *
15 * @copyright     Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
16 * @link          http://cakephp.org CakePHP(tm) Project
17 * @package       cake
18 * @subpackage    cake.cake.libs.model
19 * @since         CakePHP(tm) v 0.2.9
20 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
21 */
22
23/**
24 * Load Model and AppModel
25 */
26App::import('Model', 'App');
27
28/**
29 * ACL Node
30 *
31 *
32 * @package       cake
33 * @subpackage    cake.cake.libs.model
34 */
35class AclNode extends AppModel {
36
37/**
38 * Explicitly disable in-memory query caching for ACL models
39 *
40 * @var boolean
41 * @access public
42 */
43        var $cacheQueries = false;
44
45/**
46 * ACL models use the Tree behavior
47 *
48 * @var array
49 * @access public
50 */
51        var $actsAs = array('Tree' => 'nested');
52
53/**
54 * Constructor
55 *
56 */
57        function __construct() {
58                $config = Configure::read('Acl.database');
59                if (isset($config)) {
60                        $this->useDbConfig = $config;
61                }
62                parent::__construct();
63        }
64
65/**
66 * Retrieves the Aro/Aco node for this model
67 *
68 * @param mixed $ref Array with 'model' and 'foreign_key', model object, or string value
69 * @return array Node found in database
70 * @access public
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(sprintf(__("Model class '%s' not found in AclNode::node() when trying to bind %s object", true), $type, $this->alias), 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(sprintf(__("AclNode::node() - Couldn't find %s node identified by \"%s\"", true), $type, print_r($ref, true)), E_USER_WARNING);
192                        }
193                }
194                return $result;
195        }
196}
197
198/**
199 * Access Control Object
200 *
201 * @package       cake
202 * @subpackage    cake.cake.libs.model
203 */
204class Aco extends AclNode {
205
206/**
207 * Model name
208 *
209 * @var string
210 * @access public
211 */
212        var $name = 'Aco';
213
214/**
215 * Binds to ARO nodes through permissions settings
216 *
217 * @var array
218 * @access public
219 */
220        var $hasAndBelongsToMany = array('Aro' => array('with' => 'Permission'));
221}
222
223/**
224 * Action for Access Control Object
225 *
226 * @package       cake
227 * @subpackage    cake.cake.libs.model
228 */
229class AcoAction extends AppModel {
230
231/**
232 * Model name
233 *
234 * @var string
235 * @access public
236 */
237        var $name = 'AcoAction';
238
239/**
240 * ACO Actions belong to ACOs
241 *
242 * @var array
243 * @access public
244 */
245        var $belongsTo = array('Aco');
246}
247
248/**
249 * Access Request Object
250 *
251 * @package       cake
252 * @subpackage    cake.cake.libs.model
253 */
254class Aro extends AclNode {
255
256/**
257 * Model name
258 *
259 * @var string
260 * @access public
261 */
262        var $name = 'Aro';
263
264/**
265 * AROs are linked to ACOs by means of Permission
266 *
267 * @var array
268 * @access public
269 */
270        var $hasAndBelongsToMany = array('Aco' => array('with' => 'Permission'));
271}
272
273/**
274 * Permissions linking AROs with ACOs
275 *
276 * @package       cake
277 * @subpackage    cake.cake.libs.model
278 */
279class Permission extends AppModel {
280
281/**
282 * Model name
283 *
284 * @var string
285 * @access public
286 */
287        var $name = 'Permission';
288
289/**
290 * Explicitly disable in-memory query caching
291 *
292 * @var boolean
293 * @access public
294 */
295        var $cacheQueries = false;
296
297/**
298 * Override default table name
299 *
300 * @var string
301 * @access public
302 */
303        var $useTable = 'aros_acos';
304
305/**
306 * Permissions link AROs with ACOs
307 *
308 * @var array
309 * @access public
310 */
311        var $belongsTo = array('Aro', 'Aco');
312
313/**
314 * No behaviors for this model
315 *
316 * @var array
317 * @access public
318 */
319        var $actsAs = null;
320
321/**
322 * Constructor, used to tell this model to use the
323 * database configured for ACL
324 */
325        function __construct() {
326                $config = Configure::read('Acl.database');
327                if (!empty($config)) {
328                        $this->useDbConfig = $config;
329                }
330                parent::__construct();
331        }
332}
Note: See TracBrowser for help on using the repository browser.