Как отсортировать представление, используя значения, не сохраненные в базе данных


Я использую представление, в котором элементы сортируются по значениям цен, при определенных условиях значения цен переписываются на дисплее (если есть предложения), но не в базе данных. Проблема в том, что мне нужно, чтобы результаты были упорядочены по переписанной цене. Я могу изменить порядок результатов, возвращаемых запросом, с помощью крючка views_pre_render:

Https://stackoverflow.com/questions/2471361/how-to-sort-view-results-programmatically

Но это только влияет на текущую страницу, поэтому элементы не упорядочены должным образом внутри элементов, не показанных на текущей странице.

Другим вариантом было бы заказать представление, изменяющее сам запрос, но, поскольку правильные значения цен на самом деле не существуют в базе данных, я не знаю, как это можно сделать. Есть ли способ упорядочить результаты всего представления, когда существует пагинатор?

Я подумал о том, чтобы не использовать разбивку на страницы и запросить все элементы представления, чтобы я мог создать свой собственный разбиение на страницы после того, как я заказал результаты, но я не уверен, как это повлияет на скорость страницы.

Author: Community, 2016-03-10

1 answers

Я использовал крюк предварительной визуализации представления, чтобы изменить порядок возвращаемых строк (мне пришлось отключить разбиение на страницы и создать свою собственную систему разбиения на страницы). Вот пример функции:

function your_theme_or_module_views_pre_render(&$view) {
  if ('your_view' == $view->name && 'your_display' == $view->current_display ) {
    if(isset($_GET['sort_order'])){
      if($_GET['sort_order'] == 'ASC'){
        $sortorder = SORT_ASC;
      }else{
        $sortorder = SORT_DESC;
      }
      if($_GET['sort_by'] == 'field_price_value'){
        $byprice = true;
      }else{
        $byprice = false;
      }    
    }else{
      $byprice = true;
      $sortorder = SORT_ASC;
    }
    $order = array();
    foreach ($view->result as $key => $row){
    /* Here you can modify the values you want to show
    and put them in an order array */
      $row->field_field_price[0]['rendered']['#markup'] = $thenewprice[$index]."€";
      $row->field_field_price[0]['raw']['value'] = $thenewprice[$index];
      $order[$key] = $thenewprice[$index]; // we will use this array for multisorting
    }

    //this will be used for pagination In my case I'll show 8 results per page
    $numpages = ceil(count($view->result)/8);
    if($byprice){
      /* we only change the rows order if we are sorting by the
      modified field, otherwise the order returned by the view is fine */
      array_multisort($order, $sortorder, $view->result);
    }

Теперь мы создаем систему разбивки на страницы, которую вы можете использовать в качестве примера

    if(!isset($_GET['page'])){
      $view->result = array_slice($view->result, 0, 8);
    }else{
      $sumando = ((int)$_GET['page']*8);
      $view->result = array_slice($view->result, $sumando, 8);
    }
    $links = array();
    if(isset($_GET['page'])){
      $page = $_GET['page'];
      $absolute_url = full_url( $_SERVER );
      for($i=0;$i<$numpages;$i++){
        if($page == $i){
          $active = " active";
        }else{
          $active = "";
        }
        $urlconpage = str_replace("page=".$page,"page=".$i,$absolute_url);
        $links[] = "<a class='paginator ".$active."' href='".$urlconpage."'>".$i."</a>";
      }
    }else{
      $absolute_url = full_url( $_SERVER );
      $countarray = explode("?",$absolute_url);
      if(count($countarray)>1){
        for($i=0;$i<$numpages;$i++){
          if(0 == $i){
            $active = " active";
          }else{
            $active = "";
          }
          $urlconpage = $absolute_url."&page=".$i;
          $links[] = "<a class='paginator".$active."' href='".$urlconpage."'>".$i."</a>";
        }
      }else{
        for($i=0;$i<$numpages;$i++){
          if(0 == $i){
            $active = " active";
          }else{
            $active = "";
          }
          $urlconpage = $absolute_url."?page=".$i;
          $links[] = "<a class='paginador".$active."' href='".$urlconpage."'>".$i."</a>";
        }
      }
    }
    $_SESSION['links'] = $links;
  }

Большая часть кода в пагинаторе предназначена только для того, чтобы сохранить неизменными параметры в URL-адресе, необходимые для представления, возвращающего правильные результаты. Функция full_url, которую я вызываю в коде, является адаптацией функция, описанная в:

Https://stackoverflow.com/questions/6768793/get-the-full-url-in-php

Используя переменную СЕАНСА, вы можете распечатать ссылки, которые вы предпочитаете, например, в глобальной текстовой области в нижнем колонтитуле представления, внутри структуры <ul> <li>.

 2
Author: Miquel Correa Casablanca, 2017-05-23 12:41:25