Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [php][oop] Architektura aplikacji, grupy/profile i odpowiedne dla nich modele/widoki
jastu
post
Post #1





Grupa: Zarejestrowani
Postów: 382
Pomógł: 0
Dołączył: 29.11.2005
Skąd: :jestem();

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


Witam
problem opiszę na przykładzie :
- mamy w bazie rekord który dla różnych profili użytkownika wyświetla inne kolumny

Gdzie powinno się znaleźć zapytanie o rekord ?
- czy w klasie ModelUserProfil dziedziczącej po klasie ModelUser (chyba nie) ?
( tutaj mamy tylko kod do operacji na danych użytkownika )
- czy w klasie ModelDane która odpowiada za dane które chcemy uzyskać (raczej tak) ?
( wtedy trzeba do ModelDane przekazać informacje o profilu bierzącego użytkownika )
- czy w klasie ViewDane który generuje odpowiedni widok dla bierzącego usera (zdecydowanie tak) ?
( przekazujemy informacje o profilu użytkownika do widoku i na tej podstawie wyświetlamy tylko własciwe dla użytkownika dane, ale pobieramy zawsze komplet danych )

3 rozwiązanie chyba najlepsze, tylko w ModelDane zawsze byśmy pobierali te same dane, a nie każdy profil wymaga pobrania danych dla rekordu z 3 tabel (po np. jeden z profili wymaga danych z jednej tabeli) - co wtedy z wydajnością ?

Jak rozwiązujecie to u siebie ?
pzdr


--------------------
Powyższy post wyraża jedynie opinię autora w dniu dzisiejszym. Nie może on służyć przeciwko niemu w dniu jutrzejszym. Ponadto autor zastrzega sobie prawo zmiany poglądów, bez podawania przyczyny.
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 6)
Sedziwoj
post
Post #2





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


Jak dla mnie problem nie jest dokładnie opisany.
Na starcie nie podoba mi się odniesienie do rekordu... bo to ma niewiele wspólnego. Ważniejsze jest co to są za dane.
Piszesz o że jest to zależne od użytkownika co wyświetli, ale w jaki sposób?
Bo jak to są różnice typu NIP, nazwa itd. dla firmy a dla osoby fizycznej brak to inaczej bym to rozwiązał, niż informacje o czymś i w zależności od typu użytkownika wyświetla je lub nie. No i czy to jest parę typów czy całkowita dowolność i ilość przez to.


--------------------
Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami.
Go to the top of the page
+Quote Post
jastu
post
Post #3





Grupa: Zarejestrowani
Postów: 382
Pomógł: 0
Dołączył: 29.11.2005
Skąd: :jestem();

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


Wydawało mi się że opisałem jasno sad.gif

Przykładowy przykład nr 2.
- mamy aplikację do ewidencji bydła hehe
- w aplikacji mamy trzy rodzaje użytkowników (użytkownik,moderator,administrator)
- wyświetlenie informacji dla użytkownika o jakimś bydlaku wymaga pobrania danych z jednej tabeli
- wyświetelenie informacji o bydlaku dla moderatora wymaga pobrania danych z dwóch tabel (join), dla administratora z 3 (join)

Pytanie -> gdzie umieścić zapytania o te dane lub/czy pobierać wszystkie dane a wyświetlać tylko wybrane (wydajność) ?

Cytat
Piszesz o że jest to zależne od użytkownika co wyświetli, ale w jaki sposób?

no właśnie ?
Cytat
Bo jak to są różnice typu NIP, nazwa itd. dla firmy a dla osoby fizycznej brak to inaczej bym to rozwiązał, niż informacje o czymś i w zależności od typu użytkownika wyświetla je lub nie.

czy o wyświetlonych informacjach/danych/linkach/przyciskach/opcjach nie decuduje właśnie typ/profil/grupa użytkownika ?

Ten post edytował jastu 12.06.2007, 23:38:01


--------------------
Powyższy post wyraża jedynie opinię autora w dniu dzisiejszym. Nie może on służyć przeciwko niemu w dniu jutrzejszym. Ponadto autor zastrzega sobie prawo zmiany poglądów, bez podawania przyczyny.
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #4





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


Cytat(jastu @ 13.06.2007, 00:36:34 ) *
Wydawało mi się że opisałem jasno sad.gif

Może ja jestem po prostu tępy biggrin.gif

Czyli problem jest uprawnienia użytkownika i gdzie mają być egzekwowane, na poziomie modelu czy widoku.
Teraz w tym co korzystam uprawnienia są na poziomie controlera, po ale mam właściwie dwa typy osób, użytkownik i administrator. Więc po zalogowaniu jako admin masz dostęp do panelu gdzie jest wszytko.
Ogólnie jak masz prezentować różne ilości danych to i tak powinny być to różne widoki, aby w każdym to dobrze wyglądało, choć jest czasem tak że pewne elementy się ukrywa dla nie uprawnionych.
Czyli w tym moim przypadku, nie wiem czy dobre jest to rozwiązanie, z modelu jest pobierany komplet informacji.


--------------------
Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami.
Go to the top of the page
+Quote Post
Ludvik
post
Post #5





