Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: user class + dziedziczenie
Forum PHP.pl > Forum > PHP > Object-oriented programming
PawelC
Hej piszę sobie klasę users, która jest odpowiedzialna za logowanie i dodanie użytkownika, później dojdzie kasowanie i edycja konta. Moje pytanie brzmi czy sposób w który piszę jest dobry:
  1. <?
  2. class user extends sqli
  3.  {
  4.  
  5.    public function userLogin()
  6.      {    
  7.  
  8.       $this->log=trim($_POST['log']);
  9.       $this->pass=$pass=trim($_POST['pass']);
  10.       $result=$this->mysqli->query("select log,pass from users where log='$this->log' and pass='$this->pass'");
  11.        if(mysqli_num_rows($result)==0)
  12.            {
  13.                echo "brak takiego usera";
  14.             }
  15.             else
  16.             {
  17.                $_SESSION['zalogowany']="$this->log";
  18.                header("Location: test.php");
  19.              }
  20.  
  21.  
  22.            }
  23.            
  24.            
  25.   public function addUser()
  26.            {
  27.  
  28.             $this->log=trim($_POST['log']);
  29.             $this->pass=$pass=trim($_POST['pass']);
  30.             $result=$this->mysqli->query("insert into users values('$this->log','$this->pass')");
  31.             if($result===true)
  32.              {
  33.                  echo "Użytkownik został dodany poprawnie.";
  34.              }
  35.               else
  36.               {
  37.                  echo "Wystąpił błąd podczas dodawania nowego użytkownika!";
  38.              }
  39.  
  40.            }
  41.  
  42.  
  43.  
  44.        }
  45. $user=new user('localhost','root','','katalog');
  46. ?>

I dodawanie użytkownika i samo logowanie działa poprawnie, a mi chodzi o Waszą ocenę czy to jest dobrze napisane. Oczywiście zdaję sobie sprawę, że można to napisać zawsze lepiej.
ayeo
Witam!

Nie jest różowo smile.gif Na początek taki detal, nazwy klas dobrze zaczynać wielką literą. Twoja klasa dziedziczy po sqli (?). Podejrzewam, że to coś co odpowiada za połączenie z bazą itd. Czyli każda instancja tej klasy tworzy nowe połączenie? Klasę do obsługi bazy danych zrób sobie jako Singleton (najprościej). Nie dziedzicz po niej. Metoda loginUser() powinna przyjmować parametry, a nie czytać z posta. Może od początku. Obiekt user reprezentuje użytkownika, mianowicie jego id, imię, nazwisko, login, email i hasło (dla przykładu). Fajnie zrobić statyczną metodę login( $login, $password ), która po prostu zwróci obiekt User wypełniny kompletem danych z bazy lub false w przypadku błędnych danych logowania.

Dodawanie Usera... Moim zdaniem (podkreślam, że to moje zdanie) powinno to wyglądać tak:
  1. <?php
  2. $user = new User;
  3. $user->login= "adam";
  4. $user->password = "dupa8";
  5. $user->save();
  6. ?>


Oczywiście można dorobić jakiś obiekt bazowy, który ma metody typu setData( $post ) - czyli ustawia właściwości obiektu na podstawie danych z tablicy $_POST itd. Jednak nie o to chodzi. Obiekt to nie pojemnik na funkcje. Niech faktycznie będzie to obiekt User.

Statyczna metoda login(); powinna ustawiac też flagę w obiekcie czy dane są z bazy czy jest to nowy obiekt User. Wtedy metoda save() wie czy robić insert czy update. Przdałyby się jakieś walidatory jako prywatne metody (w uproszczeniu). Przykład: tworzę nowego Usera, podaję login (ale nie podaję hasła). Robię $user->save(); metoda powinna wyrzucić stosowny wyjątek.

Tak bym to widział.

