D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
lampp
/
lib
/
php
/
Tree
/
Memory
/
Filename :
Array.php
back
Copy
<?php /* vim: set expandtab tabstop=4 shiftwidth=4: */ // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.02 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Wolfram Kriesing <wolfram@kriesing.de> | // +----------------------------------------------------------------------+ // // $Id: Array.php 320703 2011-12-08 22:08:40Z danielc $ require_once 'Tree/Error.php'; /** * EXPERIMENTAL * * @access public * @author Wolfram Kriesing <wolfram@kriesing.de> * @version 2002/08/30 * @package Tree */ class Tree_Memory_Array { var $data = array(); /** * this is the internal id that will be assigned if no id is given * it simply counts from 1, so we can check if($id) i am lazy :-) */ var $_id = 1; // {{{ Tree_Memory_Array() /** * set up this object * * @version 2002/08/30 * @access public * @author Wolfram Kriesing <wolfram@kriesing.de> * @param string $dsn the path on the filesystem * @param array $options additional options you can set */ function Tree_Memory_Array(&$array, $options = array()) { $this->_array = &$array; $this->_options = $options; // not in use currently } // }}} // {{{ setup() /** * * * @version 2002/08/30 * @access public * @author Wolfram Kriesing <wolfram@kriesing.de> * @return boolean true on success */ function setup() { unset($this->data); if (is_array($this->_array)) { $this->data[0] = null; $theData = array(&$this->_array); $this->_setup($theData); } return $this->data; } // }}} // {{{ _setup() /** * we modify the $this->_array in here, we also add the id * so methods like 'add' etc can find the elements they are searching for, * if you dont like your data to be modified dont pass them as reference! */ function _setup(&$array, $parentId = 0) { foreach ($array as $nodeKey => $aNode) { $newData = $aNode; // if the current element has no id, we generate one if (!isset($newData['id']) || !$newData['id']) { // build a unique numeric id $newData['id'] = $this->_id++; // set the id $array[$nodeKey]['id'] = $newData['id']; } else { $idAsInt = (int)$newData['id']; if ($idAsInt > $this->_id) { $this->_id = $idAsInt; } } // set the parent-id, since we only have a 'children' array $newData['parentId'] = $parentId; $children = null; // remove the 'children' array, since this is only info for // this class foreach ($newData as $key => $val) { if ($key == 'children') { unset($newData[$key]); } } $this->data[$newData['id']] = $newData; if (isset($aNode['children']) && $aNode['children']) { if (!isset($array[$nodeKey]['children'])) { $array[$nodeKey]['children'] = array(); } $this->_setup($array[$nodeKey]['children'], $newData['id']); } } } // }}} // {{{ setData() /** * this is mostly used by switchDataSource * this method put data gotten from getNode() in the $this->_array * */ function setData($data) { $unsetKeys = array('childId', 'left', 'right'); foreach ($data as $aNode) { foreach ($aNode as $key => $val) { if (is_array($val) || in_array($key,$unsetKeys)) { unset($aNode[$key]); } } $this->add($aNode,$aNode['parentId']); } $this->_array = $this->_array['children'][0]; } // }}} // {{{ _prepareResults() /** * prepare multiple results * * @see _prepareResult() * @access private * @version 2002/03/03 * @author Wolfram Kriesing <wolfram@kriesing.de> */ function _prepareResults($results) { $newResults = array(); foreach($results as $aResult) { $newResults[] = $this->_prepareResult($aResult); } return $newResults; } // }}} // {{{ _prepareResult() /** * map back the index names to get what is expected * * @access private * @version 2002/03/03 * @author Wolfram Kriesing <wolfram@kriesing.de> */ function _prepareResult($result) { $map = $this->getOption('columnNameMaps'); if ($map) { foreach($map as $key => $columnName) { $result[$key] = $result[$columnName]; unset($result[$columnName]); } } return $result; } // }}} // {{{ add() /** * add a new item to the tree * what is tricky here, we also need to add it to the source array * * @param array the data for the new node * @param int the ID of the parent node * @param int the ID of the previous node */ function add($data, $parentId, $previousId = null) { if (!isset($data['id'])) { $data['id'] = ++$this->_id; } elseif((int)$data['id'] > $this->_id) { // Since we dont want to overwrite anything. just in case update // the $this->_id if the data['id'] has a higher number. $this->_id = (int)$data['id']; } $data['parentId'] = $parentId; $this->data[$data['id']] = $data; // there might not be a root element yet if (!isset($this->_array['children'])) { $data['parentId'] = 0; $this->_array['children'][] = $data; } else { array_walk($this->_array['children'], array(&$this,'_add'), array($data,$parentId,$previousId) ); } return $data['id']; } // }}} // {{{ _add() /** * we need to add the node to the source array * for this we have this private method which loops through * the source array and adds it in the right place * * @param mixed the value of the array, as a reference. So we work * right on the source * @param mixed the key of the node * @param array an array which contains the following * new data, * parent ID under which to add the node, * the prvious ID */ function _add(&$val, $key, $data) { // is the id of the current elment ($val) == to the parentId ($data[1]) if ($val['id'] == $data[1]) { if (isset($data[2]) && $data[2] === 0) { // if the previousId is 0 means, add it as the first member $val['children'] = array_merge(array($data[0]), $val['children']); } else { $val['children'][] = $data[0]; } } else { // if we havent found the new element go on searching if (isset($val['children'])) { array_walk($val['children'],array(&$this,'_add'),$data); } } } // }}} // {{{ update() /** * update an entry with the given id and set the data as given * in the array $data * * @param int the id of the element that shall be updated * @param array the data, [key]=>[value] * @return void */ function update($id,$data) { if ($this->_array['id']==$id) { foreach ($data as $key=>$newVal) { $this->_array[$key] = $newVal; } } else { array_walk($this->_array['children'], array(&$this,'_update'), array($id,$data) ); } } // }}} // {{{ _update() /** * update the element with the given id * * @param array a reference to an element inside $this->_array * has to be a reference, so we can really modify * the actual data * @param int not in use, but array_walk passes this param * @param array [0] is the id we are searching for * [1] are the new data we shall set * @return void */ function _update(&$val, $key, $data) { // is the id of the current elment ($val) == to the parentId ($data[1]) if ($val['id'] == $data[0]) { foreach ($data[1] as $key => $newVal) { $val[$key] = $newVal; } } else { // if we havent found the new element go on searching // in the children if (isset($val['children'])) { array_walk($val['children'],array(&$this,'_update'), $data); } } } // }}} // {{{ remove() /** * remove an element from the tree * this removes all the children too * * @param int the id of the element to be removed */ function remove($id) { // we only need to search for element that do exist :-) // otherwise we save some processing time if ($this->data[$id]) { $this->_remove($this->_array,$id); } } // }}} // {{{ _remove() /** * remove the element with the given id * this will definitely remove all the children too * * @param array a reference to an element inside $this->_array * has to be a reference, so we can really modify * the actual data * @param int the id of the element to be removed * @return void */ function _remove(&$val, $id) { if (isset($val['children'])) { foreach ($val['children'] as $key => $aVal) { if ($aVal['id'] == $id) { if (sizeof($val['children']) < 2) { unset($val['children']); } else { unset($val['children'][$key]); } } else { $this->_remove($val['children'][$key],$id); } } } } // }}} }