Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Drzewko left-right, Klasa, PHP 5
bela
post
Post #1


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

Ostrzeżenie: (0%)
-----


  1. <?php
  2. class Tree {
  3. /**
  4.  * Instance of Creole
  5.  */
  6. private $db;
  7.  
  8. /**
  9.  * Constructor, initialize Creole
  10.  *
  11.  * @param $dsn
  12.  */
  13. public function __construct($dsn) {
  14. $this->db = Creole::getConnection($dsn);;
  15. }
  16.  
  17. /**
  18.  * Adds node to tree
  19.  *
  20.  * @param object_id Id of object in system (this is not db id)
  21.  * @param parent Id of parent - db id
  22.  */
  23. public function addNode($object_id, $parent) {
  24. $rs = $this->db->executeQuery('SELECT `id`, `left`, `right` FROM tree WHERE `id`="' . $parent . '"');
  25. if($rs->getRecordCount() == 0) {
  26. $left = 1;
  27. $right = 2;
  28. } else {
  29. while($rs->next()) {
  30. $left = $rs->getInt('left');
  31. $right = $rs->getInt('right');
  32. $parentId = $rs->getInt('id');
  33. }
  34. }
  35. $sql = 'UPDATE tree SET `right` = `right` +2 WHERE `right` >' . ($right - 1);
  36. $this->db->executeQuery($sql);
  37.  
  38. $sql = 'UPDATE tree SET `left` = `left` +2 WHERE `left` > '. ($right - 1);
  39. $this->db->executeQuery($sql);
  40.  
  41. $sql = 'INSERT INTO tree SET `left`=' . ($right - 1) .', `right`=' . $right . ', `object_id`="'. $object_id .'", `parent_id`="' . $parentId .'";';
  42. $this->db->executeQuery($sql);
  43. }
  44.  
  45. /**
  46.  * Adds root node
  47.  *
  48.  * @param object_id Id of object in system (this is not db id)
  49.  * @return boolean
  50.  */
  51. public function addRoot($object_id) {
  52. $rs = $this->db->executeQuery('SELECT * FROM `tree` WHERE `parent_id` ="0"');
  53. if($rs->getRecordCount() == 0) {
  54. $this->db->executeQuery('INSERT INTO `tree` ( `id` , `object_id` , `left` , `right` ) VALUES ( '0', '' . $object_id . '', '1', '2')');
  55. return true;
  56. }
  57. return false;
  58. }
  59.  
  60. /**
  61.  * Removes node
  62.  *
  63.  * @param $id Id of node
  64.  */
  65. public function deleteNode($id) {
  66. $rs = $this->db->executeQuery('SELECT `parent_id`, `left` FROM `tree` WHERE `id`="'. $id .'"');
  67. while($rs->next()) {
  68. $node = array();
  69. $node['parent'] = $rs->getInt('parent_id');
  70. $node['left'] = $rs->getInt('left');
  71. }
  72.  
  73. $this->db->executeQuery('DELETE FROM `tree` WHERE `id`="' . $id . '" LIMIT 1');
  74. $this->rebuild($node['parent'], $node['left'] - 1);
  75. }
  76.  
  77. /**
  78.  * Rebuilds tree recursively
  79.  * If something goes wrong, you'll use this
  80.  *
  81.  * @param $parent Id of parent node
  82.  * @param $left Left
  83.  */
  84. public function rebuild($parent, $left) {
  85. $right = $left+1;
  86.  
  87. $rs = $this->db->executeQuery('SELECT `id` FROM `tree` WHERE `parent_id`="' . $parent . '";');
  88. while ($rs->next()) {
  89. $right = $this->rebuild($rs->getInt('id'), $right);
  90. }
  91. $this->db->executeQuery('UPDATE tree SET `left`=' . $left . ', `right`=' . $right . ' WHERE `id`="' . $parent . '";');
  92. return $right+1;
  93. }
  94.  
  95. /**
  96.  * Test method
  97.  *
  98.  * @param $root Id of node which is root to display
  99.  */
  100. function display($root) {
  101. $rs = $this->db->executeQuery('SELECT `left`, `right` FROM `tree` WHERE `id`="'.$root.'";');
  102. while($rs->next()) {
  103. $l = $rs->getInt('left');
  104. $r = $rs->getInt('right');
  105. }
  106.  
  107. $right = array();
  108.  
  109. $rs = $this->db->executeQuery('SELECT `object_id`, `left`, `right` FROM tree WHERE `left` BETWEEN '. $l .' AND ' . $r . ' ORDER BY `left` ASC;');
  110. while ($rs->next()) {
  111. if (count($right)>0) {
  112.  while ($right[count($right)-1] < $rs->getInt('right')) {
  113.  array_pop($right);
  114.  }
  115.  }
  116.  echo str_repeat('&nbsp;&nbsp;&nbsp;',count($right)) . $rs->getString('object_id'). ' Left: ' . $rs->getInt('left') . ' Right: '. $rs->getInt('right') . "<br/>n";
  117.  
  118.  $right[] = $rs->getInt('right');
  119.  }
  120. }
  121.  
  122. /**
  123.  * Gets object id
  124.  *
  125.  * @param id of node
  126.  * @return object id
  127.  */
  128. public function getNode($id) {
  129. $rs = $this->db->executeQuery('SELECT `object_id` FROM `tree` WHERE `id`="'.$id.'";');
  130. while($rs->next()) {
  131. return $rs->getInt('object_id');
  132. }
  133. }
  134. }
  135. ?>


  1. CREATE TABLE `tree` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `parent_id` int(11) NOT NULL DEFAULT '0',
  4. `object_id` int(11) NOT NULL DEFAULT '0',
  5. `left` int(11) NOT NULL DEFAULT '0',
  6. `right` int(11) NOT NULL DEFAULT '0',
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;