Grupa: Przyjaciele php.pl
Postów: 698
Pomógł: 3
Dołączył: 28.03.2004
Skąd: Wrocław

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


Ja pomyślał bym nad fabryką i DAO dla obiektów reprezentujących wyświetlane dane. Szkoda trochę wydajności, żeby w większości przypadków (odwołania przeciętnych użytkowników) wykonywać potrójnego joina. Najlepiej widać to na pseudo-kodzie.
  1. <?php
  2. class UserData {
  3. public function getSomething() {}
  4. }
  5.  
  6. class ModData extends UserData {
  7. public function getSomethingMore() {}
  8. }
  9.  
  10. class AdminData extends ModData {
  11. public function getSomethingElse() {}
  12. } 
  13.  
  14. class DataDAOFactory {
  15. public static function getDAO(User $u) {
  16. if ($u->isAdmin()) {
  17. return new AdminDataDAO();
  18. } else if ($u->isMod()) {
  19. return new ModDataDAO();
  20. } else {
  21. return new UserDataDAO();
  22. }
  23. }
  24. }
  25.  
  26. interface DataDAO {
  27. public function getUserData(User $u);
  28. }
  29.  
  30. class UserDataDAO implements DataDAO {
  31. public function getUserData(User $u) {
  32. // Pobierasz dane dla zwykłego użytkownika
  33. return new UserData();
  34. }
  35. }
  36.  
  37. class ModDataDAO implements DataDAO {
  38. public function getUserData(User $u) {
  39. // Pobierasz dane dla moderatora
  40. return new ModData();
  41. }
  42. }
  43.  
  44. class AdminDataDAO implements DataDAO {
  45. public function getUserData(User $u) {
  46. // Pobierasz dane dla administratora
  47. return new AdminData();
  48. }
  49. }
  50. ?>

Tyle, że z tym rozwiązaniem jest jeden problem: dużo klas. Przyda się, jeżeli w tym DAO będziesz miał więcej operacji zależnych od typu użytkownika. Jeżeli będziesz miał tylko jedną metodę, może to być strata czasu. Wtedy można utworzyć uniwersalne DAO, w którym dokonasz wyboru zapytania po uprawnieniach (tak jak w fabryce wyboru DAO). Wypada wtedy fabryka i dwie klasy DAO. Widok możesz wybrać po typie obiektu z danymi albo uprawnieniach użytkownika.


--------------------
Go to the top of the page
+Quote Post
Reigon
post
Post #6





Grupa: Zarejestrowani
Postów: 33
Pomógł: 0
Dołączył: 19.10.2004

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


Sprawdzalbym uprawnienia (admin, mod, user) czy to w jakies specjalnej klasie z uprawnieniami, czy to zwyczajnie w kontrolerze i w zaleznosci o tego wykonywal metode klasy DAO (cos jak poprzednik opisal, tylko on to zrobil na wielu klasach) - szukaj(dla usera), szukajMod(), szukajAdmin(). Ja mam np. klase macierzysta dla warstwy DAO - SQL, a w niej zklejanie zapytania i wyszukiwanie i zwracanie badz to obiektu modelu badz tablicy obiektow. Wtedy mozesz napisac klase User, a w niej dodatkowe metody dla moda i admina. W nich pisalbys zapytanie ze zlaczeniem (az do WHERE) i zwracal poczatek zapytania do klasy realizujacej jego dalsze sklejanie.
Go to the top of the page
+Quote Post
jastu
post
Post #7





Grupa: Zarejestrowani
Postów: 382
Pomógł: 0
Dołączył: 29.11.2005
Skąd: :jestem();

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


Tworzenie DAO dla każdego użytkownika jest chyba najlepszym rozwiazaniem ( wg mnie najbardziej elastycznym w kontekscie zmian ). Rozumiem też, że w tej sytuacji trzeba będzie budować odrębne klasy prezentacji danych ( lub szablony ) questionmark.gif lub widok generować wspólny, ale każdy przycisk/link/cokolwiek w tym widoku (wywołujący kontroler/metodę/akcję) sprawdzać przed wyświetleniem uwzględniając właśnie uprawnienia użytkownika ... i może to że użytkownik jest jego właścicielem (np ja edytuję swój post więc button edit mi się wyświetli) questionmark.gif?

W tej sytuacji tworzenie odrębnych widoków (bądź jego elementów) wydaje się dobry rozwiązaniem, chociaż wg mnie nie jest to najlepsze rozwiązanie (w przypadku zmian nie jest to już jeden szablon)
  1. <?php
  2. class Fast{
  3.  
  4. static function check($user,$controller,$function,$param){
  5.  // pobranie informacji o wymaganiach żądania (bądź wartości domyślne)
  6. $actionDemand = getActionDemand($controller,$function,$param); 
  7.  
  8. // pobranie uprawnień użytkownika dla tego żądania,(jeśli brak to dane domyślne )
  9. $userPossibility = getUserPossibility($user,$controller,$function,$param);
  10.  
  11.  
  12. // sprawdzenie czy użytkownik może zrealizować ządanie (flagi bitowe)
  13.  ((int)$actionDemand & (int)$userPossibility == $actionDemand) ? return true : return false ;
  14. }
  15. }
  16.  
  17. // i gratis helper do linków :)
  18. function Link($link,$name,$title){
  19. return '<a href= " '.base_url().$link.' "  title= " '$title' " >'.$name.'</a>';
  20. }
  21.  
  22. // wykorzystanie w szablonie 
  23. if(Fast::check($this->User,'post','delete',3)){ echo link('/post/delete/3','Usuń','Usuń tego posta');}
  24. ?>



