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à.
Combattere contro il codice del “cugino”? Symfony può aiutarti a sopravvivere...
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à.
3. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
4. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
5.
6. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il progetto
c Fr
amew
ork
s
ne
i
t
Bus
ip bash
P
cr Li
OO
as
MV
nu
x
av
C
J
PHP MySQL
mac
chi
na
fisApache CSS
e
ica
dal e
en
v 1.0
azi abas
site
e
t
ret
da nale
o
co v 1.5 site
gesti
de contents
ages
df im
files p
pl
il
ema
se
databa
ML
HT
ug
in
s
i
Log
s
7. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il progetto
c Fr
amew
ork
s
ne
i
t
Bus
ip bash
P
cr Li
OO
as
MV
nu
x
av
C
J
PHP MySQL
mac
chi
na
fisApache CSS
e
ica
dal e
en
v 1.0
azi abas
site
e
t
ret
da nale
o
co v 1.5 site
gesti
de contents
ages
df im
files p
pl
il
ema
se
databa
ML
HT
ug
in
s
i
Log
s
8. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il progetto
c
es
sin
Bu
i
Log
s
pl
se
databa
ML
il
ema
liente
rete del c
HT
ug
in
s
t
ip bash
r
sc Lin
a
ux
av
J
P
PH MySQL
mac
chi
na
fisApache CSS
e
ica
dal e
en
v 1.0
azi abas
site
e
t
ret
da nale
o
co v 1.5 site
gesti
de contents
ages
df im
files p
9. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
10. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il team
Andrea
responsabile sito
comunicazione
cliente
Giordano
amministratore
Oddo
Fabio
titolare
Coach
Alessandro
Danilo
project manager
Luna
Web Developer
Luigi
content & copy
Dario
Web Developer
responsabile
gestionale
Raff
titolare
Giuliano
sistemista
fornitore del
gestionale
11. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
12. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
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
13. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
c
es
sin
Bu
i
Log
s
pl
se
databa
ML
il
ema
liente
rete del c
HT
ug
in
s
t
ip bash
r
sc Lin
a
ux
av
J
P
PH MySQL
mac
chi
na
fisApache CSS
e
ica
dal e
en
v 1.0
azi abas
site
e
t
ret
da nale
o
co v 1.5 site
gesti
de contents
ages
df im
files p
14. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
c
es
sin
Bu
i
Log
s
pl
se
databa
ML
il
ema
liente
rete del c
HT
ug
in
s
t
ip bash
r
sc Lin
a
ux
av
J
P
PH MySQL
mac
chi
na
fisApache CSS
e
ica
dal e
en
v 1.0
azi abas
site
e
t
ret
da nale
o
co v 1.5 site
gesti
de contents
ages
df im
files p
15. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
c
es
sin
Bu
i
Log
s
pl
se
databa
ML
il
ema
liente
rete del c
HT
ug
in
s
t
ip bash
r
sc Lin
a
ux
av
J
P
PH MySQL
mac
chi
na
fisApache CSS
e
ica
dal e
en
v 1.0
azi abas
site
e
t
ret
da nale
o
co v 1.5 site
gesti
de contents
ages
df im
files p
16. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
c
es
sin
Bu
i
Log
s
pl
se
databa
ML
il
ema
liente
rete del c
HT
ug
in
s
t
ip bash
r
sc Lin
a
ux
av
J
P
PH MySQL
mac
chi
na
fisApache CSS
e
ica
dal e
en
v 1.0
azi abas
site
e
t
ret
da nale
o
co v 1.5 site
gesti
de contents
ages
df im
files p
17. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
liente
rete del c
18. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
Test co
n
PHPUn
it e
Seleniu
m
liente
rete del c
19. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
macchina di
sviluppo
rete del cliente
20. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
DB
www
.sh
macchina di
sviluppo
21. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
DB
www
.sh
macchina di
sviluppo
22. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La messa in sicurezza
macchina di
sviluppo
23. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
24. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il Codice ed il nuovo Tree
c
es
sin
Bu
i
Log
s
pl
il
ema
se
databa
ML
HT
ug
in
s
t
ip bash
r
sc Lin
a
ux
av
J
P
PH MySQL
mac
chi
na
fisApache CSS
e
ica
dal e
en
v 1.0
azi abas
site
e
t
ret
da nale
o
co v 1.5 site
gesti
de contents
ages
df im
files p
25. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il Codice ed il nuovo Tree
c
es
sin
Bu
i
Log
s
pl
il
ema
se
databa
ML
HT
ug
in
s
t
ip bash
r
sc Lin
a
ux
av
J
P
PH MySQL
mac
chi
na
fisApache CSS
e
ica
dal e
en
v 1.0
azi abas
site
e
t
ret
da nale
o
co v 1.5 site
gesti
de contents
ages
df im
files p
31. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il Codice ed il nuovo Tree
macchina di
sviluppo
32. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il Codice ed il nuovo Tree
macchina di
sviluppo
33. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il Codice ed il nuovo Tree
code
macchina di
sviluppo
34. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
35. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il file di inizializzazione
hello.php
init.php
autoloader
/src
/vendor
functions.php
36. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il file di inizializzazione
macchina di
sviluppo
37. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il file di inizializzazione
<?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');
macchina di
sviluppo
38. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il file di inizializzazione
<?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');
macchina di
sviluppo
39. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il file di inizializzazione
# /app/config/config.yml
test:
mode: local
baseUrl:
remote: http://example.com
local: http://example
products:
a01:
code: A01
description:
CalPrezzo: "
b02:
code: B02
description:
CalPrezzo: "
...
MODULO A-01
23+ 0+ 0+ 0"
DISPOSITIVO B-02
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
...
macchina di
sviluppo
40. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il file di inizializzazione
# /app/config/parameter.yml
parameters:
display_errors: true
database:
host: localhost
name: site_new
username: root
password: root
macchina di
sviluppo
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: ~
41. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il file di inizializzazione
# /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"
}
}
}
macchina di
sviluppo
42. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il file di inizializzazione
<?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";
}
}
...
macchina di
sviluppo
43. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
44. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Codice e Contenuti
c
es
sin
Bu
i
Log
s
pl
il
ema
se
databa
ML
HT
ug
in
s
t
ip bash
r
sc Lin
a
ux
av
J
P
PH MySQL
mac
chi
na
fisApache CSS
e
ica
dal e
en
v 1.0
azi abas
site
e
t
ret
da nale
o
co v 1.5 site
gesti
de contents
ages
df im
files p
45. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Codice e Contenuti
28Gb
resources
macchina di
sviluppo
46. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Codice e Contenuti
code
macchina di
sviluppo
resources
contents
47. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Codice e Contenuti
contents
http://example.com/eae.pdf
/resources/eae.pdf
code
macchina di
sviluppo
48. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
49. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Funzioni isolanti
<?php # /web/Articoli/Carrello.php
...
$connessione=mysql_connect($host);
$stringa="select codint from anamagge where coarfo='$Inscoarfo'";
$rst = _mysql($database,$stringa,$connessione);
mysql
if ( mysql_numrows($rst) > 0 )
$inscodint = mysql_result($rst,0,"codint");
else
$inscodint = " ";
...
macchina di
sviluppo
50. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Funzioni isolanti
<?php # /app/config/functions.php
use IabadabaduCommonServiceConfig;
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;
}
...
51. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Funzioni isolanti
<?php # /web/Articoli/Carrello.php
...
()."/Ambiente.php");
require(_getWebDir
require("../Ambiente.php");
/include/Base.php");
require("../include/Base.php");
require(_getWebDir()."
");
/include/FormatNum.php
require("../include/FormatNum.php");
require(_getWebDir()."
a.php");
/include/JSFormatDat
require("../include/JSFormatData.php");
require(_getWebDir()."
$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 = " ";
...
macchina di
sviluppo
52. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Funzioni isolanti
Conversione da iso-8859-1 a utf-8:
iconv -f iso-8859-1 -t utf-8 <infile> <outfile>
Cerca e sostituisci:
❖
❖
❖
❖
❖
❖
❖
❖
mysql(...)
mysql_query(...)
content="text/html; charset=iso-8859-1"
�
href="http://www.example.com/New/aiuto.php"
href="../catalogo.pdf"
if ( file_exists("../foto/".$file) ) {
mail(...)
=>
=>
=>
=>
=>
=>
=>
=>
_mysql
_mysql
charset=utf-8
à|€|...
/New/aiuto.php
/New/resources/catalogo.pdf
_href2Path("/New/resources/foto/".$file)
... SwiftMailer?
53. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Funzioni isolanti
<?php
<?php
...
...
$stringa = "../CalPrezzo.sh ".$code." ".$user;
$stringa = _CalPrezzo($code, $user);
$fp = popen($stringa,"r");
...
$stringa = fgets($fp,1024);
...
macchina di
sviluppo
54. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Funzioni isolanti
<?php
...
$From="info@example.it";
$Subj = "...";
$Dest = $email;
$filetesto=tempnam("/tmp","");
$fp=fopen($filetesto,"w");
fwrite($fp,"Spett.len ");
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);
...
macchina di
sviluppo
55. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Funzioni isolanti
<?php
...
$log = new MonologLogger('Mail');
$log->pushHandler(new MonologHandlerStreamHandler($logFile));
$log->addInfo(...);
$message = _getSwiftMessage();
$message->setSubject(...)
->setTo(array($email))
->setBody(
"Spett.len " . $nome . "n" .
"a seguito Vs. gentile richiesta ..."
);
_sendSwiftMessage($message);
...
macchina di
sviluppo
56. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
57. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’iniezione di Symfony
58. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’iniezione di Symfony
59. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’iniezione di Symfony
60. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’iniezione di Symfony
61. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’iniezione di Symfony
62. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’iniezione di Symfony
63. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
64. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Git Play
Installazione indipendente di Symfony
❖ Symfony
❖ Hello World!
❖ FOSUserBundle
❖ SonataAdminBundle
❖ SonataUserBundle
[https://github.com/danielsan80/symfony-app]
master
helloworld
admin
admin_oauth
users
oauth
65. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Git Play
Git playing:
$
$
$
$
git
git
git
git
branch symfony
checkout symfony
remote add symfony git@github.com:danielsan80/symfony-app.git
pull symfony admin
admin
66. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
67. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
La convivenza
# /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>
68. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
69. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’entry point principale
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
70. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’entry point principale
<?php # /src/Iabadabadu/MainBundle/Controller/DefaultController.php
namespace IabadabaduMainBundleController;
use IabadabaduMainBundleHelperRetro;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationMethod;
use SensioBundleFrameworkExtraBundleConfigurationTemplate;
use SymfonyComponentHttpFoundationResponse;
use IabadabaduCommonServiceConfig;
/**
* @Route("")
*/
class DefaultController extends Controller
{
...
}
71. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’entry point principale
<?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()
{
...
}
}
72. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’entry point principale
<?php # /src/Iabadabadu/MainBundle/Controller/DefaultController.php
...
public function indexAction() {
http://www.example.it/New/index.php?page=contatti
$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);
}
...
}
...
}
...
73. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’entry point principale
<?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;
}
...
}
...
74. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’entry point principale
<?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;
}
...
75. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
L’entry point principale
<?php # /app/config/functions.php
use IabadabaduMainBundleHelperRetro;
...
function _mysql($database_name, $query, $link_identifier = null)
{
return Retro::sql($database_name, $query, $link_identifier);
}
...
<?php # /src/Iabadabadu/MainBundle/Helper/Retro.php
namespace IabadabaduMainBundleHelper;
class Retro
{
...
static public function sql($database_name, $query, $link_identifier = null)
{
...
}
...
}
76. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
77. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il tapping
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
78. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il tapping
<?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");
}
...
}
79. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il tapping
<?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);
/Ordini/something.php
/Ordini/!_something.php
$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;
}
...
}
}
80. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il tapping
<?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>';
}
81. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Il tapping
/New/{filename}.php
app.php
Router
Action
/New/index.php?page={page}
Action
/New/index.php
/New
/
Index.php
!_hello.php
aiuto.php
chisiamo.php
/filial/{code}
init.php
Action
init.php
NOT IN SYMFONY
init.php
82. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
Indice
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...
83. 1 -> a -> 2 -> a -> b -> c -> d -> 3 -> a -> b -> c -> d -> 4
To be continue...
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
...