Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MVC] - Akcje "administracyjne"
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
radziel
Ostatnio, dość często rozmyślam nad różnorodnymi problemami, które napotkałem w swojej dotychczasowej karierze programisty.

Jednym z tych "problemów" jest dostarczenie klientowi pełnego interfejsu graficznego do obsługi jakiegoś serwisu. Wiadomo, pisanie tysiąca akcji (formularzy,list, itp.) nie leży do najprzyjemniejszych rzeczy. Prawdę mówiąc, ja tego nie nawidzę :-/. Najchętniej odesłałbym go do nauki phpMyAdmin/phpPgAdmin 'a tongue.gif.

Chciałbym Was zapytać jak Wy, radzicie sobie z tą "częścią" dostosowywania systemu do wymagań klienta?

Sp 1. - piszemy wszystkie akcje administracyjne (narazie tak robię...)
Sp 2. - piszemy "generator formularzy" który generuje je wg. schematu przekazujemy mu nazwy pól,typy i opis a on generuje resztę. Wiadomo, formularz dodawania newsa i artykułu jest podobny ;] Korzyści? Odpadają nam już administacyjne akcje-widoki. Minusy? To się gryzie z samą ideą gdyż generator generuje widok...

Sp 3. - każda normalna akcja typu view. ma np. funkcję display() która pokazuje normalną treść oraz funkcja np. AdminDisplay() - widok dla administratora. Korzyści? Mniejsza ilość plików tongue.gif

Macie jakieś inne pomysły?
NuLL
Rozwiązanie drugie - bynajmniej ja preferuję tongue.gif - i jest cudowne.

A co do tego czy to się zgadza z założeniami czy nie - mnie to rybka guitar.gif

Napisanie czegoś takiego do łatwych nie należy - ja mając ustalony sposób nazewnictwa tabeli i pól jestem w stanie wygenerować ok 90% panelu administracyjnego biggrin.gif
Ace
No nie iwem czy 2 gryzie sie z MVC, w koncu generator moze wytworzyc dane ktore trafia do widoku, a widok odpowiednio sie ukrztaltuje wtedy... (stworzy sie odpowiedni formularz)

tez niedlugo bede pisal taki generator ale nie wiem czy sam pisac czy uzyc gotowca. Slyszalem cos o jakim generatorze QuickForm? ponoc walidacjie ma wbudowana na poziomie phpa jak i js... winksmiley.jpg wiec moze ulatwic zycie.

pzdr.
squid
Cytat(radziel @ 2005-05-23 19:57:02)
Ostatnio, dość często rozmyślam nad różnorodnymi problemami, które napotkałem w swojej dotychczasowej karierze programisty.

Jednym z tych "problemów" jest dostarczenie klientowi pełnego interfejsu graficznego do obsługi jakiegoś serwisu.  Wiadomo, pisanie tysiąca akcji (formularzy,list, itp.) nie leży do najprzyjemniejszych rzeczy. Prawdę mówiąc, ja tego nie nawidzę :-/.          Najchętniej odesłałbym go do nauki phpMyAdmin/phpPgAdmin 'a tongue.gif.

Chciałbym Was zapytać jak Wy, radzicie sobie z tą "częścią" dostosowywania systemu  do wymagań klienta?

Sp 1. - piszemy wszystkie akcje administracyjne (narazie tak robię...)
Sp 2. - piszemy "generator formularzy" który generuje je wg. schematu przekazujemy  mu nazwy pól,typy i opis a on generuje resztę. Wiadomo, formularz dodawania newsa i artykułu jest podobny ;]  Korzyści? Odpadają nam już administacyjne akcje-widoki. Minusy? To się gryzie z samą ideą gdyż generator generuje widok...

Sp 3. - każda normalna akcja typu view. ma np. funkcję display() która pokazuje normalną treść oraz funkcja np. AdminDisplay() - widok dla administratora. Korzyści? Mniejsza ilość plików tongue.gif

Macie jakieś inne pomysły?

ja robie tak:
mam model np katalog i rozne akcje (metody) w nim dostepne w zaleznosci od uprawnien danego uzytkownika, zalozmy ze zaloguje sie admin wtedy poprostu zminiam template na taki jaki odpowada adminowi, ew. formularze tworzy widok, niestety jeszcze nie zautomatyzowalem tego sad.gif

