Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16591 anikendra 1
<?php
2
/**
3
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice.
9
 *
10
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11
 * @link          http://cakephp.org CakePHP(tm) Project
12
 * @package       Cake.Model
13
 * @since         CakePHP(tm) v 0.2.9
14
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
15
 */
16
 
17
App::uses('Model', 'Model');
18
 
19
/**
20
 * ACL Node
21
 *
22
 * @package       Cake.Model
23
 */
24
class AclNode extends Model {
25
 
26
/**
27
 * Explicitly disable in-memory query caching for ACL models
28
 *
29
 * @var bool
30
 */
31
	public $cacheQueries = false;
32
 
33
/**
34
 * ACL models use the Tree behavior
35
 *
36
 * @var array
37
 */
38
	public $actsAs = array('Tree' => array('type' => 'nested'));
39
 
40
/**
41
 * Constructor
42
 *
43
 */
44
	public function __construct() {
45
		$config = Configure::read('Acl.database');
46
		if (isset($config)) {
47
			$this->useDbConfig = $config;
48
		}
49
		parent::__construct();
50
	}
51
 
52
/**
53
 * Retrieves the Aro/Aco node for this model
54
 *
55
 * @param string|array|Model $ref Array with 'model' and 'foreign_key', model object, or string value
56
 * @return array Node found in database
57
 * @throws CakeException when binding to a model that doesn't exist.
58
 */
59
	public function node($ref = null) {
60
		$db = $this->getDataSource();
61
		$type = $this->alias;
62
		$result = null;
63
 
64
		if (!empty($this->useTable)) {
65
			$table = $this->useTable;
66
		} else {
67
			$table = Inflector::pluralize(Inflector::underscore($type));
68
		}
69
 
70
		if (empty($ref)) {
71
			return null;
72
		} elseif (is_string($ref)) {
73
			$path = explode('/', $ref);
74
			$start = $path[0];
75
			unset($path[0]);
76
 
77
			$queryData = array(
78
				'conditions' => array(
79
					$db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft"),
80
					$db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght")),
81
				'fields' => array('id', 'parent_id', 'model', 'foreign_key', 'alias'),
82
				'joins' => array(array(
83
					'table' => $table,
84
					'alias' => "{$type}0",
85
					'type' => 'INNER',
86
					'conditions' => array("{$type}0.alias" => $start)
87
				)),
88
				'order' => $db->name("{$type}.lft") . ' DESC'
89
			);
90
 
91
			$conditionsAfterJoin = array();
92
 
93
			foreach ($path as $i => $alias) {
94
				$j = $i - 1;
95
 
96
				$queryData['joins'][] = array(
97
					'table' => $table,
98
					'alias' => "{$type}{$i}",
99
					'type' => 'INNER',
100
					'conditions' => array(
101
						$db->name("{$type}{$i}.alias") . ' = ' . $db->value($alias, 'string')
102
					)
103
				);
104
 
105
				// it will be better if this conditions will performs after join operation
106
				$conditionsAfterJoin[] = $db->name("{$type}{$j}.id") . ' = ' . $db->name("{$type}{$i}.parent_id");
107
				$conditionsAfterJoin[] = $db->name("{$type}{$i}.rght") . ' < ' . $db->name("{$type}{$j}.rght");
108
				$conditionsAfterJoin[] = $db->name("{$type}{$i}.lft") . ' > ' . $db->name("{$type}{$j}.lft");
109
 
110
				$queryData['conditions'] = array('or' => array(
111
					$db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft") . ' AND ' . $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght"),
112
					$db->name("{$type}.lft") . ' <= ' . $db->name("{$type}{$i}.lft") . ' AND ' . $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}{$i}.rght"))
113
				);
114
			}
115
			$queryData['conditions'] = array_merge($queryData['conditions'], $conditionsAfterJoin);
116
			$result = $db->read($this, $queryData, -1);
117
			$path = array_values($path);
118
 
119
			if (!isset($result[0][$type]) ||
120
				(!empty($path) && $result[0][$type]['alias'] != $path[count($path) - 1]) ||
121
				(empty($path) && $result[0][$type]['alias'] != $start)
122
			) {
123
				return false;
124
			}
125
		} elseif (is_object($ref) && $ref instanceof Model) {
126
			$ref = array('model' => $ref->name, 'foreign_key' => $ref->id);
127
		} elseif (is_array($ref) && !(isset($ref['model']) && isset($ref['foreign_key']))) {
128
			$name = key($ref);
129
			list(, $alias) = pluginSplit($name);
130
 
131
			$model = ClassRegistry::init(array('class' => $name, 'alias' => $alias));
132
 
133
			if (empty($model)) {
134
				throw new CakeException('cake_dev', "Model class '%s' not found in AclNode::node() when trying to bind %s object", $type, $this->alias);
135
			}
136
 
137
			$tmpRef = null;
138
			if (method_exists($model, 'bindNode')) {
139
				$tmpRef = $model->bindNode($ref);
140
			}
141
			if (empty($tmpRef)) {
142
				$ref = array('model' => $alias, 'foreign_key' => $ref[$name][$model->primaryKey]);
143
			} else {
144
				if (is_string($tmpRef)) {
145
					return $this->node($tmpRef);
146
				}
147
				$ref = $tmpRef;
148
			}
149
		}
150
		if (is_array($ref)) {
151
			if (is_array(current($ref)) && is_string(key($ref))) {
152
				$name = key($ref);
153
				$ref = current($ref);
154
			}
155
			foreach ($ref as $key => $val) {
156
				if (strpos($key, $type) !== 0 && strpos($key, '.') === false) {
157
					unset($ref[$key]);
158
					$ref["{$type}0.{$key}"] = $val;
159
				}
160
			}
161
			$queryData = array(
162
				'conditions' => $ref,
163
				'fields' => array('id', 'parent_id', 'model', 'foreign_key', 'alias'),
164
				'joins' => array(array(
165
					'table' => $table,
166
					'alias' => "{$type}0",
167
					'type' => 'INNER',
168
					'conditions' => array(
169
						$db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft"),
170
						$db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght")
171
					)
172
				)),
173
				'order' => $db->name("{$type}.lft") . ' DESC'
174
			);
175
			$result = $db->read($this, $queryData, -1);
176
 
177
			if (!$result) {
178
				throw new CakeException(__d('cake_dev', "AclNode::node() - Couldn't find %s node identified by \"%s\"", $type, print_r($ref, true)));
179
			}
180
		}
181
		return $result;
182
	}
183
 
184
}