Problem/Motivation

I have two nodes types--one for contact information for a person, and one for a product. These node types are linked together with an unlimited-length entity reference field with a bi-directional relationship established with Corresponding Entity References. Some of the products linked to contacts are unpublished.

I have created a view to output all of the contact nodes. This view includes the entity reference field linking to products as a hidden field, and I've added a selective filter so users can filter contacts by product.

The problem I'm having is that, while viewing the site as an anonymous user (Or any user that does not have the requisite permissions to see unpublished nodes), those unpublished products are being exposed in the selective filter as as "Empty (nid)", which is bad for the user experience.

My assumption is that, when the entity reference field is being retrieved, all of the nids in that field are being returned, regardless of their Published state; but when the view (Or is it the selective filter module?) tries to retrieve the metadata (title), that fails, leaving it with the 'Empty (nid)' response. These entries seem to already be formatted as 'Empty (nid)' before Views Selective Filters reformats them on line 428 (described below).

This is because the referenced products are not also filtered for Published:Yes.

Proposed resolution

As a quick and dirty patch to remove inaccessible items from the filter drop-down, this portion of code:
views_handler_filter_selective.inc:428
$oids[$key] = empty($value) ? t('Empty (@key)', array('@key' => empty($key) ? json_encode($key) : $key)) : $value;
can be simplified to:

        if($value) {
          $oids[$key] = $value;
        }

This has worked for my purposes--not showing inaccessible nodes in the options list--but, as david_garcia has noted, this needs more eyes and a better understanding of what the root cause is.

The solution was to:

  1. Add a relationship of type "Entity Reference: Referenced Entity" to the entity reference field on the contact node
  2. Add a second "Content: Published" filter, set to 'Yes', and using the entity reference relationship

Comments

nmalinoski created an issue. See original summary.

Mike.Conley’s picture

+1 - I'll be using nmalinoski's fix as well for now.

dak5859’s picture

Can this same fix be accomplished using some sort of hook_views_default_views_alter?

dak5859’s picture

Actually, maybe just a patch.

jalpesh’s picture

Do you need a patch on proposed solution by @nmalinoski?

dak5859’s picture

I didn't think it was best practice to alter the actual module code. I thought that's what a patch was intended to do without actually changing the code in the original views_handler_filter_selective.inc file. But I may not be understanding that correctly. So maybe just applying a local patch file with @nmalinoski's solution is all that is needed.

nmalinoski’s picture

In my case, I am using version control with a branch for modifications like this; so it's not like I'm hacking in modifications on a production server. :P

I simply have not produced/released a patch of my suggested modification because I am not set up with git, and I am unsure if TortoiseSVN will produce a compatible patch file.

david_garcia’s picture

Just before anyone does any effort. This issue is missing proper issue description, objectives and impact of proposed resolution. The root of the issue is not explained, neither how it is being dealt with.

As to my understanding, because selective values are obtained from the original query, there should be no issue because "published" or whatever criteria is inhertied by the view used to build the selective values.

Thanks!

timwood’s picture

@david_garcia have you tried to reproduce the issue to see what is happening or is there not enough information for you to do that? We've run into this problem as well, but with referenced taxonomy terms as selective filters, unpublished using the termstatus module.

david_garcia’s picture

@timwood My post in #8 points to the need to make a greater effort from the community to properly approach the issue. It needs proper description and deep analysis explaining whats is wrong, why and how it is fixed.

With that in place, it will be possible to review and consider for commit. Unfortunately the current patch gives no hint at to what is wrong and how it is being solved. To my understanding, filters are built on top of a cloned view, so if permissions are failing they should do so in both places. And explanation is needed as to why this is not happening and under what circumstances.

Thanks!

nmalinoski’s picture

Issue summary: View changes

@david_garcia My apologies; you're right; the original report is inadequate. I've updated it to try to better explain the setup I'm working with and the problem I was experiencing.

I'm just starting to trace the issue further back; I'll update if I find anything.

timwood’s picture

@nmalinoski I assume your view has a filter for Drupal Published state, to only show published items? By the way, thanks for updating the description!

nmalinoski’s picture

Issue summary: View changes

@timwood The view has a filter for Published state Yes, but.. Oh. Gah. It only applies to the contact nodes the view is configured to show, not the referenced products.

This is easily solved by adding an Entity Reference: Referenced Entity relationship on the ER field, then adding a second Published filter, set to Yes and using that relationship. After configuring the relationship, I no longer get 'Empty (nid)' items in the filter.

Thank you for pointing me in the right direction! I'm going to update the proposed solution and close this ticket.

nmalinoski’s picture

Issue summary: View changes
Status: Active » Closed (works as designed)
nmalinoski’s picture

For anyone that tried my workaround and found that the view was displaying duplicate rows, this is caused by the relationship to the linked products. You will need to edit the view, open Query settings under Advanced, and enable 'Distinct'.

dak5859’s picture

I would like to re-open this issue as the proposed solution did not resolve the problem we're still having in our situation. We are using a view with relationships to a profile node to allow users to filter on those profiles/users by the users Organization taxonomy field. When a profile contains an unpublished Organization term in their Org field, it shows up to the anonymous user as "Empty (NID)" in the Org filter. When trying to add a relationship of type "Entity Reference: Referenced Entity" to the Organization taxonomy and subsequent filter for "Published State: YES" of the Org terms, IT DID remove the "Empty (NID)" references to unpublished terms, but it also removed the profiles from our list that had unpublished Org terms. We don't want the profile to disappear just because it's using an Org term that's unpublished.

