function UserSelection::entityQueryAlter

Same name in other branches
  1. 8.9.x core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php \Drupal\user\Plugin\EntityReferenceSelection\UserSelection::entityQueryAlter()
  2. 10 core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php \Drupal\user\Plugin\EntityReferenceSelection\UserSelection::entityQueryAlter()
  3. 11.x core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php \Drupal\user\Plugin\EntityReferenceSelection\UserSelection::entityQueryAlter()

Overrides SelectionPluginBase::entityQueryAlter

File

core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php, line 216

Class

UserSelection
Provides specific access control for the user entity type.

Namespace

Drupal\user\Plugin\EntityReferenceSelection

Code

public function entityQueryAlter(SelectInterface $query) {
    parent::entityQueryAlter($query);
    // Bail out early if we do not need to match the Anonymous user.
    if (!$this->getConfiguration()['include_anonymous']) {
        return;
    }
    if ($this->currentUser
        ->hasPermission('administer users')) {
        // In addition, if the user is administrator, we need to make sure to
        // match the anonymous user, that doesn't actually have a name in the
        // database.
        $conditions =& $query->conditions();
        foreach ($conditions as $key => $condition) {
            if ($key !== '#conjunction' && is_string($condition['field']) && $condition['field'] === 'users_field_data.name') {
                // Remove the condition.
                unset($conditions[$key]);
                // Re-add the condition and a condition on uid = 0 so that we end up
                // with a query in the form:
                // WHERE (name LIKE :name) OR (:anonymous_name LIKE :name AND uid = 0)
                $or = $this->connection
                    ->condition('OR');
                $or->condition($condition['field'], $condition['value'], $condition['operator']);
                // Sadly, the Database layer doesn't allow us to build a condition
                // in the form ':placeholder = :placeholder2', because the 'field'
                // part of a condition is always escaped.
                // As a (cheap) workaround, we separately build a condition with no
                // field, and concatenate the field and the condition separately.
                $value_part = $this->connection
                    ->condition('AND');
                $value_part->condition('anonymous_name', $condition['value'], $condition['operator']);
                $value_part->compile($this->connection, $query);
                $or->condition($this->connection
                    ->condition('AND')
                    ->where(str_replace($query->escapeField('anonymous_name'), ':anonymous_name', (string) $value_part), $value_part->arguments() + [
                    ':anonymous_name' => \Drupal::config('user.settings')->get('anonymous'),
                ])
                    ->condition('base_table.uid', 0));
                $query->condition($or);
            }
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.