Pozdrawiam!
PawelC
Dodałem wzorzec projektowy singleton i coś mi nie działa, mama taki kod:
  1. <?
  2.  
  3.  
  4.        class Sqli
  5.            {
  6.                
  7.                private static $instance = false;
  8.                
  9.                //Konstruktor
  10.            public function __construct()
  11.            {
  12.                self::$instance=new mysqli('localhost','root','','katalog');
  13.            }
  14.            
  15.            
  16.            static function instance()
  17.            {
  18.            if( !self::$instance )
  19.            {
  20.            self::$instance = new self;
  21.            }                              
  22.        
  23.            return self::$instance;
  24.            }
  25.            
  26.            
  27.            public function getRow($query)
  28.            {
  29.                return Sqli::instance()->query($query)->fetch_object();
  30.                
  31.            }
  32.                    
  33.            
  34.            
  35.            
  36.            // Pobranie danych z bazy
  37.            public function getRows($query)
  38.            {
  39.                $dane=array();
  40.                $result=Sqli::instance()->query($this->query=$query);
  41.                while($wynik=$result->fetch_object()){
  42.                    $data[]=$wynik;
  43.                    
  44.                }
  45.                return $data;
  46.                
  47.                /* $rows=$sqli->getRows("select * from users");
  48.                 foreach($rows as $row)
  49.                 {
  50.                 echo $row->log.' | '.$row->pass;
  51.                 }
  52.                 */
  53.            }
  54.            
  55.            
  56.            
  57.            //Dodawania wartości do bazy danych
  58.            public function insert($query)
  59.            {
  60.                $result=Sqli::instance()->query($query);
  61.                if($result===true)
  62.                {
  63.                    echo "Dane zostały dodane do tabeli!";
  64.                }
  65.                else {
  66.                    echo "Wystąpił błąd podczas dodawania danych do tabeli!";
  67.                }
  68.            }
  69.            
  70.            
  71.            
  72.            // Aktualizacja danych w bazie
  73.            public function update($query)
  74.            {
  75.                $result=Sqli::instance()->query($query);
  76.                if($result===true)
  77.                {
  78.                    echo "Dane zostały zaaktualizowane!";
  79.                }
  80.                else {
  81.                    echo "Wystąpił błąd podczas aktualizowania danych!";
  82.                }
  83.            }
  84.            
  85.            
  86.            
  87.            
  88.            // Kasowania z bazy danych
  89.            public function delete($query)
  90.            {
  91.                $result=Sqli::instance()->query($query);
  92.                if($result===true)
  93.                {
  94.                    echo "Dane zostały usunięte!";
  95.                }
  96.                else {
  97.                    echo "Wystąpił błąd podczas usuwania danych!";
  98.                }
  99.            }
  100.            
  101.            
  102.            // Koniec klasy
  103.        }
  104.        
  105.  
  106. $sqli = Sqli::instance();
  107.  
  108.  
  109.  
  110. ?>

Robię np:
  1. <?php
  2. require 'mysqli.class.php';
  3. $sqli->delete("delete from users where log='admin'");
  4. ?>

I dostaje błąd:
  1. <?php
  2. [b]Fatal error[/b]:  Call to undefined method Sqli::query() in [b]C:wampwwwmysqlimysqli.class.php[/b] on line [b]91[/b]
  3. ?>

Co najdziwniejsze dla mnie w klasie user, działa wszystko bez problemu jakiegokolwiek, a w tej klasie do obsługi bazy danych nie działa sad.gif
Crozin
Ale dlaczego
  1. <?php
  2. $result=Sqli::instance()->query($query);
  3. ?>
Przecież wewnątrz metody masz już obiekt, więc $this.

Poza tym nie korzystaj z (anty)wzorca Singleton tutaj - istnieje prawdopodobieństwo, że możesz w przyszłości pokusić się o to by skrypt działał na dwóch bazach danych - co wtedy?

Pozatym:
1) Klasa użytkownik jest rozszerzeniem klasy sqli - widzisz logikę w tym? Ja nie. Do klasy User powinienenś w jakiś sposób przekazać już istniejący obiekt klasy Sqli (swoją drogą skąd taka nazwa?)
2) Klasa User jak sama nazwa mówi powinna w pierwszej kolejności reprezentować użytkownika - tutaj internaute. I bez znaczenia jest to czy jest on zalogowany czy nie.
3) Pozatym jak już ayeo wskazał: dane powinny być przekazywane w parametrach funkcji, a nie odczytywane z globalnych danych w jej wnętrzu
PawelC
Cytat
Poza tym nie korzystaj z (anty)wzorca Singleton[...]

Taka była rada ayeo, żeby z niego korzystać.
Cytat
3) Pozatym jak już ayeo wskazał: dane powinny być przekazywane w parametrach funkcji, a nie odczytywane z globalnych danych w jej wnętrzu