Może komuś się przyda.
Object_id to nr obiektu w cmsie, równie dobrze możecie zastąpić to przez jakiś TEXT.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Mógłbyś chociaż dodać możliwość przenoszenia (góra/dół) elementów po drzewku:
  1. <?php
  2. public function moveNodes($row, $direction){
  3. $parentID = is_null($row->{$this->parentID}) ? ' IS NULL ' : ' = ' . $row->{$this->parentID} . ' ';
  4.  
  5. $query = 'SELECT ' . $this->id .', ' . $this->left . ', ' . $this->right . 
  6.  ' FROM ' . $this->table . 
  7.  ' WHERE ' . $this->parentID . $parentID . 
  8.  ' AND ' . 
  9.  (($direction == 'up') ? $this->right . ' < ' . $row->{$this->right} . 
  10.  ' ORDER BY ' . $this->right . ' DESC' 
  11.  : $this->left . ' > ' . $row->{$this->left} .
  12.  ' ORDER BY ' . $this->left . ' ASC') .
  13.  ' LIMIT 1;';
  14.  
  15. $target = $this->db->getRow($query);
  16. if(!$target)
  17. return false;
  18.  
  19. if($direction == 'up'){
  20. $leftID = $target->{$this->left};
  21. $rightID = $row->{$this->right};
  22.  
  23. $diffUp = $row->{$this->left} - $target->{$this->left};
  24. $diffDown = $row->{$this->right} + 1 - $row->{$this->left};
  25.  
  26. $moveUpLeft = $row->{$this->left};
  27. $moveUpRight = $row->{$this->right};
  28. }else{
  29. $leftID = $row->{$this->left};
  30. $rightID = $target->{$this->right};
  31.  
  32. $diffUp = $row->{$this->right} + 1 - $row->{$this->left};
  33. $diffDown = $target->{$this->right} - $row->{$this->right};
  34.  
  35. $moveUpLeft = $row->{$this->right} + 1;
  36. $moveUpRight = $target->{$this->right};
  37. }
  38.  
  39. $query = 'UPDATE ' . $this->table . 
  40.  ' SET ' . $this->left . ' = ' . $this->left . ' + CASE' .
  41. ' WHEN ' . $this->left . ' BETWEEN ' . $moveUpLeft . ' AND ' . $moveUpRight .' THEN -' . $diffUp .
  42.  ' ELSE ' . $diffDown . 
  43.  ' END, ' .
  44.  $this->right . ' = ' . $this->right . ' + CASE' .
  45.  ' WHEN ' . $this->right . ' BETWEEN ' . $moveUpLeft . ' AND ' . $moveUpRight .' THEN -' . $diffUp .
  46.  ' ELSE ' . $diffDown .
  47.  ' END' .
  48.  ' WHERE ' . $this->left . ' BETWEEN ' . $leftID . ' AND ' . $rightID . 
  49. ' AND ' . $this->right . ' BETWEEN ' . $leftID . ' AND ' . $rightID . ';';
  50. $this->db->query($query);
  51.  
  52. return true;
  53. }
  54. ?>
I tak jeszcze w ramach objaśnienia:
  1. <?php
  2. $this->table; //nazwa tabeli przechowywujacej drzewko
  3. //nazwy pol w bazie (w konstruktorze klasy definujemy je sobie - nazwe tabeli tez)
  4. $this->id //np: moduleID
  5. $this->left 
  6. $this->right //np. treeRight
  7. $this->parentID
  8. $this->indent
  9. ?>



Metoda ta przyjmuje dwa argumenty - pierwszy to wynik zapytania pobierającego wszystko n/t elementu (node) którego chcemy przenieś. Drugi to string (up/down) - kierunek przesunięcia


EDIT: To wycinek z klasy gdzieś z początku 2007 (gdy zaczynałem OOP) - więc proszę bez zbednych komentarzy (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif)

Ten post edytował Crozin 4.05.2008, 16:04:44
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 8.10.2025 - 03:04