nmalinoski’s picture

@dak5859: Is the relationship to organization term set to required? Are there any other settings in your view that would cause filter out profile nodes that aren't linked to an org term?

dak5859’s picture

@nmalinoski Thank you for responding and offering assistance. Just to be completely clear, the relationships we currently have on our "Directory" view are as follows:

- one relationship to the Profile node
- one relationship to a field collection within that profile node that contains the Organization field (with selections from the Org term taxonomy) or the ability to allow users to add a new Org term which by default is unpublished.
- one relationship to the actual org field within that field collection.

So that last relationship can also be used to add a filter for Org taxonomy term published state: YES. But again, it removes any profiles with an unpublished org term from the view.

And that relationship is not set to "Required" as we don't want users that did not add an Organization to their profile (not a required field) to be removed from the view.

I don't see any other settings in my view that would be removing those profiles with unpublished org terms other than when I add that Org Term Published State filter.

toddwoof’s picture

The proposed solution looks like it works, but it breaks the search results.

It will improperly exclude from the search results any node(s) that don't have a reference to at least one published node for that filter, even if you don't make a selection for that filter.

This means that your search results will be wrong, unless (a) every node in the search criteria happens to have a reference to at least one published node -- which is not always the case, or (b) you have actually selected an option for this particular filter -- which is also not always the case.

Example:

Products have entity references to color and size. You want a search page, to filter products by color, size, or both. So, two selective filters, one for color and one for size. However, there is an unpublished color node, and there are some products which reference the unpublished color.

There are other products that don't have colors -- so, no referenced color nodes -- but they do have sizes.

Without the proposed solution, the unpublished color shows up in the select options. With the proposed solution it's removed -- but the products that don't have a reference to a published color are also excluded from the results, even if you're not using that filter. That is, products with sizes but no colors don't show up in the search results at all, even if you are not trying to filter by color.

I assume this is because the filter "is published" via the relationship is looking for a referenced node that's published, but in this case, there isn't one.

It seems that what's need is a way to ignore entity references to unpublished nodes, rather than evaluating whether there is a published, referenced node.

(Please, someone tell me I missed the hidden checkbox ... would love to solve this.)

toddwoof’s picture

Status: Closed (works as designed) » Active

Changing to Active. If I missed something, and I'm wrong in saying the proposed solution doesn't work as expected, feel free to close it again (but please tell me what I missed).

gilgabar’s picture

@toddwoof I ran into the same issue. I ended up creating a custom filter handler to allow it to work. I'm not sure, it may make sense to add it to this module as a patch, but it works just as well in a separate custom module. Here is the code for anyone interested. You will need to put it in a custom module and change the hook function names as appropriate to match your module name. Then you use the new filter in place of the 'Content: Published' filter in the instructions in the issue summary above.


/**
 * Implements hook_views_api().
 */
function my_module_views_api($module = NULL, $api = NULL) {
  return array("api" => "3.0");
}

/**
 * Implements hook_views_data().
 */
function my_module_views_data() {
  $data['node']['status_null'] = array(
    'title' => t('Published or null relationship'),
    'help' => t('Filters out unpublished content if the current user cannot view it, but when using a relationship then it will not filter out items that do not have related content when the publish check is on the related content.'),
    'filter' => array(
      'field' => 'status',
      'handler' => 'views_handler_filter_node_status_null',
      'label' => t('Published or null relationship'),
    ),
  );

  return $data;
}

/**
 * Filter by published status, allow null relationships.
 *
 * @ingroup views_filter_handlers
 */
class views_handler_filter_node_status_null extends views_handler_filter {
  function admin_summary() { }
  function operator_form(&$form, &$form_state) { }
  function can_expose() { return FALSE; }

  function query() {
    $table = $this->ensure_my_table();
    $this->query->add_where_expression($this->options['group'], "$table.status = 1 OR $table.status IS NULL");
  }
}
gilgabar’s picture

Its also worth noting that I have seen the 'Empty (xx)' items issue in one other case with taxonomy term reference fields. In that case it appears to be a referential integrity issue. The term has been deleted, but a node referencing that term still has a reference stored in the term reference field. Views selective filters loads the list of terms for the select menu from the field table, but doesn't validate the existence of the referenced terms, so it ends up displaying empty items.

The solution in that case is really easy. When you see empty items in the view, use the filter to see which items are responsible for that item. Then just visit the node edit page and resave those nodes. It will remove any references that no longer exist.

gilgabar’s picture

One more thought: is there really a valid case where anyone would actually want Empty items rendered in the select menu for end users to see? I'm struggling to come up with any.

The empty items do help us to know that there is a configuration problem with our view, that is something that I do want to know about, but there are better ways to tell the developer/site builder without involving end users. I would recommend logging a message as a less intrusive means of notifying the admin about problems with the view. And to be clear that would specifically be a watchdog log message, not a message rendered to the same page as the view. The issues that result in the empty items are largely content dependent, so it is likely that the issue will not become known until a point when a site is already live and the right combination of content has been added. A series of status messages on the page would be more obnoxious than the empty items in the menu.

I would be happy to put together a patch if that sounds acceptable to the maintainer.