From d37eb6858bb47776d9497336178059fa87963e10 Mon Sep 17 00:00:00 2001
From: Sylvester Johansson <syljo361@gmail.com>
Date: Tue, 3 Jun 2008 22:41:54 +0200
Subject: [PATCH] Extended the JSON interface with a query method.

---
 web/html/rpc.php          |    8 +++++-
 web/lib/aurjson.class.php |   67 +++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/web/html/rpc.php b/web/html/rpc.php
index 033cba5..8ca0f4b 100644
--- a/web/html/rpc.php
+++ b/web/html/rpc.php
@@ -19,11 +19,17 @@ if ( $_SERVER['REQUEST_METHOD'] == 'GET' ) {
         echo '<ul>';
         echo '<li>search</li>';
         echo '<li>info</li>';
+        echo '<li>query</li>';
         echo '</ul><br />';
-        echo 'Each method requires the following HTTP GET syntax:<br />';
+        echo '<i>search</i> and <i>info</i> requires the following HTTP GET syntax:<br />';
         echo '&nbsp;&nbsp; type=<i>methodname</i>&arg=<i>data</i> <br /><br />';
         echo 'Where <i>methodname</i> is the name of an allowed method, and <i>data</i> is the argument to the call.<br />';
         echo '<br />';
+        echo '<br />';
+        echo '<i>query<i> has the following syntax: <br />';
+        echo 'type=query&arg=&lt;<i>term</i>&gt;&include=&lt;<i>field1</i>&gt;:&lt;<i>field2</i>&gt;:...:&lt;<i>fieldN</i>&gt; <br />';
+        echo 'where <i>fieldN</i> is a field to be included in the result. Allowed fields are: <br />';
+        echo 'ID, Name, Version, Description, URL, URLPath, License, NumVotes and OutOfDate <br />';
         echo 'If you need jsonp type callback specification, you can provide an additional variable <i>callback</i>.<br />';
         echo 'Example URL: <br />&nbsp;&nbsp; http://aur-url/rpc.php?type=search&arg=foobar&callback=jsonp1192244621103';
         echo '</body></html>';
diff --git a/web/lib/aurjson.class.php b/web/lib/aurjson.class.php
index be92c25..02fe387 100644
--- a/web/lib/aurjson.class.php
+++ b/web/lib/aurjson.class.php
@@ -1,4 +1,5 @@
 <?php
+# vim: set et sw=4 ts=4:
 /**
  * AurJSON
  * 
@@ -21,7 +22,9 @@ if (!extension_loaded('json'))
  **/
 class AurJSON {
     private $dbh = false;
-    private $exposed_methods = array('search','info');
+    private $exposed_methods = array('search','info','query');
+    private $valid_parameters = array('ID','Name','Version','Description','URL','URLPath','License','NumVotes','OutOfDate');
+
 
     /**
      * Handles post data, and routes the request.
@@ -42,13 +45,18 @@ class AurJSON {
         // do the routing
         if ( in_array($http_data['type'], $this->exposed_methods) ) {
             // ugh. this works. I hate you php.
-            $json = call_user_func_array(array(&$this,$http_data['type']),$http_data['arg']);
-            // allow rpc callback for XDomainAjax
-            if ( isset($http_data['callback']) ) {
-                return $http_data['callback'] . "({$json})";
+            if ($http_data['type'] === 'query') {
+               return $this->query($http_data['arg'],$http_data['include']);
             }
             else {
-                return $json;
+                $json = call_user_func_array(array(&$this,$http_data['type']),$http_data['arg']);
+                // allow rpc callback for XDomainAjax
+                if ( isset($http_data['callback']) ) {
+                    return $http_data['callback'] . "({$json})";
+                }
+                else {
+                    return $json;
+                }
             }
         }
         else {
@@ -137,5 +145,52 @@ class AurJSON {
             return $this->json_error('No result found');
         }
     }
+
+    /**
+     * Returns the information of packages.
+     * @param   $term is the term to search for
+     *          $pqdata is a colon separated string with the fields to include in 
+     *          result
+     * @return  If $term is found and $pqdata is valid, a json list, else json-error
+     **/
+
+    private function query($term,$pqdata) {
+        $pqdata = explode(":",$pqdata);
+        $term = mysql_real_escape_string($term);
+
+        if (! $this->parameter_sanity($pqdata)) {
+            return $this->json_error('Parameter error');
+        }
+
+        $base_query = "SELECT " . implode(',',$pqdata) . " FROM Packages WHERE DummyPkg=0 AND " . sprintf("( Name LIKE '%%%s%%' OR Description LIKE '%%%s%%' )",$term,$term);
+        $result = db_query($base_query,$this->dbh);
+        if($result && (mysql_num_rows($result)>0)){
+            $search_data = array();
+            while($row = mysql_fetch_assoc($result)) {
+                array_push($search_data,$row);
+            }
+            mysql_free_result($result);
+            return $this->json_results('query',$search_data);
+        }
+        else {
+            return $this->json_error('No result found');
+        }
+
+    }
+
+    /**
+     * @param   $parameters is a array with parameters that will be compared
+     *          against valid_parameters.
+     * @return True if the parameters are acceptable, otherwise false
+     **/
+    private function parameter_sanity($parameters) {
+       foreach($parameters as $param) {
+           if (!in_array($param, $this->valid_parameters)) {
+               return false;
+           }
+       }
+       return true;
+    }
 }
 ?>
+
-- 
1.5.5.3

