DiscoverPlaces Raport #4

Czas na kolejny raport odnośnie projektu tworzonego w ramach konkursu Daj się Poznać 2017. API zostało ukończone, przynajmniej w podstawowej wersji. Teraz przechodzę do tworzenia aplikacji w React Native.

Opis projektu znajduje się tutaj.

Zmiany

Dokładne zmiany w kodzie można śledzić na githubie. Od ostatniego raportu dodana została ostatnia pozostała obecnie rzecz do zrobienia w API, czyli pobieranie wiadomości na podstawie przesłanych współrzędnych. Odbywa się to w taki sposób, że podczas wyciągania z bazy danych wyliczana jest odległość między punktem określonym przed współrzędne pobrane z Requesta, a punktem definiowanym przez współrzędne wiadomości, następnie odległość porównywana jest z zasięgiem danej wiadomości, jeśli jest mniejsza bądź równa to wiadomość jest zwracana. Algorytm obliczania odległości oparty o promień Ziemi opisany jest tutaj:

<?php

namespace AppBundle\Repository;

use AppBundle\Entity\Message;
use Doctrine\ORM\EntityRepository;

/**
 * Class MessageRepository
 * @package AppBundle\Repository
 */
class MessageRepository extends EntityRepository
{
    /**
     * @param float $lat
     * @param float $long
     * @return array
     */
    public function findByCoordinates(float $lat, float $long)
    {
        $qb = $this
            ->createQueryBuilder('m')
            ->select('m, 
                (6371 * acos(
                        cos(radians(m.latitude)) 
                        * cos(radians(:lat)) 
                        * cos(
                            radians(:long) - radians(m.longitude)
                        ) 
                        + sin(radians(m.latitude)) 
                        * sin(radians(:lat)) 
                    ) 
                ) 
                AS distance
            ')
            ->setParameters([
                'lat' => $lat,
                'long' => $long
            ])
            ->having('distance <= m.scope')
        ;

        return $qb->getQuery()->getResult();
    }
}

Doctrine Extensions

Dodatkowo, aby w DQL mieć dostęp do funkcji acos(), cos(), radians(), sin() etc. wystarczy zainstalować pakiet Doctrine Extensions. Następnie wystarczy prosta konfiguracja, przykładowo dla tego przypadku mamy:

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

Circular Reference

W przypadku serializacji encji zawierających relacje dwukierunkowe(ang. bidirectrional), abyśmy nie dostali błędu Circular Reference …, trzeba wykluczyć serializacje niektórych elementów. W tym przypadku problem pojawiał się przy serializacji wiadomości, która zawierała komentarz, który również miał w sobie zawartą referencję do wiadomości. Rozwiązane to zostało za pomocą grup.

/**
 * @var int
 *
 * @Groups({"api"})
 */
private $id;

/**
 * @var string
 *
 * @Groups({"api"})
 */
private $content;

/**
 * @var string
 *
 * @Groups({"api"})
 */
private $photo;

/**
 * @var string
 *
 * @Groups({"api"})
 */
private $video;

/**
 * @var \DateTime
 *
 * @Groups({"api"})
 */
private $date;

/**
 * @var Message
 */
private $message;

Gdzie do wiadomości nie została dodana grupa, następnie serializer konfigurujemy tak, aby „zajmował się” tylko polami z adnotacją grupy api. Oczywiście można dodać kilka grup. Dodatkowe opcje serializacji można uzyskać za pomocą JMS Serializer.

Dalsze plany

Jak już wspomniałem podstawowa wersja api jest gotowa. W kolejnych dniach będę zajmował się tworzeniem aplikacji w React Native.

 

Udostępnij: