Sorting

When selecting and displaying required records from model table, the results can be sorted in needed order. If sorting occurs in one direction only, then a parameter is used as described in Query Constructor.

//Sorting by date (the latest go first)
$rows = $mv -> events -> select(array("order->desc" => "date"));
 
//Sorting by date (the earliest go first)
$rows = $mv -> events -> select(array("order->desc" => "date"));

//The earliest record
$row = $mv -> events -> selectOne(array("order->desc" => "date"));

Dynamic Sorting

In case when a user himself can sort query results on the webpage (for example, catalog products), we need to launch a sorter. The procedure of sorting is managed by "Sorter" class, inside a model the object of this class is created with the help of "runSorter()" method.

Samples

class Vacancy extends Model
{
    protected $name = "Vacancy";
 
    protected $model_elements = array(
        array("Activate", "bool", "active"),
        array("Name", "char", "name", array("required" => true, "min_max_length" => "2,40")),
        array("Date of creation", "date", "date"), 
        array("Salary", "int", "salary", array("positive" => true)),
        array("Description", "text", "desc"));
}

public function display($parent, $current_brand)
{
    $rows = $this -> select(array("active" => 1));
    $html = "";

    foreach($rows as $row)
    {
        $html .= "<div>";
        $html .= "<h3>".$row['name']."(".$row['salary'].")</h3>";
        $html .= "<span>".I18n :: formatDate($row['date'])."</span>";
        $html .= "<p>".$row['desc']."</p>";
        $html .= "</div>";
    }

    return $html;
}
 
//To sort data in template we run Sorter on required fields
$mv -> vacancy -> runSorter(array("date", "name", "salary"));

//Sorters searches for passed parameters of sorting 
//$_GET["sort-field"] and $_GET["sort-order"], 
//from which it takes the values of sorting parameters,
//if they are not found, we can specify default sorting parameters by ourselves
if(!$mv -> vacancy -> sorter -> hasParams())
    $mv -> vacancy -> sorter -> setParams("date", "desc");

//Then extend "display()" method in "Vacancy" model
public function display($parent, $current_brand)
{
    $rows = $this -> select(array("active" => 1, 
                                  "order->".$this -> sorter -> getOrder() => $this -> sorter -> getField()));

    ...
}

//In template create links to pass GET parametrs
//A current active link will be assigned to "active-asc" or "active-desc" CSS class
<div class="sorting">
    <?
        echo $mv -> vacancy -> sorter -> displayLink("date", "Date");
        echo $mv -> vacancy -> sorter -> displayLink("name", "Vacancy name");
        echo $mv -> vacancy -> sorter -> displayLink("salary", "Salary");
    ?>
</div>

In this example we create one link to each field for sorting in “both direction”. It is possible to create a link to each type of sorting. A current link will be assigned to "active" CSS class. Also, by default, only the path of "?sort-field=name&sort-order=asc" format will be set. If we want to set a link to a full path, then we need to pass it as a 4rd parameter (in displayLink method it will be the 3rd parameter). See examples.

//Initial URL of current page
$path = $mv -> root_path."jobs/".$job -> id."/";

//Any additional GET parameters if exist
if($current_section)
    $path .= "?section=".$current_section;

//Add sorter URL params for URL
$path = $mv -> vacancy -> pager -> addUrlParams($path);

//Links of "one-way" sorting
echo $mv -> vacancy -> sorter -> displaySingleLink("name", "asc", "Name A-Z ", $path);
echo $mv -> vacancy -> sorter -> displaySingleLink("name", "desc", "Name A-Z ", $path);
echo $mv -> vacancy -> sorter -> displaySingleLink("date", "asc", "The earlier first", $path);
echo $mv -> vacancy -> sorter -> displaySingleLink("date", "desc", "The latest first", $path);
echo $mv -> vacancy -> sorter -> displaySingleLink("salary", "asc", "Salary increase", $path);
echo $mv -> vacancy -> sorter -> displaySingleLink("salary", "desc", "Salary decrease", $path);

//In a similar way a path parameter is being passed into displayLink() method
echo $mv -> vacancy -> sorter -> displayLink("date", "Date", $path);
echo $mv -> vacancy -> sorter -> displayLink("name", "Vacancy name", $path);
echo $mv -> vacancy -> sorter -> displayLink("salary", "Salary", $path, "reverse");

Methods of Sorter Object

  • getField(), getOrder() - returns the current filed of sorting and order of sorting accordingly
  • setParams($field, $order) - sets (passes) current parameters of sorting
  • hasParams() - checks if there are sorting parameters, if the fields and value are defined, returns "true"
  • getUrlParams() - returns GET parameters of current sorting ("sort-field=price&sort-order=desc")
  • addUrlParams($path) - adds GET parameters of "sort-field=name&sort-order=asc" format (current order of sorting) to the passed URL, inserts by itself "?" or "&" if needed. Usually is being used to transfer parameters of pagination into other modules (sorting, filter).
  • displayLink($field, $title [, $path, $reverse]), displaySingleLink($field, $order, $title [, $path]) - displays links of sorter (as described above), $reverse option is described in Additional Settings section below, examples of use are above.
  • getParamsForSQL() - returns a part of SQL queries of "ORDER BY `date` DESC" format with current parameters of soritng

Additional settings

When you call "displayLink()" method, MV generates a link for sorting on specified field in both direction, that is if at the current moment an ascending sorting is set, then at double click on this link a descending sorting will occur, If at the current moment the srting goes not on the field as specified or not set at all, then the link will be set to the default order of sorting for this field.

Default order of sorting depends on data types and shown below.

//Code fragment from Sorter core class
//Initial sort orders for fields depending on datatype
$initial_orders = array(
    'id' => 'asc',
    'bool' => 'desc',
    'int' => 'desc',
    'float' => 'desc',
    'char' => 'asc',
    'url' => 'asc',
    'redirect' => 'asc',
    'email' => 'asc',
    'enum' => 'asc',
    'parent' => 'desc',
    'order' => 'asc',
    'date' => 'desc',
    'date_time' => 'desc',
    'image' => 'desc',
    'multi_images' => 'desc',
    'file' => 'asc',
    'many_to_one' => 'desc',
    'many_to_many' => 'desc'
);

In some cases we need to change the initial order of sorting, for example when sorting a catalog of products by a price and when clicking on Sort by price link we want to show cheaper product first. Be default, for integer fields the sorting order is descending, in order to make initial sorting as ascending, you need to pass a 4rd parameter as "reverse" into "displayLink()" method.

$path = $mv -> root_path."catalog/34/";
echo $mv -> products -> sorter -> displayLink("price", "sort by price ", $path, "reverse");

Previous

Pagination