/**
  * {@inheritdoc}
  */
 public function setUp()
 {
     $entity_type_id_key = $this->randomMachineName();
     $entity_type_id = $this->randomMachineName();
     $this->database = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock();
     $this->fieldStorageDefinitions = array($entity_type_id_key => $this->getMock(FieldDefinitionInterface::class));
     $this->entityManager = $this->getMock(EntityManagerInterface::class);
     $this->entityManager->expects($this->atLeastOnce())->method('getFieldStorageDefinitions')->with($entity_type_id)->willReturn($this->fieldStorageDefinitions);
     $this->entityType = $this->getMock(ContentEntityTypeInterface::class);
     $this->entityType->expects($this->atLeastOnce())->method('id')->willReturn($entity_type_id);
     $this->storage = $this->getMockBuilder(SqlContentEntityStorage::class)->disableOriginalConstructor()->getMock();
     $this->sut = new PaymentStorageSchema($this->entityManager, $this->entityType, $this->storage, $this->database);
 }
Example #2
0
 /**
  * {@inheritdoc}
  */
 public function getFieldTableName($field_name)
 {
     $result = NULL;
     if (isset($this->fieldStorageDefinitions[$field_name])) {
         // Since a field may be stored in more than one table, we inspect tables
         // in order of relevance: the data table if present is the main place
         // where field data is stored, otherwise the base table is responsible for
         // storing field data. Revision metadata is an exception as it's stored
         // only in the revision table.
         // @todo The table mapping itself should know about entity tables. See
         //   https://www.drupal.org/node/2274017.
         /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */
         $storage = \Drupal::entityManager()->getStorage($this->entityType->id());
         $table_names = array($storage->getDataTable(), $storage->getBaseTable(), $storage->getRevisionTable());
         // Collect field columns.
         $field_columns = array();
         $storage_definition = $this->fieldStorageDefinitions[$field_name];
         foreach (array_keys($storage_definition->getColumns()) as $property_name) {
             $field_columns[] = $this->getFieldColumnName($storage_definition, $property_name);
         }
         foreach (array_filter($table_names) as $table_name) {
             $columns = $this->getAllColumns($table_name);
             // We assume finding one field column belonging to the mapping is enough
             // to identify the field table.
             if (array_intersect($columns, $field_columns)) {
                 $result = $table_name;
                 break;
             }
         }
     }
     if (!isset($result)) {
         throw new SqlContentEntityStorageException(SafeMarkup::format('Table information not available for the "@field_name" field.', array('@field_name' => $field_name)));
     }
     return $result;
 }
 /**
  * Gets an array of entity type permissions.
  *
  * @param ContentEntityTypeInterface $entity_type
  *   The custom entity definition.
  *
  * @return array
  *   The entity type permissions.
  *
  * @see \Drupal\user\PermissionHandlerInterface::getPermissions()
  */
 public function entityPermissions(ContentEntityTypeInterface $entity_type = NULL)
 {
     $perms = [];
     if (!empty($entity_type)) {
         // Get the entity ID.
         $entity_type_id = $entity_type->id();
         // Build replacement data for lables and descriptions.
         $replacements = ['@entity_type_id' => $entity_type_id, '@entity_label' => $entity_type->getLabel()];
         // Add the default entity permissions.
         $perms = ["bypass {$entity_type_id} access" => ['title' => $this->t('Bypass @entity_label access control', $replacements), 'description' => $this->t('View, edit and delete all @entity_label regardless of permission restrictions.', $replacements), 'restrict access' => TRUE], "administer {$entity_type_id} types" => ['title' => $this->t('Administer @entity_label types', $replacements), 'description' => $this->t('Promote, change ownership, edit revisions, and perform other tasks across all @entity_label types.', $replacements), 'restrict access' => TRUE], "administer {$entity_type_id}" => ['title' => $this->t('Administer @entity_label', $replacements), 'restrict access' => TRUE], "access {$entity_type_id} overview" => ['title' => $this->t('Access the @entity_label overview page', $replacements), 'description' => $this->t('Get an overview of all @entity_label.', $replacements)], "access {$entity_type_id}" => ['title' => $this->t('View published @entity_label', $replacements)], "view own unpublished {$entity_type_id}" => ['title' => $this->t('View own unpublished @entity_label', $replacements)], "view all {$entity_type_id} revisions" => ['title' => $this->t('View all @entity_label revisions', $replacements)], "revert all {$entity_type_id} revisions" => ['title' => $this->t('Revert all @entity_label revisions', $replacements), 'description' => $this->t('Role requires permission <em>View all @entity_label revisions</em> and <em>edit rights</em> for @entity_label in question or <em>Administer @entity_label</em>.', $replacements)], "delete all {$entity_type_id} revisions" => ['title' => $this->t('Delete all @entity_label revisions', $replacements), 'description' => $this->t('Role requires permission to <em>View all @entity_label revisions</em> and <em>delete rights</em> for @entity_label in question or <em>Administer @entity_label</em>.', $replacements)]];
         // Load bundles if any are defined.
         if (($entity_type_storage = $this->entityManager->getStorage($entity_type->getBundleEntityType())) && ($entity_types = $entity_type_storage->loadMultiple())) {
             // Generate entity permissions for all types for this entity.
             foreach ($entity_types as $type) {
                 $perms += $this->buildPermissions($type);
             }
         }
     }
     return $perms;
 }
 /**
  * Tests entity ID sanitization.
  */
 public function testCleanIds()
 {
     $valid_ids = array(-1, 0, 1, '-1', '0', '1', 0123, -0x1a, 0x1afc, -0b111, 0b101, '0123', '00123', '000123', '-0123', '-00123', '-000123', -10.0, -1.0, 0.0, 1.0, 10.0, -10.0, -1.0, 0.0, 1.0, 10.0);
     $this->fieldDefinitions = $this->mockFieldDefinitions(array('id'));
     $this->fieldDefinitions['id']->expects($this->any())->method('getType')->will($this->returnValue('integer'));
     $this->setUpEntityStorage();
     $this->entityType->expects($this->any())->method('getKey')->will($this->returnValueMap(array(array('id', 'id'))));
     $method = new \ReflectionMethod($this->entityStorage, 'cleanIds');
     $method->setAccessible(TRUE);
     $this->assertEquals($valid_ids, $method->invoke($this->entityStorage, $valid_ids));
     $invalid_ids = array('--1', '-0x1A', '0x1AFC', '-0b111', '0b101', 'a', FALSE, TRUE, NULL, '32acb', 123.123, 123.678);
     $this->assertEquals(array(), $method->invoke($this->entityStorage, $invalid_ids));
 }
 /**
  * @covers ::doLoadMultiple
  * @covers ::buildCacheId
  * @covers ::getFromPersistentCache
  * @covers ::setPersistentCache
  */
 public function testLoadMultiplePersistentCacheMiss()
 {
     $this->setUpModuleHandlerNoImplementations();
     $id = 1;
     $entity = $this->getMockBuilder('\\Drupal\\Tests\\Core\\Entity\\ContentEntityDatabaseStorageTestEntityInterface')->getMockForAbstractClass();
     $entity->expects($this->any())->method('id')->will($this->returnValue($id));
     $this->entityType->expects($this->any())->method('isPersistentlyCacheable')->will($this->returnValue(TRUE));
     $this->entityType->expects($this->atLeastOnce())->method('id')->will($this->returnValue($this->entityTypeId));
     $this->entityType->expects($this->atLeastOnce())->method('getClass')->will($this->returnValue(get_class($entity)));
     // In case of a cache miss, the entity is loaded from the storage and then
     // set in the cache.
     $key = 'values:' . $this->entityTypeId . ':1';
     $this->cache->expects($this->once())->method('getMultiple')->with(array($key))->will($this->returnValue(array()));
     $this->cache->expects($this->once())->method('set')->with($key, $entity, CacheBackendInterface::CACHE_PERMANENT, array($this->entityTypeId . '_values' => TRUE, 'entity_field_info' => TRUE));
     $entity_storage = $this->getMockBuilder('Drupal\\Core\\Entity\\ContentEntityDatabaseStorage')->setConstructorArgs(array($this->entityType, $this->connection, $this->entityManager, $this->cache))->setMethods(array('getFromStorage'))->getMock();
     $entity_storage->expects($this->once())->method('getFromStorage')->with(array($id))->will($this->returnValue(array($id => $entity)));
     $entities = $entity_storage->loadMultiple(array($id));
     $this->assertEquals($entity, $entities[$id]);
 }
 /**
  * Sets up the storage schema object to test.
  *
  * This uses the field definitions set in $this->storageDefinitions.
  *
  * @param array $expected
  *   (optional) An associative array describing the expected entity schema to
  *   be created. Defaults to expecting nothing.
  */
 protected function setUpStorageSchema(array $expected = array())
 {
     $this->entityManager->expects($this->any())->method('getDefinition')->with($this->entityType->id())->will($this->returnValue($this->entityType));
     $this->entityManager->expects($this->any())->method('getFieldStorageDefinitions')->with($this->entityType->id())->will($this->returnValue($this->storageDefinitions));
     $db_schema_handler = $this->getMockBuilder('Drupal\\Core\\Database\\Schema')->disableOriginalConstructor()->getMock();
     if ($expected) {
         $invocation_count = 0;
         $expected_table_names = array_keys($expected);
         $expected_table_schemas = array_values($expected);
         $db_schema_handler->expects($this->any())->method('createTable')->with($this->callback(function ($table_name) use(&$invocation_count, $expected_table_names) {
             return $expected_table_names[$invocation_count] == $table_name;
         }), $this->callback(function ($table_schema) use(&$invocation_count, $expected_table_schemas) {
             return $expected_table_schemas[$invocation_count] == $table_schema;
         }))->will($this->returnCallback(function () use(&$invocation_count) {
             $invocation_count++;
         }));
     }
     $connection = $this->getMockBuilder('Drupal\\Core\\Database\\Connection')->disableOriginalConstructor()->getMock();
     $connection->expects($this->any())->method('schema')->will($this->returnValue($db_schema_handler));
     $key_value = $this->getMock('Drupal\\Core\\KeyValueStore\\KeyValueStoreInterface');
     $this->storageSchema = $this->getMockBuilder('Drupal\\Core\\Entity\\Sql\\SqlContentEntityStorageSchema')->setConstructorArgs(array($this->entityManager, $this->entityType, $this->storage, $connection))->setMethods(array('installedStorageSchema'))->getMock();
     $this->storageSchema->expects($this->any())->method('installedStorageSchema')->will($this->returnValue($key_value));
 }
 /**
  * @param ContentEntityTypeInterface $entity
  * @return array
  */
 public function getViewsData(ContentEntityTypeInterface $entity = NULL)
 {
     $data = parent::getViewsData();
     if ($entity) {
         // Get some info to work off.
         /** @var string $entity_table */
         $entity_table = $entity->get('base_table');
         /** @var string $entity_data_table */
         $entity_data_table = $entity->get('data_table');
         /** @var string $entity_revision_table */
         $entity_revision_table = $entity->get('revision_table');
         // Replacements for all strings.
         $replacements = ['@entity_label' => $entity->getLabel(), '!entity_id' => $entity->id()];
         if (!empty($entity_data_table)) {
             // Add the entity ID field.
             $data[$entity_data_table]['id']['field']['id'] = 'field';
             // Add entity info.
             $data[$entity_data_table]['info']['field']['id'] = 'field';
             $data[$entity_data_table]['info']['field']['link_to_entity default'] = TRUE;
             // Add the bundle (type).
             $data[$entity_data_table]['type']['field']['id'] = 'field';
         }
         if (!empty($entity_table) && !empty($entity_revision_table)) {
             // Advertise this table as a possible base table.
             $data[$entity_revision_table]['table']['base']['help'] = $this->t('@entity_label revision is a history of changes to a "!entity_id" entity.', $replacements);
             $data[$entity_revision_table]['table']['base']['defaults']['title'] = 'info';
             // @todo EntityViewsData should add these relationships by default.
             //   https://www.drupal.org/node/2410275
             $data[$entity_revision_table]['id']['relationship']['id'] = 'standard';
             $data[$entity_revision_table]['id']['relationship']['base'] = $entity_table;
             $data[$entity_revision_table]['id']['relationship']['base field'] = 'id';
             $data[$entity_revision_table]['id']['relationship']['title'] = $this->t('@entity_label', $replacements);
             $data[$entity_revision_table]['id']['relationship']['label'] = $this->t('Get the actual @entity_label from a @entity_label revision.', $replacements);
             $data[$entity_revision_table]['revision_id']['relationship']['id'] = 'standard';
             $data[$entity_revision_table]['revision_id']['relationship']['base'] = $entity_table;
             $data[$entity_revision_table]['revision_id']['relationship']['base field'] = 'revision_id';
             $data[$entity_revision_table]['revision_id']['relationship']['title'] = $this->t('@entity_label', $replacements);
             $data[$entity_revision_table]['revision_id']['relationship']['label'] = $this->t('Get the actual @entity_label from a @entity_label revision.', $replacements);
         }
     }
     return $data;
 }
 /**
  * Returns the base field definitions for entity keys.
  *
  * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type
  *   The entity type.
  *
  * @return \Drupal\Core\Field\BaseFieldDefinition[]
  */
 protected static function entityKeysBaseFieldDefinitions(ContentEntityTypeInterface $entity_type)
 {
     $fields = [];
     if ($entity_type->hasKey('id')) {
         $fields[$entity_type->getKey('id')] = BaseFieldDefinition::create('integer')->setLabel(t('ID'))->setReadOnly(TRUE)->setSetting('unsigned', TRUE);
     }
     if ($entity_type->hasKey('uuid')) {
         $fields[$entity_type->getKey('uuid')] = BaseFieldDefinition::create('uuid')->setLabel(t('UUID'))->setReadOnly(TRUE);
     }
     if ($entity_type->hasKey('revision')) {
         $fields[$entity_type->getKey('revision')] = BaseFieldDefinition::create('integer')->setLabel(t('Revision ID'))->setReadOnly(TRUE)->setSetting('unsigned', TRUE);
     }
     if ($entity_type->hasKey('langcode')) {
         $fields[$entity_type->getKey('langcode')] = BaseFieldDefinition::create('language')->setLabel(t('Language'))->setTranslatable(TRUE)->setRevisionable(TRUE)->setDisplayOptions('view', ['type' => 'hidden'])->setDisplayOptions('form', ['type' => 'language_select', 'weight' => 2]);
     }
     $bundle_entity_type_id = $entity_type->getBundleEntityType();
     if ($bundle_entity_type_id && $entity_type->hasKey('bundle')) {
         $fields[$entity_type->getKey('bundle')] = BaseFieldDefinition::create('entity_reference')->setLabel(t('Type'))->setSetting('target_type', $bundle_entity_type_id)->setReadOnly(TRUE);
     }
     return $fields;
 }
 /**
  * Gets the name to be used for the given entity index.
  *
  * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type
  *   The entity type.
  * @param string $index
  *   The index column name.
  *
  * @return string
  *   The index name.
  */
 protected function getEntityIndexName(ContentEntityTypeInterface $entity_type, $index)
 {
     return $entity_type->id() . '__' . $index;
 }
 /**
  * Provides the page title for the entity form.
  *
  * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_definition
  *   The custom entity definition.
  * @param \Drupal\content_entity_base\Entity\EntityTypeBaseInterface $entity_bundle
  *   The custom entity type bundle to use.
  *
  * @return string
  *   The page title.
  */
 public function getAddFormTitle(ContentEntityTypeInterface $entity_definition = NULL, EntityTypeBaseInterface $entity_bundle = NULL)
 {
     // Build the form page title using the type.
     return $this->t('Add %type @entity_label', ['@entity_label' => $entity_definition->getLabel(), '%type' => $entity_bundle ? $entity_bundle->label() : 'Invalid Bundle']);
 }
 /**
  * Modifies an entity definition to include moderation support.
  *
  * This primarily just means an extra handler. A Generic one is provided,
  * but individual entity types can provide their own as appropriate.
  *
  * @param \Drupal\Core\Entity\ContentEntityTypeInterface $type
  *   The content entity definition to modify.
  *
  * @return \Drupal\Core\Entity\ContentEntityTypeInterface
  *   The modified content entity definition.
  */
 protected function addModerationToEntity(ContentEntityTypeInterface $type)
 {
     if (!$type->hasHandlerClass('moderation')) {
         $handler_class = !empty($this->moderationHandlers[$type->id()]) ? $this->moderationHandlers[$type->id()] : ModerationHandler::class;
         $type->setHandlerClass('moderation', $handler_class);
     }
     if (!$type->hasLinkTemplate('latest-version')) {
         $type->setLinkTemplate('latest-version', $type->getLinkTemplate('canonical') . '/latest');
     }
     // @todo Core forgot to add a direct way to manipulate route_provider, so
     // we have to do it the sloppy way for now.
     $providers = $type->getRouteProviderClasses() ?: [];
     if (empty($providers['moderation'])) {
         $providers['moderation'] = EntityModerationRouteProvider::class;
         $type->setHandlerClass('route_provider', $providers);
     }
     return $type;
 }
 /**
  * {@inheritdoc}
  */
 protected function setUp()
 {
     parent::setUp();
     $this->entityType = $this->getMock('\\Drupal\\Core\\Entity\\ContentEntityTypeInterface');
     $this->entityType->expects($this->any())->method('id')->willReturn('entity_test');
 }
 /**
  * Returns the name to be used for the given entity index.
  *
  * @param string $index
  *   The index column name.
  *
  * @return string
  *   The index name.
  */
 protected function getEntityIndexName($index)
 {
     return $this->entityType->id() . '__' . $index;
 }
 /**
  * Sets up the schema handler.
  *
  * This uses the field definitions set in $this->fieldDefinitions.
  */
 protected function setUpSchemaHandler()
 {
     $this->entityManager->expects($this->once())->method('getFieldStorageDefinitions')->with($this->entityType->id())->will($this->returnValue($this->storageDefinitions));
     $this->schemaHandler = new ContentEntitySchemaHandler($this->entityManager, $this->entityType, $this->storage);
 }