co do QuickForm to zebym wiedzial ze mi to tyle namiesza to bym go nie uzyl ale teraz jak juz zaadoptowalem go do MVC to jest fajnie.
Istnieje cos takiego jak QuicForm_controller ktory powstal do tworzenia wielostronnicowych formularzy przy pomocy QuicForm i jest zbudowany podobnie do klasycznego wzorca MVC, wystepuje tam pagecontroller aczkolwiek po tygodniu zmagania sie z tym rozwiazaniem stworzylem cos wlasnego co dziala lepiej wg mnie smile.gif
NuLL
Cytat
Slyszalem cos o jakim generatorze QuickForm?

@Ace - w PEAR-ze jest taki pakiet.
ActivePlayer
ja mam zamiar na dniach napisac taki generator formularza na podstawie zapytania z sqla. bede tworzyc kod klasy, formularz, itp. mam nadzieje ze da rade. ale jak da to bedzie pieknie smile.gif
radziel
Taki kod znalazłem na Zendzie:
  1. <?php
  2. class DBtable2form {
  3.  
  4. //these vars determine whether to use default form input type 
  5. //or alternate based on field size
  6. //enum field default is select, alternate is radio
  7. //set field default is multiselect, alternate is checkbox
  8. //blob or text field default is textarea, alternate is text
  9. var $enumField_toggle = 3;
  10. var $setField_toggle = 4;
  11. var $strField_toggle = 255;
  12.  
  13. //these vars determine form input size attributes
  14. var $textInputLength = 50;
  15. var $textareaRows = 4;
  16. var $textareaCols = 50;
  17. var $multiSelectSize = 4;  
  18.  
  19. //class constructor sets form name and gets table info
  20. //args are DB link, DB name, table name
  21. function DBtable2form(&$conn,$DB,$table){
  22.  
  23. $this->formName = $this->table = $table;
  24.  
  25. $this->fields = @mysql_list_fields($DB, $table, $conn)
  26. or die(&#092;"DB, table or connection error.\");
  27. $this->columns = @mysql_num_fields($this->fields);
  28.  
  29. }
  30.  
  31. //The following function modified from php.net:
  32. //http://www.php.net/manual/en/function.mysql-fetch-field.php
  33. //Courtesy of: justin@quadmyre.com & chrisshaffer@bellsouth.net
  34. function mysql_enum_values($tableName,$fieldName){
  35.  
  36. $result = @mysql_query(&#092;"DESCRIBE $tableName\");
  37.  
  38. while($row = @mysql_fetch_array($result)){
  39.  
  40. ereg('^([^ (]+)(((.+)))?([ ](.+))?$',$row['Type'],$fieldTypeSplit);
  41. //split type up into array
  42. $fieldType = $fieldTypeSplit[1];
  43. $fieldLen = $fieldTypeSplit[3];
  44.  
  45. if ( ($fieldType=='enum' || $fieldType=='set') && ($row['Field']==$fieldName) ){
  46. $fieldOptions = split(&#092;"','\",substr($fieldLen,1,-1));
  47. return $fieldOptions;
  48. }
  49. }
  50.  
  51. return FALSE;
  52.  
  53. }
  54.  
  55. //this function forces a field to a specific
  56. //form input type regardless of size
  57. //args are field name and form input type
  58. //form input types are as follows:
  59. //for enum field - \"select\" or \"radio\"
  60. //for set field- \"multiselect\" or \"checkbox\"
  61. //for string or blob field - \"text\" or \"textarea\"
  62. function forceType($fieldName,$inputType){
  63.  
  64. $this->forced[$fieldName] = $inputType;
  65.  
  66. }
  67.  
  68. //this function hides a field from HTML output
  69. //arg is field name
  70. function hideField($fieldName){
  71.  
  72. $this->hidden[$fieldName] = &#092;"hide\";
  73.  
  74. }
  75.  
  76. //this function outputs entire form
  77. function printForm(){
  78.  
  79. echo &#092;"<FORM name=\"$this->formName\" action=\"\".$_SERVER['PHP_SELF'].\"\" method=POST>n\";
  80. for ($i=0; $i<$this->columns; $i++){
  81.  
  82. $byForce = false;
  83. $name = @mysql_field_name($this->fields,$i);
  84. $type = @mysql_field_type($this->fields,$i);
  85. $len = @mysql_field_len($this->fields,$i);
  86. $flag = @mysql_field_flags($this->fields,$i);
  87.  
  88. if( isset($this->forced[$name]) ) $byForce = $this->forced[$name];
  89. if( isset($this->hidden[$name]) ) $type = &#092;"skip\";
  90.  
  91. switch($type){
  92.  
  93.  case &#092;"real\":
  94.  case &#092;"int\":
  95. echo &#092;"<b>\".$name.\":</b><br>n\";
  96. if($len<$this->textInputLength) $length = $len; else $length=$this->textInputLength; 
  97. echo &#092;"<input type=text name=$name size=$length MAXLENGTH=$len><br><br>n\";
  98.  break; 
  99.  
  100.  case &#092;"blob\":
  101. echo &#092;"<b>\".$name.\":</b><br>n\";
  102. if( ($len>$strField_toggle || $byForce == &#092;"textarea\") && $byForce != \"text\" )
  103.  echo &#092;"<textarea name=$name rows=$this->textareaRows cols=$this->textareaCols></textarea><br><br>n\";
  104. else echo &#092;"<input type=text name=$name size=$this->textInputLength MAXLENGTH=$len><br><br>n\";
  105.  break; 
  106.  
  107.  case &#092;"string\":
  108. echo &#092;"<b>\".$name.\":</b><br>n\";
  109.  
  110. if($flag == &#092;"enum\"){
  111. $options = $this->mysql_enum_values($this->table,$name);
  112. if( ($len > $this->enumField_toggle || $byForce == &#092;"select\") && $byForce != \"radio\"){
  113. echo &#092;"<select name=$name>n\";
  114. foreach($options as $opt) echo &#092;" <option value=\"$opt\">$opt</option>n\";
  115. echo &#092;"</select><br><br>n\";
  116. } else {
  117. foreach($options as $opt) echo &#092;"<input type=radio name=\"$name\" value=\"$opt\">$opt &nbsp;&nbsp;&nbsp;n\";
  118. echo &#092;"<br><br>n\";
  119. }
  120. }
  121. else if($flag == &#092;"set\"){
  122. $options = $this->mysql_enum_values($this->table,$name);
  123. if( ($len > $this->enumField_toggle || $byForce == &#092;"multiselect\") && $byForce != \"checkbox\" ){
  124. echo &#092;"<select name=\".$name.\"[] size=$this->multiSelectSize multiple=\"multiple\">n\";
  125. foreach($options as $opt) echo &#092;" <option value=\"$opt\">$opt</option>n\";
  126. echo &#092;"</select><br><br>n\"; 
  127. } else {
  128. foreach($options as $opt) echo &#092;"<input type=checkbox name=\"\".$name.\"[]\" value=\"$opt\">$opt &nbsp;&nbsp;&nbsp;n\";
  129. echo &#092;"<br><br>n\";
  130. }  
  131. }
  132. else{
  133. if($len<$textInputLength) $length = $len; else $length=$this->textInputLength;
  134. if( ($len>$strField_toggle || $byForce == &#092;"textarea\") && $byForce != \"text\" ) echo \"<textarea name=$name rows=$this->textareaRows cols=$this->textareaCols></textarea><br><br>n\";
  135. else echo &#092;"<input type=text name=$name size=$length MAXLENGTH=$len><br><br>n\";
  136. }
  137.  break; 
  138.  
  139.  case &#092;"date\":
  140. echo &#092;"<b>\".$name.\":</b><br>n\";
  141. echo &#092;"<input type=text name=$name size=10 MAXLENGTH=10 value=0000-00-00><br><br>n\";
  142.  break; 
  143.  
  144.  case &#092;"datetime\":
  145. echo &#092;"<b>\".$name.\":</b><br>n\";
  146. echo &#092;"<input type=text name=$name size=19 MAXLENGTH=19 value=0000-00-00 00:00:00><br><br>n\";
  147.  break; 
  148.  
  149.  case &#092;"timestamp\":
  150. for($ts=0;$ts<$len;$ts++) $value .= &#092;"0\";
  151. echo &#092;"<b>\".$name.\":</b><br>n\";
  152. echo &#092;"<input type=text name=$name size=$len MAXLENGTH=$len value=$value><br><br>n\";
  153.  break; 
  154.  
  155.  case &#092;"time\":
  156. echo &#092;"<b>\".$name.\":</b><br>n\";
  157. echo &#092;"<input type=text name=$name size=8 MAXLENGTH=8 value=00:00:00><br><br>n\";
  158.  break; 
  159.  
  160.  case &#092;"year\":
  161. echo &#092;"<b>\".$name.\":</b><br>n\";
  162. echo &#092;"<input type=text name=$name size=4 MAXLENGTH=4 value=0000><br><br>n\";
  163.  break; 
  164.  
  165.  case &#092;"skip\":
  166.  break;
  167.  
  168. } //end switch
  169. } //end for
  170.  
  171. echo &#092;"</FORM>\";
  172.  
  173. } //end function putForm
  174.  
  175. } //end class
  176.  
  177. $resConn = mysql_connect('localhost','user','pass');
  178. $objForm = new DBtable2form($resConn,'baza','tabela');
  179. $objForm->printForm();
  180. ?>


Klasa niezła, tylko przy pracy na kilku tabelach nie zdaje egzaminu :/ ... Ale mam przynajmniej zarys winksmiley.jpg
dr_bonzo
Porazka na wstepie:
  1. <input type=text name=$name size=19 MAXLENGTH=19 value=0000-00-00 00:00:00><br>

a gdzie cydzuslowy "" questionmark.gif?

Reszty nie sprawdzalem (logiki dzialania)
bigZbig
Ja na chwile obecna robie wszystko recznie. Staram sie tworzyc znormalizowane bazy danych dlatego tworzac jeden formularz zwykle musze "korzystac" z kilku relacji. Pobieram informacje do selectow, zapisuje dane z formularza. Lubie miec porzadek i staram sie dbac o bezpieczenstwo. Tak czy inaczej QuickForm jest dla mnie zbyt duzym uproszczeniem w negatywnym tego slowa znaczeniu.

Staram sie oczywiscie ulatwiac sobie robote. Staram sie pisac w miare uniwersalny kod do wielokrotnego uzytku. Podjalem tez probe napisania klasy, ktora na podstawie definicji tabel i ich wzajemnych relacji bedzie zdolna wygenerowac zapytanie sql dodajace, usuwajace lub zmieniajace wpis. Przy czym wczesniej sprawdzi czy wymagane dane są podane i czy ich format sie zgada. Klasa ma tez zaimplementowany prosty mechanizm antyflodowy uniemozliwiajacy dodanie dwoch identycznych, bezposrednio po sobie nastepujacych wpisow (np. przez odswierzenie strony). Narazie moje rozwiazanie jest malo elastyczne i czasmi sie zastanawiam czy mi ulatwia prace tongue.gif czy raczej wrecz odwrotnie. Szczegolnie upierdliwe jest to definiowanie tabel i wymaganych wartosci. Mam jednak w planach automatyzacje tego procesu poprzez odczytanie definicji tabel zapisanych w formacie sql.
radziel
Cytat(bigZbig @ 2005-06-07 14:48:32)
[...] Podjalem tez probe napisania klasy, ktora na podstawie definicji tabel i ich wzajemnych relacji bedzie zdolna wygenerowac zapytanie sql [...]

A w jaki sposób ustalasz/przechwytujesz relacje między tabelami? "Stywno" je definiujesz czy gdzieś przechowujesz? //Byłbym wdzięczny za kawałek kodu winksmiley.jpg
squid
Cytat(radziel @ 2005-06-07 14:53:56)
Cytat(bigZbig @ 2005-06-07 14:48:32)
[...] Podjalem tez probe napisania klasy, ktora na podstawie definicji tabel i ich wzajemnych relacji bedzie zdolna wygenerowac zapytanie sql [...]

A w jaki sposób ustalasz/przechwytujesz relacje między tabelami? "Stywno" je definiujesz czy gdzieś przechowujesz? //Byłbym wdzięczny za kawałek kodu winksmiley.jpg

latwo jest wykryc relacje w dobrze zaprojektowanej bazie danych np. poprzez istnienie takich samych nazw kolumn w roznych tabelach (w projektowanych przezemnie bazach dancych najczesciej klucze obce maja ta sama nazwe co w tabeli pierwotnej). Nieco trudniej bylo by wykryc jakie typu jest to relacja 1:n czy 1:1 ale nie wiem czy to akurat byloby istotne
bigZbig
Ja tez przyjmuje podobna zasadę co do nazewnictwa ale nie zawsze to sie sprawdza. Podam przyklad.

Kod
PRACOWNIK
-----
#id_pracownik
imie
nazwisko
id_szef

// gdzie id_sze jest kluczem obcym tabeli PRACOWNIK
// id_szef jest tak naprawde identyfikatorem innego pracownika
// mowiac inaczej kazdy jest pracownikiem, ale niektorzy sa tez szefami dla innych
NuLL
Ja też deinuje na sztywno tyleże robie to inaczej
Kod
pracownicy : pracownik_id | nazwa
szefowie : szef_id | nazwa
polaczenia: pracownik | szef

Pierwsze pole w tabelach autoicrementowanych zawiera po podkresleniu id natomiast w tabelach gdzie sa jakies odowlania tego id juz nie. Roziwązuje to mi problemy przy zapytaniach zożonych np. z JOIN'ami smile.gif
I całą masę innych winksmiley.jpg
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-2024 Invision Power Services, Inc.