Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] Drzewko IP - Wielopoziomowa lista
Forum PHP.pl > Forum > Przedszkole
arturpiotrowski
W tym wątku nauczyłem się robić drzewko IP z kategoriami. (dzięki nospor).
Udało mi się zrobić formularz z polem select i wszystkimi kategoriami i podkategoriami:
  1. INSERT INTO `kategorie` (`kategoria_id`, `nazwa`, `ip`, `poziom`) VALUES
  2. (1, 'Root', '1.', 0),
  3. (2, 'Produkty spożywcze', '1.2.', 1),
  4. (3, 'Sprzęt AGD', '1.3.', 1),
  5. (4, 'Sprzęt RTV', '1.4.', 1),
  6. (11, 'Auto / Moto', '1.11.', 1),
  7. (12, 'Sprzęt sportowy', '1.12.', 1),
  8. (13, 'Komputery', '1.13.', 1),
  9. (14, 'Zabawki', '1.14.', 1),
  10. (15, 'Miksery', '1.3.15.', 2),
  11. (16, 'Zmywarki', '1.3.16.', 2),
  12. (17, 'Opony', '1.11.17.', 2),
  13. (18, 'Rowery', '1.12.18.', 2),
  14. (19, 'Dyski twarde', '1.13.19.', 2),
  15. (20, 'Monitory', '1.13.20.', 2),
  16. (22, 'Puzzle', '1.14.22.', 2),
  17. (23, 'Odkurzacze', '1.3.23.', 2),
  18. (25, 'Pieczywo', '1.2.25.', 2),
  19. (28, 'Telewizory', '1.4.28.', 2),
  20. (30, 'Soki i napoje', '1.2.30.', 2);

  1. $space = '';
  2. $out = '<select name="jednostki" class="form-control">';
  3. $kat = '' // wynik zapytania o wszystkie kategorie
  4. foreach($kat as $item){
  5. if($item->poziom > 0){
  6. for($i=1;$i<=$item->poziom;$i++){
  7. if($i==$item->poziom){
  8. $space .= '-&nbsp;';
  9. } else{
  10. $space .= '-';
  11. }
  12. }
  13. }
  14. $out .= '<option value="' . $item->ip . '">'. $space . $item->nazwa . '</option>';
  15. $space = '';
  16. }
  17. $out .= '</select>';
  18. echo $out;

ale nie umiem zrobić z tego listy <ul></ul> wielopoziomowej, może jakaś dobra dusza mi podpowiedzieć jak to zrobić? z jednym poziomem sobie jakoś radzę. Nie wiem jak zaimplementować listę z kolejnymi poziomami tego drzewa sad.gif
nospor
Pobierasz wszystkie kategorie selectem, ale wazne bys dla zapytania ustawil ORDER BY LEVEL ASC + ewentualnie inne pola jesli chcesz sortowac po np. nazwie
Potem lecisz pokolei po rekordach w php i budujesz tablice, ktorej indexem jest ID kategorii a wartoscia reszta danych kategorii + pole na CHILDREN ktore jest tablica i tam bedziesz wstawial bezposrednie dzieci danej kategorii/subkategorii

Gdy juz bedziesz mial tak zbudowana tablice lecisz foreachem najpierw po elementach ktore maja level 0. Jesli one maja dzieci to wchodzisz foreachem w dzieci i iterujesz po dzieciach itd itd. Tutaj bardzo przydatna bedzie rekurencja.

Sory ze tak ogolnikowo ale mam troche na glowie dzisiaj
arturpiotrowski
Kod
// [b]$cats[/b] zawiera tablice z wynikami zapytania o wszystkie kategorie

foreach($cats as $cat) {
        $arr[$cat->kategoria_id] = array(
          'nazwa'=>$cat->nazwa,
          'ip' => $cat->ip,
          'poziom' => $cat->poziom,
          'dzieci'=>array() // i tu nie wiem co i jak wstawic w te tablice...
        );
      }

