Classi Javascript e PHP per validare un’indirizzo di posta elettronica

Mercoledì 3 Gennaio, 2007

Riprendendo il post Validare email in Javascript e PHP, ecco una simpatica classe Javascript in grado di verificare e controllare indirizzi di posta elettronica. Il suo uso è davvero semplice, anche se è un controllo lato client, quindi facilmente bypassabile; basta infatti disabilitare Javascript (propongo petizione contro questa possibilità ;) oramai tutti i browser permettono di eludere Javascript, e quindi tutti i controlli associato - a breve non funzionerà più nulla su Internet, vedi Ajax :o ).

JavaScript:
  1. /*
  2. ** @name              : ckmail.js
  3. ** @description       : Check email syntax
  4. ** @author            : =undo=
  5. ** @author-web        : http://www.undolog.com
  6. ** @author-email      : g.fazioli@undolog.com - g (dot) fazioli (at) undolog (dot) com
  7. ** @date              : 21/09/2006 21.24
  8. ** @ver               : 1.0
  9. */
  10.  
  11. var oCKMail = {
  12.     __release: "1.0",
  13.     __filter: /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i,
  14.     __username: "",
  15.     __domain: "",
  16.     __ext: "",
  17.  
  18.     // TO DO
  19.     getUsername: function(e) {
  20.         if(this.__init(e)) return(this.__username);
  21.         return(false);
  22.     },
  23.  
  24.     // TO DO
  25.     getDomain: function(e) {
  26.         if(this.__init(e)) return(this.__domain);
  27.         return(false);
  28.     },
  29.  
  30.     // TO DO
  31.     getExtension: function(e) {
  32.         if(this.__init(e)) return(this.__ext);
  33.         return(false);
  34.     },
  35.  
  36.     // TO DO
  37.     __init: function(e) {
  38.         if( !this.__filter.test(e) ) return(false);
  39.         var t = e.split("@");
  40.         this.__username = t[0];
  41.         this.__domain = t[1];
  42.         t = this.__domain.split(".");
  43.         this.__ext = t[1];
  44.         return(true);
  45.     },
  46.  
  47.     // TO DO
  48.     // synopsis
  49.     //    check(e,extlist,domainlist);
  50.     // Esegue una serie di controlli standard su un indirizzo e-mail.
  51.     //    extlist        - Si può passare un secondo parametro opzionale che corrisponde ad un array di estensioni che
  52.     //                   sono ammesse o escluse (include/exclude extension) in base al primo valore dell'array, tutte le
  53.     //                   altre saranno considerate errore.
  54.     //                   Eg. [true,"it","com"] passano (include list)
  55.     //                   Eg. [false,"it","com"] NON passano (exclude list)
  56.     //                   Se -1 non viene preso in considerazione
  57.     //    domainlist    - Si può passare un terzo parametro opzionale che corrisponde ad un array di domini che
  58.     //                   sono ammessi o esclusi (include/exclude domain) in base al primo valore dell'array, tutte gli
  59.     //                   altri saranno considerate errore.
  60.     //                   Eg. [true,"alice.it","mac.com"] passano (include list)
  61.     //                   Eg. [false,"alice.it","mac.com"] NON passano (exclude list)
  62.     //                   Se -1 non viene preso in considerazione
  63.     //
  64.     check: function(e) {
  65.         if( this.__init(e) ) {
  66.             // check domainExt array check
  67.             if( arguments.length> 1 ) {
  68.                 if( typeof( arguments[1] ) == "object" ) {
  69.                     if( arguments[1][0] ) { // include list
  70.                         for(var i=0; i <arguments[1].length; i++) {
  71.                             if( this.__ext == arguments[1][i].toLowerCase() ) return(true);
  72.                         }
  73.                     } else { // exclude list
  74.                         for(var i=0; i <arguments[1].length; i++) {
  75.                             if( this.__ext == arguments[1][i].toLowerCase() ) return(false);
  76.                         }
  77.                         return(true);
  78.                     }
  79.                     return(false);
  80.                 }
  81.             }
  82.             // check domainName array check
  83.             if( arguments.length> 2 ) {
  84.                 if( typeof( arguments[2] ) == "object" ) {
  85.                     if( arguments[2][0] ) { // include list
  86.                         for(var i=1; i <arguments[2].length; i++) {
  87.                             if( this.__domain == arguments[2][i].toLowerCase() ) return(true);
  88.                         }
  89.                     } else { // exclude list
  90.  
  91.                         for(var i=1; i <arguments[2].length; i++) {
  92.                             if( this.__domain == arguments[2][i].toLowerCase() ) return(false);
  93.                         }
  94.                         return(true);
  95.                     }
  96.                     return(false);
  97.                 }
  98.             }
  99.             return(true); // email correct
  100.         }
  101.         return(false); // error
  102.     }
  103. };

