Daca ati citit articolul scris de Andru, “Web development folosind Masina Virtuala (VM): de ce si cum“, atunci stiti ca aici la Innobyte folosim Masini Virtuale pentru dezvoltarea proiectelor, alaturi de alte unelte/ servicii interesante precum GitHub.
Totodata, avem si un mediu de stage pentru aproape toate proiectele astfel incat clientii sa poata vedea progresul, sa poata sugera modificari si asa mai departe.
Aceasta metoda functioneaza minunat pentru noi, in special pentru proiectele noi.
Insa, atunci cand avem proiecte care sunt deja live si trebuie sa dezvoltam doar noi elemente/ module, lucrurile devin putin mai complicate.
La unul dintre aceste proiecte lucram chiar acum, un proiect foarte mare cu peste 100 de module custom Magento. Pe langa noile module, dezvoltam si unelte variate pentru a automatiza diverse lucruri.
Una dintre cele mai mari provocari este necesitatea de a ne asigura ca fiecare lucru marunt pe care il dezvoltam va merge pe Masina Virtuala, in mediul de stage si, desigur, atunci cand il implementam pe serverele live.
Sa luam, spre exemplu, una dintre cele mai recente unelte pe care le-am dezvoltat: o unealta micuta (script php rulat din CLI) ce ar crea 16 noi categorii si pentru fiecare dintre acele categorii trebuie sa copiem produse din 3 pana la 5 categorii deja aflate in magazin.
Partea in care cream categoriile este usoara. Problema principala este reprezentata de potrivirea ID-urilor categoriilor pe Masinile Virtuale, web site-ul stage si, bineinteles, cel live.
Iata, aici apare nevoia unui mediu de dezvoltare.
Magento standard nu sustine asa ceva, cum se intampla in cazul altor software-uri sau framework-uri (CodeIgniter, Symfony, etc). Ati ghicit, ne cream propriul mediu de dezvoltare!
Ei bine… avem nevoie de o multime multi-dimensionala cu ID-uri din care trebuie sa copiem produsele pentru fiecare mediu (VM, stage si live).
Dupa dezbateri lungi cu echipa Innobyte, am decis sa scriem un modul Magento custom pentru a-l putea folosi pentru mai multe module. Am decis, totodata sa hack-uim putin index.php pentru a face cateva verificari (daca este necesar) inainte ca totul sa fie incarcat.
Partea 1 – Hacking
In index.php avem urmatorul cod:
[php] <!–?php ini_set(‘error_reporting’, 0); /* START DEVELOPMENT ENVIRONMENT */ $allowEnvs = array( ‘live’, ‘stage’, ‘dev’ ); $defaultEnv = ‘live’; if ( isset($_SERVER[‘DEV_ENV’]) && in_array( trim($_SERVER[‘DEV_ENV’]), $allowEnvs) ) { $env = trim($_SERVER[‘DEV_ENV’]); } else { if ( PHP_SAPI == ‘cli’ ){ $env = ‘cli’; } else { $search = array( ‘dev’ =—-> array( ‘dev.’, ‘devel.’, ‘test.’),‘stage’ => array( ‘stage.’, ‘staging.’),
‘live’ => array( ‘www.’ )
);
$found = false;
$host = $_SERVER[‘HTTP_HOST’];
$parts = explode(‘.’, $host);
foreach ( $parts as $part ) {
foreach ( $search as $dev => $bits ) {
if ( in_array($part.’.’, $bits) ) {
$found = true;
$env = $dev;
}
}
}
if ( !$found ) {
$env = $defaultEnv;
}
}
}
define(‘DEV_ENV’, $env );
/* END DEVELOPMENT ENVIRONMENT */
?>
[/php]
Asa cum puteti vedea, asta s-a facut inainte ca orice altceva sa fie incarcat. In prima instanta verifica daca exista o directiva SetEnv in .htaccess. Daca exista si se afla in multimea permisa (pentru a preveni eroarea umana la tastare) trece la sectiunea unde definim constanta.
Daca nu, codul verifica HTTP_HOST-ul si seteaza variabila bazata pe acesta. Daca nu se gaseste nicio potrivire, seteaza mediul implicit (live, in cazul nostru).
Partea 2 – Modulul Magento
Am creat un nou modul numit Base. Vom plasa codul aici pentru a-l putea refolosi oriunde avem nevoie doar chemand un Helper.
Este nevoie doar de crearea fisierului Innobyte_Base.xml in directorul app/etc/modules cu urmatorul continut:
[php] <?xml version="1.0" ?><config>
<modules>
<Innobyte_Base>
<active>true</active>
<codePool>local</codePool>
</Innobyte_Base>
</modules>
</config>
[/php]
Asta ii spune Magento sa incarce modulul nostru.
Apoi, creati urmatoarea structura a directorului:
app/code/local/Innobyte
app/code/local/Innobyte/Base
app/code/local/Innobyte/Base/Helper
app/code/local/Innobyte/Base/etc
Acum sa realizam fisierul de configuratie pentru modulul nostru.
Porniti IDE-ul sau editorul de text preferat si creati un nou fisier in app/code/local/Innobyte/Base/etc numit config.xml si faceti paste la urmatoarele:
[php] <?xml version="1.0"?><config>
<modules>
<Innobyte_Base>
<version>0.0.1</version>
</Innobyte_Base>
</modules>
<global>
<helpers>
<base>
<class>Innobyte_Base_Helper</class>
</base>
</helpers>
</global>
</config>
Acum ca avem acest set-up, este timpul sa scriem clasa helper.
Avem o singura metoda definita in aceasta clasa.
Ii trimitem o multime cu toate valorile pentru toate mediile si o returneaza pe cea pentru mediul curent. Atat de simplu.
Doar creati un nou fisier numit Data.php in directorul app/code/local/Innobyte/Base si inserati urmatorul cod:
[php] <!–?php class Innobyte_Base_Helper_Data extends Mage_Core_Helper_Data { public function getValues ( $input ) { $allowEnvs = array( ‘live’, ‘stage’, ‘dev’, ‘cli’ ); if ( PHP_SAPI === ‘cli’ ) { define(‘DEV_ENV’, ‘cli’); } if ( !defined( ‘DEV_ENV’ ) || !in_array( DEV_ENV, $allowEnvs ) ) { return false; } else { if ( !array_key_exists( DEV_ENV, $input ) ) { return false; } return $input[ DEV_ENV ]; } } } ?–>[/php]
Apoi va verifica daca constanta definita este una dintre cele de care avem nevoie ( $allowEnvs). Se intoarce apoi ca array-ul de care avem nevoie bazat pe cheile din array-ul de intrare.
Array-ul va arata asa:
[php] $input = array (‘dev’ => array ( 1, 2, 3 ) // array of ids for dev env
‘stage’ => array( 1, 2, 5) // values for stage
‘live’ => array( 1, 7, 14) // values for live
);
[/php]
Presupunand ca vom folosi acest cod in mediul dev, vom apela astfel:
[php]print_r(Mage::helper(‘base’)->getValues($input)) [/php]si va returna primul array ( 1, 2, 3 );
Este o bucata de cod foarte simpla dar ajuta foarte mult in procesul de dezvoltare.
Daca nu am folosi asta ar trebui sa modificam fisierele de fiecare data inainte de a le implementa in mediul de stage sau live, sa le adaugam la git, commit, etc.
Daca ar fi probleme, ar trebui sa modificam fisierul inca o data cu valorile initiale pentru VM si sa refacem intreg procesul.
Pentru cei care citesc acest articol dar nu doresc sa hack-uiasca fisierul index.php, puteti lua acel cod si sa-l puneti in metoda __construct() a clasei helper.