RESTFUL Web Service get ads by GPS
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Wed, 23 May 2012 04:51:14 +0000 (06:51 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Wed, 23 May 2012 04:51:14 +0000 (06:51 +0200)
apps/userfront/modules/api/actions/actions.class.php
apps/userfront/modules/api/templates/getadsbygpsSuccess.json.php
apps/userfront/modules/category/actions/actions.class.php
apps/userfront/modules/category/templates/indexSuccess.php
lib/model/doctrine/AdDescriptionTable.class.php

index a41f588..d9fe629 100644 (file)
@@ -5,8 +5,8 @@
  *
  * @package    mobileadvertising
  * @subpackage api
- * @author     Your name here
- * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
+ * @author     Gustavo Martin Morcuende
+ * @version
  */
 class apiActions extends sfActions
 {
@@ -38,17 +38,23 @@ class apiActions extends sfActions
   */
   public function executeGetadsbygps(sfWebRequest $request)
   {
-       //With RESTFUL is allowed to use cookies to get authentication (user / password)
-       $this->ads = AdTable::getInstance()->getAdsByGPSandUserId($this->getRoute()->getParameters(), $this->getUser()->getGuardUser()->getId());
-       if (!$this->ads)
-       {
-               //If there are not results.
-               //In production replace this line by a die command (trying to stop wasting TCP bandwidth)
-               throw new sfError404Exception(sprintf('
-                       There are not offices with GPS coordinates: longitude "%s" and 
-                       latitude "%s".', $request->getParameter('longitude'), $request->getParameter('latitude')));
-               //die;
-       }
+    //RESTFUL permits to use cookies to implement authentication (user / password)
+    $parameters = $this->getRoute()->getParameters();
+    $userId = $this->getUser()->getGuardUser()->getId();
+
+    $this->ads = array();
+    $this->ads = AdDescriptionTable::getInstance()->getAdsByGPSAndUserIdAndLanguageId($this->getRoute()->getParameters(),
+                                                                                      $this->getUser()->getGuardUser()->getId(),
+                                                                                      $this->getUser()->getGuardUser()->getLanguage()->getId());
+    if (empty($this->ads))
+    {
+        //If there are not results.
+        //In production replace this line by a die command (trying to stop wasting TCP bandwidth)
+        throw new sfError404Exception(sprintf('
+            There are not offices with GPS coordinates: longitude "%s" and
+            latitude "%s".', $request->getParameter('longitude'), $request->getParameter('latitude')));
+            //die;
+    }
   }
 
  /**
index b951d93..ecbe959 100644 (file)
@@ -1,5 +1,6 @@
 [
 <?php foreach ($ads as $ad): ?>
-  { "id" : "<?php echo $ad->getId()?>", "domain" : "<?php echo $ad->getDomain()?>", "link" : "<?php echo $ad->getLinks()?>" },
+  { "id" : "<?php echo $ad->getAd()->getId()?>", "image" : "<?php echo $ad->getAd()->getAdMobileImageLink() ?>", "link" : "<?php echo $ad->getAdLink()?>",
+    "text" : "<?php echo $ad->getAdMobileText()?>" },
 <?php endforeach ?>
 ]
index 3a2fecc..c59f661 100644 (file)
@@ -86,6 +86,8 @@ class categoryActions extends sfActions
     //Get data from user
     $checked = $request->getParameter('checked');
 
+    $uniqChecked =  array_unique($checked, SORT_NUMERIC);
+
     //We retrieve a Doctrine_Collection
     $userBaskets = UserBasketTable::getInstance()->findByUserId($userId);
 
@@ -94,13 +96,13 @@ class categoryActions extends sfActions
     $iterator = $userBaskets->getIterator();
     while ($userBasket = $iterator->current())
     {
-        if (!empty($checked))
+        if (!empty($uniqChecked))
         {
-            foreach ($checked as $index => $value)
+            foreach ($uniqChecked as $index => $value)
             {
                 if ($userBasket->getGeneralCategId() == $value)
                 {
-                    unset($checked[$index]);
+                    unset($uniqChecked[$index]);
                     $iterator->next();
                     continue 2;
                 }
@@ -110,9 +112,9 @@ class categoryActions extends sfActions
         $iterator->next();
     }
 
-    if (!empty($checked))
+    if (!empty($uniqChecked))
     {
-        foreach ($checked as $index => $value)
+        foreach ($uniqChecked as $index => $value)
         {
             //Never trust in data coming from users... Performance vs security.
             $generalCategory = GeneralCategoryTable::getInstance()->findOneById($value);
@@ -135,6 +137,6 @@ class categoryActions extends sfActions
 
     //Bypass completely the view layer and set the response code directly from this action.
     //In this way the user may know if the data were updated
-    return $this->renderText(json_encode($checked));
+    return $this->renderText(json_encode($uniqChecked));
   }
 }
index 228997b..67c0f2e 100644 (file)
@@ -14,7 +14,7 @@
                });
         $.post('<?php echo url_for('category/choose') ?>', {'checked[]': checked},
             function(data){
-                alert("hola");
+                alert("Updated successfully!");
         }, "json");
     };
 </script>
index ba48ecc..a65c7f6 100644 (file)
@@ -30,4 +30,82 @@ class AdDescriptionTable extends Doctrine_Table
                                                   ->innerjoin('addescription.Ad ad')
                                                   ->orderBy('ad.id');
     }
+
+
+    public function getAdsByGPSAndUserIdAndLanguageId(array $parameters, $userId, $languageId)
+    {
+        $longitude = $parameters['longitude'];
+        $latitude = $parameters['latitude'];
+        $longitude = str_replace(',', '.', $longitude);
+        $latitude = str_replace(',', '.', $latitude);
+
+
+        // I will use this style to retrieve the radius because this is an Academic Project and I want to learn the ins and outs of using Symfony.
+        // I am wasting CPU cycles using this symfony helper. My Web Service will get worse cause this sentence. In production get the radius
+        // from a constant value or something like that.
+        $radius = sfConfig::get('app_radius', '100');
+
+        try{
+            $adIds = Doctrine_Manager::getInstance()->getCurrentConnection()->fetchColumn(
+                    "SELECT ad_id from office INNER JOIN office_ads ON (office_ads.office_id=office.id) 
+                    WHERE ST_DWithin(office_gps, ST_GeographyFromText('SRID=4326;POINT($longitude $latitude)'), $radius)"
+            );
+        }
+        catch (Exception $e)
+        {
+            //In case of error return as soon as posible.
+            return null;
+        }
+        if (empty($adIds))
+        {   //There are not offices with those GPS coordinates.
+            //In many situations we will get this result, so a fast response.
+            return null;
+        }
+
+        $uniqAdIds =  array_unique($adIds, SORT_NUMERIC);
+
+        //We can not waste time doing this query. What is the best way to achieve this goal? 
+        //Is a direct query the best way? With big tables I think this is not going to work.
+        $adIds = array();
+        foreach ($uniqAdIds as $uniqAdId)
+        {
+            try
+            {
+                $adIds[] = Doctrine_Manager::getInstance()->getCurrentConnection()->fetchOne(
+                    "SELECT ad.id FROM ad INNER JOIN company_category ON (ad.company_categ_id=company_category.id)
+                    INNER JOIN general_category ON (company_category.general_categ_id=general_category.id)
+                    INNER JOIN user_basket ON (user_basket.general_categ_id=general_category.id)
+                    WHERE user_id=$userId AND ad.id=$uniqAdId"
+                );
+            }
+            catch (Exception $e)
+            {
+                //In case of error return as soon as posible.
+                return null;
+            }
+        }
+        if (empty($adIds))
+        {
+            //There are not linked ads in those GPS coordinates with the specified user.
+            return null;
+        }
+        $ads = array();
+        foreach($adIds as $adId)
+        {
+            //Array with Doctrine_Records Ads
+            $ad = $this->findOneByAdIdAndLanguageId($adId, $languageId);
+            if ($ad != null)
+            {
+                $ads[] = $ad;
+            }
+            else
+            {
+                //Return with the default language
+                $languageCode = sfConfig::get('app_default_language');
+                $languageId = LanguageTable::getInstance()->findOneByCode($languageCode)->getId();
+                $ads[] = $this->findOneByAdIdAndLanguageId($adId, $languageId);
+            }
+        }
+        return $ads;
+    }
 }