Page 1
Combattere contro il codice del “cugino”?
Symfony può aiutarti a sopravvivere...
Scenario: Una grande azienda ha un sito internet.
Il sito internet contiene un’applicazione interfacciata al
gestionale aziendale che le permette di raccogliere gli ordini dai
suoi clienti via web.
L’azienda vuole aggiungere nuove funzionalità al sito.
Scenario tipico giusto?
Ma: Il sito internet è stato fatto tanto tempo fa, dal cugino del
figlio del proprietario senza l’ausilio di framework, il
gestionale aziendale conta 1600 tabelle e l'applicativo accede
direttamente al suo database.
Beh! Anche questo è tipico, purtroppo. La nostra soluzione?
Inglobiamo il vecchio sito in Symfony 2, facciamoli convivere per
un po e lasciamo che il nuovo contamini virtuosamente il vecchio,
mangiandoselo un po' per volta fino a sostituirlo completamente.
Dopo alcuni mesi di lavoro credo di poter condividere esperienza,
trucchi e tecniche per far si che questa bella metafora diventi
realtà.
Page 2
@danielsan80
[email protected]
danilosanchi.net
Page 3
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 4
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 6
Il progetto
PHP
Linux
MySQL
Apache
HTM
LJavasc
rip
t
CSS
plugins
macchina fisica
rete aziendale
em
ail
v 1.5 site
v 1.0 site
code contents
database
database
gestionale
filespdf images
bash
MVC
OOP
Framework
Business Logic
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 7
Il progetto
PHP
Linux
MySQL
Apache
HTM
LJavasc
rip
t
CSS
plugins
macchina fisica
rete aziendale
em
ail
v 1.5 site
v 1.0 site
code contents
database
database
gestionale
filespdf images
bash
MVC
Framework
Business Logic
OOP
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 8
Il progetto
PHP
Linux
MySQL
Apache
HTM
LJavasc
rip
t
CSS
plugins
macchina fisica
rete aziendale
em
ail
v 1.5 site
v 1.0 site
code contents
database
database
gestionale
filespdf images
bashBusiness Logic
rete del cliente
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 9
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 10
Il team
Andrearesponsabile sito
Giordanoamministratore
Luigiresponsabile gestionale
Giulianosistemista
DaniloWeb Developer
FabioCoach
Oddotitolare
Alessandroproject manager
DarioWeb Developer
Rafftitolare
Lunacontent & copy
cliente
comunicazione
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
fornitore del
gestionale
Page 11
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 12
La messa in sicurezza
Obbiettivi preliminari:
❖ codice versionabile
❖ progetto installabile su una macchina di sviluppo
❖ processo di deploy automatico
Mezzi:
❖ Griglia di test con PHPUnit e Selenium
❖ Git e Bitbucket
❖ Composer per l’autoloader
❖ Capistrano per il deploy
❖ Macchina virtuale per tests, preview e CI
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 13
La messa in sicurezza
PHP
Linux
MySQL
HTM
LJavasc
rip
t
CSS
plugins
macchina fisica
Apache
rete aziendale
em
ail
v 1.5 site
v 1.0 site
contents
code
database
database
gestionale
filespdf images
bashBusiness Logic
rete del cliente
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 14
La messa in sicurezza
PHP
Linux
MySQL
HTM
LJavasc
rip
t
CSS
plugins
Apache
macchina fisica
rete aziendale
em
ail
v 1.5 site
v 1.0 site
contents
code
database
database
gestionale
filespdf images
bashBusiness Logic
rete del cliente
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 15
La messa in sicurezza
PHP
Linux
MySQL
HTM
LJavasc
rip
t
CSS
plugins
macchina fisica
Apache
rete aziendale
em
ail
v 1.5 site
v 1.0 site
contents
code
database
database
gestionale
filespdf images
bashBusiness Logic
rete del cliente
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 16
La messa in sicurezza
PHP
Linux
MySQL
Apache
HTM
LJavasc
rip
t
CSS
plugins
macchina fisica
rete aziendale
em
ail
v 1.5 site
v 1.0 site
code contents
database
database
gestionale
filespdf images
bashBusiness Logic
rete del cliente
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 17
La messa in sicurezza
rete del cliente
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 18
La messa in sicurezza
rete del cliente
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Test conPHPUnit e Selenium
Page 19
La messa in sicurezza
rete del cliente
macchina di sviluppo
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 20
La messa in sicurezza
DB
www
.sh
macchina di sviluppo
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 21
La messa in sicurezza
DB
www
.sh
macchina di sviluppo
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 22
La messa in sicurezza
macchina di sviluppo
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 23
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 24
Il Codice ed il nuovo Tree
PHP
Linux
MySQL
HTM
LJavasc
rip
t
CSS
macchina fisica
plugins
Apache
rete aziendale
em
ail
v 1.5 site
v 1.0 site
contents
code
database
database
gestionale
filespdf images
bashBusiness Logic
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 25
PHP
Linux
MySQL
HTM
LJavasc
rip
t
CSS
macchina fisica
plugins
Apache
rete aziendale
em
ail
v 1.5 site
v 1.0 site
contents
code
database
database
gestionale
filespdf images
bashBusiness Logic
Il Codice ed il nuovo Tree
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 26
ROOT├── acquisti.php├── eae.pdf├── eae_trapani.pdf├── aiuto.php├── Ambiente.php├── anaope.php├── ancona.php├── archivio-example-days.php├── area_riservata.php├── area_riservata.php.20120124├── Articoli├── AvvisiPagine├── cosenza.php├── .bash_history├── .bashrc├── bg_postit_old.png├── bin├── bmeters_zagabria.pdf├── bodyLogon.php├── bodyMes.php├── bodyN.php├── bologna.php├── Budget├── budget.php├── CalPrezzo.sh├── CalPrezzoGia.sh...
├── CambioPassword.php├── cat2011├── cat2013c├── catalogo2013├── catalogo2013b├── catalogoExamplespagnolo2011.pdf├── cesena.php├── cg├── chat.php├── chisiamo.php├── caltanisetta.php├── codice_etico1.php├── CodiceEtico_Modello_Organizzativo.pdf├── Company-Profile ENG1.pdf├── Company-Profile ENG.pdf├── company-profile-eng.php├── Company-Profile FR1.pdf├── Company-Profile FR.pdf├── company-profile-fr.php├── Company-Profile ITA1.pdf├── Company-Profile ITA.pdf├── company-profile-ita.php├── Company-profile.pdf├── Company-Profile TED1.pdf├── Company-Profile TED.pdf├── company-profile-ted.php├── Contabilita├── contabilita.php├── contatti.php├── counter_old.txt├── counter.php├── counter.txt...
Il Codice code
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 27
├── css├── DataBase├── Documenti├── Documents├── dove.php├── error.php├── ateam_milano.pdf├── eurobisbo.pdf├── eurobisce.pdf├── eurobisci.pdf├── eurobisfa.pdf├── eurobispe.pdf├── .exrc├── roma.php├── Fatture.sh├── favicon.ico├── files├── firenze2.php├── FirstPage.php├── footer--.php├── footer.php├── fornitori.php├── gel1_bologna.pdf├── gel_bologna.pdf├── gel_cittadicastello.pdf├── gel_firenze.pdf├── gel_trieste.pdf├── gel_milano.pdf├── gel_napoli.pdf├── gel_cagliari.pdf├── gel_aosta.pdf├── gel_torino4.pdf...
├── genova.php├── gestione_ordini.php├── googleabcdef0cd0cd413.html├── bolzano.php├── vieste.php├── godline_bologna.pdf├── header.php├── .htaccess├── .htaccess.txt├── identificazione.php├── images├── img├── include├── index.php├── info.php├── informativa_privacy_example.pdf├── .inputrc├── InsCodiceFis.php├── inserimento_dati.php├── InserisciPassword.php├── .kermrc├── lavoraconnoi1.php├── lavoraconnoi.php├── lingue├── listini.php├── login_ope.php├── login.php├── login.save.php├── _logon.php├── logon.php├── logon.php.20111222├── .logon.php.swm...
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 28
├── .logon.php.swn├── .logon.php.swo├── logout.php├── mailerIm.sh├── mailer.sh├── mail_html.php├── mail_richiesta_catoffer.php├── main.php├── menu.php├── menu.php.20130205├── modifica_dati.php├── modificaMail.php├── modifica_pwd.php├── moduli.php├── modulo_Example_Card__.html├── modulocorso2.pdf├── modulo-richiesta-documentazione.html├── .muttrc├── napoli.php├── news.php├── nologin.php├── Novita├── novita.php├── Oasi.httpd.conf├── old├── ordini.php├── output├── venezia.php├── perugia.php├── pesaro.php├── peschici.php├── popup...
├── leuca.php├── Preventivi├── preventivi.php├── prodotti_ar.php├── prodotti_out.php├── prodotti.php├── prodotti.phpdacancellare├── .profile├── promotemp├── Promozioni├── promozionic.php├── promozioni.php├── ptemp.html├── public_html├── RecuperoPassword.php├── RegCodiceFis.php├── registraMail.php├── registraMail.php.20100415├── registraPassword.php├── registrazione.php├── ReinserisciPwd.php├── Remember.php├── Resi├── rete.php├── ricambi-caldaie_BLOCCOVIABILITA.php├── ricambi-caldaie-bologna27-02-2012.php├── ricambi-caldaie-cesena14-03-2012.php├── ricambi-caldaie-cinisello16-03-2012.php├── ricambi-caldaiee.php├── ricambi-caldaie-firenze23-09-2011.php├── ricambi-caldaie-firenze29-02-2012.php...
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 29
├── ricambi-caldaie-firenze29-11-2011.php├── ricambi-caldaie-bolzano29-02-2012.php├── ricambi-caldaie-MAC2012.php├── ricambi-caldaie-milano18-05-2012.php├── ricambi-caldaie-venezia12-05-2010.php├── ricambi-caldaie-venezia31-01-2012.php├── ricambi-caldaie-vieste13-03-2012.php├── ricambi-caldaie.php├── ricambi-caldaie-aosta30-01-2012.php├── ricambi-caldaie-roma13-07-2011.php├── ricambi-caldaie-roma20-09-2011.php├── ricambi-caldaie-leuca03-04-2012.php├── ricambi-caldaie-otranto02-04-2012.php├── ricambi-caldaie-otranto19-04-2013.php├── ricambi-caldaie-otranto31-10-2012.php├── ricambi-caldaie-torino04-04-2012.php├── ricambi-caldaie-torino18-07-2011.php├── robots.txt├── roca_napoli.pdf├── roma.php├── ._sanson_bari.pdf├── sanson_bari.pdf├── scambio├── verona.php├── SchedeTecniche├── scriptjs├── ScrPro├── servizi.php├── Session.php├── sesto.php├── milano1.php...
├── milano.php├── solar_milano.pdf├── solar_settimo.pdf├── sitemap.xml├── splash2.html├── splash.html├── swf├── tecnicalcontrol.pdf├── tecnicalcontrol_milano.pdf├── tmp├── torino2.php├── torino.php├── .urlview├── verona.php├── VerificaCliente.php├── sansepolcro.php├── visualizza_articoli.php├── VisualizzaDocumento.php├── visualizza_ordinato_art.php├── visualizza_ordinato_data.php├── welcome.php├── vagam_milano.pdf├── vagam_verona.pdf├── .xcoralrc├── .xemacs├── .xim.template├── .xinitrc.template└── .xtalkrc
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 30
Don’t touch the old code!it stinks!!
Page 31
macchina di sviluppo
Il Codice ed il nuovo Tree
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 32
macchina di sviluppo
Il Codice ed il nuovo Tree
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 33
code
macchina di sviluppo
Il Codice ed il nuovo Tree
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 34
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 35
hello.php
init.php
functions.php
autoloader /src
Il file di inizializzazione
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
/vendor
Page 36
macchina di sviluppo
Il file di inizializzazione
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 37
macchina di sviluppo
<?php# /app/config/init.php
$pattern = '/display_errors:[ ]*(?P<display_errors>[\w]*)/';$parameters = file_get_contents(__DIR__.'/parameters.yml');preg_match($pattern, $parameters, $matches);
ob_start();
ini_set('register_globals', true);ini_set('display_errors', $matches['display_errors']=='true');error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);extract($_COOKIE);extract($_GET);extract($_POST);
require_once __DIR__ . '/../../vendor/autoload.php';
require(__DIR__ . '/../../app/config/functions.php');
Il file di inizializzazione
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 38
macchina di sviluppo
<?php# /app/config/init.php
$pattern = '/display_errors:[ ]*(?P<display_errors>[\w]*)/';$parameters = file_get_contents(__DIR__.'/parameters.yml');preg_match($pattern, $parameters, $matches);
ob_start();
ini_set('register_globals', true);ini_set('display_errors', $matches['display_errors']=='true');error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);extract($_COOKIE);extract($_GET);extract($_POST);
require_once __DIR__ . '/../../vendor/autoload.php';
require(__DIR__ . '/../../app/config/functions.php');
Il file di inizializzazione
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 39
macchina di sviluppo
# /app/config/config.yml
test: mode: local baseUrl: remote: http://example.com local: http://example
products: a01: code: A01 description: MODULO A-01 CalPrezzo: " 23+ 0+ 0+ 0" b02: code: B02 description: DISPOSITIVO B-02 CalPrezzo: " 30.42+ 0+ 0+ 0" ...
emails: file_download: [email protected] from: address: [email protected] name: Example Srl to: [email protected] check: [email protected] questionario: [email protected] vendite: [email protected]
...
Il file di inizializzazione
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 40
macchina di sviluppo
# /app/config/parameter.yml
parameters: display_errors: true
database: host: localhost name: site_new username: root password: root
domain: env: dev database: dev: site: host: localhost name: SiteDB username: root password: root main: host: localhost name: MainDB username: root password: root prod: site: host: localhost name: SiteDB username: ~ password: ~ main: host: 256.268.350.400 name: mainDB username: ~ password: ~
Il file di inizializzazione
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 41
macchina di sviluppo
# /composer.json{ "name": "Iabadabadu/Example", "authors": [ { "name": "Danilo Sanchi", "email": "[email protected] " } ],
"require": { "guzzle/guzzle": "~3.1", "symfony/yaml": "*", "twig/twig": "1.*", "swiftmailer/swiftmailer": "4.3.*@dev", "monolog/monolog": "1.0.*" },
"minimum-stability": "dev", "autoload": { "psr-0": { "Iabadabadu": "src", "Tests": "app" } }}
Il file di inizializzazione
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 42
macchina di sviluppo
<?php # /web/index.php
require_once(__DIR__.'/../app/config/init.php');
if (($_GET["lang"] == "it")||($_GET["lang"] == "")){
if (($_GET["page"] == "ricambi-caldaie")|| ($_GET["page"] == "")){ $titolo_pagina = "Novit� e promozioni su ricambi per caldaie";$descrizione_pagina = "Scopri le ultime novit� sui prodotti Example e sui ricambi per le caldaie";
}else if ($_GET["page"] == "chisiamo"){$titolo_pagina = "Azienda Example, vendita ricambi caldaie e per il condizionamento con oltre 15.000 articoli"; $descrizione_pagina = "Example si occupa di vendita di ricambi per caldaie, vendita di prodotti per il condizionamento e ricambi per bruciatori";
...
}else if ($_GET["page"] == "vicenza"){$titolo_pagina = "Ricambi caldaie Vicenza";$descrizione_pagina = "Ricambi caldaie Vicenza";
}
}
...
Il file di inizializzazione
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 43
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 44
PHP
Linux
MySQL
HTM
LJavasc
rip
t
CSS
macchina fisica
plugins
Apache
rete aziendale
em
ail
v 1.5 site
v 1.0 site
code contents
database
database
gestionale
filespdf images
bashBusiness Logic
Codice e Contenuti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 45
resources
macchina di sviluppo
28Gb
28Gb
Codice e Contenuti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 46
code contentsresources
macchina di sviluppo
Codice e Contenuti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 47
code
contentshttp://example.com/eae.pdf
/resources/eae.pdf
macchina di sviluppo
Codice e Contenuti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 48
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 49
<?php # /web/Articoli/Carrello.php
...
$connessione=mysql_connect($host);
$stringa="select codint from anamagge where coarfo='$Inscoarfo'"; $rst = mysql($database,$stringa,$connessione); if ( mysql_numrows($rst) > 0 ) $inscodint = mysql_result($rst,0,"codint"); else $inscodint = " ";
...
_mysql
macchina di sviluppo
Funzioni isolanti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 50
<?php # /app/config/functions.php
use Iabadabadu\Common\Service\Config;
function _mysql($database_name, $query, $link_identifier = null){ if (!$database_name) { $database_name = 'main'; } $config = new Config('parameters'); $env = $config->get('domain.env');
if ($database_name == 'site') { $conn = mysql_connect( $config->get('domain.database.' . $env . '.site.host'), $config->get('arbo.database.' . $env . '.site.username'), $config->get('arbo.database.' . $env . '.site.password') ); mysql_select_db($config->get('arbo.database.' . $env . '.site.name'), $conn); }
if ($database_name == 'main') { ... } $result = mysql_query($query, $conn); if (mysql_error()) { //throw new \Exception(mysql_error()); } mysql_close($conn);
return $result;}
...
Funzioni isolanti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 51
macchina di sviluppo
<?php # /web/Articoli/Carrello.php
...
require("../Ambiente.php"); require("../include/Base.php"); require("../include/FormatNum.php"); require("../include/JSFormatData.php"); $connessione=mysql_connect($host);
$stringa="select codint from anamagge where coarfo='$Inscoarfo'"; $rst = mysql($database,$stringa,$connessione); if ( mysql_numrows($rst) > 0 ) $inscodint = mysql_result($rst,0,"codint"); else $inscodint = " ";
...
require(_getWebDir()."/Ambiente.php");
require(_getWebDir()."/include/Base.php");
require(_getWebDir()."/include/FormatNum.p
hp");
require(_getWebDir()."/include/JSFormatDat
a.php");
Funzioni isolanti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 52
Conversione da iso-8859-1 a utf-8:
iconv -f iso-8859-1 -t utf-8 <infile> <outfile>
Cerca e sostituisci:
❖ mysql(...) => _mysql❖ mysql_query(...) => _mysql❖ content="text/html; charset=iso-8859-1" => charset=utf-8❖ � => à|€|...❖ href="http://www.example.com/New/aiuto.php" => /New/aiuto.php❖ href="../catalogo.pdf" => /New/resources/catalogo.pdf❖ if ( file_exists("../foto/".$file) ) { => _href2Path("/New/resources/foto/".$file)❖ mail(...) => ... SwiftMailer?
Funzioni isolanti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 53
macchina di sviluppo
<?php
...
$stringa = "../CalPrezzo.sh ".$code." ".$user;
$fp = popen($stringa,"r");
$stringa = fgets($fp,1024);
...
<?php
...
$stringa = _CalPrezzo($code, $user);
...
Funzioni isolanti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 54
macchina di sviluppo
<?php...$From="[email protected] ";$Subj = "...";$Dest = $email;
$filetesto=tempnam("/tmp","");$fp=fopen($filetesto,"w");
fwrite($fp,"Spett.le\n ");fwrite($fp,$nome);fwrite($fp,"\n");fwrite($fp,"a seguito Vs. gentile richiesta ...");
fclose($fp);
$stringa= "mailer.sh -b $filetesto ";$stringa .= " -f $From ";$stringa .= " -s \"$Subj\" ";$stringa .= " -t $Dest ";
exec ($stringa);...
Funzioni isolanti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 55
macchina di sviluppo
<?php
...
$log = new Monolog\Logger('Mail');
$log->pushHandler(new Monolog\Handler\StreamHandler($logFile));
$log->addInfo(...);
$message = _getSwiftMessage();
$message->setSubject(...)
->setTo(array($email))
->setBody(
"Spett.le\n " . $nome . "\n" .
"a seguito Vs. gentile richiesta ..."
);
_sendSwiftMessage($message);
...
Funzioni isolanti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 56
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 57
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 58
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 59
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 60
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 61
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 62
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 63
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 64
Installazione indipendente di Symfony
❖ Symfony
❖ Hello World!
❖ FOSUserBundle
❖ SonataAdminBundle
❖ SonataUserBundle
[https://github.com/danielsan80/symfony-app]
master
helloworldadmin
users
oauth
admin_oauth
Git Play
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 65
Git playing:
$ git branch symfony$ git checkout symfony$ git remote add symfony [email protected] :danielsan80/symfony-app.git$ git pull symfony adminadmin
Git Play
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 66
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 67
# /web/.htaccess
<IfModule mod_rewrite.c> RewriteEngine On
RewriteCond %{REQUEST_FILENAME} catalogo2013 RewriteRule . - [L]
RewriteCond %{REQUEST_FILENAME} OldSite RewriteRule . - [L]
RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ app.php [QSA,L]</IfModule>
La convivenza
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 68
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 69
L’entry point principale
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Obbiettivi:
❖ separare la vista dal controller
❖ definire i template di layout
❖ gestire le vecchie rotte
Mezzi:
❖ Refactoring ed integrazione con Symfony di index.php
❖ Twig, layout.html.twig
❖ Router, Controller, @Route Annotation
Page 70
<?php # /src/Iabadabadu/MainBundle/Controller/DefaultController.php
namespace Iabadabadu\MainBundle\Controller;
use Iabadabadu\MainBundle\Helper\Retro;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Response;
use Iabadabadu\Common\Service\Config;
/**
* @Route("")
*/
class DefaultController extends Controller
{
...
}
L’entry point principale
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 71
<?php # /src/Iabadabadu/MainBundle/Controller/DefaultController.php
...
class DefaultController extends Controller
{
/**
* @Route("/New/index.php", name="home_new_index")
* @Route("/", name="home_root")
* @Route("/index.php", name="home_index")
* @Template
*/
public function indexAction()
{
...
}
}
L’entry point principale
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 72
<?php # /src/Iabadabadu/MainBundle/Controller/DefaultController.php
...
public function indexAction() {
$request = $this->getRequest();
$pathInfo = $request->getPathInfo();
$page = $request->get('page');
if ($pathInfo == '/New/index.php') {
switch ($page) {
case null:
case '':
case 'ricambi-caldaie':
return $this->redirect($this->generateUrl('home'), 301);
case 'contatti':
return $this->redirect($this->generateUrl('contatti'), 301);
case 'dove':
return $this->redirect($this->generateUrl('dovesiamo'), 301);
case 'area_riservata':
return $this->redirect($this->generateUrl('reserved', array('page' => 'ordini')), 301);
}
...
}
...
}
...
L’entry point principale
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
http://www.example.it/New/index.php?page=contatti
Page 73
<?php # /src/Iabadabadu/MainBundle/Controller/DefaultController.php
...
public function indexAction() {
$request = $this->getRequest();
$pathInfo = $request->getPathInfo();
$page = $request->get('page');
if ($pathInfo == '/New/index.php') {
switch ($page) { ... }
if (in_array($page, array( 'roma', 'milano', 'bologna', ...))) {
return $this->redirect($this->generateUrl('filiale', array('code' => $page)), 301);
}
}
if (strpos($pathInfo, '/New') === false) {
$response = new Response('', 301, array(
'Location' => '/New/'
));
return $response;
}
...
}
...
L’entry point principale
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 74
<?php # /src/Iabadabadu/MainBundle/Controller/DefaultController.php
...
public function indexAction() {
...
$page = $request->get('page');
$page = $page ? $page : "ricambi-caldaie";
if ( $page != basename($page)
|| !preg_match("/^[A-Za-z0-9\-_]+$/", $page)
|| $page == "index"
|| !file_exists(Retro::href2Path('/New/' . $page . ".php"))
) {
$page = "error";
}
ob_start();
require $this->get('kernel')->getRootDir() . "/../web/$page.php";
$content = ob_get_contents();
ob_end_clean();
$data = array(
'content' => $content,
);
return $data;
}
...
L’entry point principale
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 75
<?php # /app/config/functions.php
use \Iabadabadu\MainBundle\Helper\Retro;
...
function _mysql($database_name, $query, $link_identifier = null)
{
return Retro::sql($database_name, $query, $link_identifier);
}
...
<?php # /src/Iabadabadu/MainBundle/Helper/Retro.php
namespace Iabadabadu\MainBundle\Helper;
class Retro
{
...
static public function sql($database_name, $query, $link_identifier = null)
{
...
}
...
}
L’entry point principale
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 76
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 77
Il tapping
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Obbiettivi:
❖ Allargare il lavoro fatto con index.php a tutti i file .php
❖ Avere all’interno dei vecchi file .php l’ambiente di Symfony
❖ Gestire le vecchie rotte
Mezzi:
❖ Router, Controller, @Route Annotation
Page 78
<?php # /src/Iabadabadu/MainBundle/Controller/DefaultController.php
class DefaultController extends Controller {
public function indexAction() { ... }
/**
* @Route(
* "/New/{directory}/{filename}.{_format}", name = "tap_dir_phpfile",
* requirements = {
* "directory" = "(Ordini|Articoli|Novita|Budget|Contabilita)",
* "_format" = "php"
* }
* )
*/
public function tapDirPHPFileAction($directory, $filename) {
return $this->tapPHPFile('/' . $directory . '/' . $filename . ".php");
}
/**
* @Route("/New/{filename}.{_format}", name="tap_phpfile", requirements={"_format" ="php"})
*/
public function tapPHPFileAction($filename) {
return $this->tapPHPFile('/' . $filename . ".php");
}
...
}
Il tapping
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 79
Il tapping
/Ordini/something.php
/Ordini/!_something.php
<?php # /src/Iabadabadu/MainBundle/Controller/DefaultController.php
class DefaultController extends Controller {
...
private function tapPHPFile($filename) {
$filename = explode('/', $filename);
$last = count($filename)-1;
$filename[$last] = '!_' . $filename[$last];
$filename = implode('/', $filename);
$request = $this->getRequest();
$symfony = true;
require_once($this->get('kernel')->getRootDir() . '/../app/config/init.php');
$GLOBALS['Kcodice'] = $Kcodice = (int) $this->get('user')->getUsername();
extract($request->query->all());
extract($request->request->all());
foreach($request->query->all() as $key => $value) {
$GLOBALS[$key] = $value;
}
foreach($request->request->all() as $key => $value) {
$GLOBALS[$key] = $value;
}
...
}
}
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 80
<?php # /src/Iabadabadu/MainBundle/Controller/DefaultController.php
class DefaultController extends Controller {
...
private function tapPHPFile($filename) {
...
try {
ob_start();
require $this->get('kernel')->getRootDir() . "/../web" . $filename;
$content = ob_get_contents();
ob_end_clean();
} catch (\Exception $e) {
echo '<pre>'.$e->getMessage().'</pre>';
echo '<pre>'.$e->getTraceAsString().'</pre>';
}
return new Response($content);
}
}
<?php # /app/config/init.php
...
if ($display_errors && !isset($symfony)) {
echo '<pre>------ NOT IN SYMFONY ------</pre>';
}
Il tapping
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Page 81
!_hello.php
init.php
app.php RouterAction
/New/{filename}.php
Action
/New/index.php?page={page}
chisiamo.php
init.php
Action
/filial/{code}
/New/index.php/New/
Index.php
aiuto.php
init.php
Il tapping
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
NOT IN SYMFONY
Page 82
Indice
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
1. Il progetto
a. Il team
2. La messa in sicurezza
a. Il Codice ed il nuovo Tree
b. Il file di inizializzazione
c. Codice e Contenuti
d. Funzioni isolanti
3. L’iniezione di Symfony
a. Git Play
b. La convivenza
c. L'entry point principale
d. Il tapping
4. To be continue...
Page 83
To be continue...
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Obbiettivi:
❖ Autonomia nella gestione del sito da parte di Andrea
❖ Una nuova gestione degli Utenti
❖ Costruzione di un Modello sul database di Oasi
❖ Aggiungere nuove funzionalità
❖ Rendere dinamiche le parti statiche
❖ Potenziare il processo di vendita online
❖ ...
Mezzi:
❖ Backend, SonataAdminBundle
❖ FOSUserBundle, SonataUserBundle
❖ Doctrine, OasiService, OasiBundle
❖ Vespolina || Sylius || Integrazione con Prestashop
❖ ...
Page 85
Qualcuno va verso
la Romagna
stasera?