Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Klasa Generująca Widoki - Problem
reptilerex
post
Post #1





Grupa: Zarejestrowani
Postów: 16
Pomógł: 0
Dołączył: 25.03.2011

Ostrzeżenie: (10%)
X----


Witam, jestem w trakcie tworzenia biblioteki do code ignitera, ale mniejsza o to bo to nie jest przedmiotem problemu.

Mam w planie stworzyć klasę, która za pomącą swoich metod będzie generować tabelkę HTML z wynikami z bazy danych + paginacja, filtry, sortowanie itd.
Klasa ma być w pełni konfigurowalna, to jest największym problemem, bo gdyby miała tylko działać dla mnie, to problem by nie istniał.

Póki co zrobiłem, generowanie kolumn + ustalanie nazw/nagłówków tych kolumn (wymieniając je z separatorem i rozdzielając później explodem)
Nazwy pól z bazy danych potrzebne do wyświetlenia/sortowania wyników są określane w taki sam sposób.

Cytat
Przykład:
Kolumna id | kolumna data | kolumna title
Pole id | Pole data | Pole title


Przekazuję sobie to do metody, która rozdziela to sobie i generuję kolumny po czym zapisuję to do zmiennej
Ok działa lecimy dalej.

Nadszedł czas na generowanie wierszy (rekordów), przesyłam więc z kontrolera result z bazy danych do metody mojej biblioteki i wyświetlam wyniki w foreachu, lecz tutaj problem.
Każda tabelka ma także narzuconą z góry kolumnę "Akcja" - dodaj, usuń, edytuj, generuj pdf itd itp
I muszę zrobić tak, aby była możliwość wyłączenia np dwóch lub trzech, a nawet wszystkich akcji dla danego rekordu.

Cytat
Przykład:

Rekord 1 - Usuń, Edytuj, Generuj PDF
Rekord 2 - Usuń, Edytuj, Generuj PDF
Rekord 3 - Usuń, Edytuj, Generuj PDF
Rekord 4 - Edytuj, Generuj PDF
Rekord 5 - Generuj PDF
Rekord 6 - [pusto]
Rekord 7 - Usuń, Edytuj, Generuj PDF


Nie mogę wpaść na pomysł jak się za to zabrać, proszę o wszelkie podpowiedzi.
Z góry dziękuję.
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%)
-----


@marcio: Różne obiekty mogą mieć w takiej tabeli różne akcje, ponieważ przykładowo użytkownik może nie mieć praw do usunięcia części danych, część danych może nie być zdatna do generowania w PDF-ie itp.

Taka tabelka to wręcz książkowy przykład na to, gdzie można sensownie zastosować taki bardzo popularny ostatnio wzorzec MVC. Na dobrą sprawę jest to przykład na to gdzie w ogóle jest miejsce tego wzorca. Ale o tym już było nie raz i nie ma sensu ciągnąć tego tutaj. (IMG:style_emoticons/default/wink.gif)

Zastanów się czego potrzebujesz. Potrzebujesz narzędzia uniwersalnego, które będzie w stanie przyjąć coś (konkretnie to implementację interfejsu, który sobie zdefiniujesz) co na podstawie jakiś tam informacji (np. filtry, paginacja) utworzy sobie kolekcję obiektów, które na końcu zostaną wyświetlone w jakiejś formie, np. tabelki. Narzędzie musi być rozbudowane. Inaczej przy pierwszej próbie zrobienia czegoś niestandardowego polegnie i będzie przyczyną całej masy problemów do obejścia.

Tutaj piszę bez większego namysłu - Ty powinieneś zastanowić się czy aby na pewno takie rozwiązanie nie ma jakiś defektów, czy nie będzie ograniczać w jakiś skrajnych przypadkach itp. itd.

