In handlers/views_handler_filter_boolean_operator_string.inc, the query() method is setting up a where clause string, and then calling:

    $this->query->add_where($this->options['group'], $where);

This calls (in plugins/views_plugin_query_default.inc) the add_where() method on the query class, which adds it to the query conditions... but I think it should be calling add_where_expression() instead, because add_where() doesn't seem to handle a full where clause correctly, and the query is coming out IS NULL every time, even though the handler is setting the where clause to <> ''

Does that make any sense? What I'm trying to say is that the where clause from this filter is coming out (fieldname IS NULL) or (fieldname IS NOT NULL) even though the $where that the function calculates is either (fieldname = '') or (fieldname <> ''). The reason is that calling add_where() doesn't work for a where expression. You need to call add_where_expression() instead.

This patch fixes it. You might want to see if there are other places in Views where the same thing is happening too?

I encountered this in trying to set up a hook_views_data() by the way, so I don't have a way to test it directly in the UI... I'm not sure that filter is being used in Views anywhere directly?

Comments

Status: Needs review » Needs work
Issue tags: -Quick fix

The last submitted patch, handlerfilterbooleanstring.patch, failed testing.

jhodgdon’s picture

Status: Needs work » Needs review
Issue tags: +Quick fix

handlerfilterbooleanstring.patch queued for re-testing.

jhodgdon’s picture

Status: Needs review » Reviewed & tested by the community

I'm wondering if I dare to just mark this RTBC? It's a fairly obvious fix affecting one line of code, and the patch definitely works for me, and we'll need it on api.drupal.org the next time we update the API module, so that we can make a listing page of all items marked with @deprecated documentation tags. And your Views tests pass.

Yes, I dare to do it! You can always mark it back to "needs review" or "needs work" if you disagree. :)

jhodgdon’s picture

Is it possible that this could get committed sometime soon?

I would like to deploy some new code from the API module to api.drupal.org sometime soon, and it depends on the fix to this issue. I can grab the dev version of Views, but dealing with a patch in the bzr repo there is kind of annoying... Please? :)

dawehner’s picture

Project: Views (for Drupal 7) » Drupal core
Version: 7.x-3.x-dev » 8.x-dev
Component: Code » views.module
Issue tags: +Needs tests, +VDC

Committed but not pushed yet, but it will happen the next time I really come online.

jhodgdon’s picture

Status: Reviewed & tested by the community » Patch (to be ported)

It does look to me as though the Drupal 8 code is probably making the same mistake.

The code is in
core/modules/views/lib/Drupal/views/Plugin/views/filter/BooleanOperatorString.php
and just like the D7 code, it's calling
$this->query->addWhere([group], $where).
on line 40.

However, I'm not sure what this addWhere() method is. It doesn't appear to be part of Views' QueryPluginBase class, which is what HandlerBase::$query is documented to be.

Oh I see. It's on the Sql class.

Yeah, it looks like it should be calling Sql::addWhereExpression() and not Sql::addWhere.

jhodgdon’s picture

Status: Patch (to be ported) » Needs review
StatusFileSize
new618 bytes

Here's a completely untested patch to fix this. I think it's correct but unlike in D7 I do not have code in place to test it.

jhodgdon’s picture

So... Shouldn't the QueryInterface class in D8 views have this addWhere method and others on it that SQL has, so that a Handler like Boolean String whatever it's called can call this method reliably? And shouldn't the $query member variable on the Handler base class be documented to be QueryInterface rather than QueryPluginBase? And yes these questions are both off-topic for this issue... but it's sloppy to say the least...

jhodgdon’s picture

I checked the other filters in the same directory and I am pretty sure their calls to addWhere() are fine. None of them is attempting to pass in a string WHERE clause except this one. I didn't go back to Views 7.x contrib to check there.

I also looked at the arguments directory in D8 core Views and didn't see anything obvious there either.

So this one filter is probably the only place this problem occurs? hopefully.

jhodgdon’s picture

Well, the test bot didn't complain. I'm not going to RTBC my own patch here because I didn't test it in D8, but the equivalent patch is definitely working in D7.

dawehner’s picture

We haven't really made progress with defining a proper interface for queries, but the general problem is that query plugins are independent from things like the database, so something like addWhere might need a different interface if you are dealing with apache solr for example.

I would RTBC it, if there would be a test, but actually, do you know of any example where this handler could be actually useful in core, because then maybe already the HandlerAll test would be triggered and test what we need.

jhodgdon’s picture

Well, let's see. I used it in the D7 API module... What I had is a database field with this hook_schema() definition:

      'deprecated' => array(
        'description' => 'Deprecated descriptions',
        'type' => 'text',
        'size' => 'medium',
        'not null' => FALSE,
      ),

This database field stores the description that people put after the @deprecated tag in API documentation.

And what I wanted to do is be able to use that to filter API documentation based on whether that database field was empty or not. So I put the following into hook_views_data():

    'deprecated' => array(
      'title' => t('Deprecated'),
      'help' => t('Whether this item is deprecated or not'),
      'filter' => array(
        'handler' => 'views_handler_filter_boolean_operator_string',
      ),
    ),

And then I was able to use this as a filter in a view, to set up a page displaying all deprecated functions (which is coming soon to api.drupal.org, like maybe today or this week, now that the views 7 patch has been committed):

  $handler->display->display_options['filters']['deprecated']['id'] = 'deprecated';
  $handler->display->display_options['filters']['deprecated']['table'] = 'api_documentation';
  $handler->display->display_options['filters']['deprecated']['field'] = 'deprecated';
  $handler->display->display_options['filters']['deprecated']['value'] = '1';

So this handler basically allows you to set up a filter for a text-containing database field that acts as a Boolean. I'm not sure if it would be useful in Core for anything or not... I cannot think of anything off-hand?

dawehner’s picture

StatusFileSize
new6.41 KB

Just wrote a test, but they don't work yet.

Status: Needs review » Needs work

The last submitted patch, vdc-2006560-13.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new2.21 KB
new7.91 KB

This was easy to fix.

The change in the base test class is indented, because it was useful here.

Status: Needs review » Needs work

The last submitted patch, vdc-2006560-15.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new2.37 KB
new8.58 KB

There we go.

jhodgdon’s picture

Status: Needs review » Needs work

The documentation on the test class needs some work:

a) I think we need @inheritdoc on the getInfo() function?

b)

+   * Tests the boolean filter with grouped exposed form enabled.
+   */
+  public function testFilterBooleanOperatorString() {

The word Boolean is a proper noun and should be capitalized.

c)

+   * @return array
+   */
+  protected function getGroupedExposedFilters() {

@return statements need a line of descriptive documentation as well.

d) There may be an extra blank line at the end of the test file.

e) It would also probably be good to attach just the test addition part of the patch so we can verify that it fails without the code fix (to verify that it is testing the actual bug reported here).

dawehner’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new1.07 KB
new8.64 KB
new5.87 KB

a) I think we need @inheritdoc on the getInfo() function?

I can't find a parent function also called getInfo(), so @inheritdoc would be kind of pointless

jhodgdon’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs tests

OK on (a). Stupid getInfo().

Anyway, the docs now look good, and I gave both the code patch and the tests a close review. They make sense to me. The patch is what was needed in Drupal 7 Views to fix this bug, and the tests certainly look like they are testing this exact functionality.

So assuming that the test bot returns red for the FAIL patch and green for the PASS patch, I believe this is good to go, and I'm marking it RTBC. I suppose that when the FAIL patch fails, the bot will change the status, but we can change it back then.

jhodgdon’s picture

Issue tags: -Needs tests

fixing inadvertent tag re-add

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorStringTest.phpundefined
@@ -0,0 +1,231 @@
+    $view = views_get_view('test_view');
...
+    $view = views_get_view('test_view');

views_get_view has been deprecated see #2032031: [Change notice] Deprecate use of views_get_view function in favour of Views::getView() method. We need to use \Drupal\views\Views::getView()

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new1.2 KB
new8.66 KB

Good catch!

Status: Needs review » Needs work

The last submitted patch, vdc-2006560-23.patch, failed testing.

alexpott’s picture

StatusFileSize
new8.66 KB

Re-uploading patch because the test fail is interesting... I know I can press retest but it makes retrieving the borked test super hard. See #2057247: On really quick testbots LocaleUpdateCronTest can fail

No commit credit should be given!

alexpott’s picture

Status: Needs work » Needs review
dawehner’s picture

I will try to look at the messages in the future in order to detect maybe other random failures.

jhodgdon’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC, since the two changes in the latest patch appear to have fixed all the views_get_view() calls.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed c5b9bb0 and pushed to 8.x. Thanks!

Status: Fixed » Closed (fixed)

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

ZenDoodles’s picture

Project: Drupal core » Views (for Drupal 7)
Version: 8.x-dev » 7.x-3.x-dev
Component: views.module » Code
Status: Closed (fixed) » Needs work
Issue tags: +needs backport to 7.x-3.x

Patch does not appear to have made it into 7.x-3.7. Original patch will probably work, but tests should prolly be backported too.

rudiedirkx’s picture

Issue summary: View changes

Why handle it so differently from parent class views_handler_filter_boolean_operator? I reused that logic, which uses add_where() and db_or():

  function query() {
    $this->ensure_my_table();
    $field = "$this->table_alias.$this->real_field";

    if (empty($this->value)) {
      if ($this->accept_null) {
        $or = db_or()
          ->condition($field, '', '=')
          ->condition($field, NULL, 'IS NULL');
        $this->query->add_where($this->options['group'], $or);
      }
      else {
        $this->query->add_where($this->options['group'], $field, '', '=');
      }
    }
    else {
      $this->query->add_where($this->options['group'], $field, '', '<>');
    }
  }

Makes more sense IMO.

jhodgdon’s picture

There was a patch for 7.x in the very early stages of this issue, which is here:
https://drupal.org/files/handlerfilterbooleanstring.patch

On comment #5, @dawehner said he committed it, but it may never have gotten pushed. Could we just get it committed and pushed?

micahw156’s picture

Status: Needs work » Closed (fixed)

Looks like this was committed for 7.x and is now included in 7.x-3.8 release.

http://cgit.drupalcode.org/views/commit/?id=356aee7686b96f6c15e262a2d5e4...

micahw156’s picture

Status: Closed (fixed) » Needs work

Whoops. Reopening -- didn't quite read the part about needing tests in #31.