<?php/** * Klasa odpowiedzialna za zarządzanie wyjątkami typu "Niepoprawny ID elementu" * * @author Daniel Ancuta <daniel.ancuta@whisnet.pl> * @package HeniuTree * @version $id: 1.0 Build 1 */class HeniuTreeIncorrectIdException extends Exception {}?><?php/** * Klasa reprezentująca model zarządzający struktórą drzewiastą * * @abstract * @author Daniel Ancuta <daniel.ancuta@whisnet.pl> * @package HeniuTree * @subpackage NestedTree * @version $id: 1.0 Build 2 */abstract class HeniuTree{ /** * Dodanie gałęzi * * @param object $node */ abstract public function addNode($node); /** * Edycja gałęzi * * @param object $node */ abstract public function editNode($node); /** * Usunięcie gałęzi * * @param object $id */ abstract public function deleteNode($id); /** * Przeniesienie gałęzi * * @param object $from * @param object $to */ abstract public function moveNode($from, $to); /** * Pobranie gałęzi * * @param object $from */ abstract public function getMany($from);}?><?php/** * Klasa reprezentująca pojedyńczy obiekt liścia drzewa * * @abstract * @author Daniel Ancuta <daniel.ancuta@whisnet.pl> * @package HeniuTree * @subpackage NestedTree * @version $id: 1.0 Build 2 */abstract class HeniuTreeNode{ /** * Ustawienie ID gałęzi * * @param unknown_type $id */ public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } /** * Ustawienie nazwy elementu * * @param string $name */ public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } private $id = null; private $name = null;}?><?php/** * Manager zarządzający drzewkiem typu Nested tree * * @author Daniel Ancuta <daniel.ancuta@whisnet.pl> * @package HeniuTree * @subpackage NestedTree * @version $id: 1.0 Build 2 */class HeniuTreeNested extends HeniuTree{ /** * * @param handler $dbh Obiekt bazy danych (PDO) */ public function __construct($dbh) { $this->dbh = $dbh; } /** * Dodanie nowego elementu do drzewka * * @param object $node */ public function addNode($node) { // Wyciągamy rgt elementu drzewka do którego dodamy dziecko $sth = $this->dbh->prepare("SELECT rgt FROM ".$this->getTableName()." WHERE id = :id "); $sth->bindValue(':id', $node->getParentId(), PDO::PARAM_INT); $sth->execute(); $rgt = $sth->fetchColumn(); // Robimy miejsce na nowy element w drzewie $sth = $this->dbh->prepare("UPDATE ".$this->getTableName()." SET rgt = rgt+2 WHERE rgt >= :rgt "); $sth->bindParam(':rgt', $rgt, PDO::PARAM_INT); $sth->execute(); $sth = $this->dbh->prepare("UPDATE ".$this->getTableName()." SET lft = lft+2 WHERE lft >= :lft"); $sth->bindParam(':lft', $rgt, PDO::PARAM_INT); $sth->execute(); // Dodajemy element $this->_addNode($node, $rgt, ($rgt+1)); } /** * Samo dodanie elementu * * @param object $node Obiekt elementu * @param int $lft Wartość left * @param int $rgt Wartość right */ private function _addNode($node, $lft, $rgt) { $sth = $this->dbh->prepare("INSERT INTO ".$this->getTableName()." (lft, rgt, parent_id, name) VALUES ( :lft, :rgt, :parent_id, :name )"); $sth->bindParam(':lft', $lft, PDO::PARAM_STR); $sth->bindParam(':rgt', $rgt, PDO::PARAM_STR); $sth->bindValue(':parent_id', $node->getParentId(), PDO::PARAM_INT); $sth->bindValue(':name', $node->getName(), PDO::PARAM_STR); $sth->execute(); } /** * Edycja istniejącej gałęzi * * @param object $node Obiekt gałęzi którą chcemy zedytować */ public function editNode($node) { $sth = $this->dbh->prepare("UPDATE ".$this->getTableName()." SET name = :name WHERE id = :id"); $sth->bindValue(':name', $node->getName(), PDO::PARAM_STR); $sth->bindValue(':id', $node->getId(), PDO::PARAM_INT); $sth->execute(); } /** * Usunięcie gałęzi drzewa wraz z wszystkimi dziećmi * * @param int $id ID elementu który usówamy */ public function deleteNode($id) { if ( $id <= 1 ) { throw new HeniuTreeIncorrectIdException('ID elementu do usunięcia nie może być mniejszy, równy 1'); } else { $sth = $this->dbh->prepare("SELECT lft, rgt FROM ".$this->getTableName()." WHERE id = :id "); $sth->bindParam(':id', $id, PDO::PARAM_INT); $sth->execute(); $result = $sth->fetch(PDO::FETCH_ASSOC); $lft = $result['lft']; $rgt = $result['rgt']; $amountChildren = ($rgt-$lft-1)/2; // Usówamy elementy $sth = $this->dbh->prepare("DELETE FROM ".$this->getTableName()." WHERE lft >= :lft AND rgt <= :rgt LIMIT ".($amountChildren+1)." "); $sth->bindParam(':lft', $lft, PDO::PARAM_INT); $sth->bindParam(':rgt', $rgt, PDO::PARAM_INT); $sth->execute(); // Ustawiamy lft i rgt dla reszty elementów $sth = $this->dbh->prepare("UPDATE ".$this->getTableName()." SET lft = lft-".($amountChildren*2).", rgt = rgt-".($amountChildren*2)." WHERE lft > :rgt"); $sth->bindParam(':rgt', $rgt, PDO::PARAM_INT); $sth->execute(); } } /** * Przeniesienie gałęzi wraz z wszystkimi dziećmi do innej gałęzi * * @param object $from Obiekt elementu który przenosimy * @param object $to Obiekt elementu do którego przenosimy gałąź */ public function moveNode($from, $to) { // Ustawiamy rgt starego rodzica elementu $sth = $this->dbh->prepare("UPDATE ".$this->getTableName()." SET rgt = :rgt WHERE id = :id"); $sth->bindParam(':rgt', $from->getLft(), PDO::PARAM_INT); $sth->bindParam(':id', $from->getParentId(), PDO::PARAM_INT); //$sth->execute(); // Ustawiamy nowy lft dla rodzica który otrzymuje dziecko $sth = $this->dbh->prepare("UPDATE ".$this->getTableName()." SET lft = :lft WHERE id = :id"); $sth->bindValue(':lft', ($from->getRgt()+1), PDO::PARAM_INT); $sth->bindValue(':id', $to->getId(), PDO::PARAM_INT); //$sth->execute(); // Pobieramy (jeśli istnieje) rgt ostatniej kategorii elementu do którego dodajemy dziecko $sth = $this->dbh->prepare("SELECT MAX(rgt) FROM ".$this->getTableName()." WHERE rgt < :rgt "); $sth->bindValue(':rgt', $to->getRgt(), PDO::PARAM_INT); $sth->execute(); $latestNodeRgtTo = $sth->fetchColumn(); // Ustawiamy lft i rgt // Jak kurwa? } /** * Pobranie pojedyńczej gałęzi * * @return object Obiekt klasy HeniuTreeNodeNested */ public function getOne($id) { $sth = $this->dbh->prepare("SELECT id, parent_id, lft, rgt FROM ".$this->getTableName()." WHERE id = :id"); $sth->bindParam(':id', $id, PDO::PARAM_INT); $sth->execute(); $result = $sth->fetch(PDO::FETCH_ASSOC); $args = array(); $args['id'] = $result['id']; $args['parent_id'] = $result['parent_id']; $args['lft'] = $result['lft']; $args['rgt'] = $result['rgt']; $args['name'] = $result['name']; return new HeniuTreeNodeNested($args); } /** * Pobranie elementów z drzewka * * @param int $from ID elementu od którego zacząć pobieranie * @return array Tablica obiektów klasy HeniuTreeNodeNested */ public function getMany($from) { // Pobranie lft i rgt elementu od którego chcemy zacząć pobieranie $sth = $this->dbh->prepare("SELECT lft, rgt FROM ".$this->getTableName()." WHERE id = :id"); $sth->bindParam(':id', $from, PDO::PARAM_INT); $sth->execute(); $result = $sth->fetch(PDO::FETCH_ASSOC); $lft = $result['lft']; $rgt = $result['rgt']; // Pobranie elementów $sth = $this->dbh->prepare("SELECT id, parent_id, lft, rgt, name FROM ".$this->getTableName()." WHERE lft >= :lft AND rgt <= :rgt AND id != 1 ORDER BY lft"); $sth->bindParam(':lft', $lft, PDO::PARAM_INT); $sth->bindParam(':rgt', $rgt, PDO::PARAM_INT); $sth->execute(); $nodes = $sth->fetchAll(PDO::FETCH_ASSOC); $result = array(); foreach($nodes AS $node) { $args = array(); $args['id'] = $node['id']; $args['parent_id'] = $node['parent_id']; $args['lft'] = $node['lft']; $args['rgt'] = $node['rgt']; $args['name'] = $node['name']; $result[] = new HeniuTreeNodeNested($args); } return $result; } /** * Ustawienie nazwy tabeli w której mamy drzewko * * @param string $tblName */ public function setTableName($tblName) { $this->tblName = $tblName; } public function getTableName() { return $this->tblName; } protected $dbh = null; protected $tblName = null;}?><?php/** * Klasa reprezentująca pojedyńczy obiekt liścia drzewa * * @author Daniel Ancuta <daniel.ancuta@whisnet.pl> * @package HeniuTree * @subpackage NestedTree * @version $id: 1.0 Build 2 */class HeniuTreeNodeNested extends HeniuTreeNode{ /** * * @param array $args Tablica argumentów gałęzi */ public function __construct(array $args=null) { isset($args['id']) ? $this->setId($args['id']):''; isset($args['name']) ? $this->setName($args['name']):''; isset($args['parent_id']) ? $this->setParentId($args['parent_id']):''; isset($args['lft']) ? $this->setLft($args['lft']):''; isset($args['rgt']) ? $this->setRgt($args['rgt']):''; } /** * Ustawienie ID rodzica elementu * * @param int $parentId */ public function setParentId($parentId) { $this->parentId = $parentId; } public function getParentId() { return $this->parentId; } /** * Pobranie left gałęzi * * @return int */ public function getLft() { return $this->lft; } /** * Pobranie right gałęzi * * @return int */ public function getRgt() { return $this->rgt; } private $parentId = null;}?><?php/** * Dodanie nowego liścia do drzewa. Należy pamiętać że po utworzeniu bazy TRZEBA dodać element główny o ID - 1 i parent_id - 0 * * @author Daniel Ancuta <daniel.ancuta@whisnet.pl> */require_once('../HeniuTree/HeniuTree.class.php');require_once('../HeniuTree/HeniuTreeNode.class.php');require_once('../HeniuTree/Exceptions/HeniuTreeIncorrectIdException.class.php');require_once('../HeniuTree/NestedTree/HeniuTreeNested.class.php');require_once('../HeniuTree/NestedTree/HeniuTreeNodeNested.class.php');$nodeManager = new HeniuTreeNested( new PDO('mysql:dbname=database_name;host=localhost', 'user', 'password') );$nodeManager->setTableName('tableName');$node = new HeniuTreeNodeNested();$node->setName('Telewizory');$node->setParentId(1);$nodeManager->addNode($node);?><?php/** * Dodanie nowego liścia do drzewa. Należy pamiętać że po utworzeniu bazy TRZEBA dodać element główny o ID - 1 i parent_id - 0 * * @author Daniel Ancuta <daniel.ancuta@whisnet.pl> */require_once('../HeniuTree/HeniuTree.class.php');require_once('../HeniuTree/HeniuTreeNode.class.php');require_once('../HeniuTree/Exceptions/HeniuTreeIncorrectIdException.class.php');require_once('../HeniuTree/NestedTree/HeniuTreeNested.class.php');require_once('../HeniuTree/NestedTree/HeniuTreeNodeNested.class.php');$nodeManager = new HeniuTreeNested( new PDO('mysql:dbname=database_name;host=localhost', 'user', 'password') );$nodeManager->setTableName('tableName');try { $nodeManager->deleteNode(2); } catch (HeniuTreeIncorrectIdException $e) { echo $e->getMessage();}?>