L'oggetto oCKMail mette a disposizione alcuni metodi per effettuare tutta una serie di controlli paralleli sull'indirizzo, come l'estensione, il dominio, ecc...

Per essere proprio sicuri se disponete di PHP potete aggiungere un'ulteriore ed efficace controllo prima di eseguire il comando mail(). Ecco la classe PHP utile a tale scopo:

PHP:
  1. /*
  2. ** @name              : cckmail.php
  3. ** @description       : Check email syntax
  4. ** @author            : =undo=
  5. ** @author-web        : http://www.undolog.com
  6. ** @author-email      : g.fazioli@undolog.com - g (dot) fazioli (at) undolog (dot) com
  7. ** @date              : 21/09/2006 23.58
  8. ** @ver               : 1.0
  9. **
  10. ** EXAMPLES
  11. **
  12. **    // Controlla un indirizzo ESCLUDENDO quelle e-mail con dominio "e-lementi.com" e "mac.com"
  13. **
  14. **    $oCKMail = new CCKMail();
  15. **    $oCKMail->check($email, NULL, array(false,"e-lementi.com","mac.com") );
  16. **
  17. **    // Controlla un indirizzo INCLUDENDO quelle e-mail con dominio "e-lementi.com" e "mac.com"
  18. **
  19. **    $oCKMail = new CCKMail();
  20. **    $oCKMail->check($email, NULL, array(true,"e-lementi.com","mac.com") );
  21. **
  22. **    // Controlla un indirizzo ESCLUDENDO quelle e-mail con estensione "net","it","org"
  23. **
  24. **    $oCKMail = new CCKMail();
  25. **    $oCKMail->check($email, array(false,"net","it","org") );
  26. **
  27. ** HISTORY / CHANGE LOG
  28. **
  29. */
  30.  
  31.     if (!function_exists('checkdnsrr')) {
  32.         function checkdnsrr($host, $type = '') {
  33.             if(!empty($host)) {
  34.                 if($type == '') $type = "MX";
  35.                 @exec("nslookup -type=$type $host", $output);
  36.                 while(list($k, $line) = each($output)) {
  37.                     if(eregi("^$host", $line)) {
  38.                         return true;
  39.                     }
  40.                 }
  41.                 return false;
  42.             }
  43.         }
  44.     }
  45.     //
  46.     class CCKMail {
  47.         var $__release = "1.1";
  48.         var $status = false;
  49.         var $username;
  50.         var $domain;
  51.         var $ext;
  52.         //
  53.         function CCKMail() {}
  54.         //
  55.         function _test($e) {
  56.             $this->status = false;
  57.             $p = '/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/';
  58.             if( (preg_match($p, $e)) ) {
  59.                 $t               = explode("@",$e);
  60.                 $this->username  = strtolower( $t[0] );
  61.                 $this->domain    = strtolower( $t[1] );
  62.                 $t               = explode(".",$this->domain);
  63.                 $this->ext       = strtolower( $t[1] );
  64.                 //
  65.                 if(checkdnsrr($this->domain.'.', 'MX') )    $this->status = true;
  66.                 if(checkdnsrr($this->domain.'.', 'A') )     $this->status = true;
  67.                 if(checkdnsrr($this->domain.'.', 'CNAME') ) $this->status = true;
  68.             }
  69.         }
  70.         //
  71.         function check($m, $e=NULL,$d=NULL) {
  72.             $this->_test($m);
  73.             if( $this->status ) {
  74.                 // check domainExt array check
  75.                 if( !is_null($e) ) {
  76.                     if( $e[0] ) { // include list
  77.                         for($i=1; $i <sizeof($e); $i++) {
  78.                             if( $this->ext == strtolower( $e[$i] ) ) return(true);
  79.                         }
  80.                     } else { // exclude list
  81.                         for($i=1; $i <sizeof($e); $i++) {
  82.                             if( $this->ext == strtolower( $e[$i] ) ) return(false);
  83.                         }
  84.                         return(true);
  85.                     }
  86.                     return(false);
  87.                 }
  88.                 // check domainName array check
  89.                 if( !is_null($d) ) {
  90.                     if( $d[0] ) { // include list
  91.                         for($i=1; $i <sizeof($d); $i++) {
  92.                             if( $this->domain == strtolower( $d[$i] ) ) return(true);
  93.                         }
  94.                     } else { // exclude list
  95.                         for($i=1; $i <sizeof($d); $i++) {
  96.                             if( $this->domain == strtolower( $d[$i] ) ) return(false);
  97.                         }
  98.                         return(true);
  99.                     }
  100.                     return(false);
  101.                 }
  102.                 return(true);
  103.             }
  104.             return(false);
  105.         }
  106.     }
  107. ?>