Skomplikowane moze być pobieranie danych w aspekcie jakiegoś lokalnego wydarzenia zależnego od parametru dla wskazanej funkcji w kontrollerze tzn. jestem moderatorem jakiegoś subforum na forum, i w moim subforum do przycisku usuń_posta uprawnienia mają już trzy osoby (user do swojego posta oraz moderator i administrator do każdego posta)...więc procedura spradzenia czy przycisk usuń_linka może odbiegać od innych.


Obecnie walcze z uzyskaniem zgrabnego rozwiązania dla generowania widoków (zależnych od uprawnień) i dynamicznym przydzielaniem uprawnień .

Wnoisek : mamy dla kontrollera DAO zależne od profilu użytkownika...czy z widokiem zrobić tak samo ?

Poradzicie coś ? aarambo.gif



////////////////////////////////////////////////////////////////////////////////////////


Pozwolę sobię odświeżyć El Temato worriedsmiley.gif
Napisałem klasę wykorzystującą wzorzec Composite View, jest to jedna klasa która przyjmuje tablicę z danymi i nazwę szablonu - po czym podstawia zmienne,wykonuje kod php w szablonie i wyświetla lub przechowuje wynik uruchomienia szablonu.

  1. <?php
  2. // ZAWARTOŚĆ CONTROLLERA
  3.  
  4. $tplName =  'calendar';
  5. $data =  array('poniedziałek','środa','czwartek');
  6. // 3 argument to false tzn.wynik wykanania kodu php w szablonie jest w składowej $calendar_view
  7. $calendar_view = new View($tplName,$data,false);
  8. $banner_view = new View('banner',false,false);
  9.  
  10. $viewElements = array('calendar' => $calendar_view,'banner'=>$banner_view);
  11.  
  12. // wyświetlenie
  13. new View('startPage',$viewElements,true);
  14. ?>


Co zrobić z uprawnieniami do np. opcji w menu dostępnych tylko dla moderatora. Schemat działania widoku jest prosty - przyjmuje on już przygotowane przez kontroler dane....tzn że w kontrolerze zadecydujemy czy button USUŃ ma się wyświetlić bieżącemu userowi ? Kolejnym rozwiązaniem jest przekazanie danych o uprawnieniach do klasy View....tylko wtedy ta klasa powinna mieć możliwość komunikacji z modelem żeby w oparciu o uprawnienia odpowiednie dane pobierać. Czy ktoś potrafi przedstawić wstępny zarys działania takiej implementacji ?

Można...
- napisać 5 różnych szablonów tego samego widoku i ładować odpowiedni w zależności od uprawnień ?

Nie mam już innego pomysłu .....

-------------------------------------------------------------------------
Może się komuś przyda (dla prostych wywołań typu CI czy VFrame) :
- bieżący uzytkownik (zalogowany czy nie) ma jakiś tam profil (administrator/moderator czy Anonymous)
- do szablonu widoku przekazujemy obiekt użytkownika
- zanim wyświetlimy jakiś link lub przycisk sprawdzamy czy user ma uprawnienia do akcji wywoływanej przez ten link
- sprawdzić instancję użytkownika można podczas wywołania kontrollera w jednej z jego metod lub w konstruktorze
KLASA UŻYTKOWNIKA
  1. <?php
  2.  
  3. class User{
  4. private $instance = null;
  5.  
  6. function isAdministrator(){
  7. // sprawdzenie czy user jest administratorem
  8. // return true : false
  9. }
  10.  
  11. function isModerator($id = null){
  12.  // sprawdzenie czy user jest moderatorem czegośtam o wskazanym ID
  13.  // return true : false
  14. }
  15.  
  16. // pozostały kod
  17. }
  18.  
  19. ?>



KONTROLER
  1. <?
  2. class index extends controller{
  3.  
  4. function index(){
  5. $this->load->class('User');
  6. $this->view->display('index',array('user'=>User::init()));
  7.  
  8. }
  9. }
  10. ?>




  1. <html>
  2. <body>
  3. <!-- jakaś treść strony -->
  4. <? php 
  5. <? if( $user->isAdministrator() ) { echo '<a href="www.system.pl/destroy.php">Link</a>' ; } ?>
  6.  
  7.  
  8. </body>
  9. </html>


Czekam na słowa krytyki...

Ten post edytował jastu 23.07.2007, 11:43:34


--------------------
Powyższy post wyraża jedynie opinię autora w dniu dzisiejszym. Nie może on służyć przeciwko niemu w dniu jutrzejszym. Ponadto autor zastrzega sobie prawo zmiany poglądów, bez podawania przyczyny.
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 21.08.2025 - 12:53