Comment puis-je modifier la valeur d'un filtre et faire modifier la sortie avant le rendu de la vue?

15

Lorsque vous utilisez Drupal 7 et Views 3, quelle est la bonne façon de modifier une valeur de filtre Views afin qu'elle affecte le contenu qui est sur le point d'être rendu?

J'ai essayé tout ce qui est mentionné ici pour D6.

Même si quelques personnes l'ont fait fonctionner, Merlin déclare que la modification des options d'affichage n'est pas la bonne façon d'y parvenir, mais il est vague dans sa réponse quant à ce qu'il faut faire ( http://drupal.org/node/789710#comment- 2927556 ).

J'ai essayé:

function pages_views_pre_view($view){
    $view = views_get_view('north_carolina');
    $view->set_display('default');

    $view->display_handler->options['filters']['province']['value'] = 'Georgia';
    dsm($view->display_handler->options['filters']['province']);
}

Remarques:

1) J'ai créé une vue appelée north_carolinaqui a deux types d'affichages - une page et un bloc (page_1 et bloc_1).

2) mes filtres sont les mêmes sur tous mes écrans, donc j'essaie de changer l'affichage «par défaut» pour qu'il les affecte tous.

3) La valeur par défaut de mon filtre est «Caroline du Nord» (que j'ai définie dans l'interface utilisateur des vues), mais remarquez que j'essaye de le changer en «Géorgie»

4) Si j'exécute DSM immédiatement après, je constate que le filtre a été changé, cependant, mes résultats affichent toujours des résultats «Caroline du Nord». La mise en cache est désactivée et j'obtiens toujours la même chose après avoir exécuté drush cc all.

J'ai également essayé d'exécuter ce même code via hook_views_pre_buildet hook_views_pre_execute.

Aucune suggestion?

ÉDITER:

Comme suggéré, il peut être utile d'avoir des informations supplémentaires. Voici un cliché de la vue:

$view = new view();
$view->name = 'north_carolina';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'North Carolina';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'test nc block';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'fields';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Sort criterion: Content: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'node';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Location: Province */
$handler->display->display_options['filters']['province']['id'] = 'province';
$handler->display->display_options['filters']['province']['table'] = 'location';
$handler->display->display_options['filters']['province']['field'] = 'province';
$handler->display->display_options['filters']['province']['value'] = 'North Carolina';
$handler->display->display_options['filters']['province']['exposed'] = TRUE;
$handler->display->display_options['filters']['province']['expose']['operator_id'] = 'province_op';
$handler->display->display_options['filters']['province']['expose']['label'] = 'State';
$handler->display->display_options['filters']['province']['expose']['operator'] = 'province_op';
$handler->display->display_options['filters']['province']['expose']['identifier'] = 'province';
$handler->display->display_options['filters']['province']['expose']['remember_roles'] = array(
  2 => '2',
  1 => 0,
  3 => 0,
  4 => 0,
);

/* Display: Block */
$handler = $view->new_display('block', 'Block', 'block_1');
$handler->display->display_options['block_description'] = 'test nc block';

Notez que ces gestionnaires sont fournis par le module locations. Plus précisément pour le filtre "Emplacement: Province", je reçois un formulaire de saisie automatique. Quand je tape en Caroline du Nord, ça apparaît, et je dois choisir ça. Cependant, notez dans l'instruction SQL que les vues générées utilisent l'abréviation à deux caractères pour l'état:

SELECT node.title AS node_title, node.nid AS nid, node.created AS node_created
FROM 
{node} node
LEFT JOIN {location_instance} location_instance ON node.vid = location_instance.vid
LEFT JOIN {location} location ON location_instance.lid = location.lid
WHERE (( (node.status = '1') AND (location.province = 'NC') ))
ORDER BY node_created DESC
LIMIT 10 OFFSET 0
blue928
la source

Réponses:

8

Il peut être difficile de déterminer la partie exacte de l'objet vues à modifier. J'exporte généralement la vue en premier et regarde le code généré pour commencer.

L'extrait ci-dessous n'est pas modifié et fonctionne comme prévu sur l'un de mes sites de production. Espérons que cela suffira pour vous mettre dans la bonne direction (évidemment, c'est dans un module personnalisé nommé offer_select). Si vous pouvez fournir le code à partir de la vue exportée, quelqu'un pourra peut-être y jeter un œil.

//Alter the End date filter on the offer views
function offer_select_views_pre_view(&$view) {
  if ($view->name == 'active_offers') {
    $view->display['default']->handler->options['filters']['field_end_value']['value']['value'] = time();
  }
}

--MISE
À JOUR - Pour votre vue spécifique, j'ai installé le module Emplacement et créé quelques nœuds en NC et quelques en Géorgie et importé votre vue pour tester. Dans mon module personnalisé (nommé dev), j'ai commencé avec ce code (avec devel installé):

function dev_views_pre_view(&$view) {
  if ($view->name == 'north_carolina') {
    dpm($view->display['default']->handler->options['filters']);
  }
}

À partir de là, j'ai continué à ajouter les valeurs évidentes affichées dans krumo au tableau jusqu'à ce que j'arrive ici:

function dev_views_pre_view(&$view) {
  if ($view->name == 'north_carolina') {
    dpm($view->display['default']->handler->options['filters']['province']['value']);
  }
}

Qui a simplement imprimé North Carolinaen Krumo. À ce stade, j'ai changé d'imprimer la valeur pour la définir comme ceci:

function dev_views_pre_view(&$view) {
  if ($view->name == 'north_carolina') {
    $view->display['default']->handler->options['filters']['province']['value'] = 'Georgia';
  }
}

Et le tour est joué. Cela a fait l'affaire.

Adam Balsam
la source
Cool. Lorsque j'en aurai l'occasion, je vais jouer avec votre point de vue et voir si je peux trouver une réponse plus concrète.
Adam Balsam
@ blue928 voir ci-dessus. J'ai mis à jour ma réponse avec une réponse spécifique à vos questions et des instructions générales sur la façon d'y arriver.
Adam Balsam
cela a très bien fonctionné. Remarque sur la bonne réponse: Une partie de mon problème est que je n'ai pas eu besoin d'appeler views_get_view ni de régler l'affichage.
blue928
2

Dans le cas où quelqu'un a ce fil surgi lors de la recherche de la même solution sur D8 (comme je l'ai fait):

La nouvelle API permet de manipuler ces paramètres de manière beaucoup plus claire. Voir cette section pour les références.

Petit exemple

function dev_views_pre_view(ViewExecutable &$view, $display_id, array &$args) {
  if ($display_id === 'my_unique_display_name') {
      $args[0] = 'desired_value';
  }
}
Der Zinger
la source