Na razie probuje stworzyc te tablice i stanalem na stworzeniu tablicy w elemencie 'dzieci'.
Wiem ze w tablicach w elemencie 'dzieci' powinny byc dane kolejnych dzieci tak jak w powyzszej tablicy, z tablicami w 'dzieci' do ostatniego zagniezdzenia, tylko nie wiem jak te tablice stworzyc
nospor
Nie, chodzilo mi tylko o bezposrednie dzieci. To bedzie w miare plaska tablica

  1. <?php
  2. foreach($cats as $cat) {
  3. $idRodzica = //tu wstaw id rodzica dla danego $cat. wyciagnij to z IP
  4. $arr[$cat->kategoria_id] = array(
  5. 'nazwa'=>$cat->nazwa,
  6. 'ip' => $cat->ip,
  7. 'poziom' => $cat->poziom,
  8. 'dzieci'=>array() // tu wlasnie tak ma zostac
  9. );
  10.  
  11. //tutaj jest to dziecko, to dodaje wpis do rodzica
  12. if ($idRodzica) {
  13. $arr[$idRodzica]['dzieci'][] = $cat->kategoria_id; //i juz
  14. }
  15. }
arturpiotrowski
Przepraszam że dopiero teraz piszę, a idRodzica z IP jak mam wyciągnąć?
np. przez explode IP po kropce rozbić na tablicę i wyciągając element po numerze level?
nospor
Moze byc tak jak mowisz ale rownie dobrze moze byc tak, ze przedostatni element po robiciu po kropce to rodzic smile.gif
arturpiotrowski
chyba z 1 zadaniem się udało, wydaje mi się że działa dobrze:
  1. // w $cats jest tablica obiektów z wynikami z bazy
  2. foreach($cats as $cat) {
  3. $ip_array = explode('.',$cat->ip);
  4. $key = $cat->level-1 // - 1 bo explode dodaje 1 pusty element na końcu przez kropkę na końcu IP;
  5. if($key >= 0){
  6. $parent_id = $ip_array[$key];
  7. }
  8.  
  9. $arr[$cat->cat_id] = array(
  10. 'cat_name'=>$cat->cat_name,
  11. 'ip' => $cat->ip,
  12. 'level' => $cat->level,
  13. 'childrens'=>array();
  14. );
  15.  
  16. //tutaj jest to dziecko, to dodaje wpis do rodzica
  17. if (isset($parent_id)) {
  18. $arr[$parent_id]['childrens'][] = $cat->cat_id;
  19. }
  20. }
  21. var_dump($arr);

biorę się za 2 zadanie:)

Przepraszam ale chyba sam sobie nie poradzę, siedzę nad tym już 2 dzień i nic mądrego do głowy mi nie przychodzi. Nie wiem jak się za to zabrać sad.gif

Jak rozumiem powienienem teraz napisać funkcję z 2 pętlami foreach

pierwsza pętla dla elementów tablicy głównej druga dla childrens? Tylko co zrobić aby przypisać subkategorie do właściwego children[cat_id]

mam zbudować kolejną tablicę czy już taką listę <ul><li></li></ul>?
nospor
Nie, nie dwa foreach tylko rekurencja.

Wpierw pobierasz id kategorii z level 1 i to jako parametr przekazujesz do funkcji. Funkcja ta leci po twojej glownej kategorii ale tylko dla przekazanych id.
Gdy dana kategoria ma dzieci, to masz id tych dzieci i znowu odpalasz funkcje z parametrami tych dzieci. itd itd ladna rekurencja, ktora generuje ci twoje zagniezdzone ul
arturpiotrowski
Dzięki, coś się ruszyło do przodu choć jeszcze daleko do ideału:
  1. function cat_tree()
  2. {
  3. $cats = '' // obiekt z wynikiem pobierania wszystkich kategorii z bazy
  4.  
  5. foreach($cats as $cat) {
  6. $ip_array = explode('.',$cat->ip);
  7. $key = $cat->level-1;
  8. if($key >= 0){
  9. $parent_id = $ip_array[$key];
  10. }
  11.  
  12. $arr[$cat->cat_id] = array(
  13. 'cat_name'=>$cat->cat_name,
  14. 'ip' => $cat->ip,
  15. 'level' => $cat->level,
  16. 'childrens'=>array(),
  17. );
  18.  
  19. if (isset($parent_id)) {
  20. $arr[$parent_id]['childrens'][] = $cat->cat_id;
  21. }
  22. }
  23.  
  24. return $arr;
  25. }
  26.  
  27. function categories_tree($level = 1){
  28. $tree = $this->cat_tree();
  29. if (is_array($tree)){
  30. $output = '<ul>';
  31. foreach ($tree as $leaf){
  32. if($leaf['level'] == $level){
  33. if (!empty($leaf['childrens'])){
  34. $output .= '<li>'.$leaf['cat_name'];
  35. $output .= $this->categories_tree($leaf['childrens']);
  36. $output .= '</li>';
  37. }
  38. else{
  39. $output .= '<li>'.$leaf['cat_name'].'</li>';
  40. }
  41. }
  42. }
  43. $output .= '</ul>';
  44. }
  45. var_dump($output);
  46. }

