Filtration

Initially filtration is made by parameters from the Query constructor section. With its help we can build SQL queries with required parameters to get needed records from database. On the frontend of the website we often need to organize a search of records (products, news etc) by several specific parameters. For this task a "Filter" core class is used together with its object located inside a model object.

Let’s see a filtration example of furniture items.

class Furniture extends Model
{
    protected $name = "Furniture";

    protected $model_elements = array(
        array("Active", "bool", "active", array("on_create" => true)),
        array("Images", "multi_images", "images"),
        array("Description", "text", "description"),
        array("Price", "int", "price"),
        array("Room’s square", "int", "square"),
        array("Location", "enum", "location", array("empty_value" => true, 
                                                    "values_list" => array("badroom" => "In bedroom",
                                                                           "livingroom" => "Living room",
                                                                           "childrenroom" => "Child room",
                                                                           "corridor" => "Corridor")))
    );
}

We are interested in "price", "square" and "location" fields, which we will make our products filtration on. In template file create an object of "Filter" class, which may accept GET parameters with filter values ("price-from=12000&square-to=50&location=livingroom"). When running an object, the search of GET parameters is launched automatically.

//Run filter
$mv -> furniture -> runFilter(array("price", "square", "location"));

//Now in a model an object of filtration is accessible
$mv -> furniture -> filter;

//Display fields of all specified filters 
echo $mv -> furniture -> filter -> display();

//Display certain filters in required order
echo $mv -> furniture -> filter -> display(array("location", "price"));

//Display one filter with wrappers
echo $mv -> furniture -> filter -> display("square");

//Full example with form, after submit filter parameters will go to GET data
//and later will be processed by runFilter() method, so we will be able to use them inside the model
<form method="get" action="">
    <? echo $mv -> furniture -> filter -> display(); ?>
    <p><input type="submit" value="Filter" /></p>
</form>

Methods of Filter Object

  • display() - displays HTML code for filter fields or one field (examples are above), the passed values are populated automatically
  • displayCheckbox($field) - displays HTML code for "bool", "image", "file", "multi_images" fields as a checkbox element (by default, "select" tag with options "yes", "no", "not set" will be displayed). In case of "checkbox" the value "no" is not defined, so if it's marked, then the search goes by cells with value= "1" and if it isn't marked, that this field doesn't participate in search at all
  • getConditions() - returns an array of values of the passed filters, in the format of Query constructor
  • getUrlParams() - returns the list of GET parameters of filters values for URL
  • addUrlParams($path) - adds values (GET parameters) of the used filters to the passed URL, usually to pass them into pagination or sorting
  • hasParams() - checks if there is at least one filter applied, if yes, that returns "true"
  • getValue($field [, $condition]) - returns value of the filter if it was passed to GET, the second optional parameter is required for "date", "date_time", "int", "float", "order" fields where values are passed as intervals. The parameter accepts "from" and "to" values.
  • setValue($field, $value [, $condition]) - allows to insert a value for the filter, accepts arguments as the name of a field and value. Optional parameter is required for passing parameters for interval filters, similar to previous method.
  • setEnumEmptyValueTitle($field, $title) - for "enum" fields it is possible to change the caption of empty value (it is used in cases when in the select tag itself you need to put its name), see an example below. For this element of a model you need to set a default option "empty_value" => "true".
  • displaySingleField($field) - by default, for "date", "date_time", "int", "float", "order" fields 2 "input" will be displayed to set an interval of values ("from" and "to"). If you don't need an interval and you only need to display one element of the form, then use this method.
  • filterValuesList($field, $params) - for "enum" fields (with foreign key), "parent" and "many_to_many" there is an option of filtering the list of values, using parameters in the format of Query constructor, $field - the name of a field, $params - an array of parameters for filtering and/or ordering.
  • setDisplaySingleField($field) - for "date", "date_time", "int", "float", "order" fields sets an option where the field will be displayed as one text box, and not an interval of two fields. Also, the filter will accept a value as a single GET parameter, instead of "from" and "to" interval values.
  • setDisplayCheckbox($field) - for "bool", "image", "file", "multi_images" fields sets an option to display as checkbox elements, as a result of "display()" method call
  • setDisplayEnumRadio($field, $columns) - for "enum" fields sets an option to display html code as a table with radio buttons, the parameter $columns sets the number of columns in the table
  • setDisplayEnumCheckboxes($field, $columns [, $empty_checkbox]) - for "enum" field sets an option to display the list of values as a table with chekboxes. $field parameter is the name of a field, $columns - number of columns in the table, $empty_checkbox - optional parameter, indicating if there is a need to display the first checkbox with an empty value (for example for vendors "All vendors"). Displays HTML table with checkbox fields. This way you can organize a multiple selection. The filter for this field in such case will return a value in "2,7,24" format.
  • setDisplayCheckboxTable($field, $columns) - for "many_to_many" fields sets an option to display as a table with chekboxes similar to previous method. Without calling this method "many_to_many" field will be displayed as select tag in filters.
  • setManyToManyEmptyValueTitle($field, $title) - for "many_to_many" fields sets a title for empty value option if this field is displayed as select tag
