0

I use commerce, search api and facets. I have a "shop" view with indexed products. It works good and I can filter and sort the view using "search api" facets and "search api" sorts fields.
I can sort the view by an indexed field, like product base price which is a field of a product object. The problem is this base price could change due to rules (discounts, offers, etc), and then, the final price for the customer could be different. I need to sort the "shop" view by the final customer prices, but I don't know how to do it with this indexed view. Any sugestion? TIA

1 Answer 1

0

Although I didn't find how to do it with views, I have found an alternative solution using views hooks.
First I have to unset the pager, because I need all records to sort. Only if it's this view and this sort criteria.

function MYMODULENAME_filters_views_pre_execute(&$view) {
  if (('shop' == $view->name) && ($view->exposed_raw_input['sort_by'] == 'field_product_commerce_price_amount_decimal_desc')) {
    $view->query->set_limit(NULL); 
    $view->query->set_offset(NULL);     
}}

After this, I reorder the $view->results as I need in another hook:

function MYMODULENAME_views_post_execute(&$view) {

    if (('shop' == $view->name) && ($view->exposed_raw_input['sort_by'] == 'field_product_commerce_price_amount_decimal_desc')) {

    $milista = array();
    foreach($view->result as $clave=>$valor) {
        $prdd = node_load($valor->entity);
        $producto = commerce_product_load($prdd->field_product['und'][0]['product_id']);
        $price = commerce_product_calculate_sell_price($producto);
        array_push($milista,array(0=>$clave, 1=>$valor->entity, 2=>$price['amount']));
    }

    if ($view->exposed_raw_input['sort_order']=='ASC') $ordenado = SortByKeyValue($milista, 2);
    else $ordenado = SortByKeyValue($milista, 2, SORT_DESC);

    $listafinal = array();
    foreach($ordenado as $datos) {
        array_push($listafinal, $view->result[$datos[0]]);
    }

    // Now, the pager
    $itemsperpage = 16;  // default items per page
    if ($view->exposed_raw_input['items_per_page']) $itemsperpage = $view->exposed_raw_input['items_per_page'];
    $page=1;
    if (isset($view->query->pager->current_page)) $page =  $view->query->pager->current_page;

    $indice = $itemsperpage * $page;

    if (($indice>sizeof($listafinal)) && ($itemsperpage!=0)) $indice = sizeof($listafinal) / $itemsperpage;

    $listafinal = array_slice($listafinal,$indice,$itemsperpage);

    // Lastly, I change the view results
    $view->result = $listafinal;
  }
}

To sort the array, I used the next functions:

function SortByKeyValue($data, $sortKey, $sort_flags=SORT_ASC)
{
    if (empty($data) or empty($sortKey)) return $data;

    $ordered = $data;

    if ($sort_flags==SORT_ASC) uasort($ordered,'cmpasc');
    else uasort($ordered,'cmpdesc');

    return $ordered;
}

function cmpasc($a, $b) {
    if ($a[2] == $b[2]) {
        return 0;
    }
    return ($a[2] < $b[2]) ? -1 : 1;
}

function cmpdesc($a, $b) {
    if ($a[2] == $b[2]) {
        return 0;
    }
    return ($a[2] > $b[2]) ? -1 : 1;
}

I hope this solution could help someone with my same use case.

1
  • Could you post code for commerce_product_calculate_sell_price()?
    – Dunot
    Commented Apr 14 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.