Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Dynamiczna strona wyświetlanie błędów
Forum PHP.pl > Forum > PHP
ZuyPan
Witam.
Podczas tworzenia skryptu strony napotkałem problem. Cała strona ma działanie dynamiczne tj. linki w stylu bla.php?akcja=bla&akcja2=ble. Dajmy na to pojawia się problem przy wysyłaniu komentarza do newsa: ktoś nie wypełni pola nick i pola treść. W moim systemie zakładam, że wiadomość będzie wyświetlać się dynamicznie: jest jeden plik który po otrzymaniu wartości zmiennej $wiadomosc wyświetla ją jako jedyny tekst na świecie (wszystko inne znika, zaś wiadomość zostaje ładnie wycentrowana i wyświetlona). Niby proste ale pojawiają się problemy...
oto kilka plików dla przedstawienia problemu: index.php - odpowiedzialny za dynamiczne wyświetlanie strony:

  1.  
  2. <?php
  3.  
  4. if (!$_GET['akcja']){
  5. include ('news.php');
  6.  
  7. }elseif ($_GET['akcja'] == 'raporter'){
  8. echo $wiadomosc;
  9.  
  10. }elseif(!empty($_GET['akcja']) && $_GET['akcja'] != 'raporter'){
  11. $plik = $_GET['akcja'];
  12. if(is_file("$plik.php")){
  13. include "$plik.php";
  14. include ('includes/config.php');
  15. }else{
  16. $wiadomosc .= '<font color="red">Podana podstrona nie istnieje!</font><br>';
  17. }
  18. }
  19. ?>