//Get filters values 
$mv -> furniture -> filter -> getValue("location");
$mv -> furniture -> filter -> getValue("price", "from");
$mv -> furniture -> filter -> getValue("price", "to");

//Add filtering parameters into URL
$path = $mv -> root_path."search/?page=3";
$path = $mv -> furniture -> filter -> addUrlParams($path);

//Display method of required fields with filtration 
class Furniture extends Model 
{
    ...

    public function display()
    {
        //An array of conditions for applied filters 
        $conditions = $this -> filter -> getConditions();

        //We can add our own parameters
        $conditions["active"] = 1;

        //Selecting rows from database
        $rows = $this -> select($conditions);

        ...
    }
}

//If there is at least one filter set
if($mv -> furniture -> filter -> hasParams())
{
    ...
}

//Set a caption for an empty value of "enum" field
$mv -> furniture -> filter -> setEnumEmptyValueTitle("location", "Choose a location");
echo $mv -> furniture -> filter -> display("location");

//Create an option of multiple choice for "Location" field
$mv -> furniture -> filter -> setDisplayEnumCheckboxes("location", 2);

//Set field display as radio buttons with 3 columns
$mv -> furniture -> filter -> setDisplayRadio("location", 3);

//"Active" field will be displayed as a checkbox
$mv -> furniture -> filter -> setDisplayCheckbox("active");

//Display price field as a single field to set a value without an interval
$mv -> furniture -> filter -> setDisplaySingleField("price");

//Display all filters fields with all specified options
echo $mv -> furniture -> filter -> display();

Notes and recommendations

  • As a result of "getConditions()" method call a set of conditions will return, which will be connected with each other with "AND" condition by Queries constructor, thus if for "enum" and "many_to_many" fields a multiple selection is set as a table with checkboxes, then a construction like "field-> in" => "8,25,87" will be returned, which means a connection for this field through "OR" condition.
  • "Date", "date_time", "int", "float", "order" fields are filtered by "from" and "to" intervals. After calling "display()" method for this field, 2 text inputs of the form will be returned to set an interval ("from", "to"). For example in the "Furniture" model for the "price" field - the fields with the names "price-from" and "price-to" will be displayed. If you need to display one general field without intervals, then use "displaySingleField()" method.
  • "Many to many" field initially will be displayed as "select" tag to choose one value for filtering. If you want ot select many values at one time, you should set an option to display this field as a table with checkboxes using "setDisplayCheckboxTable($field, $columns)" method.
  • If in the filter of one model there are 2 or more "many_to_many" fields - the result of "getConditions()" method call for all these fields anyway will return a single construction in "id->in" => "3,6,23" format. It occurres because when in the list of ids were found any intersections of all filters for "many_to_many" fields, they will be brought together in one final list if ids. So if in result of intersection of "many_to_many" filters no record is found, then a construction of "id->in" => "0" will be returned that means there are no records that meet all m2m filters criteria.
  • For "image", "file", "multi_images" fields the "getConditions()" method returns a construction of "field->like" => "." that means, in SQL query there will be a check for availability of the file path in SQL table cell, and if you need to check the availability of real file on a disk, you need to use PHP functions.