The purpose of this is related to my question on DA: http://drupal.stackexchange.com/questions/13417/how-can-i-set-a-view-con...

I would love to be able to set a context based on how many rows a View is returning. For instance in my example, I would like to display all videos attached to a node, unless the current node is not attached to any videos, in which case it would output all videos flagged as global.

This could easily be 2 separate view displays (node_videos and global_videos), and then have Context module set a context based on the number of rows node_videos returns.

EDIT: Also, could this use something related to how VBO hooks into Rules? VBO provides a condition such as "Check the number of results returned by a View"

Comments

carn1x’s picture

Ok, decided to write my own context condition plugin for this, all in a single file for now:


function custom_context_context_registry() {
  $registry = array(
    'conditions' => array(
      'views_result' => array(
        'title' => t('Views Results'),
        'description' => t('Set this context when one of these views returns a result.'),
        'plugin' => 'custom_context_condition_views_result',
      )
    )
  );
  return $registry;
}

function custom_context_context_plugins() {
  $plugins = array();
  $plugins['custom_context_condition_views_result'] = array(
    'handler' => array(
      'class' => 'custom_context_condition_views_result',
      'parent' => 'context_condition',
    ),
  );
  return $plugins;
}

function custom_context_init(){
  if ($plugin = context_get_plugin('condition', 'views_result')) {
    $plugin->execute();
  }
}

class custom_context_condition_views_result extends context_condition {

  /**
   * Generate a list of database and module provided views.
   */
  function condition_values() {
    $enabled_views = array();

    $views = views_get_all_views();
    ksort($views);

    foreach ($views as $view) {
      if (!isset($views[$view->name]->disabled) || !$views[$view->name]->disabled) {
        $displays = array();
        foreach ($view->display as $id => $display) {
          $displays[$view->name . ":" . $id] = check_plain("{$view->name} : {$display->display_title}");
        }
        $enabled_views += $displays;
      }
    }
    return $enabled_views;
  }

  function execute() {

    $view_name_displays = array();

    // Gather all required views for checking, to prevent duplicate checking
    foreach ($this->get_contexts() as $context) {
      foreach ($context->conditions['views_result']['values'] as $view_name_display){
        $view_name_displays[$view_name_display] = $view_name_display;
      }
    }

    foreach($view_name_displays as $view_name_display){
      list($view_name, $view_display) = explode(':',$view_name_display);
      $view = views_get_view($view_name);
      $view->set_display($view_display);
      $view->build();
      $view->execute($view->current_display);
      if(count($view->result)){
        foreach ($this->get_contexts($view_name_display) as $context) {
          $this->condition_met($context, $view_name_display);
        }
      }
    }
  }
}

Just to explain how this works, it loads all the views which context module should check on hook_init and checks whether each view has rows or not. I've combined this with certain views which obtain their contextual filters from the current node ID.

carn1x’s picture

Status: Active » Needs review

I guess I'll set this to needs review in case the maintainers or anybody feels like this might be worth integrating.

broeker’s picture

I used this as the basis for a custom module to solve a particular use case -- still works like a charm on latest dev, and it seems generic enough that it would make a nice official plugin to context if there are enough people with similar use cases. Ours involved setting a context based on whether nodes of a certain type existed within an Organic Group but I can think of several other places it would be useful to set context based on the results of a views.

jpstrikesback’s picture

Thanks @carn1x here is a version I placed in a sandbox that uses hook_views_post_execute() instead of hook_init so as to only be executed when a view is executed. That wouldn't work for a global type of condition but it works for checking the results of a view that is just about to be rendered.

Views Result Context

jpstrikesback’s picture

Issue summary: View changes

additional

kevinquillen’s picture