Combattere contro il codice del “cugino”? Symfony può aiutarti a sopravvivere...

Post on 05-Dec-2014

1.388 views 0 download

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 of Combattere contro il codice del “cugino”? Symfony può aiutarti a sopravvivere...

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à.

@danielsan80

danilo.sanchi@gmail.com

danilosanchi.net

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: info@example.it from: address: info@example.it name: Example Srl to: info@example.it check: admin@example.it questionario: quest@example.it vendite: vendite@example.it

...

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": "d.sanchi@iabadabadu.it" } ],

"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 = "&nbsp;";

...

_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 = "&nbsp;";

...

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="info@example.it";$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 git@github.com: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