La cosa ineteressante è la capacità di questa classe di connettersi ai server MX (vedi checkdnsrr() ) per verificare la presenza del dominio. Quindi oltre ad eseguire un controllo sintattico sull'indirizzo di posta elettronica viene eseguito un vero e proprio ping del dominio passato. Possiamo dire che questo metodo è sicuro all'80%...

Classe Javascript per il rilevamento di Flash

Mercoledì 3 Gennaio, 2007

Anche se non si realizza un sito interamente in Flash, alcuni componenti possono presentarsi comunque all'interno della pagina, come banner, claim, visori RSS, ecc... Eco quindi un modo semplice per verificare se Flash è attivo e installato. Proponiamo qui un metodo che non necessità di più pagine, come proposto dalla stessa Adobe. Faremo in modo di risolvere tutto all'interno di un'unica pagina.

La classe qui presentata permette anche di risolvere l'ultimo problema nato con Explorer, ovvero quello dell'attivazione di un controllo ActiveX. Per risolverlo basta utilizzare Javascript per inserire il componente Flash, proprio quello che fa la nostra classe.

La prima cosa di cui abbiamo bisogno è una simpatica classe Javascript che ci permetterà di eseguire tutti i controlli necessari:

JavaScript:
  1. <!--
  2.     /*
  3.     ** Detect Flash Class & Path insertFlash Object
  4.     **
  5.     */
  6.  
  7. var df = {
  8.     __release: "1.0",
  9.     _isIE: ( (navigator.appVersion.indexOf("MSIE") != -1) ? true : false),
  10.     _isWin:( (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false),
  11.     _isOpera:( (navigator.userAgent.indexOf("Opera") != -1) ? true : false),
  12.    
  13.     getSwfVer: function (i) {
  14.         // Le versioni di NS/Opera dalla 3 in poi verificano la presenza del plug-in Flash nell'array dei plug-in
  15.         if (navigator.plugins != null && navigator.plugins.length> 0) {
  16.             if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
  17.                 var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
  18.               var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
  19.                 var descArray = flashDescription.split(" ");
  20.                 var tempArrayMajor = descArray[2].split(".");
  21.                 var versionMajor = tempArrayMajor[0];
  22.                 var versionMinor = tempArrayMajor[1];
  23.                 if ( descArray[3] != "" ) var tempArrayMinor = descArray[3].split("r");
  24.                 else var tempArrayMinor = descArray[4].split("r");
  25.                 //
  26.               var versionRevision = tempArrayMinor[1]> 0 ? tempArrayMinor[1] : 0;
  27.                 var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
  28.             } else    var flashVer = -1;
  29.         }
  30.         else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
  31.         else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
  32.         else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
  33.         else flashVer = -1;
  34.         //
  35.         return flashVer;
  36.     },
  37.    
  38.     detectFlashVer:function (reqMajorVer, reqMinorVer, reqRevision) {
  39.         var reqVer = parseFloat(reqMajorVer + "." + reqRevision);
  40.         for (var i=25;i>0;i--) {   
  41.             if (this._isIE && this._isWin && !this._isOpera) var versionStr = VBgetSwfVer(i);
  42.             else var versionStr = this.getSwfVer(i);
  43.             if (versionStr == -1 ) return false;
  44.             else if (versionStr != 0) {
  45.                 if(this._isIE && this._isWin && !this._isOpera) {
  46.                     var tempArray         = versionStr.split(" ");
  47.                     var tempString        = tempArray[1];