Commit 1776b019 authored by catch's avatar catch

Issue #2337753 by alexpott: ContentEntityNullStorage does not implement a query service

parent dc52e851
......@@ -724,6 +724,8 @@ services:
arguments: ['@database']
tags:
- { name: backend_overridable }
entity.query.null:
class: Drupal\Core\Entity\Query\Null\QueryFactory
entity.query.keyvalue:
class: Drupal\Core\Entity\KeyValueStore\Query\QueryFactory
arguments: ['@keyvalue']
......
......@@ -2,7 +2,7 @@
/**
* @file
* Contains \Drupal\Core\Entity\FieldableNullStorage.
* Contains \Drupal\Core\Entity\ContentEntityNullStorage.
*/
namespace Drupal\Core\Entity;
......@@ -79,7 +79,7 @@ public function save(EntityInterface $entity) {
* {@inheritdoc}
*/
protected function getQueryServiceName() {
throw new QueryException('Null implementation can not be queried.');
return 'entity.query.null';
}
/**
......
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Query\Null\Condition.
*/
namespace Drupal\Core\Entity\Query\Null;
use Drupal\Core\Entity\Query\ConditionBase;
/**
* Defines the condition class for the null entity query.
*/
class Condition extends ConditionBase {
/**
* Implements \Drupal\Core\Entity\Query\ConditionInterface::compile().
*/
public function compile($query) {
}
/**
* Implements \Drupal\Core\Entity\Query\ConditionInterface::exists().
*/
public function exists($field, $langcode = NULL) {
return $this->condition($field, NULL, 'IS NOT NULL', $langcode);
}
/**
* Implements \Drupal\Core\Entity\Query\ConditionInterface::notExists().
*/
public function notExists($field, $langcode = NULL) {
return $this->condition($field, NULL, 'IS NULL', $langcode);
}
}
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Query\Null\Query.
*/
namespace Drupal\Core\Entity\Query\Null;
use Drupal\Core\Entity\Query\QueryAggregateInterface;
use Drupal\Core\Entity\Query\QueryBase;
use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\Core\Entity\Query\Sql\ConditionAggregate;
/**
* Defines the entity query for configuration entities.
*/
class Query extends QueryBase implements QueryInterface, QueryAggregateInterface {
/**
* Implements \Drupal\Core\Entity\Query\QueryInterface::execute().
*/
public function execute() {
if ($this->count) {
return 0;
}
return [];
}
/**
* {@inheritdoc}
*/
public function existsAggregate($field, $function, $langcode = NULL) {
return $this->conditionAggregate->exists($field, $function, $langcode);
}
/**
* {@inheritdoc}
*/
public function notExistsAggregate($field, $function, $langcode = NULL) {
return $this->conditionAggregate->notExists($field, $function, $langcode);
}
/**
* {@inheritdoc}
*/
public function conditionAggregateGroupFactory($conjunction = 'AND') {
return new ConditionAggregate($conjunction, $this);
}
}
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Query\Null\QueryFactory.
*/
namespace Drupal\Core\Entity\Query\Null;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\Query\QueryBase;
use Drupal\Core\Entity\Query\QueryFactoryInterface;
/**
* Provides a factory for creating entity query objects for the null backend.
*/
class QueryFactory implements QueryFactoryInterface {
/**
* The namespace of this class, the parent class etc.
*
* @var array
*/
protected $namespaces;
/**
* Constructs a QueryFactory object.
*/
public function __construct() {
$this->namespaces = QueryBase::getNamespaces($this);
}
/**
* {@inheritdoc}
*/
public function get(EntityTypeInterface $entity_type, $conjunction) {
return new Query($entity_type, $conjunction, $this->namespaces);
}
/**
* {@inheritdoc}
*/
public function getAggregate(EntityTypeInterface $entity_type, $conjunction) {
return new Query($entity_type, $conjunction, $this->namespaces);
}
}
<?php
/**
* @file
* Contains \Drupal\system\Tests\Entity\ContentEntityNullStorageTest.
*/
namespace Drupal\system\Tests\Entity;
use Drupal\contact\Entity\ContactForm;
use Drupal\Core\Config\ConfigImporter;
use Drupal\Core\Config\StorageComparer;
use Drupal\simpletest\KernelTestBase;
/**
* Tests ContentEntityNullStorage entity query support.
*
* @see \Drupal\Core\Entity\ContentEntityNullStorage
* @see \Drupal\Core\Entity\Query\Null\Query
*
* @group Entity
*/
class ContentEntityNullStorageTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('system', 'contact', 'user');
/**
* Tests using entity query with ContentEntityNullStorage.
*
* @see \Drupal\Core\Entity\Query\Null\Query
*/
public function testEntityQuery() {
$this->assertIdentical(0, \Drupal::entityQuery('contact_message')->count()->execute(), 'Counting a null storage returns 0.');
$this->assertIdentical([], \Drupal::entityQuery('contact_message')->execute(), 'Querying a null storage returns an empty array.');
$this->assertIdentical([], \Drupal::entityQuery('contact_message')->condition('contact_form', 'test')->execute(), 'Querying a null storage returns an empty array and conditions are ignored.');
$this->assertIdentical([], \Drupal::entityQueryAggregate('contact_message')->aggregate('name', 'AVG')->execute(), 'Aggregate querying a null storage returns an empty array');
}
/**
* Tests deleting a contact form entity via a configuration import.
*
* @see \Drupal\Core\Entity\Event\BundleConfigImportValidate
*/
public function testDeleteThroughImport() {
$contact_form = ContactForm::create(['id' => 'test']);
$contact_form->save();
$this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.staging'));
// Set up the ConfigImporter object for testing.
$storage_comparer = new StorageComparer(
$this->container->get('config.storage.staging'),
$this->container->get('config.storage'),
$this->container->get('config.manager')
);
$config_importer = new ConfigImporter(
$storage_comparer->createChangelist(),
$this->container->get('event_dispatcher'),
$this->container->get('config.manager'),
$this->container->get('lock'),
$this->container->get('config.typed'),
$this->container->get('module_handler'),
$this->container->get('module_installer'),
$this->container->get('theme_handler'),
$this->container->get('string_translation')
);
// Delete the contact message in staging.
$staging = $this->container->get('config.storage.staging');
$staging->delete($contact_form->getConfigDependencyName());
// Import.
$config_importer->reset()->import();
$this->assertNull(ContactForm::load($contact_form->id()), 'The contact form has been deleted.');
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment