Frage Wie sortiere ich Ergebnisse programmatisch?


Ich versuche, die Ergebnisse einer Ansicht zu nehmen - mit der Funktion views_get_view_result() - und sortiere das Array so, wie ich es von der Views-Oberfläche aus nicht tun konnte. So weit, ist es gut. Ich habe eine Variable $ rows mit all den Sachen, die ich brauche.

Jetzt ... Wie lege ich es zurück? :) Bevor ich diese Art brauchte, benutzte ich views_embed_view()Aber ich kann das nicht mehr machen.

Dankbar für jede Hilfe, fühlt sich an, als wäre ich kurz davor, es zu knacken!

$important_var = important_function();
$result = views_get_view_result($view, $display, $args);
$result = sorting_function($result, $important_var);

//TODO: Put the result back into the view

11
2018-03-18 16:04


Ursprung


Antworten:


Das Sichtenmodul bietet einige Haken für 'externe' Manipulationen, genau wie Drupal Core.

Sie können implementieren hook_views_pre_render(&$view) innerhalb eines benutzerdefinierten Moduls und manipulieren Sie das Ergebnis Array in verfügbar $view->result:

/**
 * Implementation of hook_views_pre_render()
 *
 * @param view $view
 */
function YourModuleName_views_pre_render(&$view) {
  // Check if this is the view and display you want to manipulate
  // NOTE: Adjust/Remove the display check, if you want to manipulate some/all displays of the view
  if ('YourViewName' == $view->name && 'YourDisplayName' == $view->current_display) {
    // EXAMPLE: Just reverse result order
    // TODO: Replace with your desired (re)ordering logic
    $view->result = array_reverse($view->result);
  }
}

Der Hook wird in der Mitte des Ansichtserzeugungsprozesses aufgerufen, nachdem alle Ergebnisdaten zusammengestellt wurden, aber bevor die tatsächliche Ausgabe gerendert wird, werden Änderungen am Ergebnisarray in der endgültigen Ausgabe der Ansichten wiedergegeben.

BEARBEITEN: Alternativ könnten Sie die Ansicht 'manuell' bearbeiten, indem Sie das Verhalten des views_get_view_result() Funktion, aber anstatt das Ergebnis zurückzugeben, manipulieren Sie es und rendern die Ansicht weiter:

function yourModule_get_custom_sorted_view($display_id = NULL) {
  // As the custom sorting probably only works for a specific view,
  // we 'demote' the former $name function parameter of 'views_get_view_result()'
  // and set it within the function:
  $name = 'yourViewName';
  // Prepare a default output in case the view definition can not be found
  // TODO: Decide what to return in that case (using empty string for now)
  $output = '';

  // Then we create the result just as 'views_get_view_result()' would do it:
  $args = func_get_args();
  if (count($args)) {
    array_shift($args); // remove $display_id
  }

  $view = views_get_view($name);
  if (is_object($view)) {
    if (is_array($args)) {
      $view->set_arguments($args);
    }
    if (is_string($display_id)) {
      $view->set_display($display_id);
    }
    else {
      $view->init_display();
    }
    $view->pre_execute();
    $view->execute();
    // 'views_get_view_result()' would just return $view->result here,
    // but we need to go on, reordering the result:
    $important_var = important_function();
    $view->result = sorting_function($result, $important_var);
    // Now we continue the view processing and generate the rendered output
    // NOTE: $view->render will call $view->execute again,
    // but the execute method will detect that it ran already and not redo it.
    $output = $view->render();
    // Clean up after processing
    $view->post_execute();
  }

  return $output;
}

Hinweis: Das ist eine Menge Code-Duplikation und daher fehleranfällig - ich empfehle das nicht und würde lieber mit der obigen Hook-Implementierung fortfahren und versuchen, einen Weg zu finden, von dort aus Zugang zu Ihrer '$ wichtig_var' zu bekommen.


17
2018-03-18 23:59



Abhängig von Ihrer Sortierlogik versuchen Sie möglicherweise, hook_views_query_alter () zu verwenden, um Ihre Sortierung direkt in die Abfrage zu implementieren.

Dies kann ein wenig schwierig sein, aber Sie können sich mit dem Objekt views_query vertraut machen.

Hier ist ein Beispiel aus der realen Welt, wo ich eine Join-Regel basierend auf dem Kontext der Seite anwendete und dann zusätzlich Sortierregeln hinzufügte.

/** 
 * Implementation of hook_views_query_alter(). 
 */ 
function yourmodule_views_query_alter(&$view, &$query) { 
  if ($view->name == 'view_projects' && $view->current_display == 'panel_pane_4') { 
    if (arg(0) == 'node' && is_numeric(arg(1))) { 
      $node = node_load(arg(1)); 
      if ($client_nid = $node->field_ref_client[0]['nid']) { 
        $query->table_queue['node_node_data_field_ref_client']['join']->extra = "field_ref_client_nid = " . $client_nid;
        $query->add_orderby('node', NULL, 'DESC', 'node_node_data_field_ref_client_nid'); 
        $query->add_orderby('node', 'created', 'DESC'); 
      } 
    }
  } 
}

Sehen: http://drupalcontrib.org/api/function/hook_views_query_alter/6


9
2018-03-22 17:18



Ich benutze einen solchen Code dafür:

/**
 * Implementation of hook_views_post_execute()
 *
 * @param view $view
 */
function YourModuleName_views_post_execute(&$view) {
  // Check if this is the view and display you want to manipulate
  // NOTE: Adjust/Remove the display check, if you want to manipulate some/all displays of the view
  if ('YourViewName' == $view->name && 'YourDisplayName' == $view->current_display) {
    // EXAMPLE: Just reverse result order
    // TODO: Replace with your desired (re)ordering logic
    $view->result = array_reverse($view->result);
  }
}

hook_views_pre_render funktioniert nicht für mich.


3
2017-08-27 20:43



Ich kombinierte die obigen Beispiele und schrieb sie wie folgt um. In meinem Fall musste ich die Artikel einzeln sortieren.

Hinweis: Ich habe die Join-Bedingung nicht aufgenommen und habe es nicht mit dem benutzerdefinierten Feld versucht. Aber ich denke, Sie können es leicht herausfinden.

/** 
 * Implementation of hook_views_query_alter(). 
 */ 
function yourmodule_views_query_alter(&$view, &$query) { 
  if ($view->name == 'your_view_name' && $view->current_display == 'your_pane_name') {
    if ($query->orderby[0]['field'] == 'my_order_field') {
      $query->orderby[0]['field'] = "FIELD(my_order_field, 'ord3','ord1','ord2')";
    }
  }
}

0
2018-04-13 17:41