Archives mensuelles : janvier 2018

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>