plik news.php - wyświetlanie newsów i dodawanie komentarzy:

  1. <?php
  2. /*****************************************/
  3. /* PerfectMT2 */
  4. /* By: ZuyPan */
  5. /* www.perfectmt2.pl */
  6. /* */
  7. /*****************************************/
  8. $baza = 'perfectmt2';
  9. include ('includes/config.php');
  10. if (!$_GET['akcja2']){
  11.  
  12. $zapytanie = 'SELECT * FROM newsy';
  13. $query = mysql_query($zapytanie);
  14. if (mysql_num_rows($query) >= 1){
  15. while ($rekord = mysql_fetch_assoc($query)){
  16.  
  17. echo 'Tytuł:';
  18. echo $rekord['tytul'];
  19. echo '<br>';
  20. echo $rekord['tresc'];
  21. echo '<br>dodał: ';
  22. echo $rekord['autor'];
  23. echo '<br>';
  24.  
  25. echo "<a href='?akcja=news&akcja2=pokaz_komentarze&id=$rekord[id]'>Pokaż komentarze</a>";
  26. echo '<hr>';
  27. }
  28.  
  29. }else{
  30. $wiadomosc .= '<font color="red">Brak newsów do wyświetlenia.</font>';
  31. }
  32.  
  33. }elseif($_GET['akcja2'] == 'pokaz_komentarze'){
  34.  
  35. if ($_GET[id]){
  36. $id = $_GET['id'];
  37. $formularz = "<table border='0' width='400'>
  38. <form action='?akcja=news&akcja2=pokaz_komentarze&id=$_GET[id]' method='POST'>
  39. <tr><td>Nick: </td><td><input type='text' name='nick' size='26'></td></tr>
  40. <tr><td>Treść: </td><td> <textarea name='tresc' cols='25' rows='5'></textarea></td></tr>
  41. <tr><td><input type='submit' name='submit' value='Wyślij'></td><td><Input type='reset' name='reset' value='Wyczyść'></td></tr>
  42. </form></td></tr></table>
  43. ";
  44.  
  45. if (!$_POST['submit']){
  46. echo 'Komentarze innych użytkowników:<br><br>';
  47. $zapytanie = "SELECT * FROM komentarze_newsy WHERE id_newsa='$id'";
  48. $query = mysql_query($zapytanie);
  49. if (mysql_num_rows($query) >= 1){
  50. while ($rekord = mysql_fetch_assoc($query)){
  51. echo 'Autor: ';
  52. echo $rekord['autor'];
  53. echo '<br>';
  54. echo 'Treść: ';
  55. echo $rekord['tresc'];
  56. if ($_SESSION['ranga'] == 'admin'){
  57. echo "<a href='?akcja=news&akcja2=usun_komentarz&id=$rekord[id_komentarza]'>Usuń</a>";
  58. }
  59. echo '<hr>';
  60. }
  61.  
  62. }else{
  63. echo 'Brak komentarzy innych użytkowników! Bądź pierwszy i wyraź swoją opinię!';
  64. }
  65. echo '<br>Dodaj swój komentarz!<br>';
  66. echo $formularz;
  67.  
  68. }else{
  69. if ($_POST['nick']){
  70. $nick = zabezpiecz(0, $_POST['nick']);
  71. }else{ $wiadomsc .= '<font color="red">Proszę wpsiać nick!</font>'; }
  72.  
  73. if ($_POST['tresc']){
  74. $tresc = zabezpiecz(0, $_POST['tresc']);
  75. }else{ $wiadomosc .= '<font color="red">Proszę wpisać treść!</font>'; }
  76.  
  77. if ($nick && $tresc){
  78.  
  79. $zapytanie = "INSERT INTO komentarze_newsy (id_newsa, autor, tresc) VALUES ('$id', '$nick', '$tresc')";
  80. $query = mysql_query($zapytanie);
  81. if ($query){
  82. $wiadomosc .= '<font color="green">Pomyślnie dodano komentarz do newsa.<br> <a href="index.php">Wróć na stronę główną</a></font>';
  83. }else{
  84. $wiadomosc .= '<font color="red">Wystąpił błąd podczas dodawania komentarza. Spróbuj ponownie.<br> <a href="index.php?akcja=news">Wróć do wszystkich newsów</a></font>';
  85. }
  86.  
  87. }else{
  88. echo $formularz;
  89. }
  90.  
  91. }
  92.  
  93. }else{
  94. $wiadomosc .= '<font color="red">Błędne id newsa. Proszę spróbować ponownie.</font>';
  95. }
  96.  
  97. }elseif ($_GET['akcja2'] == 'usun_komentarz'){
  98. if ($_SESSION['ranga'] == 'admin'){
  99. if ($_GET['id']){
  100.  
  101. $zapytanie = "DELETE FROM komentarze_newsy WHERE id_komentarza='$_GET[id]'";
  102. $query = mysql_query($zapytanie);
  103. if ($query){
  104. $wiadomosc .= '<font color="green">Pomyślnie usunięto komentarz <a href="index.php">Wróć</a></font>';
  105. }else{
  106. $wiadomosc .= '<font color="red">Nie udało się usunąć komentarza <a href="?akcja=news">Wróć</a></font>';
  107. }
  108.  
  109. }else{
  110. $wiadomosc .= '<font color="red">Błędne id komentarza!</font>';
  111. }
  112.  
  113. }else{
  114. $wiadomosc .= '<font color="red">Nie masz odpowiednich uprawnień aby tu przebywać!</font>';
  115. }
  116.  
  117. }
  118.  
  119. if ($wiadomosc){
  120. echo '<META HTTP-EQUIV="Refresh" CONTENT="0"; URL=index.php?akcja=raporter">';
  121. }
  122.  
  123. ?>


kod troszkę przydługi ale uspokajam - nie chodzi o jego całość a raczej o logikę... Jak widać jeśli jest coś do wyświetlenia (jakiś komunikat) to przypisuje się go do zmiennej $wiadomosc. Pod koniec skryptu jeśli zmienna istnieje następuje przekierowanie do index.php?akcja=raporter (część raportująca komunikaty).
Niby wszystko działa, ale dzieje się dziwna rzecz - strona owszem zmienia się na index.php?akcja=raporter ale tylko na jedną sekundę i znów wraca do swojej postaci. Poza tym widoczne jest, że nie tylko treść wiadomości się wyświetla ale także formularz do wysyłania komentarzy. Sam się zastanawiam dlaczego tak się dzieje. Macie jakieś inne pomysły jak rozwiązać problem wyświetlania takich komunikatów? Jest to dość częsty skrypt spotykany na większości for (również na tym forum są tego typu komunikaty).
Liczę na odpowiedź, pozdrawiam
Fifi209
Przekieruj za pomocą nagłówków header

np. :
  1.  
  2. header('Location: index.php?page=error');
  3.  