To już zmieniłem.
Cytat
(swoją drogą skąd taka nazwa?)

Tak jakoś, to tylko w celach treningowych.
Cytat
1) Klasa użytkownik jest rozszerzeniem klasy sqli - widzisz logikę w tym? Ja nie. Do klasy User powinienenś w jakiś sposób przekazać już istniejący obiekt klasy Sqli

W jaki sposób? Gdzieś czytałem coś o parent::

Klasa user ma być odpowiedzialna, za logowanie, dodanie, edytowanie i usunięcie użytkownika. Czyli rozumiem że nie mam korzystać z singletonu w tym wypadku.
Crozin
Cytat
Taka była rada ayeo, żeby z niego korzystać.
IMO była ona tutaj błędna.
Cytat
W jaki sposób? Gdzieś czytałem coś o parent::

Klasa user ma być odpowiedzialna, za logowanie, dodanie, edytowanie i usunięcie użytkownika. Czyli rozumiem że nie mam korzystać z singletonu w tym wypadku.
parent:: oznacza odwołanie się do rodzica, ale jak już napisałem klasa User nie powinna dziedziczyć po sqli bo ona nie jest rozwinięciem sqli, ona tylko obiektu takiej klasy używa.
PawelC
Ok dzięki za rady, coś wykombinuje, bo bez wzorca projektowego singleton wszystko ładnie pięknie mi działa.
To powiedz mi jeszcze jak wykorzystać klasę Sqli, w klasie Users nie dziedzicząc jej.
Wiem, że zadaje głupie pytania ale dopiero się uczę OOP.
Crozin
Na przykład:
  1. <?php
  2.  
  3. class sqli{
  4.  //....
  5. }
  6.  
  7. class User{
  8.   private $db;
  9.  
  10.   public function __construct(sqli $db){
  11.      $this->db = $db;
  12.   }
  13.  
  14.   //...
  15.  
  16.   public function someFunction(){
  17.      $this->db->update('...');
  18.   }
  19. }
  20.  
  21. $db = new sqli(...);
  22. $user = new User($db);
  23. ?>
PawelC
Sorki że wracam do tego tematu, ale wyczarowałem pewny kod, a dokładnie wykorzystanie klasy sqli w klasie user i chciałem się dowiedzieć czy dobrze to zrobiłem. Oto kod:
  1. <?php
  2.  
  3.  
  4.        class sqli
  5.            {
  6.                
  7.                
  8.                
  9.                //Konstruktor
  10.            public function __construct($host,$login,$haslo,$baza)
  11.            {
  12.                $this->mysqli=new mysqli($host,$login,$haslo,$baza);
  13.            }
  14.            
  15.            
  16.            
  17.            
  18.            
  19.            public function getRow($query)
  20.            {
  21.                return $this->mysqli->query($this->query=$query)->fetch_object();
  22.                
  23.            }
  24.                    
  25.            
  26.            
  27.            
  28.            // Pobranie danych z bazy
  29.            public function getRows($query)
  30.            {
  31.                $dane=array();
  32.                $result=$this->mysqli->query($this->query=$query);
  33.                while($wynik=$result->fetch_object()){
  34.                    $data[]=$wynik;
  35.                    
  36.                }
  37.                return $data;
  38.                
  39.                /* $rows=$sqli->getRows("select * from users");
  40.                 foreach($rows as $row)
  41.                 {
  42.                 echo $row->log.' | '.$row->pass;
  43.                 }
  44.                 */
  45.            }
  46.            
  47.            
  48.            
  49.            //Dodawania wartości do bazy danych
  50.            public function insert($query)
  51.            {
  52.                $result=$this->mysqli->query($this->query=$query);
  53.                if($result===true)
  54.                {
  55.                    echo "Dane zostały dodane do tabeli!";
  56.                }
  57.                else {
  58.                    echo "Wystąpił błąd podczas dodawania danych do tabeli!";
  59.                }
  60.            }
  61.            
  62.            
  63.            
  64.            // Aktualizacja danych w bazie
  65.            public function update($query)
  66.            {
  67.                $result=$this->mysqli->query($this->query=$query);
  68.                if($result===true)
  69.                {
  70.                    echo "Dane zostały zaaktualizowane!";
  71.                }
  72.                else {
  73.                    echo "Wystąpił błąd podczas aktualizowania danych!";
  74.                }
  75.            }
  76.            
  77.            
  78.            
  79.            
  80.            // Kasowania z bazy danych
  81.            public function delete($query)
  82.            {
  83.                $result=$this->mysqli->query($this->query=$query);
  84.                if($result===true)
  85.                {
  86.                    echo "Dane zostały usunięte!";
  87.                }
  88.                else {
  89.                    echo "Wystąpił błąd podczas usuwania danych!";
  90.                }
  91.            }
  92.            
  93.            
  94.            // Koniec klasy
  95.        }
  96.        
  97.        
  98.        class User{
  99.              private $db;
  100.  
  101.              public function __construct(sqli $db){
  102.             $this->db = $db;
  103.              }
  104.  
  105.  
  106.              public function addUser($login,$haslo){
  107.             $this->db->insert("insert into user values('$login','$haslo')");
  108.              }
  109.        }
  110. ?>

