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 events go first)
$rows = $mv -> events -> select(array("order->desc" => "date"));
 
//Sorting by date (the earliest events go first)
$rows = $mv -> events -> select(array("order->asc" => "date"));

//The earliest record
$row = $mv -> events -> selectOne(array("order->asc" => "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 object. The object of sorter 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 with required fields
$mv -> vacancy -> runSorter(array("date", "name", "salary"));

//Sorter searches for passed parameters of sorting as $_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 update "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 we create links to pass GET parametrs
//A current active link will be assigned with "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 for each field of sorting in both directions. It is possible to create a link to each type of sorting. A current link will be assigned with "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 4th 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 GET parameters for base 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 Z-A ", $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 current parameters of sorting
  • hasParams() - checks if there are sorting parameters, if the field 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. It's usually being used to transfer parameters of pagination into other modules (pagination, 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, used in direct SQL queries

Additional settings

When you call "displayLink()" method, MV generates a link for sorting by specified field in both directions. So if at the current moment an ascending sorting is set, then after click on this link a descending sorting will be applied. And if currently sorting link is not active, then this 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 (see above code), 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. By default, for integer fields the sorting order is descending, in order to make initial sorting as ascending, you need to pass a 4th 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