AclNode.php 5.2 KB

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