A tak go używam:
  1. <?php
  2. $db = new sqli('localhost','root','','spam');
  3. $user = new User($db);
  4. $user->addUser('adminek','adminek2');
  5. ?>

Oczywiście kod działa jak należy, tylko chodzi mi o to czy jest to poprawnie napisane. Krótko mówiąc rozumuję iż, w taki sposób jak zrobiłem powyżej, uzyskuje dostęp do klasy sqli oraz jej metod, dobrze myślę czy może się mylę? Wnioskuje to po tym że uzyskałem dostęp do metody update, która jest w klasie sqli.
Crozin
A klasa User ma reprezentować jakiegoś konkretnego użytkownika z bazy danych, czy ma robić za swego rodzaju Managera pozwalającego dodawać, pobierać użytkowników?
PawelC
Ma robić za managera, czyli dodawać usera, kasować, pobierać użytkowników, logować itp
marcio
  1. <?php
  2. public function __construct($host,$login,$haslo,$baza) {
  3.  
  4.      $this->mysqli=new mysqli($host,$login,$haslo,$baza);
  5.            
  6.   }
  7. ?>

To nie jest najlepsze rozwiazanie a czym nie jest tez bledne lepiej przekazuj obiekt do construct'a jak to robisz w klase User

I do tego dla klasy sqli ja bym zrobil wspolne APi(mowa o interfejsach) zebys potem mogl latwo rozszerzac twoja klase user o nowe database'y nie zmieniajac starego kodu tylko tworzysz nowy sterownik ze takimi samymi nazwami funkcji ktore analogicznie beda mialy robic to co robia tez z innej klasy i wtedy tylko przekazujesz odpowiedni obiekt bazy ktorej chcesz uzywac do klasy User.

P.S ewentualnie mozesz uzyc inne nazwe funckji jesli ma to byc np baze dla plikow *.txt robiac adapter na stare APi i bedzie good to tylko takie moje zdanie.
Crozin
Co do bazy danych... chyba lepiej będzie skorzystać z PDO. A obiekt ów klasy, przekazać, a nie tworzyć we wnętrzu.
marcio
Cytat(Crozin @ 6.06.2009, 16:39:52 ) *
Co do bazy danych... chyba lepiej będzie skorzystać z PDO. A obiekt ów klasy, przekazać, a nie tworzyć we wnętrzu.

O tym samym mowie jednak z tym PDo to nie tak do konca na poczatek sam niech sie pobawi w pisanie sterownikow przynajmniej czlowiek sie czegos nauczy.
Crozin
Niech użyje PDO... nauczy się korzystać z całkiem dobrych, gotowych narzędzi. smile.gif

Ćwiczyć może przecież robiąc to co teraz robi.
erix
Cytat
Niech użyje PDO... nauczy się korzystać z całkiem dobrych, gotowych narzędzi.

Ta, i nieraz wkurzających (tzn. jak się nie uważa ze składnią i ciężej błędy wyłapać). tongue.gif Ale to swoją drogą. Mi w PDO brakuje czegoś w rodzaju seek po wynikach...
PawelC
Czyli krótko mówiąc podążam w dobrym kierunku, z tym że mam zamienić MySQLI na PDO
marcio
Cytat
z tym że mam zamienić MySQLI na PDO

