Created
February 27, 2009 19:19
-
-
Save pkriete/71645 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | |
/** | |
* Scribble | |
* | |
* @author Pascal Kriete | |
* @package Scribble | |
* @copyright Copyright (c) 2008, Pascal Kriete | |
*/ | |
// ------------------------------------------------------------------------ | |
/** | |
* Structure Helper Library | |
* | |
* @package Scribble | |
* @subpackage Libraries | |
* @category Structure | |
* @author Pascal Kriete | |
*/ | |
class Structure { | |
var $_struct = array(); | |
/** | |
* Constructor | |
* | |
* @access public | |
*/ | |
function Structure($data) | |
{ | |
$this->_struct = $data[0]; | |
/* Json: | |
Structure = { | |
"4893j4f": {"title":"firsttitle"}, | |
"485hfkd": {"title":"secondtitle"}, | |
"kg84083": {"title":"thirdtitle","children": { | |
"fkjowi":{"title":"firstchild"}, | |
"8j4tjd":{"title":"secondchild"} | |
}}, | |
"9088jl": {"title":"fourthtitle"}} | |
$structure = array( | |
'4893j4f' => array('title' => 'firsttitle'), | |
'485hfkd' => array('title' => 'secondtitle'), | |
'kg84083' => array('title' => 'thirdtitle', 'children' => array( | |
'fkjowi' => array('title' => 'firstchild'), | |
'8j4tjd' => array('title' => 'secondchild') | |
) | |
), | |
'9088jl' => array('title' => 'fourthtitle') | |
); | |
$this->_struct = $structure; | |
$this->move_node('8j4tjd', '8j4tjd'); | |
// $this->remove_node('kg84083'); | |
// $this->add_node('abcdef', array('title' => 'NEW NODE!'), '9088jl'); | |
echo '<pre>'; | |
print_r($this->_struct); | |
echo '</pre>'; | |
exit; | |
*/ | |
} | |
// -------------------------------------------------------------------- | |
/** | |
* Accessor | |
* | |
* @access public | |
*/ | |
function get() | |
{ | |
return $this->_struct; | |
} | |
// -------------------------------------------------------------------- | |
/** | |
* Add a node to the current structure | |
* | |
* @access public | |
* @param string new node identifier | |
* @param mixed array of new node data | |
* @param string parent identifier | |
*/ | |
function add_node($node_id, $node_data, $parent_id = FALSE) | |
{ | |
// Parent given? | |
if ( ! $parent_id) | |
{ | |
$this->_struct[$node_id] = $node_data; | |
} | |
else | |
{ | |
// Get a path to the new parent | |
$path = $this->get_path($parent_id); | |
if ( ! $path) | |
{ | |
return FALSE; | |
} | |
// And now a reference | |
$ref =& $this->get_reference($path); | |
$ref['children'][$node_id] = $node_data; | |
} | |
return TRUE; | |
} | |
// -------------------------------------------------------------------- | |
/** | |
* Remove a node from the current structure | |
* | |
* @access public | |
* @param string node identifier | |
* @param bool delete child tree? | |
*/ | |
function remove_node($node_id, $inherit_children = FALSE) | |
{ | |
// Does the node even exist? | |
$path = $this->get_path($node_id); | |
if ( ! $path) | |
{ | |
return FALSE; | |
} | |
// Get a reference to the parent | |
$parent =& $this->_struct; | |
// Not on the root node | |
if (count($path) > 1) | |
{ | |
$tmp = array_slice($path, 0, -1, TRUE); | |
$parent =& $this->get_reference($tmp); | |
} | |
// Get a reference to the node | |
$ref =& $this->get_reference($path); | |
// If inherit_children is true - save them first | |
if ($inherit_children && isset($ref['children'])) | |
{ | |
foreach($ref['children'] as $key => &$value) | |
{ | |
$parent[$key] = $value; | |
} | |
} | |
// And finally kill it | |
unset($parent[$node_id]); | |
return TRUE; | |
} | |
// -------------------------------------------------------------------- | |
/** | |
* Move a node to a new position | |
* | |
* @access public | |
* @param string node identifier | |
* @param string new parent identifier (0 for root) | |
*/ | |
function move_node($node_id, $new_parent_id) | |
{ | |
// Nonsense | |
if ($node_id === $new_parent_id) | |
{ | |
return TRUE; | |
} | |
// Does the node even exist? | |
$path = $this->get_path($node_id); | |
$p_path = $this->get_path($new_parent_id); | |
if ($new_parent_id == '0') | |
{ | |
$p_path = array(); | |
} | |
if ( ! $path OR ( ! $p_path AND $new_parent_id != '0')) | |
{ | |
return FALSE; | |
} | |
// Get a reference to the parent(s) | |
$parent =& $this->_struct; | |
$new_parent =& $this->get_reference($p_path); | |
// Not attached to the root node | |
if (count($path) > 1) | |
{ | |
$tmp = array_slice($path, 0, -1, TRUE); | |
$parent =& $this->get_reference($tmp); | |
} | |
if ($new_parent_id != '0') | |
{ | |
// New parent needs a 'children' key | |
if ( ! isset($new_parent['children'])) | |
{ | |
$new_parent['children'] = array(); | |
} | |
$new_parent =& $new_parent['children']; | |
} | |
// Get a reference to the node | |
$ref =& $this->get_reference($path); | |
// Move it to the new parent | |
$new_parent[$node_id] = $ref; | |
// And finally kill it | |
unset($parent[$node_id]); | |
return TRUE; | |
} | |
// -------------------------------------------------------------------- | |
/** | |
* Get reference to the element at the end of the given path | |
* | |
* @access public | |
* @param array path array | |
* @return ref reference to the array segment | |
*/ | |
function &get_reference($path) | |
{ | |
$subject =& $this->_struct; | |
foreach($path as $node) | |
{ | |
$subject =& $subject[$node]; | |
} | |
return $subject; | |
} | |
// -------------------------------------------------------------------- | |
/** | |
* Get path to the id | |
* | |
* @access public | |
* @param array array to search | |
* @param int id of the node to find | |
* @return array array of nodes in the path | |
*/ | |
function get_path($id) | |
{ | |
return $this->_get_path_callback($id, $this->_struct); | |
} | |
// -------------------------------------------------------------------- | |
/** | |
* Recursive function that does the work for get_path | |
* | |
* @access private | |
* @param int id of the node to find | |
* @param array array to search | |
* @param array recursive path array | |
* @return array array of nodes in the path | |
*/ | |
function _get_path_callback($needle, $haystack, $path = array()) | |
{ | |
foreach($haystack as $key => $val) | |
{ | |
if($key == $needle) | |
{ | |
$path[] = $key; | |
return $path; | |
} | |
else if ( is_array($val) && $sub_path = $this->_get_path_callback($needle, $val, $path)) | |
{ | |
$path = array_merge($path, Array($key), $sub_path); | |
return $path; | |
} | |
} | |
return FALSE; | |
} | |
} | |
// END Structure class | |
/* End of file structure.php */ | |
/* Location: ./application/libraries/structure.php */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment