/lib/Cake/Model/AclNode.php

https://github.com/masihnewbie/cakephp · PHP · 184 lines · 122 code · 17 blank · 45 comment · 23 complexity · 9092717ee3e5bbadb6d78d590c922eae MD5 · raw file

  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.Model
  27. */
  28. class AclNode extends AppModel {
  29. /**
  30. * Explicitly disable in-memory query caching for ACL models
  31. *
  32. * @var boolean
  33. */
  34. public $cacheQueries = false;
  35. /**
  36. * ACL models use the Tree behavior
  37. *
  38. * @var array
  39. */
  40. public $actsAs = array('Tree' => array('type' => 'nested'));
  41. /**
  42. * Constructor
  43. *
  44. */
  45. public function __construct() {
  46. $config = Configure::read('Acl.database');
  47. if (isset($config)) {
  48. $this->useDbConfig = $config;
  49. }
  50. parent::__construct();
  51. }
  52. /**
  53. * Retrieves the Aro/Aco node for this model
  54. *
  55. * @param mixed $ref Array with 'model' and 'foreign_key', model object, or string value
  56. * @return array Node found in database
  57. */
  58. public function node($ref = null) {
  59. $db = $this->getDataSource();
  60. $type = $this->alias;
  61. $result = null;
  62. if (!empty($this->useTable)) {
  63. $table = $this->useTable;
  64. } else {
  65. $table = Inflector::pluralize(Inflector::underscore($type));
  66. }
  67. if (empty($ref)) {
  68. return null;
  69. } elseif (is_string($ref)) {
  70. $path = explode('/', $ref);
  71. $start = $path[0];
  72. unset($path[0]);
  73. $queryData = array(
  74. 'conditions' => array(
  75. $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft"),
  76. $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght")),
  77. 'fields' => array('id', 'parent_id', 'model', 'foreign_key', 'alias'),
  78. 'joins' => array(array(
  79. 'table' => $table,
  80. 'alias' => "{$type}0",
  81. 'type' => 'LEFT',
  82. 'conditions' => array("{$type}0.alias" => $start)
  83. )),
  84. 'order' => $db->name("{$type}.lft") . ' DESC'
  85. );
  86. foreach ($path as $i => $alias) {
  87. $j = $i - 1;
  88. $queryData['joins'][] = array(
  89. 'table' => $table,
  90. 'alias' => "{$type}{$i}",
  91. 'type' => 'LEFT',
  92. 'conditions' => array(
  93. $db->name("{$type}{$i}.lft") . ' > ' . $db->name("{$type}{$j}.lft"),
  94. $db->name("{$type}{$i}.rght") . ' < ' . $db->name("{$type}{$j}.rght"),
  95. $db->name("{$type}{$i}.alias") . ' = ' . $db->value($alias, 'string'),
  96. $db->name("{$type}{$j}.id") . ' = ' . $db->name("{$type}{$i}.parent_id")
  97. )
  98. );
  99. $queryData['conditions'] = array('or' => array(
  100. $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft") . ' AND ' . $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght"),
  101. $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}{$i}.lft") . ' AND ' . $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}{$i}.rght"))
  102. );
  103. }
  104. $result = $db->read($this, $queryData, -1);
  105. $path = array_values($path);
  106. if (
  107. !isset($result[0][$type]) ||
  108. (!empty($path) && $result[0][$type]['alias'] != $path[count($path) - 1]) ||
  109. (empty($path) && $result[0][$type]['alias'] != $start)
  110. ) {
  111. return false;
  112. }
  113. } elseif (is_object($ref) && is_a($ref, 'Model')) {
  114. $ref = array('model' => $ref->alias, 'foreign_key' => $ref->id);
  115. } elseif (is_array($ref) && !(isset($ref['model']) && isset($ref['foreign_key']))) {
  116. $name = key($ref);
  117. $model = ClassRegistry::init(array('class' => $name, 'alias' => $name));
  118. if (empty($model)) {
  119. 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);
  120. return null;
  121. }
  122. $tmpRef = null;
  123. if (method_exists($model, 'bindNode')) {
  124. $tmpRef = $model->bindNode($ref);
  125. }
  126. if (empty($tmpRef)) {
  127. $ref = array('model' => $name, 'foreign_key' => $ref[$name][$model->primaryKey]);
  128. } else {
  129. if (is_string($tmpRef)) {
  130. return $this->node($tmpRef);
  131. }
  132. $ref = $tmpRef;
  133. }
  134. }
  135. if (is_array($ref)) {
  136. if (is_array(current($ref)) && is_string(key($ref))) {
  137. $name = key($ref);
  138. $ref = current($ref);
  139. }
  140. foreach ($ref as $key => $val) {
  141. if (strpos($key, $type) !== 0 && strpos($key, '.') === false) {
  142. unset($ref[$key]);
  143. $ref["{$type}0.{$key}"] = $val;
  144. }
  145. }
  146. $queryData = array(
  147. 'conditions' => $ref,
  148. 'fields' => array('id', 'parent_id', 'model', 'foreign_key', 'alias'),
  149. 'joins' => array(array(
  150. 'table' => $table,
  151. 'alias' => "{$type}0",
  152. 'type' => 'LEFT',
  153. 'conditions' => array(
  154. $db->name("{$type}.lft") . ' <= ' . $db->name("{$type}0.lft"),
  155. $db->name("{$type}.rght") . ' >= ' . $db->name("{$type}0.rght")
  156. )
  157. )),
  158. 'order' => $db->name("{$type}.lft") . ' DESC'
  159. );
  160. $result = $db->read($this, $queryData, -1);
  161. if (!$result) {
  162. trigger_error(__d('cake_dev', "AclNode::node() - Couldn't find %s node identified by \"%s\"", $type, print_r($ref, true)), E_USER_WARNING);
  163. }
  164. }
  165. return $result;
  166. }
  167. }