ZuyPan
Wszystko działa oprócz wyświetlania błędu. Podczas działania news.php pojawił się błąd ponieważ nie wpisałem treści - $wiadomosc już istnieje. Przekierowanie owszem działa natomiast nie wyświetla się treść wiadomości. Oto rozwiązanie jakie zastosowałem:

  1.  
  2. }elseif($_GET['akcja'] == 'raporter'){
  3. echo $wiadomosc;
  4. }
  5.  
Pilsener
Cytat
nie chodzi o jego całość a raczej o logikę
- otóż to, Twoje problemy wynikają z tego, że masz złą logiczną konstrukcję kodu. Powinieneś podzielić to tak:
1. Odbieranie i walidacja zmiennych GET i POST
2. Tworzenie strony
3. Wysłanie strony do przeglądarki

Jak się "echuje" stronę po kawałku to stwarza się sobie problemy, bo trzeba masy ifów, trzeba dbać o kolejność i nie można "zawrócić" tego co się już "wyechowało" i ratuje się człowiek przekierowaniem...

Zrób sobie tablicę błędów i wszystkie błędy do niej dopisuj, a przed każdym etapem sprawdzaj, czy tablica błędów jest pusta:
  1. if(empty($errors)){ //next step
  2.  
  3.  
  4. }
- wtedy masz czytelne bloki kodu podzielone wg funkcji

I zamiast echować pracuj na zmiennych, wtedy w każdej chwili możesz usunąć lub nadpisać treść strony zastępując ją komunikatem błędu lub zmodyfikować w inny sposób. Tak jest chyba wygodniej?
ZuyPan
No cóż... Przyznam szczerze, że nie do końca zrozumiałem wstydnis.gif Od początku
Cytat
1. Odbieranie i walidacja zmiennych GET i POST
2. Tworzenie strony
3. Wysłanie strony do przeglądarki

Jeśli mógłbyś jakiś najbanalniejszy przykład. Wiem to dziwne, ale jakoś nie umiem połapać się w tym wszystkich jeśli ktoś mi po prostu napiszę. Ja muszę mieć to na przykładzie.

W każdym razie ja to tak zrozumiałem:
etap 1 - odbieranie:

  1. if ($_POST['costam']){
  2. rob_cos_tam();
  3. }else{
  4. echo $formularz;
  5. }
  6.  
  7. etap 2: tworzenie strony
  8. no tego to już raczej nie zrozumiałem ;P
  9.  
  10. etap 3: czy to się czasem nie dzieje na bieżąco ? oO
  11.  
  12. <!--quoteo--><div class='quotetop'>Cytat</div><div class='quotemain'><!--quotec-->Zrób sobie tablicę błędów i wszystkie błędy do niej dopisuj, a przed każdym etapem sprawdzaj, czy tablica błędów jest pusta:
  13. [php]
  14. if(empty($errors)){ //next step
  15.  
  16.  
  17. }


