I have a content type "message" which has a reference to an organic group. The messages also references one or more "document" nodes that belong to that same group.
I want to use the widget to allow the user to select the nodes.
When I set up the view used by the widget and add a contextual filter, the filter value doesn't seem to be available (This display does not have a source for contextual filters, so no contextual filter value will be available unless you select 'Provide default') so I also set "When the filter value is not available".
I choose "Provide default value" but neither "current OG group from context" or "content id from url" gives any result. Using - as a check - a fixed value does give me a result. (The view preview works fine of course when entering the contextual parameter)
The only way for me to solve this is to add an exposed filter for the group, so the user explicitly chooses the group id to which the "message" belongs in order to see the "documents" that are availabe in that group.
Is the issue with "OG context"? Or is it the modal form setup?

Comments

erwin k’s picture

Category: Bug report » Support request
joncjordan’s picture

Any solutions?

jsacksick’s picture

Can you try to disable the "Pass selected entity ids to View" option? Because when it's enabled, we're calling the set_arguments method on the view which is probably causing the issue.

hansrossel’s picture

The problem is a bug in the og_context module as the og_context is not available inside ajax calls, there are some patches in the bug report that try to fix this: #1635750: OG Context handler for ajax calls (system, file upload, autocomplete, etc).

You can also not use "nid from url" as an argument in views because the path of the modal is system/ajax.

So inside the function entityreference_view_widget_add_more_ajax($form, $form_state)
print_r(og_context()) is empty.

For node/*/edit pages you could get the nid and gid from the form_state:

$nid = $form_state['build_info']['args'][0]->nid;
$gid = $form_state['build_info']['args'][0]->og_group_ref[LANGUAGE_NONE][0]['target_id'];
$view->set_arguments(array($gid));
hansrossel’s picture

Category: Support request » Bug report
hansrossel’s picture

I have tried the last patch of og_context but could not get a solution with it, so if you have this specific use case where you only use the widget for a view with an organic groups argument set on the group id you could use the following temporary fix/hack until og_context is fixed:

/**
 * Ajax callback for the add_more button.
 */
function entityreference_view_widget_add_more_ajax($form, $form_state) {
  // BEGIN HACK: og_context not available inside ajax call
  // temporary solution based on https://www.drupal.org/node/1635750#comment-9189277
  //
  // editing an existing node
  $gid = $form_state['build_info']['args'][0]->og_group_ref[LANGUAGE_NONE][0]['target_id'];

  if (empty($gid)) {
    // adding a new node
    $item = menu_get_item();
    $contexts = array();
    $entity_type = $form['#entity_type'];

    if (empty($form_state[$entity_type])) {
      return;
    }

    $entity = $form_state[$entity_type];
    list($id) = entity_extract_ids($entity_type, $entity);
    if (!module_exists('entityreference_prepopulate')) {
      return;
    }

    $node_type = $form['#node']->type;

    if (!$fields = og_get_group_audience_fields('node', $node_type)) {
      return;
    }

    if (!$id) {
      $gids = array();
      foreach ($fields as $field_name => $label) {
        $field = field_info_field($field_name);
        $instance = field_info_instance('node', $field_name, $node_type);
        $group_type  = $field['settings']['target_type'];
        // For file uploads when creating a new node, use the group based on the
        // form's #action.
        if (preg_match("/".$field_name."=(\d+)/", $form['#action'], $matches)) {
          if (!isset($matches[1])) {
            return;
          }
          $group_id = $matches[1];
          if (!og_is_group($group_type, $group_id)) {
            return;
          }
          $contexts[$group_type][] = $group_id;
        }
      }
    }
    $gid = $contexts['node'][0];
  }
  // END HACK

  $commands = array();
  if (isset($form_state['triggering_element']['#ervw_settings'])) {
    $settings = $form_state['triggering_element']['#ervw_settings'];
    $target_view = explode('|', $settings['view']);
    $view = views_get_view($target_view[0]);
    if (!empty($view)) {
      // If the pass argument setting has been checked, pass a list of entity
      // ids to the view.
      if (!empty($settings['pass_argument']) && !empty($form_state['ervw_ids'][$settings['index']])) {
        $view->set_arguments(array(implode('+', $form_state['ervw_ids'][$settings['index']])));
      }
      // BEGIN HACK: hardcode $gid as argument
      $view->set_arguments(array($gid));
      // END HACK
      $view->set_display($target_view[1]);
      $view->display_handler->set_option('use_ajax', TRUE);
      $view_markup = $view->preview();
      $html = '';

      // In case there's exposed widgets, put them at the top of the modal.
      if (!empty($view->exposed_widgets)) {
        $html .= '<div class="view-filters">' . $view->exposed_widgets . '</div>';
      }

      // Prepare an array containing information used by the form displayed in
      // the modal.
      $context = array(
        'settings' => $settings,
        'view_markup' => $view_markup,
        'view' => $view,
      );
      $output = drupal_get_form('entityreference_view_widget_modal_form', $context);
      $html .= drupal_render($output);
      $modal_title = $view->get_title();
      $modal_title = empty($modal_title) ? $view->get_human_name() : $modal_title;
      $commands[] = ctools_modal_command_display($modal_title, $html);
      // Wipe the system/ajax url, if we don't do this, the ajax_get_form()
      // callback will be called and any form actions performed within the view
      // such as changing the page or submitting the exposed filters form will
      // break.
      $_GET['q'] = '';
    }
  }
  return array(
    '#type' => 'ajax',
    '#commands' => $commands,
  );
}
hansrossel’s picture

jsacksick’s picture

Status: Active » Fixed

There's normally no need for your hack, you should be able to do that using the hook_entityreference_view_widget_views_arguments_alter().

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

BarisW’s picture

I fixed this using:

<?php
/**
 * Implements hook_entityreference_view_widget_views_arguments_alter().
 */
function MY_MODULE_entityreference_view_widget_views_arguments_alter(&$arguments, $form_state) {
  if ($form_state['build_info']['form_id'] == 'NODE_TYPE_node_form') {
    $arguments[] = $form_state['node']->nid;
  }
}
?>
iaminawe’s picture

Thanks @BarisW - that works great and my view now is aware of the current og context as provided by the nid in the url.

The only problem is now the nids used as a contextual filter to exclude the already selected items does not work. It works correctly if the nid contextual filter is not added but when both are added together then the first time adding works but clicking again to add more just gives a wsod and the following errors in the logs.

Warning: array_key_exists(): The first argument should be either a string or an integer in ctools_get_plugins()
Warning: Illegal offset type in isset or empty in ctools_get_plugins()

Any help to get these 2 contextual filters to play nicely together would be appreciated. Thanks