To juz zalezy od ciebie ja bym nie zmienial tongue.gif

Ogolnie nie jest zle ale przy tak malych kodach to jest dosyc latwo napisz system news'ow z obsluga xml/rss/html i wspomagajacy bazy mysql,pliki i np oracle oczywiscie zaimplementuj co chcesz nie musisz wszystkiego ale daj taka mozliwosc bez ingerencji w kod ze strony user'a zmieniajac tylko 1-2 linijki tongue.gif to juz bedzie cos sam pisalem takie cos po wczesniejszym napisaniu klasu do autoryzacji i powiem latwo nie bylo tongue.gif ale duzo sie nauczylem biggrin.gif
PawelC
Cytat(marcio)
To juz zalezy od ciebie ja bym nie zmienial tongue.gif

Na wielu forach, doradzają mi abym korzystał z PDO, zamiast MySQLI
Cytat(marcio)
Ogolnie nie jest zle ale przy tak malych kodach to jest dosyc latwo

Zgadza się, gorzej jak się kod bardziej rozbuduje.

A właśnie co do obsługi użytkowników, to robić osobne klasy na dodawanie usera, kasowanie, pobieranie, logowanie, rejestracja etc... i na zarządzanie profilem, czyli aktualizacja profilu itp
Czy lepiej zrobić jedną klasę, takiego managera który będzie robił wszystko z użytkownikiem np dodawane, aktualizacja profilu itp

Mi się wydaje, że lepszym rozwiązaniem będzie stworzenie jednej klasy do obsługi użytkowników, a w niej wszystko co z użytkownikami związane, ale chciałbym dowiedzieć się, jakie jest wasze zdanie na ten temat.
marcio
Cytat
Na wielu forach, doradzają mi abym korzystał z PDO, zamiast MySQLI

Ja nie powiedzialem ze masz zmienic na rzecz mysqli jednak albo uzywasz FW i ich gotowe sterowniki dla baz albo korzystasz z wlasnych nie warto mieszac wedlug mnie.

Ogolnie Rejestracja to calkiem inna klasa ewentualnie do rejestracji/logowania mozesz dodac edycje/usuwanie konta etc... jednak lepiej stwotrzyc 3 klasy gdzie kazda ma swoje zadanie czyli:
-Register
-Auth
-User_manager

I to wsio

Pozdro tongue.gif
PawelC
Krótko mówiąc miałbym 3 klasy w jednym pliku, ponieważ musiałaby być klasa do:
- obsługi bazy danych która jest wykorzystywana do rejestracji itp
- obsługi rejestracji/logowania
- obsługi użytkownika

Bo jak inaczej, można wykorzystać klasę do obsługi bazy danych jak nie w taki sposób, w jaki zrobiłem to parę postów wyżej.
Cytat(marcio)
jednak albo uzywasz FW i ich gotowe sterowniki dla baz albo korzystasz z wlasnych nie warto mieszac wedlug mnie.

Masz rację, tylko nie do wszystkich projektów potrzeba FW, dlatego dobrze jest mieć własne klasy.
marcio
Cytat
Masz rację, tylko nie do wszystkich projektów potrzeba FW, dlatego dobrze jest mieć własne klasy.

No to wlasnie albo korzystasz z FW w 100% i z gotowych klas albo wszystko piszesz sam robic z kodu takie spaghetti gdzie mieszasz swoj kod z cudzym to raczej wyjdzie @#*$&* i tobie tez nie bedzie smakowalo taka moja skromna uwaga tongue.gif


Cytat
Bo jak inaczej, można wykorzystać klasę do obsługi bazy danych jak nie w taki sposób, w jaki zrobiłem to parę postów wyżej.

Jesli chodzi o post nor #9 to cos w ten desen ale troche zabardzo kombinujesz i kod nie jest elastyczny tylko 1 baza tongue.gif.

Wczesniej to robiles z tego sieczke wszystko w jednej klasie lub klasa autoryzacji dziedziczyla po klasie dla mysql ogolnie robisz te same bledy co robilem i ja tongue.gif

Oczywiscie teraz tez pro nie jestem ale mniej wiecej wiem co i jak poczytaj troche kodow to jest najlepsza nauka biggrin.gif^^
PawelC
Cytat(marcio)
No to wlasnie albo korzystasz z FW w 100% i z gotowych klas