I jeszcze to. Wiem, że tu pewnie nie ma co tłumaczyć, ale ja naprawdę mam ogromne trudności z przyswajaniem teorii, lepiej wchodzi mi to w praktyce.
Przepraszam za kłopot, mam nadzieję, że rozumiesz winksmiley.jpg
Riggs
Możesz przekazać wiadomość z błędem przez sesję. Całkiem fajne rozwiązanie i niezbyt skomplikowane.
thek
A co tu trudnego w tym co napisał Pilsener?
1. Walidacja i obróbka POST, GET na starcie + zapisywanie efektów walidacji do zmiennych
2. Tworzenie strony - albo tutaj piszesz treść, albo wrzucasz ją do zmiennej.
3. Wysyłanie, tylko gdy wrzucałeś stronę do zmiennej to tu ją wyechowujesz. Przykład? Dam banalny form z 2 zmiennymi do obróbki:
  1. <?php
  2. require 'connection.php';
  3. connect(); //nie wnikam jak się łączysz, przyjmuję, że na samym początku includujesz połączenie z jakiegoś pliku lub funkcję wywołujesz od tego
  4. $fields = array( //ta struktura zapamiętuje nam formularz usera i ustawia wartości domyślne
  5. 'email' => '',
  6. 'id' => 0
  7. );
  8. $errors = array();
  9. if( !empty( $_GET ) ) {
  10. if( array_key_exists( 'id', $_GET ) && ctype_digit( $_GET['id'] ) && $_GET['id'] > 0 ) {
  11. $email_sql = 'SELECT id, email FROM email_database WHERE id = '.$_GET['id'].' LIMIT 1';
  12. $email_res = mysql_query( $email_sql );
  13. if( $email_res && mysql_num_rows( $email_res ) ) {
  14. $email_row = mysql_fetch_assoc( $email_res ); //wpisanie do forma pól z bazy do edycji
  15. $fields['id'] = $email_row['id'];
  16. $fields['email'] = $email_row['email'];
  17. } else {
  18. $errors[] = 'Nie można było uzyskać rekordu z bazy lub takiego nie ma w niej.';
  19. $fields['id'] = 0; //pewności nigdy za wiele, choć domyślne ustawienie nam już to robi i teoretycznie jest to zbędne
  20. }
  21. } else {
  22. $errors[] = 'Nieprawidłowe id';
  23. }
  24. }
  25. if( array_key_exists( 'change', $_POST) ) {
  26. $fields['email'] = filter_var( $_POST['email'], FILTER_SANITIZE_EMAIL ); //można przypisanie robić w różnych momentach, choćby po stripowaniu czy operacjach mających modyfikować dane POST
  27. //w poniższym IF użyłem !empty i filter_var dla $fields['email'] bo działałem na stripowanej wartości. Gdybym użył $_POST['email'] mógłby do sprawdzenia pójść <a href="coś">coś</a>
  28. //a to nie przeszło by funkcji sprawdzenia czy email jest prawidłowy ;) Najlepiej byłoby oczywiście wepchnąć czyszczenie pomiędzy array_key_exists a !empty rozbijając ten potrójny IF
  29. //na dwa zagnieżdżone
  30. if( array_key_exists('email', $_POST) && !empty( $fields['email'] ) && filter_var( $fields['email'], FILTER_VALIDATE_EMAIL ) ) {
  31. $_POST['email'] = mysql_real_escape_string( $_POST['email'] );
  32. } else {
  33. $errors['email'] = 'Nie podano emaila lub jest on nieprawidłowy!'; //ważne! podajmy jako klucz nazwę pola, przyda się to później ;)
  34. }
  35. $fields['id'] = $_POST['id'];
  36. if( array_key_exists('id', $_POST) && ctype_digit( $_POST['id'] ) && $_POST['id'] >= 0 ) {
  37. //tutaj można sobie operować, zrobić coś. Ja akurat nie muszę więc zostawiam puste, choć powinienem sprawdzić, czy taki istnieje w bazie i czy user ma do niego uprawnienia!
  38. //jeśli nie istnieje to ktoś modyfikował zmienne i powinienem zabezpieczyć tu edycję oraz najlepiej errora dać.
  39. } else {
  40. $errors['id'] = 'Nie podano id lub jest on nieprawidłowy!'; //to zabezpieczenie gdy ktoś zmodyfikuje nam id waląc tekst, ujemna liczbę lub usunie id z $_POST
  41. $fields['id'] = 0;
  42. }
  43. //koniec walidacji POST i możemy zająć się operacjami zapisu do bazy
  44. if( count( $errors ) == 0 ) {
  45. if( $fields['id'] > 0 )
  46. //update do bazy
  47. else
  48. //insert do bazy
  49. }
  50. }
  51. //A dopiero tutaj tworzenie strony!
  52. ?>
  53. <html>
  54. <head>
  55. //jakieś nagłówki jakie chcesz
  56. </head>
  57. <body>
  58. <?php
  59. if( count($errors) > 0 ) {
  60. ?>
  61. <p>W formularzu wykryto błędy. Popraw je.</p>
  62. <?php
  63. }
  64. ?>
  65. <form name="formularz" method="post" action="">
  66. <label for="email">Email:</label>
  67. <input type="text" name="email" value="<?php echo $fields['email'] ?>" />
  68. <?php
  69. if( array_key_exists( 'email', $_POST ) ) {
  70. ?>
  71. <p><?php echo $errors['email'] ?></p>
  72. <?php
  73. }
  74. ?>
  75. <input type="hidden" name="id" value="<?php echo $fields['id'] ?>" />
  76. <?php
  77. if( array_key_exists( 'id', $_POST ) ) {
  78. ?>
  79. <p><?php echo $errors['id'] ?></p>
  80. <?php
  81. }
  82. ?>
  83. <input type="submit" name="change" value="Ustaw" />
  84. </form>
  85. </body>
  86. </html>
