Tuesday, 22 January 2019

PHP - Parse SDK query on ParseGeoPoint doesn't work properly

I've got an issue that I can't fix, it's been weeks I'm trying to do so but I just can't figure out what I'm doing wrong, or if there's something wrong in the Parse PHP SDK.

I have built a website with Parse Server as backend, it's a listing website with location detection, and I'm working on Chrome (I've tried Firefox and Safari as well, I get the same problem).

My steps:

  1. When you got to the home page, the browser asks you to allow location detection, I allow it.
  2. If you click on the location button, you can open a Google map into a modal and place the pin on click to the desired location, you can also set the distance range by moving a slider. I select London, UK
  3. I get the right console messages in Chrome:

    DISTANCE: 87 Km
    MARKER LAT: 51.522497992110246 - MARKER LNG: -0.12863733794108612

The issue comes here, the website shows only some of the posted Ads, but those Ads have been submitted through a mobile app (my own source code too, with Parse iOS and Android SDKs), it doesn't display those ads I've submitted through the website. Weird thing, if I post ads from the website and I open my mobile app, I can see them! Lastly, If I perform a search by keywords with the search bar on the top of the page, I can find those ads I've posted through the website. So, no keywords, no ads posted through the website...

Here's my PHP code to query ads:

/*--- variables ---*/
$isFollowing = $_GET['isFollowing'];
$option = $_GET['option'];
$upObjID = $_GET['upObjID'];
$latitude = $_GET['lat'];
$longitude = $_GET['lng'];
$dist = $_GET['distance'];
$distance = (int)$dist;
$category = $_GET['category'];
$sortBy = str_replace(' ', '', $_GET['sortBy']);
$keywords = preg_split('/\s+/', $_GET['keywords']);

// query Ads
try {
   $query = new ParseQuery($ADS_CLASS_NAME);
   $query->equalTo($ADS_IS_REPORTED, false);

   // it's following.php
   if ($isFollowing == true) {
      $currentUser = ParseUser::getCurrentUser();
      $cuObjIdArr = array(); 
      array_push($cuObjIdArr, $currentUser->getObjectId());
      $query->containedIn($ADS_FOLLOWED_BY, $cuObjIdArr);

   // it's User profile page
   } else if ($upObjID != null) {
      $userPointer = new ParseUser($USER_CLASS_NAME, $upObjID);
      $userPointer->fetch();
      $query->equalTo($ADS_SELLER_POINTER, $userPointer);

      if ($option == 'selling'){ $query->equalTo($ADS_IS_SOLD, false);
      } else if ($option == 'sold'){ $query->equalTo($ADS_IS_SOLD, true); 
      } else if ($option == 'liked'){ $query->containedIn($ADS_LIKED_BY, array($userPointer->getObjectId())); }

   // it's index.php
   } else {

      // nearby Ads
      if ($latitude != null  &&  $longitude != null) {
         $currentLocation = new ParseGeoPoint($latitude, $longitude);

         $query->withinKilometers($ADS_LOCATION, $currentLocation, $distance);
         /* NOTE - UNCOMMENT THE LINE BELOW AND COMMENT THE LINE ABOVE IN CASE YOU WANT TO FILTER FOR MILES INSTEAD OF KILOMETERS: */
         // $query->withinMiles($ADS_LOCATION, $currentLocation, $distance);

      // nearby DEFAULT LOCATION COORDINATES
      } else { 
         $defaultLocation = new ParseGeoPoint($DEFAULT_LOCATION_LATITUDE, $DEFAULT_LOCATION_LONGITUDE);

         $query->withinKilometers($ADS_LOCATION, $defaultLocation, $DISTANCE_IN_KM); 
         /* NOTE - UNCOMMENT THE LINE BELOW AND COMMENT THE LINE ABOVE IN CASE YOU WANT TO FILTER FOR MILES INSTEAD OF KILOMETERS: */
         // $query->withinMiles($ADS_LOCATION, $defaultLocation, $DISTANCE_IN_KM);
      }

      // keywords
      if (count($keywords) != 0) { $query->containedIn($ADS_KEYWORDS, $keywords); }

      // category
      if ($category != "All") { $query->equalTo($ADS_CATEGORY, $category); }

      // sort by
      switch ($sortBy) {
         case 'Newest': $query->descending("createdAt");
            break;
         case 'Price:lowtohigh': $query->ascending($ADS_PRICE);
            break;
         case 'Price:hightolow': $query->descending($ADS_PRICE);
            break;
         case 'MostLiked': $query->descending($ADS_LIKES);
            break;

         default: break;
      }// ./ sort by

   }// ./ If


   // perform query
   $adsArray = $query->find(); 
   if (count($adsArray) != 0) {
      for ($i = 0;  $i < count($adsArray); $i++) {
         // Parse Obj
         $adObj = $adsArray[$i];

         // image 1
         $adImg = $adObj->get($ADS_IMAGE1);
         // title
         $adTitle = substr ($adObj->get($ADS_TITLE), 0, 24).'...';
         // currency
         $adCurrency = $adObj->get($ADS_CURRENCY);
         // price
         $adPrice = $adObj->get($ADS_PRICE);

         echo '
            <!-- Ad card -->
            <div class="col-lg-3 col-md-5 portfolio-item">
               <div class="card">
         ';

         // Sold badge
         $isSold = $adObj->get($ADS_IS_SOLD);
         if ($isSold) { echo '<div class="card-sold-badge"><img src="assets/images/sold-badge.png"></div>'; }
         echo '
            <a href="ad-info.php?adObjID='.$adObj->getObjectId().'"><img src="'.$adImg->getURL().'"></a>
            <div class="card-body">
               <p class="card-title"><a href="ad-info.php?adObjID='.$adObj->getObjectId().'">'.$adTitle.'</a></p>
               <p class="card-price">'.$adCurrency.' '.$adPrice.'</p>
            </div>
            </div>
            </div>
         ';
      }// ./ For

   // no ads
   } else {
      echo '
         <div class="col-lg-12 col-md-12">
            <div class="text-center" style="margin-top: 40px; font-weight: 600">No Ads found.</div>
         </div>
      ';
   }

// error
} catch (ParseException $e){ echo $e->getMessage(); }

The above code comes from a separate file called query-ads.php and it gets displayed in a div:

<div class="row" id="adsGrid"></div>

I perform an AJAX function to call query-ads.php:

function queryAds(catName, keywords) {
        // category
        if (catName == null) { catName = "All"; }
        document.getElementById("categoryName").innerHTML = '<h5 id="categoryName"><strong>' + catName + '</strong></h5>';
        // keywords
        if (keywords == null) { keywords = ''; }

        // console.log('KEYWORDS: ' + keywords);
        // console.log('LAT: ' + latitude + ' -- LNG: ' + longitude);
        console.log('DISTANCE: ' + distance + ' Km');
        // console.log('SORT BY: ' + sortBy);

        $.ajax({
            url:'query-ads.php',
            data: 'lat=' + latitude + '&lng=' + longitude + '&distance=' + distance + '&category=' + catName + '&keywords=' + keywords + '&sortBy=' + sortBy,
            type: 'GET',
            success:function(data) {
                document.getElementById("adsGrid").innerHTML = data;
            }, 
            // error
            error: function(xhr, status, error) {
                var err = eval("(" + xhr.responseText + ")");
                swal(err.Message);
        }});
    }

Hope everything's clear to you and I hope you can help me somehow, I thought it was an issue with ParseGeoPoint, but it's not, because if I make a text search for keywords, I can find Ads.

Thanks in advance!



from PHP - Parse SDK query on ParseGeoPoint doesn't work properly

No comments:

Post a Comment