Filtration

When displaying list of data from models, filtration is done based on parameters from the Query Constructor section. With it’s help we can build SQL queries on required parameters. On the frontend of the website we often need to organize a search of records (products, news etc) on several parameters. For this task a "Filter" core class is used together with it’s 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", "desc"),
        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 selected filter in required ordering
echo $mv -> furniture -> filter -> display(array("location", "price"));

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

//Full example with form
<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, that is if it is marked, then the search goes on cells with value= "1" and if it isn't marked, that this field doesn't participate in search.
  • 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
  • hasParams() - checks if there is at least one filter in use, 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 iwhere the field will be displayed as one text box, and not an interval out 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 outputradio 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 for this case will return a value of "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 won't be shown in filters.
//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 specified filters 
        $conditions = $this -> filter -> getConditions(); 
        $conditions["active"] = 1;
        $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 filter 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" 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 of "field-> in" => "8,25,87" will return, which means a connection for this field through "OR".
  • "Date", "date_time", "int", "float", "order" fields are filtered by "from" and "to" intervals. After calling "display()" method for this field, 2 text boxes of the form will return 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" Fields won't be shown in result of by "display()" method call unless an option to display as checkboxes using "setDisplayCheckboxTable($field, $columns)" method is called.
  • If in the filter of one model there are 2 and more "many_to_many" fields - the result of "getConditions()" method call for all these fields anyway will return a construction of to an "id->in" => "3,6,23" format. Thus in the list of ids found the "intersections" of all filters for "many_to_many" fields will already be counted. If in result of "intersection" of "many_to_many" filters no record is found, then a construction of "id->in" => "0" will return that means there is no record that meets all 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, thus if you need to check the availability of real file on a disk, you need to use PHP functions.