No tak, tylko po co korzystać z FW przy projekcie którego kod zajmuje maks 100 linijek?

Nie chodzi mi o to że mieszam kod FW ze swoim, tylko albo korzystam z FW albo ze swojego kodu smile.gif
Cytat(marcio)
Jesli chodzi o post nor #9 to cos w ten desen ale troche zabardzo kombinujesz i kod nie jest elastyczny tylko 1 baza

Bo będę tej klasy używał tylko na bazie MySQL
Pr0100
Odnośnie PDO to jeżeli jesteś początkującym programistą (jak wywnioskowałem z twoich postów) to moim zdaniem nie warto utrudniać sobie pracy.

Odnośnie klas to proponuje 2 klasy:
- klasa do obsługi tabeli z użytkownikami w MySqlu
- klasa do obsługi pojedynczego użytkownika podczas pracy z widokiem/kontrolerem (->getNick, ->getMail, ->getProfil (link do profilu), ->checkPass($string) itp)

Mówisz że pisząc 100 liniowy projekt nie opłaca sie używać FW? Idąc tym tropem to czy opłaca się używać klas?

Moim zdaniem pisząc 100 liniowy projekt szkoda czasu na zastanawianie się nad tym problemem smile.gif
Crozin
Cytat
No to wlasnie albo korzystasz z FW w 100% i z gotowych klas albo wszystko piszesz sam robic z kodu takie spaghetti gdzie mieszasz swoj kod z cudzym to raczej wyjdzie hujow* i tobie tez nie bedzie smakowalo taka moja skromna uwaga
A co jest złego w korzystaniu z cudzych bibliotek? Jeżeli jest to w ramach treningu to może, ale jeżeli nie to po co ma tracić czas?

Cytat
Odnośnie PDO to jeżeli jesteś początkującym programistą (jak wywnioskowałem z twoich postów) to moim zdaniem nie warto utrudniać sobie pracy.
Hmmm... a co w PDO tak dokładnie miałoby mu utrudnić pracę?


Możesz spróbować zaprojektować sobie swój model nieco inaczej. Zrób wszystko od drugiej strony - nie "jakich klas potrzebuję" tylko "jakiej funkcjonalności potrzebuję".
Przykładowo masz prostą strukturę danych, gdzie każdy użytkownik jest przypisany do jakiejś grupy (relacja 1-n)
  1. <?php
  2.  
  3. //zwraca nam jeden obiekt, klasy Group
  4. $group = GroupPeer::retrieveByName('user');
  5.  
  6. //tworzymy sobie nowy obiekt, reprezentujący użytkownika
  7. $user = new User();
  8. $user->setUsername('blah blah')
  9.     ->setFirstName('blag blah')
  10.     ->setLastName('blah blag')
  11.     //tak wiem, że można by przekazać poprostu $group :)
  12.     ->setGroupId($group->getId());
  13.  
  14. $user->save();
  15. ?>
To jest akurat pokazane na przykładzie Propela. Do tego dochodzi jeszcze walidacja danych - ale to już "przy formularzach".
PawelC
Crozin pomysł jak i samo podejście ciekawe smile.gif zobaczę co mi z tego wyjdzie. A co do klas to stworzę 3, do obsługi bazy danych, do zarządzania użytkownikami czyli dodawanie, kasowanie, rejestracja i logowanie, a 3 i ostatnia to klasa która będzie obsługiwała profil danego usera czyli aktualizacja profilu, wyświetlenie profilu itp. Wydaje mi się że taki podział jest najlepszym według mnie rozwiązaniem.
Komunista
Może zrób sobie:
- klasę do obsługi bazy
- klasę do operacji na tabeli "users" - insert, update, select itd. np Model_User
- klasę user reprezentującą obiekt aktualnie zalogowanego/odwiedzającego użytkownika - np. My_User - tutaj metody setAuthenticated(), isAuthenticated(), setGroups(), hasGroups() i co tylko chces oraz dostęp do danych z sesji - do sesji oddzielna klasa ;]
Dwa pierwsze punkty zastępuje wspomniany wcześniej Propel

Samo logowanie, edycja czy wyswietlanie to umiejętne używanie tego co napisałem, budujesz kontroler i w nim działasz na obietkach Model_User i My_User
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.