$conditions = array();
foreach($GET as $k => $v)
{
if(preg_match("/(.*)()(.*)/",$k)
{
$c = explode("_",$k);
$conditions[] = array(
'field' => $c[0],
'condition' => $c[1],
'val' => $v
);
}else{
$conditions[] = array(
'field' => $k,
'condition' => "equalTo",
'val' => $v
);
}
}
It seems like you are giving your API user too much information about the internals, but if you really want to follow this path, I suggest you don't fight HTTP and use HTTP-friendly URLs. This gives your API users the ability to use URL-building libraries the way they were designed.
I suggest your API accept queries such as:
// foo > 1
"/WaferSearch?clauses[]=foo%20>%201"
// foo > 1 AND foo < 10
"/WaferSearch?clauses[]=foo%20>%201&clauses[]=foo%20<%2010"
// bar LIKE '%abcde%'
"/WaferSearch?clauses[]=bar+LIKE+%27%25abcde%25%27"
My suggested code is below. I replaced your "Wafer" model with my "Account" model. You will want to adjust the Model and the $valid_fields to suit your needs. Also, you will probably want more flexible operators ("LIKE", "IN", etc).
function is_valid_value($field_name, $field_value) {
return TRUE;
}
Route::any('WaferSearch', function () {
$valid_operators = array('=', '>', '>=', '<', '<=');
$valid_fields = array('id', 'username', 'email');
// Output format to be compatible with YUI's default JSON structure for resultsets:
// http://yuilibrary.com/yui/docs/autocomplete/#locating-results
$response_obj = (object) array(
'status' => 'error',
'query' => NULL,
'data' => NULL,
);
$search_query = Account::query();
$input_clauses = Input::get('clauses');
$sql_where_parts = array();
if(!isset($input_clauses) || !is_array($input_clauses)) {
// handle case with invalid input
$error_message = 'no valid clauses found (param "clauses" must be an array)';
Log::error($error_message);
$reponse_obj->message = $error_message;
} else {
$valid_clauses = 0;
foreach($input_clauses as $this_clause) {
$preg_pattern = '/^(' . implode('|', array_map('preg_quote', $valid_fields)) . ')\s*(' . implode('|', array_map('preg_quote', $valid_operators)) . ')\s*(.*)$/';
if(preg_match($preg_pattern, $this_clause, $matches)) {
$fieldname = $matches[1];
$operator = $matches[2];
$new_value = $matches[3];
// do some $new_value validation based on $fieldname
if(!is_valid_value($fieldname, $new_value)) {
Log::error('Bad field value.');
continue;
}
$search_query->where($fieldname, $operator, $new_value);
$sql_where_parts[]= implode(' ', array($fieldname, $operator, $new_value));
$valid_clauses++;
} else {
// handle case with no input
Log::error('invalid clause found (does not match expected format)');
continue;
}
}
if(0 < $valid_clauses) {
$matchingWafers = $search_query->get();
$response_obj->status = 'okay';
$response_obj->query = implode(' AND ', $sql_where_parts);
$response_obj->data = (object) array(
'resultCount' => $matchingWafers->count(),
'results' => (array) $matchingWafers,
);
} else {
$error_message = 'No valid clauses to process';
}
}
return Response::json($response_obj);
});
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community