Tak wygląda startowo formularz. Zauważ, że wiele zostawiłem do dowolnej interpretacji, zależnie od zawartości. Nie chciałem też Ci całego rozpisywania dodawania do bazy pisać.

P.S.: Nie dodałem oczywiście nic ze swojej strony o komunikatach dla usera, że Wpis dodano czy są inne błędy niż błędy pól. Je dodajesz oczywiście do $errors, ale już bez nazewnictwa pól i możesz wyświetlić je tam gdzie sprawdzasz czy count($errors) > 0 , tylko minimalnie warunek modyfikujesz. Jeśli są w $errors wpisy, których kluczem jest nazwa pola to wyświetlasz je pod polem odpowiednim. Jeśli sa w $errors klucze, które nie są nazwami pól - wyświetlasz je gdzieś na górze dokumentu. Najprościej kombinować z czymś w stylu
array_diff_key( $errors, array('id' => '', 'email' => '') ), czyli pominięciem z tablicy $errors ewentualnych kluczy tyczących pól.
ZuyPan
Uch -.- Po prawie 3 latach programowania w php gdzie wydawało mi się, że coś umiem okazało się, że jedno wielkie gówno potrafię -.- Może dlatego, że moje zabawy ograniczały się do wpisywania danych do mysql, robienia systemów newsów, logowania. To co napisałeś (choć to pewnie dziwne) jest dla mnie skomplikowane... (oczywiście nie wszystko, ale mam problem ze zrozumieniem tego kodu)
Boże jakie to irytujące
thek
No to strzelę wyjaśnienia poszczególnych linii:
2-3: połączenie z bazą
4-7: struktura z polami formularza i nadaniem im wartości domyślnych jako tablica
8: tablica błędów
9-24: obsługa zmiennej $_GET
10-16: sprawdzenie czy jest zmienna $_GET['id'], czy jest liczbą i jest większa od 0, a jeśli tak to pobranie rekordu z bazy i wrzucenie go do struktury $fields, co zmieni wartości domyślne na właściwe, pobrane z bazy
25-50: obsługa zmiennej $_POST
26-42: walidacja pól i przypisywanie zmiennych z $_POST do $fields, by formularz "pamiętał" co było wpisane. Ewentualne wpisywanie do $errors['nazwa_pola'] odpowiedniego komunikatu błędu
44: sprawdzenie czy udało nam się wszystko zwalidować bezbłędnie. Od tego zależy czy wyświetlimy formularz z komunikatami błędów, czy zrobimy operacje w bazie danych. Tutaj najważniejsze są błędy pól. Tylko je najlepiej tutaj liczyć, bo tylko one są istotne dla procesu operacji w bazie danych. Tak więc albo liczysz ile jest wpisów w $errors, które mają nazwę pola jako klucz, albo dla dodatkowych błędów zakładasz osobną zmienna i zamiast wywołania $errors[] we wcześniejszym kodzie robisz przykładowo $inne_bledy_niz_pol[]
45: od id zależy czy będzie robiony INSERT do bazy, czy UPDATE
53-88: wyświetlenie strony. To jest to o czym pisano jako oddzielenie logiki od prezentacji. Zauważ, że do tej pory nic nie echowałem. Wszystko szło do zmiennych, więc mogłem się śmiać z "headers already sent", bo u mnie nie miał prawa wystąpić. Nigdzie bowiem nic nie wysyłałem. Ten błąd nie ma prawa w moim przykładzie wystąpić.
59: dopiero tutaj wyświetlam ewentualnie napotkane błędy. Uzależniam ich wyświetlanie od struktury tablicy błędów. Można to zrobić na wiele sposobów.
67 i 75: do value pola wpisuję to co zawiera $fields. Trzeba uważać na podwójne apostrofy. Dla pewności najlepiej to co dostajemy z $fields potraktować, albo tutaj, albo już podczas przypisywania wartości do tego pola funkcją htmlspecialchars
69 i 77: sprawdzamy, czy tablica $errors zawiera klucze tyczące tych pól. Jeśli tak, to znaczy, że były jakieś byki podczas walidacji. To sprawdzenie może być walnięte gdzie chcesz. Ja dla wygody usera ustawiam je bezpośrednio pod polem jakiego tyczy. Dzięki temu user zerknie i wie że pole powyżej ma byka, a nie widzi komunikat na górze i szuka potem w formie które to winksmiley.jpg
71 i 79: tu są wyświetlane komunikaty błędów jakie wpisałeś.

