validateRequest($req); if (!$validity['is_valid']) { return new ApiResponse(false, $validity['error']); } // get partner $partner = $this->em->getRepository(Partner::class)->findOneBy(['id' => $pid]); if ($partner == null) { return new ApiResponse(false, 'No partner found.'); } // get reviews for partner $reviews = $this->em->getRepository(Review::class)->findBy(['partner' => $partner]); // get average rating for all reviews $average_rating = 0; if (!empty($reviews)) { $rating = 0; foreach ($reviews as $review) { $rating = $rating + $review->getRating(); } $average_rating = $rating / sizeof($reviews); } $data = []; $data['partner'] = [ 'id' => $partner->getID(), 'name' => $partner->getName(), 'branch' => $partner->getBranch(), 'address' => $partner->getAddress(), 'contact_nums' => $partner->getContactNumbers(), 'time_open' => $partner->getTimeOpen()->format("g:i A"), 'time_close' => $partner->getTimeClose()->format("g:i A"), 'longitude' => $partner->getCoordinates()->getLongitude(), 'latitude' => $partner->getCoordinates()->getLatitude(), 'average_rating' => $average_rating, ]; // response return new ApiResponse(true, '', $data); } public function getClosestPartners(Request $req) { // validate params $validity = $this->validateRequest($req, [ 'longitude', 'latitude', 'service_id', 'limit', ]); if (!$validity['is_valid']) { return new ApiResponse(false, $validity['error']); } $long = $req->query->get('longitude'); $lat = $req->query->get('latitude'); $service_id = $req->query->get('service_id'); $limit = $req->query->get('limit'); // get partners within range $query = $this->em->createQuery('SELECT p, st_distance(p.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Partner p JOIN App\Entity\Service s where s.id = :service_id ORDER BY dist') ->setParameter('lat', $lat) ->setParameter('lng', $long) ->setParameter('service_id', $service_id); $query->setMaxResults($limit); $result = $query->getResult(); $data = []; $partners = []; foreach ($result as $row) { // get all the reviews for each partner and average the ratings $partner_id = $row[0]->getID(); $partner = $this->em->getRepository(Partner::class)->find($partner_id); $partner_reviews = $this->em->getRepository(Review::class)->findBy(['partner' => $partner]); $average_rating = 0; if (count($partner_reviews) > 0) { $rating = 0; foreach ($partner_reviews as $review) { $rating = $rating + $review->getRating(); } $average_rating = $rating / sizeof($partner_reviews); } $partners[] = [ 'id' => $row[0]->getID(), 'name' => $row[0]->getName(), 'branch' => $row[0]->getBranch(), 'address' => $row[0]->getAddress(), 'contact_nums' => $row[0]->getContactNumbers(), 'time_open' => $row[0]->getTimeOpen()->format("g:i A"), 'time_close' => $row[0]->getTimeClose()->format("g:i A"), 'longitude' => $row[0]->getCoordinates()->getLongitude(), 'latitude' => $row[0]->getCoordinates()->getLatitude(), 'db_distance' => $row['dist'], 'rating' => $average_rating, ]; } $data['partners'] = $partners; // response return new ApiResponse(true, '', $data); } public function reviewPartner($pid, Request $req) { // validate params $validity = $this->validateRequest($req, [ 'rating', 'message', ]); if (!$validity['is_valid']) { return new ApiResponse(false, $validity['error']); } $rating = $req->request->get('rating'); $msg = $req->request->get('message'); // TODO: check rating if 1 - 5 // check if partner exists $partner = $this->em->getRepository(Partner::class)->find($pid); if ($partner == null) { return new ApiResponse(false, 'No partner found.'); } $rev = new Review(); $rev->setRating($rating) ->setMessage($msg) ->setPartner($partner) ->setCustomerSession($this->session); // NOTE: using new customer session entity // save to db $this->em->persist($rev); $this->em->flush(); // response return new ApiResponse(); } }