rpc.php overhaul

* Mark things static in the class rather than use a constructor every
  single invocation of the service.
* Don't call mysql_real_escape_string() before we even have a database
  connection, and don't do work in the database if we don't need to.
* Formatting consistency fixups in a few places.
* Add new process_query() helper function; use this instead of
  copy-pasted code in all of the RPC method calls.
* Remove the escaping code meant to fix FS#15526, introduced in commit
  4d1eb4dd7a. It broke more than it solved, only fixed the output in
  one of three RPC calls (and who knows what the web interface then also
  does), and proper encoding should be done at the database level rather
  than up here.

Lukas: Add special case for "info" queries to process_query() (return a
single result instead of an array of results here).

Signed-off-by: Dan McGee <dan@archlinux.org>
Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de>
This commit is contained in:
Dan McGee 2011-04-12 00:15:47 -05:00 committed by Lukas Fleischer
parent 8fdb382d67
commit aa206b343a

View file

@ -14,23 +14,12 @@ include_once("aur.inc");
**/
class AurJSON {
private $dbh = false;
private $exposed_methods = array();
private $fields = array();
/**
* Initialize methods and database fields.
**/
public function __construct() {
$this->exposed_methods = array('search', 'info', 'msearch');
$this->fields = array(
private static $exposed_methods = array('search', 'info', 'msearch');
private static $fields = array(
'Packages.ID', 'Name', 'Version', 'CategoryID',
'Description', 'URL', 'CONCAT("' .
mysql_real_escape_string(URL_DIR) .
'", Name, "/", Name, ".tar.gz") AS URLPath', 'License',
'Description', 'URL', 'License',
'NumVotes', '(OutOfDateTS IS NOT NULL) AS OutOfDate'
);
}
/**
* Handles post data, and routes the request.
@ -44,7 +33,7 @@ class AurJSON {
}
// do the routing
if ( in_array($http_data['type'], $this->exposed_methods) ) {
if ( in_array($http_data['type'], self::$exposed_methods) ) {
// set up db connection.
$this->dbh = db_connect();
@ -92,6 +81,32 @@ class AurJSON {
return json_encode( array('type' => $type, 'results' => $data) );
}
private function process_query($type, $query) {
$result = db_query($query, $this->dbh);
if ( $result && (mysql_num_rows($result) > 0) ) {
$search_data = array();
while ( $row = mysql_fetch_assoc($result) ) {
$name = $row['Name'];
$row['URLPath'] = URL_DIR . $name . "/" . $name . ".tar.gz";
if ($type == 'info') {
$search_data = $row;
break;
}
else {
array_push($search_data, $row);
}
}
mysql_free_result($result);
return $this->json_results($type, $search_data);
}
else {
return $this->json_error('No results found');
}
}
/**
* Performs a fulltext mysql search of the package database.
* @param $keyword_string A string of keywords to search with.
@ -105,24 +120,12 @@ class AurJSON {
$keyword_string = mysql_real_escape_string($keyword_string, $this->dbh);
$keyword_string = addcslashes($keyword_string, '%_');
$query = "SELECT " . implode(',', $this->fields) .
$query = "SELECT " . implode(',', self::$fields) .
" FROM Packages WHERE " .
" ( Name LIKE '%{$keyword_string}%' OR " .
" Description LIKE '%{$keyword_string}%' )";
$result = db_query($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('search', $search_data);
}
else {
return $this->json_error('No results found');
}
return $this->process_query('search', $query);
}
/**
@ -131,7 +134,7 @@ class AurJSON {
* @return mixed Returns an array of value data containing the package data
**/
private function info($pqdata) {
$base_query = "SELECT " . implode(',', $this->fields) .
$base_query = "SELECT " . implode(',', self::$fields) .
" FROM Packages WHERE ";
if ( is_numeric($pqdata) ) {
@ -147,26 +150,9 @@ class AurJSON {
$query_stub = sprintf("Name=\"%s\"",
mysql_real_escape_string($pqdata));
}
$query = $base_query . $query_stub;
$result = db_query($base_query.$query_stub, $this->dbh);
if ( $result && (mysql_num_rows($result) > 0) ) {
$row = mysql_fetch_assoc($result);
mysql_free_result($result);
foreach($row as $name => $value) {
$converted = utf8_encode($value);
if ($converted != "") {
$row[$name] = $converted;
}
else {
$row[$name] = "[PKGBUILD error: non-UTF8 character]";
}
}
return $this->json_results('info', $row);
}
else {
return $this->json_error('No result found');
}
return $this->process_query('info', $query);
}
/**
@ -176,25 +162,14 @@ class AurJSON {
**/
private function msearch($maintainer) {
$maintainer = mysql_real_escape_string($maintainer, $this->dbh);
$fields = implode(',', $this->fields);
$fields = implode(',', self::$fields);
$query = "SELECT Users.Username as Maintainer, {$fields} " .
" FROM Packages, Users " .
" WHERE Packages.MaintainerUID = Users.ID AND " .
" Users.Username = '{$maintainer}'";
$result = db_query($query, $this->dbh);
if ( $result && (mysql_num_rows($result) > 0) ) {
$packages = array();
while ( $row = mysql_fetch_assoc($result) ) {
array_push($packages, $row);
}
mysql_free_result($result);
return $this->json_results('msearch', $packages);
}
else {
return $this->json_error('No results found');
}
return $this->process_query('msearch', $query);
}
}