Popatrz, przemyśl i wiedz, że to jest tylko wstęp do znacznie bardziej rozbudowanych, który ładnie da się zapisać w formie obiektowej, gdzie utworzysz klasę formularza, klasę walidacji i ładnie będziesz na metodach działał. Mając taką jedną, zrobienie formularza z regułkami walidacji, komunikatami błędów itp to później bajka smile.gif Ograniczy się bowiem do paru wpisów, które cały formularz Ci same wygenerują smile.gif
ZuyPan
Nie rozumiem całej tej zabawy z tablicami a zwłaszcza tej od linijki 9 do 24
dalej:
  1. $fields['email'] = filter_var( $_POST['email'], FILTER_SANITIZE_EMAIL );


  1. if( array_key_exists('email', $_POST) && !empty( $fields['email'] ) && filter_var( $fields['email'], FILTER_VALIDATE_EMAIL ) ) {


Ogólnie - cała ta zabawa z tablicami jest dla mnie hmmm... Zbyt skomplikowana (?). Tego właśnie chyba najbardziej nie lubię...

Co do obiektówki, to próbowałem się nauczyć i w życiu nie zacznę tego używać. Głupie jak lewy but (takie moje osobiste zdanie smile.gif )

Dobra udało mi się to zrobić jako tako sposobem Riggs ale pojawił się problemik tongue.gif

  1. cho '<table border="0"><tr><td><fieldset>';
  2. echo $_SESSION['wiadomosc'];
  3. echo '</fieldset></tr></td></table>';

jak zniszczyć tylko sesję "wiadomosc"? session_destroy(); niszczy wszystkie a ja chcę tą konkretną.
muk4
Cytat(ZuyPan @ 5.07.2010, 18:53:14 ) *
jak zniszczyć tylko sesję "wiadomosc"? session_destroy(); niszczy wszystkie a ja chcę tą konkretną.

unset()
thek
  1. if( !empty( $_GET ) ) {//sprawdzam czy COKOLWIEK w $_GET jest
  2. if( array_key_exists( 'id', $_GET ) && ctype_digit( $_GET['id'] ) && $_GET['id'] > 0 ) { //sprawdzam czy jest tam id, czy jest liczbą i czy większe od 0
  3. $email_sql = 'SELECT id, email FROM email_database WHERE id = '.$_GET['id'].' LIMIT 1'; //zapytanie do bazy mające pobrać dane
  4. $email_res = mysql_query( $email_sql ); //wykonanie tego zapytania
  5. if( $email_res && mysql_num_rows( $email_res ) ) { //sprawdzam czy nie wywaliło mi błędu w bazie i czy jest choć jeden rekord w wyniku
  6. $email_row = mysql_fetch_assoc( $email_res ); //pobranie rekordu wyniku
  7. $fields['id'] = $email_row['id']; //przypisanie do do pola id jego faktycznego id z bazy... mogłem też użyć $_GET['id'], ten sam efekt :)
  8. $fields['email'] = $email_row['email']; //przypisanie do pola email jego wartości z bazy
  9. } else {
  10. $errors[] = 'Nie można było uzyskać rekordu z bazy lub takiego nie ma w niej.'; //komunikat błędu w razie problemów z pobraniem z bazy
  11. $fields['id'] = 0; //pewności nigdy za wiele, choć domyślne ustawienie nam już to robi i teoretycznie jest to zbędne
  12. }
  13. } else {
  14. $errors[] = 'Nieprawidłowe id'; //komunikat błedu gdy problem jest z wartością $_GET['id']
  15. }
  16. }
Teraz chyba maksymalnie wyjaśnione smile.gif Popatrz kiedy jaki if-else i sam załapiesz czemu tak a nie inaczej. Dla POST jest podobnie ale stosuje czasem wbudowane funkcje PHP by sobie ułatwić życie ( empty, filter_var ).
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.