zwraca mi w źródle coś takiego:
  1. string(9) "<ul></ul>"
  2. string(9) "<ul></ul>"
  3. string(9) "<ul></ul>"
  4. string(9) "<ul></ul>"
  5. string(9) "<ul></ul>"
  6. string(9) "<ul></ul>"
  7. string(9) "<ul></ul>"
  8. string(156) "<ul><li>Auto / Moto</li><li>Komputery</li><li>Produkty spożywcze</li><li>Sprzęt AGD</li><li>Sprzęt RTV</li><li>Sprzęt sportowy</li><li>Zabawki</li></ul>"

Nie wiem czemu mi pokazuje tylko pierwszy poziom drzewa, jak w każdym poziomie pierwszym jest co najmniej jedna gałąź niżej, a w niektórych więcej jak jedna niżej?.
Jak mniemam teraz za każdą rekurencją jest odpytanie bazy? Jak to zrobić żeby tylko raz pobrał dane z bazy? Co to jest te 7 razy puste <ul></ul> na początku, jak się tego z tamtąd pozbyć?
nospor
Cytat
Jak mniemam teraz za każdą rekurencją jest odpytanie bazy?
Ke? pokaz mi prosze palcem gdzie ty w tym kodzie rekurencji lecisz do bazy....

Nie
var_dump($output);

a
return $output;

edit:
a, tutaj
$tree = $this->cat_tree();
ze niby lecisz do bazy....

