Archives mensuelles : janvier 2018

Symfony : Afficher des dates en français dans Twig

—————————————————– Version 2023 ——————————————-
L’article n’étant plus d’actualité, voici une mise à jour rapide :
Il faut à présent utiliser le filtre format_datetime de twig

Pour cela il est nécessaire d’installer

composer require twig/intl-extra

et

composer require twig/extra-bundle

Ensuite on peux l’utiliser dans twig sur un objet date pour par exemple afficher « Novembre 2023 »

{{ maDate|format_datetime(pattern='MMMM Y') }}

—————————————————– Version 2018 ——————————————-

Lorsque travaille sous Symfony, avec des templates twig, on peut afficher des dates (généralement stocké coté PHP sous forme de DateTime()) grâce au filtre « date » de la façon suivante :

{{maDate|date('d/m/Y')}}//affiche la date au format 22/01/2018

Mais si l’on veux un affichage textuel en français du type « lundi 22 janvier 2018 » il nous faut utiliser une extension twig.
Pour installer cette extensions (ainsi que d’autres) dans votre projet, il faut lancer la commande composer suivante :

composer require twig/extensions

Nous devons ensuite configurer l’extension « intl » qui nous intéresse, dans le fichier de configurations des services :

services:
    twig.extension.intl
:
        class
: Twig_Extensions_Extension_Intl
        tags
:
            - { name
: twig.extension }

Le filtre « localizeddate » est maintenant utilisable et permet d’afficher la date au format que l’on souhaite, et dans la langue que l’on souhaite (en utilisant par défaut la langue configuré dans notre projet symfony) En voici 2 exemples.

{{entity.dateEvent|localizeddate('none', 'none', null, null, 'EEEE')}}//lundi
{{entity.dateEvent|localizeddate('none', 'none', null, null, 'MMMM Y')}}//Janvier 2018

Pour plus d’information veuillez vous référez au documentations suivantes :
http://twig-extensions.readthedocs.io/en/latest/intl.html#localizeddate
http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax

jQuery : Accéder à des champs de formulaire ayant un nom dans un tableau

Avec jQuery on peux récupérer la valeur d’un champ en le sélectionnant grâce à son nom (attribut name).
Par exemple pour connaitre la valeur sélectionné des radio boutons suivants :

<label for="radio1"><input name="choix" value="1" type="radio" id="radio1"> Choix 1</label>
<label for="radio2"><input name="choix" value="2" type="radio" id="radio2"> Choix 2</label>
<label for="radio3"><input name="choix" value="3" type="radio" id="radio3"> Choix 3</label>

Il suffit de faire :

$("input[name='choix']:checked").val();

Par contre si le nom est composé, comme dans l’exemple ci-dessous :

<label for="radio1"><input name="mon_formulaire[choix]" value="1" type="radio" id="radio1"> Choix 1</label>
<label for="radio2"><input name="mon_formulaire[choix]" value="2" type="radio" id="radio2"> Choix 2</label>
<label for="radio3"><input name="mon_formulaire[choix]" value="3" type="radio" id="radio3"> Choix 3</label>

Il faut utiliser les carractères d’échappement « \\ » pour que ça fonctionne. Comme ci-dessous.

$("input[name='mon_formulaire\\[choix\\]']:checked").val()

Doctrine : Recherche dans une table contenant des latitudes et longitudes celle situés à moins de « XX » km

Il y’a quelques mois je présentais une fonction PHP permettant de calculer la distance entre 2 coordonnées GPS (latitude et longitude). Coordonnées qui peuvent par exemple être récupérer via l’API Google Map

Nous allons voir dans cette article, comment récupérer toutes les enregistrements d’une table qui sont situé à moins de « 50km » d’une position précise. Il nous faut donc les coordonées de la position pour laquelle on fait la recherche, ainsi qu’une table avec les colonnes « lat » et « lng »

La formule permettant de faire le calcul (en km) directement en MySql et la suivante :

//la formule utilisant nos coordonées "$lat" et "$lng" ainsi que les colonne "lat" et "lng" de la table "table"
$sqlDistance = '(6378 * acos(cos(radians(' . $lat . ')) * cos(radians(table.lat)) * cos(radians(table.lng) - radians(' . $lng . ')) + sin(radians(' . $lat . ')) * sin(radians(table.lat))))';

Formule utilisable pour rechercher les enregistrements inférieur à 50km de notre position, via le requête suivante :

$requete = 'SELECT * FROM table WHERE '.$sqlDistance.' < 50 ';

Si l’on travaille sous Symfony et avec Doctrine, en ajoutant notre condition dans un « querybuilder » comme ci-dessous ça ne va pas fonctionner.

