PhpDay 2010 – 13 -15 maggio – Corropoli - Italy Form refactoring Il viaggio dei vecchi form verso il XXI secolo Manuel “Ke...
Form famosi
 
Subscription form Form da refattorizzare
 
Code: 546 line of code <?php include(&quot;common.php&quot;); require(&quot;header_html.php&quot;); $print_form = true; if...
Recipe <ul><li>Functional and unit test
AntiPattern “Reinvent the wheel”
AntiPattern “Spaghetti Code”
Pattern “Facade”
Pattern “MVC”
Small step </li></ul>
Test gabbia
AntiPattern: “Reinvent the wheel” ruota
AntiPattern: “Spaghetti code” spaghetti
Facade design pattern Wrap a complicated subsystem with a simpler interface.
Facade design pattern class Registration { public static function main() { … } }
MVC architectural pattern Original code MODEL VIEW CONTROLLER Registration RegistrationUser RegitrationForm (validators) R...
View Spostare la vista in un altro file Sostituire “echo” e “print” con assegnazione di variabili e stamparle nella vista
View if ($print_form) { ?> <form action=&quot;<?php echo $_SERVER[... ... ... </form> <?php } require(&quot;footer_html.ph...
Test kea@carminio selenium-tests $   phpunit TestSuite.php PHPUnit 3.4.3 by Sebastian Bergmann. ........ Time: 58 seconds,...
View echo &quot;A database error occurred in processing your submission.&quot;.mysql_error(); $db_error = mysql_error(); <...
Model Estraiamo tutto ciò che riguarda la rappresentazione della registrazione su database NO SQL nel controller
Model: store data $sql = &quot;INSERT INTO registered_user (name, surname, ...,  professione) VALUES ('$name', '$surname',...
Model: store data class RegisteredUser { public static function newFromArray(array $fields) { $sql = &quot;INSERT INTO reg...
Model: store data $fields = array('name' => $name, …  => …, 'professione' => $professione); try { RegisteredUser::newFromA...
Test kea@carminio selenium-tests $   phpunit TestSuite.php PHPUnit 3.4.3 by Sebastian Bergmann. ........ Time: 58 seconds,...
Model $sql = &quot;SELECT COUNT(*) FROM registered_user WHERE email = '$email' &quot;; $result = mysql_query($sql); if (!$...
Model public static function findByEmail($value) { $result = mysql_query( &quot;SELECT * FROM regitestered_user   WHERE em...
Model try { $user = RegisteredUser::findByEmail($email); if (!is_null($user)) { error(&quot;Un utente esiste già con l'ema...
Test kea@carminio selenium-tests $   phpunit TestSuite.php PHPUnit 3.4.3 by Sebastian Bergmann. ........ Time: 58 seconds,...
Model Iteriamo fino a far scomparire dal controller tutto il codice SQL e riferimenti diretti al DB (mysql_*, pg_*, PDO*, ...
Controller: 128 lines left
Validators $name = $_POST['name']; if (empty($name)) { error(&quot;Il campo nome è obbligatorio&quot;); } if (strlen($name...
Valdators class RegitrationForm { public function bind($values) { } }
Validators public function bind($values) { $errors = array(); if (empty($values['name'])) { $errors[] = &quot;Il campo nom...
Test kea@carminio selenium-tests $   phpunit TestSuite.php PHPUnit 3.4.3 by Sebastian Bergmann. ........ Time: 58 seconds,...
Anti if campaign if
sfValidators sfValidatorString sfValidatorRegex sfValidatorEmail sfValidatorUrl sfValidatorInteger sfValidatorNumber sfVal...
sfValidators $nameValidator = new sfValidatorString( array('required' => true, 'max_length' => 50, 'min_length' => 2), arr...
sfValidators try { $name = $nameValidator->clean($name); } catch (sfValidatorError $e) { $error = $e->getMessage(); $is_va...
sfValidators class RegistrationForm { private $validators = array(); public function configure() { $this->validators['nome...
sfValidators public function bind($values) { $this->is_valid = true; $this->errors = array(); foreach ($this->validators a...
Test kea@carminio selenium-tests $   phpunit TestSuite.php PHPUnit 3.4.3 by Sebastian Bergmann. ........ Time: 58 seconds,...
View: 456 lines left 456  36
sfWidgets sfWidgetFormChoice sfWidgetFormDate sfWidgetFormDateRange sfWidgetFormDateTime sfWidgetFormDoctrineChoice sfWidg...
sfWidgets $gender = array('M' => 'M', 'F' => 'F'); $years = range(1900, 2002); $this->widgets = array( 'name' => new sfWid...
sfWidget <?php echo $nameWidget ?> <input type=”text” value=”default value” name=”form_name[name]” id=”form_name_name” />
sfWidget <?php echo $nameWidget->renderRow() ?> <tr> <td> <label for=”form_name_name”>Label</label> <input … /> </td> </tr>
sfWidget: errors <?php echo $nameWidget->renderError(); ?> <ul class=&quot;error_list&quot;> <li>Name: Required.</li> </ul>
sfForm class RegistrationForm  extends sfForm { private $validators = array(); p rivate $widgets = array(); public functio...
View: 456 => 36 <form action=&quot;<?php echo $_SERVER['PHP_SELF']; ?>&quot; method=&quot;post&quot;> <table> <?php echo $...
Upcoming SlideShare
Loading in...5
×

Form refactoring

1,446

Published on

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,446
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
43
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • Ingabbiare le applicazioni legacy con test funzionali (Selenium IDE + phpUnit). Ogni passaggio dal funzionale all&apos;OOP scrivere unit test.
  • Transcript of "Form refactoring"

    1. 1. PhpDay 2010 – 13 -15 maggio – Corropoli - Italy Form refactoring Il viaggio dei vecchi form verso il XXI secolo Manuel “Kea” Baldassarri
    2. 2. Form famosi
    3. 4. Subscription form Form da refattorizzare
    4. 6. Code: 546 line of code <?php include(&quot;common.php&quot;); require(&quot;header_html.php&quot;); $print_form = true; if (isset($_POST['submitok'])) { $name = $_POST['name']; if (empty($name)) { error(&quot;Il campo nome è obbligatorio&quot;); } if (strlen($name) < 2 && strlen($name) > 50) { error(&quot;Il campo nome non è valido&quot;); } $surname = ucwords($_POST['surname']); if (!empty($name) && (strlen($surname) < 2) && strlen($surname) > 50) { error(&quot;Il campo cognome non è valido&quot;); } $sesso = $_POST['sesso']; if (!empty($sesso) && $sesso != 'M' && $sesso != 'F') { error(&quot;Il campo sesso non è valido&quot;); } $valid_mobile = true; $mobile = $_POST['mobile']; if (!empty($mobile) && !is_numeric($mobile)) { error(&quot;Il campo cellulare non è valido&quot;); $valid_mobile = false; } $da = $_POST['da']; if ($da != 'sito' && $da != 'fuoridalsito') { error(&quot;Da dove sei arrivato&quot;); } $valid_email = true; $email = $_POST['email']; if (($email != '') && !preg_match(&quot;/^([a-zA-Z0-9])+([a-zA-Z0-9._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9._-]+)+$/&quot;, $email)) { error(&quot;Il campo email non è valido&quot;); $valid_email = false; } $data_nasc = ($_POST['data_nasc']=='--')?0:$_POST['data_nasc']; $mese_nasc = ($_POST['mese_nasc']=='--')?0:$_POST['mese_nasc']; $anno_nasc = ($_POST['anno_nasc']=='--')?0:$_POST['anno_nasc']; $address = $_POST['address']; $cap = $_POST['cap']; $city = $_POST['city']; $provincia = $_POST['provincia']; $professione = $_POST['professione']; if (empty($email) && empty($mobile)) { error(&quot;Devi inserire il tuo indirizzo email o il numero del cellulare per procedere.&quot;); } dbConnect('phpday2010'); if (($email != '') && ($valid_email == true)) { $sql = &quot;SELECT COUNT(*) FROM subscribers WHERE email = '$email' &quot;; $result = mysql_query($sql); if (!$result) { error(&quot;A database error occurred.&quot;); } elseif (mysql_result($result, 0) > 0) { error(&quot;Un utente esiste già con l'email che hai inserito!&quot;); } } if (($mobile != '') && ($valid_mobile == true)) { $sql = &quot;SELECT COUNT(*) FROM subscribers WHERE mobile = '$mobile' &quot;; $result = mysql_query($sql); if (!$result) { error(&quot;A database error occurred.&quot;); } elseif (mysql_result($result, 0) > 0) { error(&quot;Un utente esiste già con il cellulare che hai inserito!&quot;); } } if (count($errors) == 0) { $data = date(&quot;Y-m-d H:i:s&quot;); $sql = &quot;INSERT INTO subscribers (name, surname, sesso, mobile, dove, email, quando, data_nasc, mese_nasc, anno_nasc, address, cap, city, provincia, professione) VALUES ('$name','$surname','$sesso','$mobile', '$dove','$email','$data','$data_nasc','$mese_nasc','$anno_nasc', '$address','$cap','$city','$provincia', '$professione')&quot;; if (!mysql_query($sql)) { echo &quot;A database error occurred in processing your submission.&quot;.mysql_error(); } else { if ($email == '') { $email = '***' . $mobile; } else { $msg = &quot;Ciao $name, ti sei appena registrato sul sito TestRefactoring.&quot;; mail($email, 'Registrazione sito TestRefactoring', $msg, 'From: info@TestRefactoring.it'); } ?> <p>Ok! Sei iscritto con l'email <?php echo $email?>!</p> <?php $print_form = false; } } else { echo &quot;<ul>&quot;; foreach ($errors as $error) { echo &quot;<li>$error</li>&quot;; } echo &quot;</ul>&quot;; } } if ($print_form) { ?> <form action=&quot;<?php echo $_SERVER['PHP_SELF']; ?>&quot; method=&quot;post&quot;> <table> <tr> <td><label>Nome (*)</label></td> <td><input id=&quot;name&quot; size=&quot;30&quot; name=&quot;name&quot; /></td> </tr> <tr> <td><label>Cognome</label></td> <td><input id=&quot;surname&quot; size=&quot;30&quot; name=&quot;surname&quot; /> <font color=&quot;#ff6600&quot;>&nbsp;</font></td> </tr> <tr> <td><label>Maschio/Femmina</label></td> <td> <input type=&quot;radio&quot; value=&quot;M&quot; name=&quot;sesso&quot; /> Maschio <input type=&quot;radio&quot; value=&quot;F&quot; name=&quot;sesso&quot; /> Femmina </td> </tr> <tr> <td><label>Data di nascita</label></td> <td> <select name=&quot;data_nasc&quot; id=&quot;data_nasc&quot;> <option selected=&quot;selected&quot;>--</option> <option value=&quot;01&quot;>01</option> <option value=&quot;02&quot;>02</option> <option value=&quot;03&quot;>03</option> <option value=&quot;04&quot;>04</option> <option value=&quot;05&quot;>05</option> <option value=&quot;06&quot;>06</option> <option value=&quot;07&quot;>07</option> <option value=&quot;08&quot;>08</option> <option value=&quot;09&quot;>09</option> <option value=&quot;10&quot;>10</option> <option value=&quot;11&quot;>11</option> <option value=&quot;12&quot;>12</option> <option value=&quot;13&quot;>13</option> <option value=&quot;14&quot;>14</option> <option value=&quot;15&quot;>15</option> <option value=&quot;16&quot;>16</option> <option value=&quot;17&quot;>17</option> <option value=&quot;18&quot;>18</option> <option value=&quot;19&quot;>19</option> <option value=&quot;20&quot;>20</option> <option value=&quot;21&quot;>21</option> <option value=&quot;22&quot;>22</option> <option value=&quot;23&quot;>23</option> <option value=&quot;24&quot;>24</option> <option value=&quot;25&quot;>25</option> <option value=&quot;26&quot;>26</option> <option value=&quot;27&quot;>27</option> <option value=&quot;28&quot;>28</option> <option value=&quot;29&quot;>29</option> <option value=&quot;30&quot;>30</option> <option value=&quot;31&quot;>31</option> </select> &nbsp; <select name=&quot;mese_nasc&quot; id=&quot;mese_nasc&quot;> <option selected=&quot;selected&quot;>-- </option> <option value=&quot;1&quot;>Gennaio </option> <option value=&quot;2&quot;>Febbraio </option> <option value=&quot;3&quot;>Marzo </option> <option value=&quot;4&quot;>Aprile </option> <option value=&quot;5&quot;>Maggio </option> <option value=&quot;6&quot;>Giugno </option> <option value=&quot;7&quot;>Luglio </option> <option value=&quot;8&quot;>Agosto </option> <option value=&quot;9&quot;>Settembre </option> <option value=&quot;10&quot;>Ottobre </option> <option value=&quot;11&quot;>Novembre </option> <option value=&quot;12&quot;>Dicembre</option> </select> &nbsp; <select name=&quot;anno_nasc&quot; id=&quot;anno_nasc&quot;> <option value=&quot;1900&quot;>1900</option> <option value=&quot;1901&quot;>1901</option> <option value=&quot;1902&quot;>1902</option> <option value=&quot;1903&quot;>1903</option> <option value=&quot;1904&quot;>1904</option> <option value=&quot;1905&quot;>1905</option> <option value=&quot;1906&quot;>1906</option> <option value=&quot;1907&quot;>1907</option> <option value=&quot;1908&quot;>1908</option> <option value=&quot;1909&quot;>1909</option> <option value=&quot;1910&quot;>1910</option> <option value=&quot;1911&quot;>1911</option> <option value=&quot;1912&quot;>1912</option> <option value=&quot;1913&quot;>1913</option> <option value=&quot;1914&quot;>1914</option> <option value=&quot;1915&quot;>1915</option> <option value=&quot;1916&quot;>1916</option> <option value=&quot;1917&quot;>1917</option> <option value=&quot;1918&quot;>1918</option> <option value=&quot;1919&quot;>1919</option> <option value=&quot;1920&quot;>1920</option> <option value=&quot;1921&quot;>1921</option> <option value=&quot;1922&quot;>1922</option> <option value=&quot;1923&quot;>1923</option> <option value=&quot;1924&quot;>1924</option> <option value=&quot;1925&quot;>1925</option> <option value=&quot;1926&quot;>1926</option> <option value=&quot;1927&quot;>1927</option> <option value=&quot;1928&quot;>1928</option> <option value=&quot;1929&quot;>1929</option> <option value=&quot;1930&quot;>1930</option> <option value=&quot;1931&quot;>1931</option> <option value=&quot;1932&quot;>1932</option> <option value=&quot;1933&quot;>1933</option> <option value=&quot;1934&quot;>1934</option> <option value=&quot;1935&quot;>1935</option> <option value=&quot;1936&quot;>1936</option> <option value=&quot;1937&quot;>1937</option> <option value=&quot;1938&quot;>1938</option> <option value=&quot;1939&quot;>1939</option> <option value=&quot;1940&quot;>1940</option> <option value=&quot;1941&quot;>1941</option> <option value=&quot;1942&quot;>1942</option> <option value=&quot;1943&quot;>1943</option> <option value=&quot;1944&quot;>1944</option> <option value=&quot;1945&quot;>1945</option> <option value=&quot;1946&quot;>1946</option> <option value=&quot;1947&quot;>1947</option> <option value=&quot;1948&quot;>1948</option> <option value=&quot;1949&quot;>1949</option> <option value=&quot;1950&quot;>1950</option> <option value=&quot;1951&quot;>1951</option> <option value=&quot;1952&quot;>1952</option> <option value=&quot;1953&quot;>1953</option> <option value=&quot;1954&quot;>1954</option> <option value=&quot;1955&quot;>1955</option> <option value=&quot;1956&quot;>1956</option> <option value=&quot;1957&quot;>1957</option> <option value=&quot;1958&quot;>1958</option> <option value=&quot;1959&quot;>1959</option> <option value=&quot;1960&quot;>1960</option> <option value=&quot;1961&quot;>1961</option> <option value=&quot;1962&quot;>1962</option> <option value=&quot;1963&quot;>1963</option> <option value=&quot;1964&quot;>1964</option> <option value=&quot;1965&quot;>1965</option> <option value=&quot;1966&quot;>1966</option> <option value=&quot;1967&quot;>1967</option> <option value=&quot;1968&quot;>1968</option> <option value=&quot;1969&quot;>1969</option> <option value=&quot;1970&quot;>1970</option> <option value=&quot;1971&quot;>1971</option> <option value=&quot;1972&quot;>1972</option> <option value=&quot;1973&quot;>1973</option> <option selected=&quot;selected&quot;>--</option> <option value=&quot;1974&quot;>1974</option> <option value=&quot;1975&quot;>1975</option> <option value=&quot;1976&quot;>1976</option> <option value=&quot;1977&quot;>1977</option> <option value=&quot;1978&quot;>1978</option> <option value=&quot;1979&quot;>1979</option> <option value=&quot;1980&quot;>1980</option> <option value=&quot;1981&quot;>1981</option> <option value=&quot;1982&quot;>1982</option> <option value=&quot;1983&quot;>1983</option> <option value=&quot;1984&quot;>1984</option> <option value=&quot;1985&quot;>1985</option> <option value=&quot;1986&quot;>1986</option> <option value=&quot;1987&quot;>1987</option> <option value=&quot;1988&quot;>1988</option> <option value=&quot;1989&quot;>1989</option> <option value=&quot;1990&quot;>1990</option> <option value=&quot;1991&quot;>1991</option> <option value=&quot;1992&quot;>1992</option> <option value=&quot;1993&quot;>1993</option> <option value=&quot;1994&quot;>1994</option> <option value=&quot;1995&quot;>1995</option> <option value=&quot;1996&quot;>1996</option> <option value=&quot;1997&quot;>1997</option> <option value=&quot;1998&quot;>1998</option> <option value=&quot;1999&quot;>1999</option> <option value=&quot;2000&quot;>2000</option> <option value=&quot;2001&quot;>2001</option> <option value=&quot;2002&quot;>2002</option> </select> </td> </tr> <tr> <td><label>Indirizzo</label></td> <td><input id=&quot;address&quot; size=&quot;30&quot; name=&quot;address&quot; /></td> </tr> <tr> <td><label>CAP</label></td> <td><input id=&quot;cap&quot; size=&quot;10&quot; name=&quot;cap&quot; /></td> </tr> <tr> <td><label>Localit&agrave;</label></td> <td><input id=&quot;city&quot; size=&quot;30&quot; name=&quot;city&quot; /></td> </tr> <tr> <td><label>Provincia</label></td> <td><select name=&quot;provincia&quot; id=&quot;provincia&quot;> <option value=&quot;&quot;>-- Selezionare -- </option> <option value=&quot;AG&quot;>Agrigento (AG)</option> <option value=&quot;AL&quot;>Alessandria (AL)</option> <option value=&quot;AN&quot;>Ancona (AN)</option> <option value=&quot;AO&quot;>Aosta (AO)</option> <option value=&quot;AP&quot;>Ascoli Piceno (AP)</option> <option value=&quot;AQ&quot;>L'Aquila (AQ)</option> <option value=&quot;AR&quot;>Arezzo (AR)</option> <option value=&quot;AT&quot;>Asti (AT)</option> <option value=&quot;AV&quot;>Avellino (AV)</option> <option value=&quot;BA&quot;>Bari (BA)</option> <option value=&quot;BG&quot;>Bergamo (BG)</option> <option value=&quot;BI&quot;>Biella (BI)</option> <option value=&quot;BL&quot;>Belluno (BL)</option> <option value=&quot;BN&quot;>Benevento (BN)</option> <option value=&quot;BO&quot;>Bologna (BO)</option> <option value=&quot;BR&quot;>Brindisi (BR)</option> <option value=&quot;BS&quot;>Brescia (BS)</option> <option value=&quot;BZ&quot;>Bolzano (BZ)</option> <option value=&quot;CA&quot;>Cagliari (CA)</option> <option value=&quot;CB&quot;>Campobasso (CB)</option> <option value=&quot;CE&quot;>Caserta (CE)</option> <option value=&quot;CH&quot;>Chieti (CH)</option> <option value=&quot;CL&quot;>Caltanissetta (CL)</option> <option value=&quot;CN&quot;>Cuneo (CN)</option> <option value=&quot;CO&quot;>Como (CO)</option> <option value=&quot;CR&quot;>Cremona (CR)</option> <option value=&quot;CS&quot;>Cosenza (CS)</option> <option value=&quot;CT&quot;>Catania (CT)</option> <option value=&quot;CZ&quot;>Catanzaro (CZ)</option> <option value=&quot;EN&quot;>Enna (EN)</option> <option value=&quot;FC&quot;>Forlì-Cesena (FC)</option> <option value=&quot;FE&quot;>Ferrara (FE)</option> <option value=&quot;FG&quot;>Foggia (FG)</option> <option value=&quot;FI&quot;>Firenze (FI)</option> <option value=&quot;FR&quot;>Frosinone (FR)</option> <option value=&quot;GE&quot;>Genova (GE)</option> <option value=&quot;GO&quot;>Gorizia (GO)</option> <option value=&quot;GR&quot;>Grosseto (GR)</option> <option value=&quot;IM&quot;>Imperia (IM)</option> <option value=&quot;IS&quot;>Isernia (IS)</option> <option value=&quot;KR&quot;>Crotone (KR)</option> <option value=&quot;LC&quot;>Lecco (LC)</option> <option value=&quot;LE&quot;>Lecce (LE)</option> <option value=&quot;LI&quot;>Livorno (LI)</option> <option value=&quot;LO&quot;>Lodi (LO)</option> <option value=&quot;LT&quot;>Latina (LT)</option> <option value=&quot;LU&quot;>Lucca (LU)</option> <option value=&quot;MC&quot;>Macerata (MC)</option> <option value=&quot;ME&quot;>Messina (ME)</option> <option value=&quot;MI&quot;>Milano (MI)</option> <option value=&quot;MN&quot;>Mantova (MN)</option> <option value=&quot;MO&quot;>Modena (MO)</option> <option value=&quot;MS&quot;>Massa-Carrara (MS)</option> <option value=&quot;MT&quot;>Matera (MT)</option> <option value=&quot;NA&quot;>Napoli (NA)</option> <option value=&quot;NO&quot;>Novara (NO)</option> <option value=&quot;NU&quot;>Nuoro (NU)</option> <option value=&quot;OR&quot;>Oristano (OR)</option> <option value=&quot;PA&quot;>Palermo (PA)</option> <option value=&quot;PC&quot;>Piacenza (PC)</option> <option value=&quot;PD&quot;>Padova (PD)</option> <option value=&quot;PE&quot;>Pescara (PE)</option> <option value=&quot;PG&quot;>Perugia (PG)</option> <option value=&quot;PI&quot;>Pisa (PI)</option> <option value=&quot;PN&quot;>Pordenone (PN)</option> <option value=&quot;PO&quot;>Prato (PO)</option> <option value=&quot;PR&quot;>Parma (PR)</option> <option value=&quot;PT&quot;>Pistoia (PT)</option> <option value=&quot;PU&quot;>Pesaro e Urbino (PU)</option> <option value=&quot;PV&quot;>Pavia (PV)</option> <option value=&quot;PZ&quot;>Potenza (PZ)</option> <option value=&quot;RA&quot;>Ravenna (RA)</option> <option value=&quot;RC&quot;>Reggio Calabria (RC)</option> <option value=&quot;RE&quot;>Reggio Emilia (RE)</option> <option value=&quot;RG&quot;>Ragusa (RG)</option> <option value=&quot;RI&quot;>Rieti (RI)</option> <option value=&quot;RM&quot;>Roma (RM)</option> <option value=&quot;RN&quot;>Rimini (RN)</option> <option value=&quot;RO&quot;>Rovigo (RO)</option> <option value=&quot;SA&quot;>Salerno (SA)</option> <option value=&quot;SI&quot;>Siena (SI)</option> <option value=&quot;SO&quot;>Sondrio (SO)</option> <option value=&quot;SP&quot;>La Spezia (SP)</option> <option value=&quot;SR&quot;>Siracusa (SR)</option> <option value=&quot;SS&quot;>Sassari (SS)</option> <option value=&quot;SV&quot;>Savona (SV)</option> <option value=&quot;TA&quot;>Taranto (TA)</option> <option value=&quot;TE&quot;>Teramo (TE)</option> <option value=&quot;TN&quot;>Trento (TN)</option> <option value=&quot;TO&quot;>Torino (TO)</option> <option value=&quot;TP&quot;>Trapani (TP)</option> <option value=&quot;TR&quot;>Terni (TR)</option> <option value=&quot;TS&quot;>Trieste (TS)</option> <option value=&quot;TV&quot;>Treviso (TV)</option> <option value=&quot;UD&quot;>Udine (UD)</option> <option value=&quot;VA&quot;>Varese (VA)</option> <option value=&quot;VB&quot;>Verbano-Cusio-Ossola (VB)</option> <option value=&quot;VC&quot;>Vercelli (VC)</option> <option value=&quot;VE&quot;>Venezia (VE)</option> <option value=&quot;VI&quot;>Vicenza (VI)</option> <option value=&quot;VR&quot;>Verona (VR)</option> <option value=&quot;VT&quot;>Viterbo (VT)</option> <option value=&quot;VV&quot;>Vibo Valentia (VV)</option> <option value=&quot;EE&quot;>--Estero--</option> </select></td> </tr> <tr> <td><label>Cellulare (**)</label></td> <td>+39 <input id=&quot;mobile&quot; maxlength=&quot;11&quot; size=&quot;11&quot; name=&quot;mobile&quot; /> </td> </tr> <tr> <td><label>Email (**)</label></td> <td><input name=&quot;email&quot; id=&quot;email&quot; value=&quot;<?php echo $email ?>&quot; size=&quot;30&quot; /></td> </tr> <tr> <td><label>Professione</label></td> <td><table cellspacing=&quot;2&quot; cellpadding=&quot;2&quot; border=&quot;0&quot;> <tbody> <tr> <td><input type=&quot;radio&quot; value=&quot;altro&quot; name=&quot;professione&quot; /></td> <td>altro</td> <td><input type=&quot;radio&quot; value=&quot;architetto&quot; name=&quot;professione&quot; /></td> <td>architetto</td> </tr> <tr> <td><input type=&quot;radio&quot; value=&quot;artigiano&quot; name=&quot;professione&quot; /></td> <td>artigiano</td> <td><input type=&quot;radio&quot; value=&quot;artista&quot; name=&quot;professione&quot; /></td> <td>artista</td> </tr> <tr> <td><input type=&quot;radio&quot; value=&quot;avvocato&quot; name=&quot;professione&quot; /></td> <td>avvocato</td> <td><input type=&quot;radio&quot; value=&quot;bancario&quot; name=&quot;professione&quot; /></td> <td>bancario</td> </tr> <tr> <td><input type=&quot;radio&quot; value=&quot;commercialista&quot; name=&quot;professione&quot; /></td> <td>commercialista</td> <td><input type=&quot;radio&quot; value=&quot;commerciante&quot; name=&quot;professione&quot; /></td> <td>commerciante</td> </tr> <tr> <td><input type=&quot;radio&quot; value=&quot;dirigente&quot; name=&quot;professione&quot; /></td> <td>dirigente</td> <td><input type=&quot;radio&quot; value=&quot;disoccupato&quot; name=&quot;professione&quot; /></td> <td>disoccupato</td> </tr> <tr> <td><input type=&quot;radio&quot; value=&quot;impiegato&quot; name=&quot;professione&quot; /></td> <td>impiegato</td> <td><input type=&quot;radio&quot; value=&quot;imprenditore&quot; name=&quot;professione&quot; /></td> <td>imprenditore</td> </tr> <tr> <td><input type=&quot;radio&quot; value=&quot;ingegnere&quot; name=&quot;professione&quot; /></td> <td>ingegnere</td> <td><input type=&quot;radio&quot; value=&quot;insegnante/docente&quot; name=&quot;professione&quot; /></td> <td>insegnante/docente</td> </tr> <tr> <td><input type=&quot;radio&quot; value=&quot;libero professionista&quot; name=&quot;professione&quot; /></td> <td>libero professionista</td> <td><input type=&quot;radio&quot; value=&quot;medico&quot; name=&quot;professione&quot; /></td> <td>medico</td> </tr> <tr> <td><input type=&quot;radio&quot; value=&quot;non te lo dico&quot; name=&quot;professione&quot; /></td> <td>non te lo dico</td> <td><input type=&quot;radio&quot; value=&quot;notaio&quot; name=&quot;professione&quot; /></td> <td>notaio</td> </tr> <tr> <td><input type=&quot;radio&quot; value=&quot;operaio&quot; name=&quot;professione&quot; /></td> <td>operaio</td> <td><input type=&quot;radio&quot; value=&quot;pensionato&quot; name=&quot;professione&quot; /></td> <td>pensionato</td> </tr> <tr> <td><input type=&quot;radio&quot; value=&quot;programmatore&quot; name=&quot;professione&quot; /></td> <td>programmatore</td> <td><input type=&quot;radio&quot; value=&quot;quadro&quot; name=&quot;professione&quot; /></td> <td>quadro</td> </tr> <tr> <td><input type=&quot;radio&quot; value=&quot;responsabile it&quot; name=&quot;professione&quot; /></td> <td>responsabile it</td> <td><input type=&quot;radio&quot; value=&quot;studente&quot; name=&quot;professione&quot; /></td> <td>studente</td> </tr> </tbody> </table> </td> </tr> <tr> <td colspan=&quot;2&quot;> <strong>(*)</strong> Campi obbligatori<br /> <strong>(**)</strong> Il telefono o l'email sono obbligatorie<br /> <input type=&quot;submit&quot; name=&quot;submitok&quot; value=&quot;Invia&quot; /> </td> </tr> </table> <input name=&quot;da&quot; type=&quot;hidden&quot; id=&quot;da&quot; value=&quot;sito&quot; /> </form> <?php } require(&quot;footer_html.php&quot;); ?>
    5. 7. Recipe <ul><li>Functional and unit test
    6. 8. AntiPattern “Reinvent the wheel”
    7. 9. AntiPattern “Spaghetti Code”
    8. 10. Pattern “Facade”
    9. 11. Pattern “MVC”
    10. 12. Small step </li></ul>
    11. 13. Test gabbia
    12. 14. AntiPattern: “Reinvent the wheel” ruota
    13. 15. AntiPattern: “Spaghetti code” spaghetti
    14. 16. Facade design pattern Wrap a complicated subsystem with a simpler interface.
    15. 17. Facade design pattern class Registration { public static function main() { … } }
    16. 18. MVC architectural pattern Original code MODEL VIEW CONTROLLER Registration RegistrationUser RegitrationForm (validators) RegistrationView RegistrationForm (widgets)
    17. 19. View Spostare la vista in un altro file Sostituire “echo” e “print” con assegnazione di variabili e stamparle nella vista
    18. 20. View if ($print_form) { ?> <form action=&quot;<?php echo $_SERVER[... ... ... </form> <?php } require(&quot;footer_html.php&quot;); ?> include &quot;registration_view.php&quot;;
    19. 21. Test kea@carminio selenium-tests $ phpunit TestSuite.php PHPUnit 3.4.3 by Sebastian Bergmann. ........ Time: 58 seconds, Memory: 9.58Mb Ok (8 tests, 21 assertions) Ok (8 tests, 21 assertions)
    20. 22. View echo &quot;A database error occurred in processing your submission.&quot;.mysql_error(); $db_error = mysql_error(); <?php if (!empty($db_error)) : ?> A database error occurred in processing your submission. <?php echo $db_error ?> <?php endif ?>
    21. 23. Model Estraiamo tutto ciò che riguarda la rappresentazione della registrazione su database NO SQL nel controller
    22. 24. Model: store data $sql = &quot;INSERT INTO registered_user (name, surname, ..., professione) VALUES ('$name', '$surname', ...,'$professione')&quot;; if (!mysql_query($sql)) { $db_error = mysql_error(); }
    23. 25. Model: store data class RegisteredUser { public static function newFromArray(array $fields) { $sql = &quot;INSERT INTO registered_user (name, surname, ..., professione) VALUES ('{$fields['name']}', ... '{$fields['professione']}')&quot;; if (!mysql_query($sql)) { throw new Exception(mysql_error()); } } }
    24. 26. Model: store data $fields = array('name' => $name, … => …, 'professione' => $professione); try { RegisteredUser::newFromArray($fields); } catch (Exception $e) { $db_error = $e->getMessage(); }
    25. 27. Test kea@carminio selenium-tests $ phpunit TestSuite.php PHPUnit 3.4.3 by Sebastian Bergmann. ........ Time: 58 seconds, Memory: 9.58Mb Ok (8 tests, 21 assertions) Ok (8 tests, 21 assertions)
    26. 28. Model $sql = &quot;SELECT COUNT(*) FROM registered_user WHERE email = '$email' &quot;; $result = mysql_query($sql); if (!$result) { error(&quot;A database error occurred.&quot;); } elseif (mysql_result($result, 0) > 0) { error(&quot;Un utente esiste già con l'email che hai inserito!&quot;); }
    27. 29. Model public static function findByEmail($value) { $result = mysql_query( &quot;SELECT * FROM regitestered_user WHERE email = '$value'&quot;); if (!$result) { throw new Exception(mysql_error()); } if (mysql_num_rows($result) == 0) { return null; } return mysql_fetch_assoc($result); }
    28. 30. Model try { $user = RegisteredUser::findByEmail($email); if (!is_null($user)) { error(&quot;Un utente esiste già con l'email che hai inserito!&quot;); } } catch (Exception $e) { error(&quot;A database error occurred.&quot;); }
    29. 31. Test kea@carminio selenium-tests $ phpunit TestSuite.php PHPUnit 3.4.3 by Sebastian Bergmann. ........ Time: 58 seconds, Memory: 9.58Mb Ok (8 tests, 21 assertions) Ok (8 tests, 21 assertions)
    30. 32. Model Iteriamo fino a far scomparire dal controller tutto il codice SQL e riferimenti diretti al DB (mysql_*, pg_*, PDO*, ...)
    31. 33. Controller: 128 lines left
    32. 34. Validators $name = $_POST['name']; if (empty($name)) { error(&quot;Il campo nome è obbligatorio&quot;); } if (strlen($name) < 2 && strlen($name) > 50) { error(&quot;Il campo nome non è valido&quot;); }
    33. 35. Valdators class RegitrationForm { public function bind($values) { } }
    34. 36. Validators public function bind($values) { $errors = array(); if (empty($values['name'])) { $errors[] = &quot;Il campo nome è obbligatorio&quot;; } if (strlen($name) < 2 && strlen($name) > 50) { $errors[] = &quot;Il campo nome non è valido&quot;; } . . . return $errors; }
    35. 37. Test kea@carminio selenium-tests $ phpunit TestSuite.php PHPUnit 3.4.3 by Sebastian Bergmann. ........ Time: 58 seconds, Memory: 9.58Mb Ok (8 tests, 21 assertions) Ok (8 tests, 21 assertions)
    36. 38. Anti if campaign if
    37. 39. sfValidators sfValidatorString sfValidatorRegex sfValidatorEmail sfValidatorUrl sfValidatorInteger sfValidatorNumber sfValidatorBoolean sfValidatorChoice sfValidatorPass sfValidatorCallback sfValidatorDate sfValidatorTime sfValidatorDateTime sfValidatorDateRange sfValidatorFile sfValidatorAnd sfValidatorOr
    38. 40. sfValidators $nameValidator = new sfValidatorString( array('required' => true, 'max_length' => 50, 'min_length' => 2), array('required' => 'Il campo nome è obbligatorio', 'invalid' => 'Il campo nome non è valido')); $emailValidator = new sfValidatorEmail( array('required' => false), array('invalid' => 'Il campo email non è valido')),
    39. 41. sfValidators try { $name = $nameValidator->clean($name); } catch (sfValidatorError $e) { $error = $e->getMessage(); $is_valid = false; }
    40. 42. sfValidators class RegistrationForm { private $validators = array(); public function configure() { $this->validators['nome'] = sfValidatorString(...); ... } }
    41. 43. sfValidators public function bind($values) { $this->is_valid = true; $this->errors = array(); foreach ($this->validators as $name => $validator) { try { $this->values[$name] = $validator-> clean($values[$name]); } catch (sfValidatorError $e) { $this->values[$name] = $values[$name]; $this->addError($e->getMessage()); $this->is_valid = false; } } }
    42. 44. Test kea@carminio selenium-tests $ phpunit TestSuite.php PHPUnit 3.4.3 by Sebastian Bergmann. ........ Time: 58 seconds, Memory: 9.58Mb Ok (8 tests, 21 assertions) Ok (8 tests, 21 assertions)
    43. 45. View: 456 lines left 456 36
    44. 46. sfWidgets sfWidgetFormChoice sfWidgetFormDate sfWidgetFormDateRange sfWidgetFormDateTime sfWidgetFormDoctrineChoice sfWidgetFormFilterInput sfWidgetFormFilterDate sfWidgetFormI18nChoiceCountry sfWidgetFormI18nChoiceLanguage sfWidgetFormI18nChoiceCurrency sfWidgetFormI18nChoiceTimezone sfWidgetFormI18nDate sfWidgetFormI18nDateTime sfWidgetFormI18nTime sfWidgetFormInput sfWidgetFormInputCheckbox sfWidgetFormInputFile sfWidgetFormInputFileEditable sfWidgetFormInputHidden sfWidgetFormInputPassword sfWidgetFormJQueryAutocompleter sfWidgetFormJQueryDate sfWidgetFormPropelChoice sfWidgetFormReCaptcha sfWidgetFormSchema sfWidgetFormSchemaDecorator sfWidgetFormSelect sfWidgetFormSelectDoubleList sfWidgetFormSelectMany sfWidgetFormSelectCheckbox sfWidgetFormSelectRadio sfWidgetFormTextarea sfWidgetFormTextareaTinyMCE sfWidgetFormTime
    45. 47. sfWidgets $gender = array('M' => 'M', 'F' => 'F'); $years = range(1900, 2002); $this->widgets = array( 'name' => new sfWidgetFormInputText(), 'sesso' => new sfWidgetFormChoice( array('choices' => self::$gender, 'expanded' => true)), 'da' => new sfWidgetFormInputHidden( array('default' => 'site')), 'anno_nasc' => new sfWidgetFormChoice( array('choices' => array_combine($years, $years))), ... );
    46. 48. sfWidget <?php echo $nameWidget ?> <input type=”text” value=”default value” name=”form_name[name]” id=”form_name_name” />
    47. 49. sfWidget <?php echo $nameWidget->renderRow() ?> <tr> <td> <label for=”form_name_name”>Label</label> <input … /> </td> </tr>
    48. 50. sfWidget: errors <?php echo $nameWidget->renderError(); ?> <ul class=&quot;error_list&quot;> <li>Name: Required.</li> </ul>
    49. 51. sfForm class RegistrationForm extends sfForm { private $validators = array(); p rivate $widgets = array(); public function configure() { $this->setWidgets(array( 'name' => sfWidgetFormInputText(), … $this->setValidators(array( 'name' => sfValidatorString(...); … } }
    50. 52. View: 456 => 36 <form action=&quot;<?php echo $_SERVER['PHP_SELF']; ?>&quot; method=&quot;post&quot;> <table> <?php echo $registration_form ?> <tr> <td colspan=&quot;2&quot;> <input type=&quot;submit&quot; name=&quot;submitok&quot; value=&quot;Invia&quot; /> </td> </tr> </table> </form>
    51. 53. Controller: 25 line left $form = new RegistrationForm(); if (isset($_POST['submitok'])) { $form-> bind ($_POST['registration']); $errors = $form-> getErrors (); if ($registration_form-> isValid ()) { $fields = $registration_form-> getValues (); $user = RegisteredUser :: newFromArray ($fields); try { $user-> save (); $user->sendRegistrationMail(); } catch (Exception $e) { $db_error = $e->message; } } }
    52. 54. Extract sfForm subframework from symfony Install symfony: <ul><li>PEAR package
    53. 55. Download sandbox (.tgz, .zip)
    54. 56. SVN checkout </li></ul>Copy from SF_INSTALL_DIR/lib <ul><li>/form
    55. 57. /validator
    56. 58. /widget
    57. 59. /util/sfCallable.class.php </li></ul>
    58. 60. Results registration.php (545) registrationForm.class.php (105) registrationUser.class.php (95) registration.class.php (33) registration.php (1) registrationView.php (36) Tot (270)
    59. 61. Questions ?
    60. 62. Credits Me [email_address] http://keasoft.it/blog Flickr: kea42 Twitter: k3a Anti if campaign http://www.antiifcampaign.com/ Foto http://www.flickr.com/photos/nikonand/3972068272/ http://www.flickr.com/photos/easyclick/4287695160/ http://www.flickr.com/photos/mrfink/3633775567/ http://cillitbang.co.uk Le altre sono mie ;)
    1. ¿Le ha llamado la atención una diapositiva en particular?

      Recortar diapositivas es una manera útil de recopilar información importante para consultarla más tarde.

    ×