Sử dụng Search API Sorts trong View Drupal 7

Sử dụng Search API Sorts trong View Drupal 7

It's been a while since I've written a post here (especially, Drupal-related). But today I have something interesting to share.

There's a module called Search API sorts (https://drupal.org/project/search_api_sorts) that provides custom sorts and a global sort block for Search API. The module itself is ok, but has one big flaw: all settings are global and will get applied to every view you want to have the sort on. But what if you want to have different default sorts for different views? For example, View 1 to be sorted by created date and View 2 by radioactivity field value? Well, as you may have guessed, regular sitebuilder won't do it via UI, you need to dig deep into code so I'll guide you through then.

If we'll look at the code of search_api_sorts.module we'll see a function that's responsible for applying sorts on the current query, it's called search_api_sorts_search_api_query_alter. The function itself, implements hook_search_api_query_alter() hook, which means, we can easily re-implement that function in our custom module with a few tweaks to reach our goal.

So what we actually need is to create a custom module that'll have less weight than search_api_module (-1) or have same weight but it's name should start on a letter that comes before S. We need this to make sure, that the hook we defined in our custom module kicks in earlier than the hook defined in search_api_sorts.

So we just take search_api_sorts_search_api_query_alter, copy it and put into our custom example_module renaming it accordingly: 

<?php

/**

* Implements hook_search_api_query_alter().

*/

function example_module_search_api_query_alter(SearchApiQueryInterface $query) {

if (!user_access('use search_api_sorts')) {

return;

}


// There's already an existing sort, so abort!

$existing = $query->getSort();

if (!empty($existing)) {

return;

}


$search_sorts = search_api_sorts_search_sorts($query->getIndex()->machine_name);

if (empty($search_sorts)) {

return;

}

$default_sort = _search_api_sorts_get_default_sort($search_sorts, $query->getKeys());


// alter sort field and sort order

$sort = $default_sort->field;

$params = drupal_get_query_parameters($_GET, array(

'q',

'page'

));

if (isset($params['sort']) && !empty($params['sort'])) {

$sort = $params['sort'];

}


$order = $default_sort->default_order;

if (isset($params['order']) && !empty($params['order'])) {

$order = $params['order'];

}


if (!empty($order) && !empty($sort)) {

$query->sort($sort, $order);

}


// Static save current search query

$_query = &drupal_static(__FUNCTION__, array());

$_query = $query;

}

Now, we need to modify it a bit to suit our needs:

1) We need to check if the current view is the view we want to put custom sort on, like this:

<?php

/**

* Implements hook_search_api_query_alter().

*/

function example_module_search_api_query_alter(SearchApiQueryInterface $query) {


if (!user_access('use search_api_sorts')) {

return;

}


$view = views_get_current_view();

if (empty($view) || $view->name != 'articles_list') {

return;

}


...


}

2) We need to tweak $search_sorts variables and set our field (field_radioactivity) as a default sort, like this:

foreach ($search_sorts as $key => $sort) {

// We set our desired field as a default sort

if ($sort->field == 'field_shared_radioactivity') {

$search_sorts[$key]->default_sort = 1;

$search_sorts[$key]->default_sort_no_terms = 1;

$search_sorts[$key]->active = TRUE;

$search_sorts[$key]->default_order = 'DESC';

}

// We reset default sorts for other fields

else {

$search_sorts[$key]->default_sort = 0;

$search_sorts[$key]->default_sort_no_terms = 0;

$search_sorts[$key]->active = FALSE;

}

}

So in the end, our modified example_module_search_api_query_alter would look like this:

<?php

/**

* Implements hook_search_api_query_alter().

*/

function example_module_search_api_query_alter(SearchApiQueryInterface $query) {


if (!user_access('use search_api_sorts')) {

return;

}


$view = views_get_current_view();

if (empty($view) || $view->name != 'articles_list') {

return;

}


if (!empty($_GET['sort'])) {

return;

}


// There's already an existing sort, so abort!

$existing = $query->getSort();

if (!empty($existing)) {

return;

}


$search_sorts = search_api_sorts_search_sorts($query->getIndex()->machine_name);


foreach ($search_sorts as $key => $sort) {

if ($sort->field == 'field_shared_radioactivity') {

$search_sorts[$key]->default_sort = 1;

$search_sorts[$key]->default_sort_no_terms = 1;

$search_sorts[$key]->active = TRUE;

$search_sorts[$key]->default_order = 'DESC';

}

else {

$search_sorts[$key]->default_sort = 0;

$search_sorts[$key]->default_sort_no_terms = 0;

$search_sorts[$key]->active = FALSE;

}

}


if (empty($search_sorts)) {

return;

}

$default_sort = _search_api_sorts_get_default_sort($search_sorts, $query->getKeys());


// alter sort field and sort order

$sort = $default_sort->field;

$params = drupal_get_query_parameters($_GET, array(

'q',

'page'

));

if (isset($params['sort']) && !empty($params['sort'])) {

$sort = $params['sort'];

}


$order = $default_sort->default_order;

if (isset($params['order']) && !empty($params['order'])) {

$order = $params['order'];

}


if (!empty($order) && !empty($sort)) {

$query->sort($sort, $order);

}


// Static save current search query

$_query = &drupal_static('search_api_sorts_search_api_query_alter', array());

$_query = $query;

}

3) This function will only get applied on our desired view, if the view is different example_module_search_api_query_alter exists and the default search_api_sorts_search_api_query_alter kicks in, so your customisation breaks nothing if the view is not the one you need.

Hope this one is helpful, let me know in comments and enjoy!

Bạn thấy bài viết này như thế nào?: 
No votes yet
Ảnh của Tommy Tran

Tommy owner Express Magazine

Drupal Developer having 9+ year experience, implementation and having strong knowledge of technical specifications, workflow development. Ability to perform effectively and efficiently in team and individually. Always enthusiastic and interseted to study new technologies

  • Skype ID: tthanhthuy

Tìm kiếm bất động sản

 

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
Mike Tyson với trang trại cần sa rộng 418 héc ta tại California

Mike Tyson với trang trại cần sa rộng 418 héc ta tại California

Không chỉ là một võ sĩ quyền Anh, một ngôi sao điện ảnh hay gần đây nhất là một diễn giả, cuộc đời của Mike Tyson dường như sắp bước sang một chương mới với tư cách là một ‘ông trùm’ cần sa.

blogspot

Cộng đồng Blogger Việt điêu đứng vì Blogspot bị chặn tại Việt Nam

Những ngày gần đây, cộng đồng blogger Việt lại một phen điêu đứng trước việc các nhà mạng trong nước liên tục chặn dịch vụ này và gần như các trang sử dụng blogspot dạng subdomain.blogspot.com không thể truy cập và nếu có cũng phải dùng proxies hay công cụ của bên thứ 3 hoặc ít nhất phải dùng domain riêng. Đây có thể là một thực tế đã được dự báo trước?

Hình mẫu vắcxin phòng COVID-19

Vắcxin phòng bệnh COVID-19 do Đại học Oxford nghiên cứu

Giới chức y tế Anh cho biết vắcxin phòng bệnh COVID-19 do Đại học Oxford nghiên cứu, phát triển đã bắt đầu được thử nghiệm trên người từ ngày 23.4.2020

Công ty diệt chuột T&C

 

Diet con trung