//Imaginons que nous sommes dans une requête classique crée avec le querybuilder $qb
//On veut rajouter la condition de la distance (en utilisant une $distance variable dans ce cas).
$qb->andWhere("" . $sqlDistance . " < :distance")->setParameter('distance', $distance);

Doctrine ne connait pas les différentes fonctions de calculs « acos », « cos », « radian » et « sin » utilisées dans la formule. Nous allons les importer grâce à la bibliothèque DoctrineExtensions. Pour cela, il suffit de faire un petit coup de composer sur notre projet :

composer require beberlei/DoctrineExtensions

Et ensuite d’indiquer les fonctions dont on à besoin dans notre configuration de doctrine de la manière suivante :

doctrine:
    orm
:
        dql
:
            numeric_functions
:
                acos
: DoctrineExtensions\Query\Mysql\Acos
                cos
: DoctrineExtensions\Query\Mysql\Cos
                radians
: DoctrineExtensions\Query\Mysql\Radians
                sin
: DoctrineExtensions\Query\Mysql\Sin

Tout doit à présente fonctionner. Vous pouvez de cette manière importer une flopée de fonctions, la configuration complète étant disponible Sur cette page

Javascript : Mettre en place un lecteur audio avec « AmplitudeJS »

Aujourd’hui nous allons découvrir AmplitudeJS qui permet de mettre en place sur vos page un lecteur audio flexible et complètement personnalisable. Comme on peux le voir sur leurs exemples avec un peu de travail on peux avoir des résultats très sympas.

Avant d’en arriver la, je vous propose un exemple bien plus simple. Le résultat est visible ici et il suffit de regarder le code source de la page pour comprendre le fonctionnement.

Le visuel obtenu sera le suivant, mais graphiquement tout est possible, il n’y à pas de contraintes à ce niveau.

Quelques explications supplémentaires ci-dessous.

Pour commencer on va inclure la « library » « amplitude.js », ainsi que « bootstrap », « font-awesome » et un fichier « styles.css » pour la mise en page.

    <!-- CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" >
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="./css/style.css">
    <!-- JS -->
    <script src="./js/amplitude.min.js"></script>

Dans le corps de la page mettons en place notre player en utilisant les éléments « amplitude », les boutons « bootstrap » et les icones « font-awesome » :

    <div class="glob-player">
        <div class="glob-btn">
            <span class="amplitude-prev btn btn-primary"><i class="fa fa-step-backward" aria-hidden="true"></i></span>
            <span class="btn amplitude-play-pause btn-primary" amplitude-main-play-pause="true"><i class="fa fa-play" aria-hidden="true"></i> <i class="fa fa-pause" aria-hidden="true"></i></span>
            <span class="my-next-btn amplitude-next btn btn-primary"><i class="fa fa-step-forward" aria-hidden="true"></i></span>
        </div>
        <div>
            <div class="meta-name" amplitude-song-info="name" amplitude-main-song-info="true"></div>
            <progress class="amplitude-song-played-progress" amplitude-main-song-played-progress="true" id="song-played-progress"></progress>
        </div>
    </div>

On ajoute juste quelques ligne pour le style dans notre fichier « styles.css »

/* player */
.glob-player{padding: 10px;border-radius: 5px;background: #000;}
.glob-player .glob-btn{text-align: center;}
.glob-player .meta-name{color:#fff;text-align: center;padding:10px;}
/*progres-bar*/
.amplitude-song-played-progress {
    -webkit-appearance: none;-moz-appearance: none;appearance: none;
    background-color: #ccc;width: 100%;height: 5px;display: block;border: none;
}
progress.amplitude-song-played-progress[value]::-webkit-progress-bar {
    background-color: #0069d9;
}
progress.amplitude-song-played-progress[value]::-moz-progress-bar {
    background-color: #0069d9;
}
progress.amplitude-song-played-progress[value]::-webkit-progress-value {
    background-color: #0069d9;
}

Il nous suffit maintenant d’uploader nos MP3 dans le dossier que l’on souhaite et d’indiquer à « amplitude » de les prendre en charge.

<script>
    Amplitude.init({
        "songs": [
            {
                "name": "Le bal masqué",
                "artist": "Opium du peuple",
                "album": "La révolte des opiumettes",
                "url": "./song/le-bal-masque.mp3",
            },
            {
                "name": "Poupée de cire, poupée de son",
                "artist": "Opium du peuple",
                "album": "La révolte des opiumettes",
                "url": "./song/poupee-de-cire.mp3",
            }
        ],
        callbacks: {
            //pour démarrer la lecture à cuaque fois que l'on passe au morceau suivant ou préc
            song_change: function () {
                Amplitude.play();
            }
        }
    });
</script>