Support the ongoing development of Laravel.io →
posted 10 years ago
Requests
Last updated 2 years ago.
0

$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 );
} }

Last updated 2 years ago.
0

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);
});
Last updated 2 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

gt324 gt324 Joined 21 Jun 2014

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.