combattere contro il codice del “cugino”? symfony può aiutarti a sopravvivere
DESCRIPTION
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à.TRANSCRIPT
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à.
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...
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...
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
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
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
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...
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
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...
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
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
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
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
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
La messa in sicurezza
rete del cliente
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
rete del cliente
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Test conPHPUnit e Selenium
La messa in sicurezza
rete del cliente
macchina di sviluppo
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
DB
www
.sh
macchina di sviluppo
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
DB
www
.sh
macchina di sviluppo
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
macchina di sviluppo
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 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...
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
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
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
├── 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
├── .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
├── 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
Don’t touch the old code!it stinks!!
macchina di sviluppo
Il Codice ed il nuovo Tree
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
macchina di sviluppo
Il Codice ed il nuovo Tree
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
code
macchina di sviluppo
Il Codice ed il nuovo Tree
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 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...
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
macchina di sviluppo
Il file di inizializzazione
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
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
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
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
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
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
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
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...
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
resources
macchina di sviluppo
28Gb
28Gb
Codice e Contenuti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
code contentsresources
macchina di sviluppo
Codice e Contenuti
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
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
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...
<?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
<?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
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
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
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
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
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
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...
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’iniezione di Symfony
1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 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...
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
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
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...
# /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
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...
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
<?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
<?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
<?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
<?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
<?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
<?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
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...
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
<?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
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
<?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
!_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
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...
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
❖ ...
Domande?
Qualcuno va verso
la Romagna
stasera?
Grazie