Welcome Guest, Not a member yet? Register   Sign In
Best way to filter data: what if parameters are missing?
#1

[eluser]developer10[/eluser]
This is a huge problem for me in CI.
here's a detailed description (and if you'd like to see live version of the site i'm rebuilding using CI, visit the link in my signature).

Lets assume this is where and how i display data:

/controller/method/Category/ --> only 1 category is listed (a link from the left column is clicked)
/controller/method/Category/City/ -> only items from a particular category and from particular city are listed (this might be done using simple search form at the top)

/controller/method/Category/City/P/ -> same as above, STARTING with P
/controller/method/Category/City/P/4/ -> same as above, page 4


as the number of parameters increases, things get more tricky. the real problem is when one (or even worse, more) parameter(s) are missing, because i have to
set up my function to expect certain number of parameters. if some of them are missing, everything gets screwed up.

what's the best practice in CI for situation like this? how should function and query for returning results (based on given criteria) look like?

here's more possible forms of urls when browsing the site:

/controller/method/Category/P/ ---> only one category (no city specified), starting with P
/controller/method/City/4/ --> only city specified, page 4

as you can see, all has to be very flexible in terms of parameters supplied to the function.

hope all of this was clear, if not, ask and i'll try to be more specific!
#2

[eluser]Dam1an[/eluser]
How much flexibility do you want?
(Assuming you specifiy both) does it have to be category/city, or can it also be city/category

Will all cases go to the same function, or could you have a by-category and by-city functions (routed, obviously), which would make life much easier

The page number is the easiest, as you can just check if it's numeric, the starting letter is next easiest, as it'll always be a single character, and I'm assuming cities and categories are more then one (right?)

As for the first 2 items (city and category) you might need to do some database lookups to see if it matches a city or category to know what it is

(It's still like this that query strings is much better for lol)
#3

[eluser]GSV Sleeper Service[/eluser]
this is by no means 'best practice', but it's something that works.

Code:
public function do_stuff()
{
    //this method expects 4 parameters
    $this->_check_parameters(4);
}

private function _check_parameters($num_params)
{
    // correct number of parameters sent?
    $params = array_slice($this->uri->rsegments,2); //ooh naughty! grabbing the (undocumented) rsegments property like that
    if(count($params) != $num_params)
    {
        exit("wrong number of parameters sent, expecting $num_params, received ".count($params).", please consult API documentation");
    } else {
        return true;
    }
}
#4

[eluser]developer10[/eluser]
[quote author="Dam1an" date="1246981013"]How much flexibility do you want?
(Assuming you specifiy both) does it have to be category/city, or can it also be city/category

Will all cases go to the same function, or could you have a by-category and by-city functions (routed, obviously), which would make life much easier

The page number is the easiest, as you can just check if it's numeric, the starting letter is next easiest, as it'll always be a single character, and I'm assuming cities and categories are more then one (right?)

As for the first 2 items (city and category) you might need to do some database lookups to see if it matches a city or category to know what it is

(It's still like this that query strings is much better for lol)[/quote]


well, i doesnt have to be only one function - more of them will do just fine

if specified, city would never come BEFORE category. filtering should go like this: category | city | letter | pageNo

now you can imagine any of the parameters missing in my URL (one or more of them), IT IS IMPORTANT THAT any of the combinations work. Existing parameters
will be ordered in the above pattern

i agree that the last 2 are simplest. category will probably be all in words (with underscores instead of spaces), city also (sometimes 2 words, of course), starting letter and page no are self descriptive enough
#5

[eluser]Michael Wales[/eluser]
The easiest way to attack this would be to implement the key/value URL scheme:
Quote:example.com/controller/method/category/cars/city/phoenix-az/alpha/P/page/4

Definitely not the prettiest though... are categories limited to a specific list (or at least a list that won't change often)? A series of routes could work:

Code:
$route['c/m/(cars|trucks|vans)/([a-z-]+)/([A-Z])/(\d+)'] = 'c/m/$1/$2/$3/$4';
$route['c/m/(cars|trucks|vans)/([a-z-]+)/([A-Z])'] = 'c/m/$1/$2';
$route['c/m/(cars|trucks|vans)/([A-Z])/(\d+)'] = 'c/m/$1/NULL/$2/$3';
$route['c/m/(cars|trucks|vans)/(\d+)'] = 'c/m/$1/NULL/NULL/$2';

Code:
function m($category = NULL, $city = NULL, $alpha_limit = NULL, $page = NULL) {
}

It wouldn't be hard to write a script that can crank out all possible combinations for you. I admit, not the easiest route - but would definitely be the prettiest.

You could also try using _remap() to disregard the parameters and figure it all out with RegEx matching and send the request off to the correct class method.
#6

[eluser]developer10[/eluser]
here's possible solution for my problem (i've done something similar in my regular PHP version of the site),
managed to use only one query for whole database (even if any parameter(s) is/are missing:

Code:
function svimodel() {

        $s4 = $this->uri->segment(4);
        $s6 = $this->uri->segment(6);

        
        $upit = "    SELECT *, djelatnost FROM _tbl_firme
                    LEFT JOIN tbl_djelatnosti
                    ON _tbl_firme.d_id = tbl_djelatnosti.d_id WHERE ";
                    
                        if($s4 && $s4 != 'Sve')
                            $out = " djelatnost = '$s4' AND ";
                        else $out = "";
                            $upit .= $out;
                            
                        if($s6 && $s6 != 'Svi')
                            $out = " _f_grad = '$s6' AND ";
                        else $out = "";
                            $upit .= $out;
                        
                    $upit .= " f_vidljivo = 1
                    ORDER BY f_istaknuto DESC
                    LIMIT 12 ";
                                    
        $query = $this->db->query($upit);
        
        if($query->num_rows() > 0) {
            $result = $query->result();
        }
        
        return $result;
    }

i'll take advantage of the next parameter being only 1 character long (first letter), so i will be able
to identify it as starting letter it in cases when parameter "city" is omitted and user tries to filter
data by starting letter.

OR, maybe i'll keep parameter city in my url (instead of city, i could place "All", as a placeholder for the parameter/segment)

what's bothering me right know, is the fact i'll have a hard time with my form, because nobody has told me how exactly
i can "make" it to give me segmented URL after submission, rather than GET form URL


if anyone has suggestion for anything, please post!




Theme © iAndrew 2016 - Forum software by © MyBB