User story

I want to create a view that is based off of a taxonomy term but shows unpublished entities to admin users.

Setup and problem

I create a content view and add the filter Unpublished or admin. So far, so good. Now, I add the relationship Taxonomy terms on node . If I require the relationship, the view is empty. If I don't require the relationship and instead use a filter to scope to one term, the view is empty.

After some digging, I found it's because Views relies on the taxonomy_index table to determine what terms are available to join on. However, taxonomy_index does not contain unpublished entities: both taxonomy_field_insert() and taxonomy_field_update() delete items from taxonomy_index upon firing, and only add items to the table if the entity is published.

Why this is here and not in the core issue queue

This sounds like a problem with a core "feature", but taxonomy_index is supposed to handle only the common use cases of taxonomy, not all use cases. So, Views shouldn't be relying on it to handle situations (like this one) that fall outside the bounds of the index.

So I figured I'd raise it here first to see if there's a way Views can work around it. The immediate workaround is, of course, to implement my own versions of taxonomy_field_insert() and taxonomy_field_update() without the $entity->status check.

Comments

dawehner’s picture

I'm sorry but if we can't rely on taxonomy_index we have to run away. It's undescribable hard to join from node to taxonomy without this table.

just a short summary:

* Join on all fieldapi tables which has a taxonomy reference availible
* join back to taxonomy table based on this fieldapi tables

Have fun, but i fear this is not fixable.

Mark Trapp’s picture

Title: Unpublished nodes do not appear in views when using a taxonomy relationship » Unpublished entities do not appear in views when using a taxonomy relationship
Component: Miscellaneous » taxonomy data

That's unfortunate. Is there a way to prevent certain filters from being available when the relationship doesn't provide enough information? It's definitely not obvious to anyone not enterprising enough to dig through the core API docs as to why it wouldn't work: I tore my hair out trying to figure out what was wrong.

dawehner’s picture

That's probably impossible, because how can views know whether you want to display unbublished nodes are not. This will probably quite hard to detect.
Perhaps this should be documented somewhere.

In general if you want to fix the issue for yourself you could write a contrib module which provides you an index table with the things needed to display unbublished entities as well.
The views integration of your table wouldn't need a lot of stuff because you can basically copy the existant structure from taxonomy.

Mark Trapp’s picture

Status: Active » Closed (works as designed)

Yeah, that's an option; it's also the case that one can just filter by tid without a relationship using the term field, although I'm sure there are use cases for using a taxonomy relationship.

For that, there's an issue in the core queue to add a global variable that would allow unpublished nodes to be indexed, #962664: Taxonomy Index for unpublished entities, so going to mark this as works as designed.

jenlampton’s picture

My fix for this bug was to use the taxonomy_entity_index module, and add a custom module of my own with a veiws_query_alter hook to swap out the taxonomy_index table for the taxonomy_entity_index table for searches. Code looked a little something like this:

/**
 * Implements hook_views_query_alter().
 * Changes the total control views per vocab to use the taxonomy entity index 
 *   instead of the taxonomy_index (which does not show unpublished content).
 */
function MYMODULE_views_query_alter(&$view, &$query) {
  // Only alter the total control content views for vocabs.
  if ($view->name == 'control_content' && ($view->current_display == 'page_1' || 
    $view->current_display == 'page_2' || $view->current_display == 'page_3' || 
    $view->current_display == 'page_4' || $view->current_display == 'page_5' ||
    $view->current_display == 'page_6' || $view->current_display == 'page_7')) {

    // Traverse through the 'join' part of the query and swap the table.
    foreach ($query->table_queue as $table => $table_info) {
      if ($table == 'taxonomy_index') {
        $query->table_queue[$table]['table'] = 'taxonomy_entity_index';
        $query->table_queue[$table]['join']->table = 'taxonomy_entity_index';
        $query->table_queue[$table]['join']->field = 'entity_id';
        $query->table_queue[$table]['join']->definition['table'] = 'taxonomy_entity_index';
        $query->table_queue[$table]['join']->definition['field'] = 'entity_id';
      }
    }
  }
}

Hope someone else finds this helpful! :)

merlinofchaos’s picture

If you only need taxonomy terms from a single vocabulary, then you can just use the relationship on the field. If you need terms from multiple vocabularies you have to use the relationship you referenced.

So, Views shouldn't be relying on it to handle situations (like this one) that fall outside the bounds of the index.

That is all the data that Drupal core offers. It is absolutely NOT a bug of Views that cannot magically use data that does not exist.

phoenix’s picture

Since I had the same problem and came across this post, I wanted to add some extra information for future visitors.

There is a solution to this problem: the taxonomy entity index module.
https://www.drupal.org/project/taxonomy_entity_index

Some more info on this Drupal Answers page:
http://drupal.stackexchange.com/questions/146925/indexing-the-term-of-un...

aks22’s picture

I have used relationship in views. #5 worked for me.

MyriamB’s picture

taxonomy_entity_index module solved my problem

kwiliarty’s picture

What a helpful thread! taxonomy_entity_index worked for me, and for the benefit of others who find their way here I add these notes.

  1. After installing and enabling taxonomy_entity_index on an existing installation I ran drush tei-rebuild as indicated in the documentation.
  2. I did not need to implement the hook offered in #5. Instead of the built in relationships, I used a new relationship for the view in question: "Taxonomy Entity Index: Taxonomy terms on Node".

It worked. I could add filters to the view based on the new relationship without limiting the results to published nodes.

rpmskret’s picture

In drupal 8 so far there is no version of taxonomy_entity_index. But you can instead go to >ADVANCED -> RELATIONSHIPS in views. Add a relationship and choose from the available taxonomy entities. Then leave advanced and add a FILTER CRITERIA; search "taxo" and now there will be more options available. And this one for example will show published and unpublished content:
(field_tags: Taxonomy term) Taxonomy term: Term (= mytag)

hkovacs’s picture

I did not need to use any of the above.

I am using https://www.drupal.org/project/termstatus to unpublish taxo terms and it provides the permissions per role to view unpublished terms so that the unpublished values are correctly displayed in the view.

HTH

trinsic’s picture

I am trying to filter content in admin/content by taxonomy term (unpublished) and I installed taxonomy_entity_index. I ran drush tei-rebuild. When I go into the view: Administration: Taxonomy terms (Term) to add a relationship, I only see "Taxonomy Entity Index: Taxonomy terms on Taxonomy term" when
#10 mentioned that "Taxonomy Entity Index: Taxonomy terms on node" should be available. Does anybody know how to expose that relationship?

Edit: sorry I was in the wrong view. I got this working thank you for the help.