to:
$tree = $this->cat_tree();
ma byc odpalone tylko raz a nie w rekurencji.
Raz wygenerowane $tree masz albo przekazywac jako parametr do funkcji albo trzymac jako wlasciwosc klasy bo widze ze masz to na klasie zrobione
arturpiotrowski
wiem o return, tu raczej chodziło mi o wyrzucenie od razu na ekran danych więc zastosowałem tymczasowo var_dump
  1. class Categories {
  2.  
  3. function __construct() {
  4. $this->all_cats = $this->cat_tree(); // o to chodziło o trzymanie we właściwości klasy?
  5. }
  6.  
  7. function cat_tree()
  8. {
  9. $cats = '' // obiekt z wynikiem pobierania wszystkich kategorii z bazy
  10.  
  11. foreach($cats as $cat) {
  12. $ip_array = explode('.',$cat->ip);
  13. $key = $cat->level-1;
  14. if($key >= 0){
  15. $parent_id = $ip_array[$key];
  16. }
  17.  
  18. $arr[$cat->cat_id] = array(
  19. 'cat_name'=>$cat->cat_name,
  20. 'ip' => $cat->ip,
  21. 'level' => $cat->level,
  22. 'childrens'=>array(),
  23. );
  24.  
  25. if (isset($parent_id)) {
  26. $arr[$parent_id]['childrens'][] = $cat->cat_id;
  27. }
  28. }
  29.  
  30. return $arr;
  31. }
  32.  
  33. function categories_tree($level = 1){
  34. $tree = $this->all_cats;
  35. if (is_array($tree))
  36. $output = '<ul>';
  37. {
  38. foreach ($tree as $leaf){
  39. if($leaf['level'] == $level){
  40. if (! empty($leaf['childrens']))
  41. {
  42. $output .= '<li>'.$leaf['cat_name'];
  43. $output .= $this->categories_tree($leaf['childrens']);
  44. $output .= '</li>';
  45. }
  46. else{
  47. $output .= '<li>'.$leaf['cat_name'].'</li>';
  48. }
  49. }
  50. }
  51. $output .= '</ul>';
  52. }
  53. return $output;
  54. }

ale to nadal zwraca tylko jeden poziom i kod html jaki podałem w poście wyżej
Wydaje mi się że kłopot jest tutaj:
  1. foreach ($tree as $leaf){
  2. if($leaf['level'] == $level){
  3. if (! empty($leaf['childrens']))
  4. {
  5. $output .= '<li>'.$leaf['cat_name'];
  6. $output .= $this->categories_tree($leaf['childrens']);
  7. $output .= '</li>';
  8. }
  9. else{
  10. $output .= '<li>'.$leaf['cat_name'].'</li>';
  11. }
  12. }
  13. }

Wydaje mi się czy rekurencja cały czas rzeźbi na tym samym drzewie $tree a nie schodzi głębiej po gałęzi 'childrens'? Ale jak mam to zrobić aby szła po childrens?
Pewnie pomogłoby przekazywanie w funkcji categories_tree(), przy rekurencji jako drugiego parametru tablicy z drzewem 'childrens' ale ono też ma teraz, tylko indeksy z cat_id sad.gif
nospor
Parametrem dla funkcji categories_tree() sa dzieci a nie poziom. Skoro sa to dzieci, to masz iterowac po tych dzieciach a nie po calym drzewie. Dzieki temu bedziesz zawsze iterowal po tym co trzeba.
Zas za pierwszym razem jak odpalasz funkcje categories_tree() masz jej przekazac id elementow z poziomu 0
arturpiotrowski
nospor, dziękuję Ci za cierpliwość, chyba pora w tym temacie zmienić forum na to z Twojej stopki smile.gif
nie wiem jakim sposobem pobrać id elementów z poziomu 0 przy pierwszym odpaleniu funkcji? :-( a także potem id dzieci zawartych w $childrens?
nospor
Cytat
nie wiem jakim sposobem pobrać id elementów z poziomu 0 przy pierwszym odpaleniu funkcji?
Normalnie iterujesz po glownej tablicy i pobierasz z niej te ID, ktore maja level 0 smile.gif

Cytat
a także potem id dzieci zawartych w $childrens?
No przeciez w children masz wlasnie id, to jaki problem?
arturpiotrowski
Coś mi wyszło, wygląda chyba na prawidłowy układ, ale nie wiem czy o to Ci chodziło?
  1. class Categories {
  2.  
  3. function __construct() {
  4. $this->all_cats = $this->cat_tree();
  5. }
  6.  
  7. function cat_tree() {
  8. // w poniższej zmiennej $cat_tree będzie wynik z bazy danych
  9. $cat_tree = array(
  10. 1=>array(
  11. "cat_name"=>"Root",
  12. "ip"=>"1.",
  13. "level"=>"0",
  14. "childs"=>array(
  15. 0=>"11",
  16. 1=>"13",
  17. 2=>"2",
  18. 3=>"3",
  19. 4=>"4",
  20. 5=>"12",
  21. 6=>"14",
  22. ),
  23. ),
  24. 11=>array(
  25. "cat_name"=>"Auto / Moto",
  26. "ip"=>"1.11.",
  27. "level"=>"1",
  28. "childs"=>array(
  29. 0=>"17",
  30. ),
  31. ),
  32. 13=>array(
  33. "cat_name"=>"Komputery",
  34. "ip"=>"1.13.",
  35. "level"=>"1",
  36. "childs"=>array(
  37. 0=>"19",
  38. 1=>"20",
  39. ),
  40. ),
  41. 2=>array(
  42. "cat_name"=>"Produkty spożywcze",
  43. "ip"=>"1.2.",
  44. "level"=>"1",
  45. "childs"=>array(
  46. 0=>"25",
  47. 1=>"30",
  48. ),
  49. ),
  50. 3=>array(
  51. "cat_name"=>"Sprzęt AGD",
  52. "ip"=>"1.3.",
  53. "level"=>"1",
  54. "childs"=>array(
  55. 0=>"15",
  56. 1=>"23",
  57. 2=>"16",
  58. ),
  59. ),
  60. 4=>array(
  61. "cat_name"=>"Sprzęt RTV",
  62. "ip"=>"1.4.",
  63. "level"=>"1",
  64. "childs"=>array(
  65. 0=>"28",
  66. ),
  67. ),
  68. 12=>array(
  69. "cat_name"=>"Sprzęt sportowy",
  70. "ip"=>"1.12.",
  71. "level"=>"1",
  72. "childs"=>array(
  73. 0=>"18",
  74. ),
  75. ),
  76. 14=>array(
  77. "cat_name"=>"Zabawki",
  78. "ip"=>"1.14.",
  79. "level"=>"1",
  80. "childs"=>array(
  81. 0=>"22",
  82. ),
  83. ),
  84. 19=>array(
  85. "cat_name"=>"Dyski twarde",
  86. "ip"=>"1.13.19.",
  87. "level"=>"2",
  88. "childs"=>array(),
  89. ),
  90. 15=>array(
  91. "cat_name"=>"Miksery",
  92. "ip"=>"1.3.15.",
  93. "level"=>"2",
  94. "childs"=>array(),
  95. ),
  96. 20=>array(
  97. "cat_name"=>"Monitory",
  98. "ip"=>"1.13.20.",
  99. "level"=>"2",
  100. "childs"=>array(),
  101. ),
  102. 23=>array(
  103. "cat_name"=>"Odkurzacze",
  104. "ip"=>"1.3.23.",
  105. "level"=>"2",
  106. "childs"=>array(),
  107. ),
  108. 17=>array(
  109. "cat_name"=>"Opony",
  110. "ip"=>"1.11.17.",
  111. "level"=>"2",
  112. "childs"=>array(),
  113. ),
  114. 25=>array(
  115. "cat_name"=>"Pieczywo",
  116. "ip"=>"1.2.25.",
  117. "level"=>"2",
  118. "childs"=>array(),
  119. ),
  120. 22=>array(
  121. "cat_name"=>"Puzzle",
  122. "ip"=>"1.14.22.",
  123. "level"=>"2",
  124. "childs"=>array(),
  125. ),
  126. 18=>array(
  127. "cat_name"=>"Rowery",
  128. "ip"=>"1.12.18.",
  129. "level"=>"2",
  130. "childs"=>array(),
  131. ),
  132. 30=>array(
  133. "cat_name"=>"Soki i napoje",
  134. "ip"=>"1.2.30.",
  135. "level"=>"2",
  136. "childs"=>array(),
  137. ),
  138. 28=> array(
  139. "cat_name"=>"Telewizory",
  140. "ip"=>"1.4.28.",
  141. "level"=>"2",
  142. "childs"=>array(),
  143. ),
  144. 16=>array(
  145. "cat_name"=>"Zmywarki",
  146. "ip"=>"1.3.16.",
  147. "level"=>"2",
  148. "childs"=>array(
  149. 0=>"31",
  150. ),
  151. ),
  152. 31=>array(
  153. "cat_name"=>"Do zabudowy",
  154. "ip"=>"1.3.16.31.",
  155. "level"=>"3",
  156. "childs"=>array(
  157. 0=>"32",
  158. 1=>"33",
  159. 2=>"34",
  160. ),
  161. ),
  162. 32=>array(
  163. "cat_name"=>"45 cm szerokie",
  164. "ip"=>"1.3.16.31.32.",
  165. "level"=>"4",
  166. "childs"=>array(),
  167. ),
  168. 33=>array(
  169. "cat_name"=>"60 cm szerokie",
  170. "ip"=>"1.3.16.31.33.",
  171. "level"=>"4",
  172. "childs"=>array(),
  173. ),
  174. 34=>array(
  175. "cat_name"=>"90 cm szerokie",
  176. "ip"=>"1.3.16.31.34.",
  177. "level"=>"4",
  178. "childs"=>array(),
  179. ),
  180. );
  181. return $cat_tree;
  182. }
  183.  
  184. function categories_tree($child){
  185. $tree = $this->all_cats;
  186. if (is_array($tree)){
  187. $output = '<ul>';
  188. foreach ($tree as $k =>$v){
  189. if($k == $child){
  190. if(!empty($v['childs'])){
  191. $output .='<li>' . $v['cat_name'];
  192. foreach($v['childs'] as $v){
  193. $output .= $this->categories_tree($v);
  194. }
  195. $output .= '</li>';
  196. } else{
  197. $output .='<li>' . $v['cat_name'] .'</li>';
  198. }
  199. }
  200. }
  201. $output .= '</ul>';
  202. }
  203. return $output;
  204. }
  205. }
  206.  
  207. $cats = new Categories();
  208. $tree = $cats->cat_tree();
  209. foreach($tree as $k => $v){
  210. if($v['level'] == 0){
  211. echo $cats->categories_tree($k);
  212. }
  213. }
nospor
Po pierwsze nie zadne childs a children... nie kalecz jezyka.

Po drugie to tu
foreach($tree as $k => $v){
if($v['level'] == 0){
echo $cats->categories_tree($k);
}
}

miales pobrac wpierw wszystkie id z level 0 a dopiero potem przekazac to do tablicy. Po chinsku zdaje sie nie pisze tongue.gif A teraz ty odpalasz funkcje dla kazdego ID z osobna. To samo zreszta robisz wewnatrz funkcji dla kazdego z dziecka :/ .

Po trzecie: wewnatrz funkcji iterujesz za kazdym razem po calym drzewie. Mowilem: masz iterowac po dzieciach a nie po calym drzewie.

Poprawny kod:
  1. class Categories {
  2.  
  3. function __construct() {
  4. $this->all_cats = $this->cat_tree();
  5. }
  6.  
  7. function cat_tree() {
  8. // w poniższej zmiennej $cat_tree będzie wynik z bazy danych
  9. return $cat_tree;
  10. }
  11.  
  12. function categories_tree($ids){
  13. $tree = $this->all_cats;
  14. if (is_array($tree)){
  15. $output = '<ul>';
  16. foreach ($ids as $id){
  17. $v = $tree[$id];
  18. if(!empty($v['childs'])){
  19. $output .='<li>' . $v['cat_name'];
  20. $output .= $this->categories_tree($v['childs']);
  21. $output .= '</li>';
  22. } else{
  23. $output .='<li>' . $v['cat_name'] .'</li>';
  24. }
  25. }
  26. $output .= '</ul>';
  27. }
  28. return $output;
  29. }
  30. }
  31.  
  32. $cats = new Categories();
  33. $tree = $cats->cat_tree();
  34. $level0 = array();
  35. foreach($tree as $k => $v){
  36. if($v['level'] == 0){
  37. $level0[] = $k;
  38. }
  39. }
  40. echo $cats->categories_tree($level0);
arturpiotrowski
Pięknie dziękuję za pomoc, faktycznie wygląda to logiczniej niż to co ja wyskrobałem, a mógłbym prosić jeszcze o podpowiedź jak nie wyświetlać elementu "Root" na tej liście? Ma on jako jedyny level = 0. Wystarczy tylko dać inny numer levela?
  1. foreach($tree as $k => $v){
  2. if($v['level'] == 1){ // za 1 podstawiamy numer levela od którego chcemy zacząć?
  3. $level0[] = $k;
  4. }

Jeszcze jedno a jakbym chciał coś wykluczyć z tego drzewa? Chodzi o wykluczenie kilku cat_id i ich dzieci. Ewentualnie pokazać tylko jedną kategorię (niekoniecznie z levela 1) i jej potomków. Jak mogę to zrobić?
nospor
ad1: tak
ad2: to daj if ktory sprawdza czy jest cos na liscie co chcesz wykluczyc czy nie i jak jest to nie jedz po tym
arturpiotrowski
Dzięki, pokombinuję, narazie zrobiłem tak i chyba nawet działa:
  1. ...
  2. foreach ($ids as $id){
  3. if(!in_array($id,$excluded)){
  4. $v = $tree[$id];
  5. if(!empty($v['childs'])){
  6. $output .='<li>' . $v['cat_name'];
  7. $output .= $this->categories_tree($v['childs'],$excluded);
  8. $output .= '</li>';
  9. } else{
  10. $output .='<li>' . $v['cat_name'] .'</li>';
  11. }
  12. }
  13. }
  14. ...

$excluded dałem jako parametr funkcji categories_tree()

Jeszcze tylko pomyślę jak zrobić breadcrumbs dla konkretnej kategorii i będę miał chyba komplet smile.gif

W tej chwili tworzy się całe drzewo z podkategoriami, a jak zrobić aby pokazać tylko kategorię i X głębokości podkategorii?
nospor
Cytat
W tej chwili tworzy się całe drzewo z podkategoriami, a jak zrobić aby pokazać tylko kategorię i X głębokości podkategorii?

No to zapytaniem pobieraj tylko te dane ktore cie interesuja
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.