Pierwsze co będzie potrzebne to to coś co ma zwracać odpowiednią kolekcję obiektów do wyświetlenia. Interfejs tego będzie bardzo prosty (wybacz słabe nazewnictwo)<!--Geshi:281492:php--><pre class="php-brief" style="font-family:monospace;"><div class="head">
  1. [topic=0]YPE</span> <span class="sy0">|</span> YouTube<span class="sy0">::</span><span class="me2">PLAYLIST_TYPE</span><span class="br0">)</span><span class="sy0">;</span></div><li class="li1"><div class="de1"> </div><li class="li2"><div class="de2"><span class="re0">$table</span><span class="sy0">-></span><span class="me1">setDataRepository</span><span class="br0">(</span><span class="re0">$data</span><span class="br0">)</span><span class="sy0">;</span></div>
  2. [/list]<div class="foot">[PHP] [url="./Pobierz-Plik-281493.html"]plaintext[/url] </div></pre><!--/Geshi:281493:php-->Na dobrą sprawę takie rzeczy jak paginacja czy sortowanie również powinny być zrealizowane przy pomocy odpowiednich interfejsów, kolejno PaginableInterface (get/setOffset, get/setLimit) oraz SortableInterface (get/setField, get/setOrder lub inny interfejs get/setComparator).
  3.  
  4. To właściwie załatwia sprawę określenia co ma zostać pobrane. Następny etap to określenie co ma zostać wyświetlone. Można to zrobić w bardzo prosty sposób, tj. poprzez określenie etykiety (w przypadku tabelki będzie to nagłówek kolumny) oraz metody zwracającej wartość.[php]$table->addColumn('Tytuł', 'getTitle');
  5. // Można by to zrobić też jako
  6. $table->addColumn('Opis', 'description'); // spróbuje wywołać metodę getDescription albo isDescription (standardowe gettery)
  7.  
  8. // Czasami potrzeba zrobić coś bardziej dynamicznego, wtedy można by zastosować coś takiego:
  9. $table->addColumn('Wielkość pliku', function($object) {
  10. return FilesystemUtils::formatFileSize($object->getFileSize()); // zwraca przykładowo 15 KiB, 7,2 GiB, 244 b
  11. });
  12.  
  13. // Albo nawet jako obiekt implementujący jakiś interfejs


Problem tego jakie konkretnie dane trzeba wyświetlać zdaje się również być rozwiązany. Kolejny problem to ustalenie jakie akcje (usuń, edytuj, drukuj, akceptuj itp.) mają być dostępne dla każdego obiektu. Takie akcje można również całkiem łatwo rozwiązać za pomocą obiektów, które będą implementowały prosty interfejs:
  1. interface ActionInterface {
  2. public function supports($object);
  3. }
Metoda ta zwraca prawdę bądź fałsz w zależności od tego czy dany akcja jest dostępna dla danego obiektu, przykładowo akcje usuń i akceptuj mogłby wyglądać tak:
  1. class RemoveAction implements ActionInterface {
  2. private $user;
  3. private $acl;
  4.  
  5. // konstruktur, get/set dla powyższych
  6.  
  7. public function supports($object) {
  8. return $this->acl->hasPermissions($this->user, $object, ACL::REMOVE);
  9. }
  10. }
  11.  
  12. class ActivateAction implements ActionInterface {
  13. public function supports($object) {
  14. return $object instanceof ActivatableInterface && !$object->isActive();
  15. }
  16. }
Później takie akcje trzeba dodać tylko do tabelki:
  1. $removeAction = new RemoveAction();
  2. $removeAction->setUser($this->getCurrentUser());
  3. $removeAction->setAcl($this->getAcl());
  4.  
  5. $activateAction = new ActivateAction();
  6.  
  7. $table->addObjectAction($removeAction);
  8. $table->addObjectAction($activateAction);


Na koniec pozostaje kwestia ostatecznego wyrenderowania tabelki. Za to również odpowiedzialny jest osobny obiekt (bo przecież możesz chcieć wyrenderować tabelkę, listę, kolekcję w JS/JSON/XML czy jeszcze coś innego). Taki renderer to oczywiście również implementacja jakiegoś tam interfejsu, który definiuje jakieś tam metody.

Ten post edytował Crozin 7.07.2011, 10:19:05
Go to the top of the page
+Quote Post

Posty w temacie


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: 10.10.2025 - 23:22