Zend Framework : sélecteur de devises

En ces temps de difficulté de la zone Euro, je vous propose un composant qui colle à l'actualité : un sélecteur de devise.

Le sélecteur de devises

Le code est très similaire au sélecteur de pays que je vous avais proposé dans un précédent article. En fait, c'est Zend_Locale qui fait le plus gros du travail, c'est lui qui fournit la liste des devises.

<?php
class Wiip_Form_Element_SelectCurrency extends Wiip_Form_Element_Select
{
    
/**
     * Désactive le traducteur (les noms de devises sont déjà traduits)
     *
     * @var bool
     */
    
protected $_translatorDisabled true;

    function 
init()
    {
        
// Tableau de devises et d'unités monétaires où la clé correspond
        // au code de la devise (norme ISO 4217 ; EUR par exemple pour l'Euro)
        
$items Zend_Locale::getTranslationList('NameToCurrency');

        
// Supprime les entrées commençant par X qui ne sont pas des devises
        // mais des unités monétaires.
        // Retire les devises qui n'ont plus cours
        // Passe en majuscule la première lettre.
        
$currencies = array();
        
$notActive = array('ADF''ADP''AFA''ALK''AOK''AON''AOR',
            
'ARP''ATS''AZM''BEC''BEF''BEL''BGL''BOP''BRB',
            
'BRC''BRE''BRR''BYB''BYP''CSD''CSK''DEM''DDM',
            
'FIM''FRF''GRD''IEP''ITL''LUF''LVR''MGF''MXP',
            
'MZE''MZM''NIC''NLG''PES''PLZ''PTE''ROL''RUR',
            
'SDD''SDP''SIT''SKK''SML''SUB''SUR''TMM''TPE',
            
'TRL''UGS''USS''USN''UYP''VAL');
        foreach (
$items as $key => $value)
        {
            if (
'X' != $key[0] and !in_array($key$notActive)) {
                
$currencies[$key] = ucfirst($value) . " ($key)";
            }
        }
        
        
// Tri de la liste
        
$oldLocale setlocale(LC_COLLATE'0');
        
setlocale(LC_COLLATE'fr_FR.utf8');
        
asort($currenciesSORT_LOCALE_STRING);
        
setlocale(LC_COLLATE$oldLocale);

        
// Déplace les devises les plus courantes en tête de liste
        
$usedMostFrequently = array('EUR''USD''GBP');
        
$topItems = array();
        foreach (
$usedMostFrequently as $currency)
        {
            
$topItems[$currency] = $currencies[$currency];
            unset(
$currencies[$currency]);
        }

        
// Ajoute un séparateur non sélectionnable
        
$topItems['--'] = '--';
        
$this->setOptions(array('disable' => array('--')));

        
$currencies array_merge($topItems$currencies);

        
$this->addMultiOptions($currencies);
    }
}
?>

Tout ce qui nous reste à faire, c'est de supprimer les entrées qui commencent par X car ce ne sont pas des devises mais des unités monétaires, supprimer les monnaies qui n'ont plus cours comme le Mark Allemand (attention, je ne suis pas un expert, j'ai peut être laissé passer certaines devises, merci de me les signaler), mettre en majuscules la première lettre pour que ce soit plus joli, ensuite on trie la liste pour faciliter la sélection. Enfin, on déplace les devises les plus courantes en tête de liste pour éviter à l'utilisateur de devoir faire défiler toute la liste à chaque fois. Ici, j'ai choisi arbitrairement l'Euro, le dollar américain et la livre Sterling. Libre à vous de personnaliser cette liste ou de la constituer par exemple en examinant les devises les plus utilisées dans votre base de données.

La valeur sélectionné est le code de la devise (norme ISO 4217 ; EUR par exemple pour l'Euro), c'est à dire un code de 3 lettres qu'on pourra stocker dans une base de données MySQL sous la forme d'un CHAR(3) en ascii_bin.

Exemple d'utilisation :

<?php
class MonFormulaire extends Zend_Form
{
    public function 
init()
    {
        [..]
 
        
// On ajoute un chemin de recherche pour que Zend_Form puisse 
        // trouver le nouvel élément
        
$this->addPrefixPath('Wiip_Form_Element''Wiip/Form/Element/',
            
Zend_Form::ELEMENT);
 
        
$this->addElement(
            
'selectCurrency',
            
'currency',
            array(
                
'label' => 'Devise'
            
)
        );
 
        [..]
     }
}
?>

Add new comment