⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tree.php

📁 Cake Framwork , Excellent
💻 PHP
📖 第 1 页 / 共 3 页
字号:
<?php/* SVN FILE: $Id: tree.php 7118 2008-06-04 20:49:29Z gwoo $ *//** * Tree behavior class. * * Enables a model object to act as a node-based tree. * * PHP versions 4 and 5 * * CakePHP :  Rapid Development Framework <http://www.cakephp.org/> * Copyright 2006-2008, Cake Software Foundation, Inc. *								1785 E. Sahara Avenue, Suite 490-204 *								Las Vegas, Nevada 89104 * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * * @filesource * @copyright		Copyright 2006-2008, Cake Software Foundation, Inc. * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP Project * @package			cake * @subpackage		cake.cake.libs.model.behaviors * @since			CakePHP v 1.2.0.4487 * @version			$Revision: 7118 $ * @modifiedby		$LastChangedBy: gwoo $ * @lastmodified	$Date: 2008-06-04 13:49:29 -0700 (Wed, 04 Jun 2008) $ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License *//** * Short description for file * * Long description for file * * @package		cake * @subpackage	cake.cake.libs.model.behaviors */class TreeBehavior extends ModelBehavior {	var $errors = array();	var $_defaults = array(		'parent' => 'parent_id', 'left' => 'lft', 'right' => 'rght',		'scope' => '1 = 1', 'type' => 'nested', '__parentChange' => false, 'recursive' => -1	);	function setup(&$model, $config = array()) {		if (!is_array($config)) {			$config = array('type' => $config);		}		$settings = array_merge($this->_defaults, $config);		if (in_array($settings['scope'], $model->getAssociated('belongsTo'))) {			$data = $model->getAssociated($settings['scope']);			$parent =& $model->{$settings['scope']};			$settings['scope'] = $model->alias . '.' . $data['foreignKey'] . ' = ' . $parent->alias . '.' . $parent->primaryKey;			$settings['recursive'] = 0;		}		$this->settings[$model->alias] = $settings;	}/** * @deprecated */	function setScope(&$model, $scope) {		trigger_error(__('(TreeBehavior::setScope) Deprecated - Use BehaviorCollection::attach() to re-attach with new settings', true), E_USER_WARNING);		$this->settings[$model->alias]['scope'] = $scope;		if ($this->settings[$model->alias]['recursive'] < 0) {			$this->settings[$model->alias]['recursive'] = 0;		}	}/** * After save method. Called after all saves * * Overriden to transparently manage setting the lft and rght fields if and only if the parent field is included in the * parameters to be saved. * * @param AppModel $model * @param boolean $created indicates whether the node just saved was created or updated * @return boolean true on success, false on failure */	function afterSave(&$model, $created) {		extract($this->settings[$model->alias]);		if ($created) {			if ((isset($model->data[$model->alias][$parent])) && $model->data[$model->alias][$parent]) {				return $this->_setParent($model, $model->data[$model->alias][$parent], $created);			}		} elseif ($__parentChange) {			$this->settings[$model->alias]['__parentChange'] = false;			return $this->_setParent($model, $model->data[$model->alias][$parent]);		}	}/** * Before delete method. Called before all deletes * * Will delete the current node and all children using the deleteAll method and sync the table * * @param AppModel $model * @return boolean true to continue, false to abort the delete */	function beforeDelete(&$model) {		extract($this->settings[$model->alias]);		list($name, $data) = array($model->alias, $model->read());		$data = $data[$name];		if (!$data[$right] || !$data[$left]) {			return true;		}		$diff = $data[$right] - $data[$left] + 1;		if ($diff > 2) {			if (is_string($scope)) {				$scope = array($scope);			}			$scope[]["{$model->alias}.{$left} BETWEEN ? AND ?"] = array($data[$left] + 1, $data[$right] - 1);			$model->deleteAll($scope);		}		$this->__sync($model, $diff, '-', '> ' . $data[$right]);		return true;	}/** * Before save method. Called before all saves * * Overriden to transparently manage setting the lft and rght fields if and only if the parent field is included in the * parameters to be saved. For newly created nodes with NO parent the left and right field values are set directly by * this method bypassing the setParent logic. * * @since 1.2 * @param AppModel $model * @return boolean true to continue, false to abort the save */	function beforeSave(&$model) {		extract($this->settings[$model->alias]);		if (isset($model->data[$model->alias][$model->primaryKey])) {			if ($model->data[$model->alias][$model->primaryKey]) {				if (!$model->id) {					$model->id = $model->data[$model->alias][$model->primaryKey];				}			}			unset($model->data[$model->alias][$model->primaryKey]);		}		$this->_addToWhitelist($model, array($left, $right));		if (!$model->id) {			if (array_key_exists($parent, $model->data[$model->alias]) && $model->data[$model->alias][$parent]) {				$parentNode = $model->find('first', array(					'conditions' => array($scope, $model->escapeField() => $model->data[$model->alias][$parent]),					'fields' => array($model->primaryKey, $right), 'recursive' => $recursive				));				if (!$parentNode) {					return false;				}				list($parentNode) = array_values($parentNode);				$model->data[$model->alias][$left] = 0; //$parentNode[$right];				$model->data[$model->alias][$right] = 0; //$parentNode[$right] + 1;			} else {				$edge = $this->__getMax($model, $scope, $right, $recursive);				$model->data[$model->alias][$left] = $edge + 1;				$model->data[$model->alias][$right] = $edge + 2;			}		} elseif (array_key_exists($parent, $model->data[$model->alias])) {			if ($model->data[$model->alias][$parent] != $model->field($parent)) {				$this->settings[$model->alias]['__parentChange'] = true;			}			if (!$model->data[$model->alias][$parent]) {				$model->data[$model->alias][$parent] = null;				$this->_addToWhitelist($model, $parent);			} else {				list($node) = array_values($model->find('first', array(					'conditions' => array($scope,$model->escapeField() => $model->id),					'fields' => array($model->primaryKey, $parent, $left, $right ), 'recursive' => $recursive)				));				$parentNode = $model->find('first', array(					'conditions' => array($scope, $model->escapeField() => $model->data[$model->alias][$parent]),					'fields' => array($model->primaryKey, $left, $right), 'recursive' => $recursive				));				if (!$parentNode) {					return false;				}				list($parentNode) = array_values($parentNode);				if (($node[$left] < $parentNode[$left]) && ($parentNode[$right] < $node[$right])) {					return false;				} elseif ($node[$model->primaryKey] == $parentNode[$model->primaryKey]) {					return false;				}			}		}		return true;	}/** * Get the number of child nodes * * If the direct parameter is set to true, only the direct children are counted (based upon the parent_id field) * If false is passed for the id parameter, all top level nodes are counted, or all nodes are counted. * * @param AppModel $model * @param mixed $id The ID of the record to read or false to read all top level nodes * @param boolean $direct whether to count direct, or all, children * @return integer number of child nodes * @access public */	function childcount(&$model, $id = null, $direct = false) {		if (is_array($id)) {			extract (array_merge(array('id' => null), $id));		}		if ($id === null && $model->id) {			$id = $model->id;		} elseif (!$id) {			$id = null;		}		extract($this->settings[$model->alias]);		if ($direct) {			return $model->find('count', array('conditions' => array($scope, $model->escapeField($parent) => $id)));		}		if ($id === null) {			return $model->find('count', array('conditions' => $scope));		} elseif (!empty ($model->data)) {			$data = $model->data[$model->alias];		} else {			list($data) = array_values($model->find('first', array('conditions' => array($scope, $model->escapeField() => $id), 'recursive' => $recursive)));		}		return ($data[$right] - $data[$left] - 1) / 2;	}/** * Get the child nodes of the current model * * If the direct parameter is set to true, only the direct children are returned (based upon the parent_id field) * If false is passed for the id parameter, top level, or all (depending on direct parameter appropriate) are counted. * * @param AppModel $model * @param mixed $id The ID of the record to read * @param boolean $direct whether to return only the direct, or all, children * @param mixed $fields Either a single string of a field name, or an array of field names * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC") defaults to the tree order * @param integer $limit SQL LIMIT clause, for calculating items per page. * @param integer $page Page number, for accessing paged data * @param integer $recursive The number of levels deep to fetch associated records * @return array Array of child nodes * @access public */	function children(&$model, $id = null, $direct = false, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) {		if (is_array($id)) {			extract (array_merge(array('id' => null), $id));		}		$overrideRecursive = $recursive;		if ($id === null && $model->id) {			$id = $model->id;		} elseif (!$id) {			$id = null;		}		$name = $model->alias;		extract($this->settings[$model->alias]);		if (!is_null($overrideRecursive)) {			$recursive = $overrideRecursive;		}		if (!$order) {			$order = $model->alias . '.' . $left . ' asc';		}		if ($direct) {			$conditions = array($scope, $model->escapeField($parent) => $id);			return $model->find('all', compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive'));		}		if (!$id) {			$constraint = $scope;		} else {			$result = array_values($model->find('first', array('conditions' => array($scope, $model->escapeField() => $id), 'fields' => array($left, $right), 'recursive' => $recursive)));			if (!empty($result) && isset($result[0])) {				$item = $result[0];			} else {				return array();			}			$constraint = array($scope, $model->escapeField($right) . ' <' . $item[$right], $model->escapeField($left) . ' >' => $item[$left]);		}		return $model->find('all', array('conditions' => $constraint, 'fields' => $fields, 'order' => $order, 'limit' => $limit, 'page' => $page, 'recursive' => $recursive));	}/** * A convenience method for returning a hierarchical array used for HTML select boxes * * @param AppModel $model * @param mixed $conditions SQL conditions as a string or as an array('field' =>'value',...) * @param string $keyPath A string path to the key, i.e. "{n}.Post.id" * @param string $valuePath A string path to the value, i.e. "{n}.Post.title" * @param string $spacer The character or characters which will be repeated * @param integer $recursive The number of levels deep to fetch associated records * @return array An associative array of records, where the id is the key, and the display field is the value * @access public */	function generatetreelist(&$model, $conditions = null, $keyPath = null, $valuePath = null, $spacer = '_', $recursive = null) {		$overrideRecursive = $recursive;		extract($this->settings[$model->alias]);		if (!is_null($overrideRecursive)) {			$recursive = $overrideRecursive;		}		if ($keyPath == null && $valuePath == null && $model->hasField($model->displayField)) {			$fields = array($model->primaryKey, $model->displayField, $left, $right);		} else {			$fields = null;		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -