Problem/Motivation

I don't know for sure if this is a bug, but I've not been able to find a workaround.

I wish to alter an SQL query with a where condition that includes a 'LIKE' clause. Drupal Database supports this with escapeLike(). Problem is, if you need to use this in a Views filter handler plugin, you modify the query in the public function query() function which does not have the database connection call in it. So, an error is called:

Error: Call to undefined method Drupal\views\Plugin\views\query\Sql::escapeLike() in Drupal\sbn\Plugin\views\filter\NodeActivityFilter->query() (line 66 of modules/custom/sbn/src/Plugin/views/filter/NodeActivityFilter.php).

Typically when I have used escapeLike() it has been in a function which contains:

$database = \Drupal::database();
$query = $database->select('group_content_field_data', 'g');

So, $query->escapeLike() is associated with that database connection.

Steps to reproduce

Create a views filter handler plugin.

In public function query(), add a condition to the base table that contains a LIKE clause. Here is my example:

public function query() {
$this->ensureMyTable();
$query = $this->query;
$table = array_key_first($query->tables);
$nid = sbn_get_nodeid_from_path();
$lookfor = '/node/'.$nid.'/edit';
$this->query->addWhere($this->options['group'], $table . '.location', '%' . $this->query->escapeLike($lookfor) . '%', 'LIKE');
}

You get this error:

Error: Call to undefined method Drupal\views\Plugin\views\query\Sql::escapeLike() in Drupal\sbn\Plugin\views\filter\NodeActivityFilter->query() (line 66 of modules/custom/sbn/src/Plugin/views/filter/NodeActivityFilter.php).
Drupal\sbn\Plugin\views\filter\NodeActivityFilter->query() (Line: 1377)
Drupal\views\ViewExecutable->_build() (Line: 1266)
Drupal\views\ViewExecutable->build() (Line: 392)
Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1634)
Drupal\views\ViewExecutable->executeDisplay() (Line: 81)
Drupal\views\Element\View::preRenderViewElement()
call_user_func_array() (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback() (Line: 788)
Drupal\Core\Render\Renderer->doCallback() (Line: 374)
Drupal\Core\Render\Renderer->doRender() (Line: 204)
Drupal\Core\Render\Renderer->render() (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 243)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare() (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse() (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray()
call_user_func() (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch() (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 19)
Drupal\sbn\Middleware\Redirect->handle() (Line: 58)
Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 23)
Stack\StackedHttpKernel->handle() (Line: 707)
Drupal\Core\DrupalKernel->handle() (Line: 19)

Proposed resolution

Add escapeLike() to Drupal\views\Plugin\views\query\Sql

If there is a way to do this now without throwing an error, I apologize. If there isn't, then this would be a fairly large bug as there are little workarounds for the LIKE clause in the query function.

p.s. I did try the only suggestion I could find in issues here: https://www.drupal.org/project/drupal/issues/2664530#comment-11681237

'%' . Database::getConnection()->escapeLike($word) . '%'

Didn't work.

Comments

SomebodySysop created an issue. See original summary.

somebodysysop’s picture

Issue summary: View changes

Corrected a little typo. Searched all my contrib modules and could not find one example of escapeLike used in a Views plugin.

somebodysysop’s picture

Issue summary: View changes

Just identifying the code I tried that didn't work:

'%' . Database::getConnection()->escapeLike($word) . '%'
somebodysysop’s picture

Status: Active » Fixed

Found the solution in: /views/src/Plugin/views/filter/StringFilter.php

use Drupal\Core\Database\Connection;

    $this->query->addWhere($this->options['group'], $field, '%' . $this->connection->escapeLike($this->value) . '%', $operator);

larowlan’s picture

Category: Bug report » Support request

Status: Fixed » Closed (fixed)

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