User Tools

Site Tools


adjacencytree
testAdjacencyTree.php
<pre>
<?php
 
include_once 'AdjacencyTree.php';
 
$list[] = array('id' => 'home',  'parentId' => 'root',  'title' => 'Home',                  'tooltip' => 'zurück zum Anfang', 'order' => '1', 'value' => null);
$list[] = array('id' => 'links', 'parentId' => 'root',  'title' => 'Links',                 'tooltip' => 'meine Links',       'order' => '2', 'value' => null);
$list[] = array('id' => 1,       'parentId' => 'links', 'title' => 'yaslaw´s tolle Seite',  'tooltip' => 'gehe zu los, ohne..','order' => '1', 'value' => 'http://yaslaw.info');
$list[] = array('id' => 45,      'parentId' => 'links', 'title' => 'tutorials',             'tooltip' => null,                'order' => '2', 'value' => 'http://www.tutorials.de');
$list[] = array('id' => 'foo',   'parentId' => 'home',  'title' => 'Foo',                   'tooltip' => null,                'order' => null, 'value' => 'foo');
$list[] = array('id' => 'bar1',  'parentId' => 'foo',   'title' => 'bar 1',                 'tooltip' => null,                'order' => null, 'value' => 'bar');
$list[] = array('id' => 'bar2',  'parentId' => 'foo',   'title' => 'bar 2',                 'tooltip' => 'noch ein bar',      'order' => 2,    'value' => 'bar');
 
/**
 * Beispiel für eine indiviudale Anwendung des Trees
 * Eine Ableitung der Node-Class bei der die Sortierung und der Ausgabetext geändert ist
 * @author C754943
 *
 */
class AdjacencyTreeNodeByName extends AdjacencyTreeNode{
	//Geänderter Text
	protected function setText(){
		$this->text = '&bull; ' . str_repeat('&rarr; ', $this->level) . $this->title;
	}
	//Sortierung innerhalb der Gruppen anhand der Parameter 'order' und 'title'
	protected function setSortText($sortParent){
		$this->sort = sprintf('%sZZZ%04d%s', $sortParent, $this->order, $this->title);
	}
}
 
//Tree erstellen
$tree = new AdjacencyTree('AdjacencyTreeNodeByName', 'root');
$usedKeys = array_flip(array('id', 'parentId', 'title'));
foreach($list as $item){
	$tree->createNode($item['id'], $item['parentId'], $item['title'], array_diff_key($item, $usedKeys));
}
 
 
//Tree berechnen
$tree->calcTree();
 
//und ausgeben
foreach($tree as $node){
	echo sprintf('<a href="%s" title="%s">%s</a><br />', $node->value, $node->tooltip, $node->text);
}
?>
</pre>
AdjacencyTree.php
<?php
/**
 * mpl           by ERB software
 * @author       stefan.erb(at)erb-software.com
 */
 
 
/**
 * Tree Class
 * @see ArrayObject
 */
class AdjacencyTree extends ArrayObject{
	const C_NODE_INTERFACE = 'IAdjacencyTreeNode';
	protected $nodeClass;
	protected $rootKey;
 
	/**
	 * Konstruktor
	 * @param String $nodeClass   Der Name der Node-Klasse die eine Ablietung von AdjacencyTreeNode ist.        
	 */
	public function __construct($nodeClass = 'AdjacencyTreeNode', $rootKey = 0){
		parent::__construct(array());
		$this->nodeClass = $nodeClass;
		$this->rootKey = $rootKey;
	}
 
	/**
	 * Hinzufügen eines Nodes. Es wird geprüft dass es ein Objekt der Klasse AdjacencyTreeNode ist.
	 * @see ArrayObject::append()
	 */
	public function append($value){
		if(is_a($value, self::C_NODE_INTERFACE))  $this->offsetSet($value->id, $value);
	}
 
	public function exchangeArray($input){
		foreach($input as $node){
			$this->append($node);
		}
	}
 
	/**
	 * Direktes Erstellen eines Nodes
	 * @param Integer   $id        ID des Nodes
	 * @param Integer   $parentId  ID des Parentnodes
	 * @param String    $title     Beschriftung
	 * @param Array     $paramArray Ein assozierter Array mit weiteren Informationen für den Node
	 */
	public function createNode($id, $parentId, $title, $paramArray = null){
//        $node = $this->nodeClass::create($id, $parentId, $title);
		$node = call_user_func("\\MyBundleNamespace\\{$this->nodeClass}::create", $id, $parentId, $title);
		if(is_array($paramArray)){
			foreach($paramArray as $name => $value){
				$node->$name = $value;
			}
		}
		$this->append($node);
		return $node;
	}
 
	/**
	 * Starte die Berechnung des Trees
	 */
	public function calcTree(){
		//Den Tree aufbauen
		$this->addTreeInfos($this->rootKey);
		//und sortieren
		$this->uasort(array($this, 'sortByNodeSort'));
	}
 
	/**
	 * Wird intern für die Sortirung gebraucht
	 */
	public static function sortByNodeSort($a, $b){
		if ($a->sort == $b->sort) {
			return 0;
		}
		return ($a->sort < $b->sort) ? -1 : 1;
	}
 
	/**
	 * Dei rekursive Funktion für die Treeberechnung
	 * @param Integer    $parentId      ID des Parentnodes
	 * @param String     $sortParent    Sortierung des ParentNodes
	 * @param Integer    $level         Level dieses Nodes
	 */
	private function addTreeInfos($parent, $sortParent = '', $lvl = 0){
		$iter = $this->getIterator();
		foreach($iter as $key => &$node){
			if((string) $node->parentId == (string) $parent){
				$node->addTreeInfos($sortParent, $lvl);
				//Und dasselbe für alle Kinder des aktellen Nodes
				$this->addTreeInfos($node->id, (string)$node->sort, $lvl+1);
			}
		}   
	}
}
 
 
 
 
 
/**
 * Interface der Node-Class
 * Wird verwendet wenn man eine eigene Klasse schreiben will
 */
interface IAdjacencyTreeNode{
	/**
	 * Konstruktor
	 * @param Integer   $id        ID des Nodes
	 * @param Integer   $parentId  ID des Parentnodes
	 * @param String    $title     Beschriftung
	 */
	public static function create($id, $parentId, $title);    
 
	/**
	 * TreeInfos des Nodes erstellen
	 * @param String     $sortParent    Sortierung des ParentNodes
	 * @param Integer    $level         Level dieses Nodes
	 */
	public function addTreeInfos($sortParent, $level);
}
 
 
 
 
 
 
 
/**
 * Ein einzelner Node des Trees
 * Um die Reihenfolge und/oder die TreeTexte zu verändern muss dies in dieser Klasse getan werden
 */
class AdjacencyTreeNode implements IAdjacencyTreeNode{
	private $id;
	private $parentId;
	private $title;
	private $sort;
	private $level;
	private $text;
	private $order;
 
	/**
	 * Konstruktor
	 * @param Integer   $id        ID des Nodes
	 * @param Integer   $parentId  ID des Parentnodes
	 * @param String    $title     Beschriftung
	 */
	public static function create($id, $parentId, $title){
		$instance = new AdjacencyTreeNode();
		$instance->id = $id;
		$instance->parentId = $parentId;
		$instacne->title = $title;        
		return $instance;
	}
 
	/**
	 * TreeInfos des Nodes erstellen
	 * @param String     $sortParent    Sortierung des ParentNodes
	 * @param Integer    $level         Level dieses Nodes
	 */
	public function addTreeInfos($sortParent, $level){
		$this->level = $level;
		$this->setSortText($sortParent);
		$this->setText();
	}
 
	/**
	 * Setzt den TreeText des Nodes
	 */
	protected function setText(){
		$this->text = str_repeat('-- ', $this->level) . $this->title;
	}
 
	/**
	 * Setzt den Sort-Value. In diesem Fall nach id
	 * @param String     $sortParent    Sortierung des ParentNodes
	 */
	protected function setSortText($sortParent){
		$this->sort = sprintf('%s.%04d', $sortParent, $this->id);
	}
 
	/**
	 * generic Getter & Setter
	 */
	public function __set($name, $value){$this->$name = $value;}
	public function __get($name){    
		//Falls ein Parameter fehlt, diesen mit NULL zurückgeben und jeden Fehler ignorieren  
		$errLvl = error_reporting();
		error_reporting(0);
		$retVal =  $this->$name;
		error_reporting($errLvl);
		return $retVal;
	}
 
}
?>
adjacencytree.txt · Last modified: 09.12.2013 09:39:54 (external edit)