2 namespace App\Controller
;
5 use App\Entity\Localisation
;
7 use Symfony\Bundle\FrameworkBundle\Controller\Controller
;
8 use FOS\RestBundle\Controller\FOSRestController
;
9 use FOS\RestBundle\Controller\Annotations
as Rest
;
10 use FOS\RestBundle\View\ViewHandler
;
11 use FOS\RestBundle\View\View
;
12 use FOS\RestBundle\Request\ParamFetcherInterface
;
13 use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter
;
14 use Symfony\Component\HttpFoundation\Request
;
15 use Symfony\Component\HttpFoundation\Response
;
16 use Symfony\Component\Routing\Generator\UrlGeneratorInterface
;
18 class PersonController
extends FOSRestController
22 * path = "/api/person/register",
23 * name = "create_person"
25 * @Rest\View(StatusCode = Response::HTTP_CREATED)
27 public function createPersonAction(Request
$request)
29 $person = new Person();
30 $person->setFirstname($request->get('firstname'));
31 $person->setLastName($request->get('lastname'));
32 //TODO: email creation should normally have a verification step
33 $person->setEmail($request->get('email'));
34 $person->setPassword($request->get('password'));
35 $person->setOnline(false);
37 $em = $this->getDoctrine()->getManager();
39 $em->persist($person);
42 return $this->view($person, Response
::HTTP_CREATED
,
43 ['Location' => $this->generateUrl('show_person',
44 ['id' => $person->getId(),
45 UrlGeneratorInterface
::ABSOLUTE_URL
])]);
49 * @Rest\Delete("/api/person/{id}")
50 * @Rest\View(statusCode = Response::HTTP_NO_CONTENT)
52 public function removePersonAction(Request
$request)
54 //TODO: check that the authenticated user have the same id
55 $em = $this->getDoctrine()->getManager();
56 $person = $em->getRepository('App:Person')->find($request->get('id'));
57 $friends = $em->getRepository('App:Friendship')->findBy(['person' => $request->get('id')]);
58 $friends_with_me = $em->getRepository('App:Friendship')->findBy(['friend' => $request->get('id')]);
59 $localisations = $em->getRepository('App:Localisation')->findBy(['person' => $request->get('id')]);
61 if (!empty($localisations)) {
62 foreach ($localisations as $localisation) {
63 $em->remove($localisation);
68 if (!empty($friends)) {
69 foreach ($friends as $friend) {
75 if (!empty($friends_with_me)) {
76 foreach ($friends_with_me as $friend) {
82 if (!empty($person)) {
90 * path = "/api/person/{id}",
91 * name = "update_person"
93 * @Rest\View(StatusCode = Response::HTTP_CREATED)
95 public function updatePersonAction(Request
$request)
97 //TODO: check that the authenticated user have the same id
98 $em = $this->getDoctrine()->getManager();
99 $person = $em->getRepository('App:Person')->find($request->get('id'));
101 if (empty($person)) {
102 return $this->PersonNotFound();
105 $person->setFirstName($request->get('firstname'));
106 $person->setLastName($request->get('lastname'));
107 //TODO: email update should normally have a verification step
108 $person->setEmail($request->get('email'));
113 return $this->view($person, Response
::HTTP_CREATED
,
114 ['Location' => $this->generateUrl('show_person',
115 ['id' => $person->getId(),
116 UrlGeneratorInterface
::ABSOLUTE_URL
])]);
121 * path = "/api/person/authenticate",
122 * name = "authenticate_person"
124 * @Rest\View(StatusCode = Response::HTTP_ACCEPTED)
126 public function authenticatePersonAction(Request
$request)
128 $em = $this->getDoctrine()->getManager();
129 $person = $em->getRepository('App:Person')->findOneBy(['email' => $request->get('email')]);
131 if (empty($person)) {
132 return $this->PersonNotFound();
135 if ($request->get('password') != $person->getPassword()) {
136 return $this->PersonWrongPassword();
138 return $this->view($person, Response
::HTTP_ACCEPTED
,
139 ['Location' => $this->generateUrl('show_person',
140 ['id' => $person->getId(),
141 UrlGeneratorInterface
::ABSOLUTE_URL
])]);
146 * @Rest\Get("/api/person/{id}/localisations")
149 public function getLocalisationsAction(Request
$request)
151 //TODO: Check that the authenticated user is allowed to see the localisation
152 $em = $this->getDoctrine()->getManager();
153 $localisations = $em->getRepository('App:Localisation')->findBy(['person' => $request->get('id')]);
155 if (empty($localisations)) {
156 return $this->PersonLocalisationsNotFound();
159 return $localisations;
164 * path = "/api/person/{id}/localisations/fuzzy/{distance}",
165 * name = "person_localisations_fuzzy",
166 * requirements = {"id"="\d+", "distance"="\d+"}
170 public function getLocalisationsFuzzyAction(Request
$request)
172 //TODO: Check that the authenticated user is allowed to see the localisation
173 $em = $this->getDoctrine()->getManager();
174 $localisations = $em->getRepository('App:Localisation')->findBy(['person' => $request->get('id')]);
176 if (empty($localisations)) {
177 return $this->PersonLocalisationsNotFound();
180 if (!$this->chk_distance($request->get('distance'), 200, 500)) {
181 return $this->PersonLocalisationFuzzyWrongDistance();
184 $fuzzy_localisations = array_map(function($item) use ($request) { return $this->randomizeLocation($item, $request->get('distance'), 200, 500); }, $localisations);
186 return $fuzzy_localisations;
189 private function getLastLocalisation($em, $id) {
190 $query = $em->createQuery("SELECT l1 FROM App\Entity\Localisation l1
191 WHERE l1.person = :person and l1.timestamp =
192 (SELECT MAX(l2.timestamp) FROM App\Entity\Localisation l2
193 WHERE l2.person = l1.person)");
194 $query->setParameter('person', $id);
195 $result = $query->getResult();
196 if (!empty($result)) {
202 * @Rest\Get("/api/person/{id}/localisation")
205 public function getLocalisationAction(Request
$request)
207 //TODO: Check that the authenticated user is allowed to see the localisation
208 $em = $this->getDoctrine()->getManager();
210 $localisation = $this->getLastLocalisation($em, $request->get('id'));
212 if (empty($localisation)) {
213 return $this->PersonLocalisationNotFound();
216 return $localisation;
219 private function chk_distance($distance, $min, $max) {
220 if ($distance >= $min && $distance <= $max) {
227 private function randomizeLocation($localisation, $distance, $min, $max) {
228 // Generate random float in [0, 1[, [0, 1)
229 $u = rand(0, getrandmax() - 1) / getrandmax();
230 $v = rand(0, getrandmax() - 1) / getrandmax();
232 if ($this->chk_distance($distance, $min, $max)) {
233 $r = $distance / 111300;
235 return $this->PersonLocalisationFuzzyWrongDistance();
242 $lng_off = $x / cos(deg2rad($localisation->getLatitude()));
243 $lat_off = $w * sin($t);
245 $fuzzy_localisation = new Localisation();
246 $fuzzy_localisation->setTimestamp($localisation->getTimestamp());
247 $fuzzy_localisation->setLatitude($localisation->getLatitude() +
$lat_off);
248 $fuzzy_localisation->setLongitude($localisation->getLongitude() +
$lng_off);
249 return $fuzzy_localisation;
254 * path = "/api/person/{id}/localisation/fuzzy/{distance}",
255 * name = "person_localisation_fuzzy",
256 * requirements = {"id"="\d+", "distance"="\d+"}
260 public function getLocalisationFuzzyAction(Request
$request)
262 //TODO: Check that the authenticated user is allowed to see the localisation
263 $em = $this->getDoctrine()->getManager();
265 $localisation = $this->getLastLocalisation($em, $request->get('id'));
267 if (empty($localisation)) {
268 return $this->PersonLocalisationNotFound();
271 return $this->randomizeLocation($localisation, $request->get('distance'), 200, 500);
275 * @Rest\Post("/api/person/{id}/localisation")
276 * @Rest\View(StatusCode = Response::HTTP_CREATED)
278 public function updateLocalisationAction(Request
$request)
280 //TODO: Check that the authenticated user is allowed to update the localisation
281 $em = $this->getDoctrine()->getManager();
283 $person = $em->getRepository('App:Person')->find($request->get('id'));
285 if (empty($person)) {
286 return $this->PersonNotFound();
289 $datetime = new DateTime($request->get('timestamp'));
291 $localisation = new Localisation();
292 $localisation->setPerson($person);
293 $localisation->setTimestamp($datetime);
294 $localisation->setLatitude($request->get('latitude'));
295 $localisation->setLongitude($request->get('longitude'));
297 $em->persist($localisation);
303 * path = "/api/person/{id}",
304 * name = "show_person",
305 * requirements = {"id"="\d+"}
309 public function showPerson(Request
$request)
311 $em = $this->getDoctrine()->getManager();
312 $person = $em->getRepository('App:Person')->find($request->get('id'));
314 if (empty($person)) {
315 return $this->PersonNotFound();
323 * path = "/api/person/{id}/friends",
324 * name = "show_person_friends",
325 * requirements = {"id"="\d+"}
329 public function showPersonFriends(Request
$request)
331 $em = $this->getDoctrine()->getManager();
332 $person = $em->getRepository('App:Person')->find($request->get('id'));
334 if (empty($person)) {
335 return $this->PersonNotFound();
338 return $person->getFriends();
343 * path = "/api/person/{id}/friendswithme",
344 * name = "show_person_friends_with_me",
345 * requirements = {"id"="\d+"}
349 public function showPersonFriendsWithMe(Request
$request)
351 $em = $this->getDoctrine()->getManager();
352 $person = $em->getRepository('App:Person')->find($request->get('id'));
354 if (empty($person)) {
355 return $this->PersonNotFound();
358 $friends_with_me = $person->getFriendsWithMe();
360 return $friends_with_me;
365 * path = "/api/persons",
366 * name = "show_persons"
370 public function showPersons(Request
$request)
372 $em = $this->getDoctrine()->getManager();
373 $persons = $em->getRepository('App:Person')->findAll();
375 if (empty($persons)) {
376 return $this->PersonsNotFound();
384 * path = "/api/person/{id}/online",
385 * name = "set_person_online"
387 * @Rest\View(StatusCode = Response::HTTP_CREATED)
389 public function onlinePersonAction(Request
$request)
391 //TODO: check that the authenticated user have the same id
392 $em = $this->getDoctrine()->getManager();
393 $person = $em->getRepository('App:Person')->find($request->get('id'));
395 if (empty($person)) {
396 return $this->PersonNotFound();
399 $person->setOnline(true);
407 * path = "/api/person/{id}/offline",
408 * name = "set_person_offline"
410 * @Rest\View(StatusCode = Response::HTTP_CREATED)
412 public function offlinePersonAction(Request
$request)
414 //TODO: check that the authenticated user have the same id
415 $em = $this->getDoctrine()->getManager();
416 $person = $em->getRepository('App:Person')->find($request->get('id'));
418 if (empty($person)) {
419 return $this->PersonNotFound();
422 $person->setOnline(false);
430 * path = "/api/person/search",
431 * name = "search_person"
433 * @Rest\QueryParam(name="keyword")
436 public function searchPerson(ParamFetcherInterface
$paramFetcher)
438 $em = $this->getDoctrine()->getManager();
439 $query = $em->createQuery("SELECT DISTINCT p FROM App\Entity\Person p WHERE
440 p.firstname LIKE :keyword OR
441 p.lastname LIKE :keyword OR
442 p.email LIKE :keyword");
443 $query->setParameter('keyword', '%'.$paramFetcher->get('keyword').'%');
444 $persons = $query->getResult();
446 if (empty($persons)) {
447 return $this->PersonsNotFound();
453 private function PersonNotFound() {
454 return View
::create(['message' => 'Person not found'], Response
::HTTP_NOT_FOUND
);
457 private function PersonsNotFound() {
458 return View
::create(['message' => 'Persons not found'], Response
::HTTP_NOT_FOUND
);
461 private function PersonLocalisationNotFound() {
462 return View
::create(['message' => 'Person localisation not found'], Response
::HTTP_NOT_FOUND
);
465 private function PersonLocalisationsNotFound() {
466 return View
::create(['message' => 'Person localisations not found'], Response
::HTTP_NOT_FOUND
);
469 private function PersonWrongPassword() {
470 return View
::create(['message' => 'Supplied password do not match'], Response
::HTTP_UNAUTHORIZED
);
472 private function PersonLocalisationFuzzyWrongDistance() {
473 return View
::create(['message' => 'Distance range do not match'], Response
::HTTP_NOT_ACCEPTABLE
);