/** * Tests Drupal 6 node type to Drupal 8 migration. */ public function testNodeType() { $migration = entity_load('migration', 'd6_node_type'); // Test the test_page content type. $node_type_page = entity_load('node_type', 'test_page'); $this->assertEqual($node_type_page->id(), 'test_page', 'Node type test_page loaded'); $expected = array('options' => array('status' => TRUE, 'promote' => TRUE, 'sticky' => TRUE, 'revision' => FALSE), 'preview' => 1, 'submitted' => TRUE); $this->assertEqual($node_type_page->settings['node'], $expected, 'Node type test_page settings correct.'); $this->assertEqual(array('test_page'), $migration->getIdMap()->lookupDestinationID(array('test_page'))); // Test we have a body field. $instance = FieldInstanceConfig::loadByName('node', 'test_page', 'body'); $this->assertEqual($instance->getLabel(), 'This is the body field label', 'Body field was found.'); // Test the test_story content type. $node_type_story = entity_load('node_type', 'test_story'); $this->assertEqual($node_type_story->id(), 'test_story', 'Node type test_story loaded'); $expected = array('options' => array('status' => TRUE, 'promote' => TRUE, 'sticky' => FALSE, 'revision' => FALSE), 'preview' => 1, 'submitted' => TRUE); $this->assertEqual($node_type_story->settings['node'], $expected, 'Node type test_story settings correct.'); $this->assertEqual(array('test_story'), $migration->getIdMap()->lookupDestinationID(array('test_story'))); // Test we don't have a body field. $instance = FieldInstanceConfig::loadByName('node', 'test_story', 'body'); $this->assertEqual($instance, NULL, 'No body field found'); // Test the test_event content type. $node_type_event = entity_load('node_type', 'test_event'); $this->assertEqual($node_type_event->id(), 'test_event', 'Node type test_event loaded'); $expected = array('options' => array('status' => FALSE, 'promote' => FALSE, 'sticky' => TRUE, 'revision' => TRUE), 'preview' => 1, 'submitted' => TRUE); $this->assertEqual($node_type_event->settings['node'], $expected, 'Node type test_event settings correct.'); $this->assertEqual(array('test_event'), $migration->getIdMap()->lookupDestinationID(array('test_event'))); // Test we have a body field. $instance = FieldInstanceConfig::loadByName('node', 'test_event', 'body'); $this->assertEqual($instance->getLabel(), 'Body', 'Body field was found.'); }
/** * Tests editing a node type using the UI. */ function testNodeTypeEditing() { $web_user = $this->drupalCreateUser(array('bypass node access', 'administer content types', 'administer node fields')); $this->drupalLogin($web_user); $instance = FieldInstanceConfig::loadByName('node', 'page', 'body'); $this->assertEqual($instance->getLabel(), 'Body', 'Body field was found.'); // Verify that title and body fields are displayed. $this->drupalGet('node/add/page'); $this->assertRaw('Title', 'Title field was found.'); $this->assertRaw('Body', 'Body field was found.'); // Rename the title field. $edit = array('title_label' => 'Foo'); $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); $this->drupalGet('node/add/page'); $this->assertRaw('Foo', 'New title label was displayed.'); $this->assertNoRaw('Title', 'Old title label was not displayed.'); // Change the name, machine name and description. $edit = array('name' => 'Bar', 'type' => 'bar', 'description' => 'Lorem ipsum.'); $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); $this->drupalGet('node/add'); $this->assertRaw('Bar', 'New name was displayed.'); $this->assertRaw('Lorem ipsum', 'New description was displayed.'); $this->clickLink('Bar'); $this->assertEqual(url('node/add/bar', array('absolute' => TRUE)), $this->getUrl(), 'New machine name was used in URL.'); $this->assertRaw('Foo', 'Title field was found.'); $this->assertRaw('Body', 'Body field was found.'); // Remove the body field. $this->drupalPostForm('admin/structure/types/manage/bar/fields/node.bar.body/delete', array(), t('Delete')); // Resave the settings for this type. $this->drupalPostForm('admin/structure/types/manage/bar', array(), t('Save content type')); // Check that the body field doesn't exist. $this->drupalGet('node/add/bar'); $this->assertNoRaw('Body', 'Body field was not found.'); }
/** * Tests that the default 'comment_body' field is correctly added. */ function testCommentDefaultFields() { // Do not make assumptions on default node types created by the test // installation profile, and create our own. $this->drupalCreateContentType(array('type' => 'test_node_type')); $this->container->get('comment.manager')->addDefaultField('node', 'test_node_type'); // Check that the 'comment_body' field is present on the comment bundle. $instance = FieldInstanceConfig::loadByName('comment', 'comment', 'comment_body'); $this->assertTrue(!empty($instance), 'The comment_body field is added when a comment bundle is created'); $instance->delete(); // Check that the 'comment_body' field is deleted. $field_storage = FieldStorageConfig::loadByName('comment', 'comment_body'); $this->assertTrue(empty($field_storage), 'The comment_body field was deleted'); // Create a new content type. $type_name = 'test_node_type_2'; $this->drupalCreateContentType(array('type' => $type_name)); $this->container->get('comment.manager')->addDefaultField('node', $type_name); // Check that the 'comment_body' field exists and has an instance on the // new comment bundle. $field_storage = FieldStorageConfig::loadByName('comment', 'comment_body'); $this->assertTrue($field_storage, 'The comment_body field exists'); $instance = FieldInstanceConfig::loadByName('comment', 'comment', 'comment_body'); $this->assertTrue(isset($instance), format_string('The comment_body field is present for comments on type @type', array('@type' => $type_name))); // Test adding a field that defaults to CommentItemInterface::CLOSED. $this->container->get('comment.manager')->addDefaultField('node', 'test_node_type', 'who_likes_ponies', CommentItemInterface::CLOSED, 'who_likes_ponies'); $field_storage = entity_load('field_instance_config', 'node.test_node_type.who_likes_ponies'); $this->assertEqual($field_storage->default_value[0]['status'], CommentItemInterface::CLOSED); }
/** * Tests user selection by roles. */ function testUserSelectionByRole() { $field_definition = FieldInstanceConfig::loadByName('user', 'user', 'user_reference'); $field_definition->settings['handler_settings']['filter']['role'] = array($this->role1->id() => $this->role1->id(), $this->role2->id() => 0); $field_definition->settings['handler_settings']['filter']['type'] = 'role'; $field_definition->save(); $user1 = $this->createUser(array('name' => 'aabb')); $user1->addRole($this->role1->id()); $user1->save(); $user2 = $this->createUser(array('name' => 'aabbb')); $user2->addRole($this->role1->id()); $user2->save(); $user3 = $this->createUser(array('name' => 'aabbbb')); $user3->addRole($this->role2->id()); $user3->save(); /** @var \Drupal\entity_reference\EntityReferenceAutocomplete $autocomplete */ $autocomplete = \Drupal::service('entity_reference.autocomplete'); $matches = $autocomplete->getMatches($field_definition, 'user', 'user', 'NULL', '', 'aabb'); $this->assertEqual(count($matches), 2); $users = array(); foreach ($matches as $match) { $users[] = $match['label']; } $this->assertTrue(in_array($user1->label(), $users)); $this->assertTrue(in_array($user2->label(), $users)); $this->assertFalse(in_array($user3->label(), $users)); $matches = $autocomplete->getMatches($field_definition, 'user', 'user', 'NULL', '', 'aabbbb'); $this->assertEqual(count($matches), 0, ''); }
/** * Tests the required property on file fields. */ function testRequired() { $type_name = 'article'; $field_name = strtolower($this->randomMachineName()); $field = $this->createFileField($field_name, 'node', $type_name, array(), array('required' => '1')); $instance = FieldInstanceConfig::loadByName('node', $type_name, $field_name); $test_file = $this->getTestFile('text'); // Try to post a new node without uploading a file. $edit = array(); $edit['title[0][value]'] = $this->randomMachineName(); $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish')); $this->assertRaw(t('!title field is required.', array('!title' => $instance->getLabel())), 'Node save failed when required file field was empty.'); // Create a new node with the uploaded file. $nid = $this->uploadNodeFile($test_file, $field_name, $type_name); $this->assertTrue($nid !== FALSE, format_string('uploadNodeFile(@test_file, @field_name, @type_name) succeeded', array('@test_file' => $test_file->getFileUri(), '@field_name' => $field_name, '@type_name' => $type_name))); $node = node_load($nid, TRUE); $node_file = file_load($node->{$field_name}->target_id); $this->assertFileExists($node_file, 'File exists after uploading to the required field.'); $this->assertFileEntryExists($node_file, 'File entry exists after uploading to the required field.'); // Try again with a multiple value field. $field->delete(); $this->createFileField($field_name, 'node', $type_name, array('cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED), array('required' => '1')); // Try to post a new node without uploading a file in the multivalue field. $edit = array(); $edit['title[0][value]'] = $this->randomMachineName(); $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish')); $this->assertRaw(t('!title field is required.', array('!title' => $instance->getLabel())), 'Node save failed when required multiple value file field was empty.'); // Create a new node with the uploaded file into the multivalue field. $nid = $this->uploadNodeFile($test_file, $field_name, $type_name); $node = node_load($nid, TRUE); $node_file = file_load($node->{$field_name}->target_id); $this->assertFileExists($node_file, 'File exists after uploading to the required multiple value field.'); $this->assertFileEntryExists($node_file, 'File entry exists after uploading to the required multiple value field.'); }
/** * Posts a comment. * * @param \Drupal\Core\Entity\EntityInterface|null $entity * Entity to post comment on or NULL to post to the previously loaded page. * @param $comment * Comment body. * @param $subject * Comment subject. * @param $contact * Set to NULL for no contact info, TRUE to ignore success checking, and * array of values to set contact info. */ function postComment(EntityInterface $entity, $comment, $subject = '', $contact = NULL) { $edit = array(); $edit['comment_body[0][value]'] = $comment; $instance = FieldInstanceConfig::loadByName('entity_test', 'entity_test', 'comment'); $preview_mode = $instance->getSetting('preview'); // Must get the page before we test for fields. if ($entity !== NULL) { $this->drupalGet('comment/reply/entity_test/' . $entity->id() . '/comment'); } // Determine the visibility of subject form field. if (entity_get_form_display('comment', 'comment', 'default')->getComponent('subject')) { // Subject input allowed. $edit['subject[0][value]'] = $subject; } else { $this->assertNoFieldByName('subject[0][value]', '', 'Subject field not found.'); } if ($contact !== NULL && is_array($contact)) { $edit += $contact; } switch ($preview_mode) { case DRUPAL_REQUIRED: // Preview required so no save button should be found. $this->assertNoFieldByName('op', t('Save'), 'Save button not found.'); $this->drupalPostForm(NULL, $edit, t('Preview')); // Don't break here so that we can test post-preview field presence and // function below. // Don't break here so that we can test post-preview field presence and // function below. case DRUPAL_OPTIONAL: $this->assertFieldByName('op', t('Preview'), 'Preview button found.'); $this->assertFieldByName('op', t('Save'), 'Save button found.'); $this->drupalPostForm(NULL, $edit, t('Save')); break; case DRUPAL_DISABLED: $this->assertNoFieldByName('op', t('Preview'), 'Preview button not found.'); $this->assertFieldByName('op', t('Save'), 'Save button found.'); $this->drupalPostForm(NULL, $edit, t('Save')); break; } $match = array(); // Get comment ID preg_match('/#comment-([0-9]+)/', $this->getURL(), $match); // Get comment. if ($contact !== TRUE) { // If true then attempting to find error message. if ($subject) { $this->assertText($subject, 'Comment subject posted.'); } $this->assertText($comment, 'Comment body posted.'); $this->assertTrue(!empty($match) && !empty($match[1]), 'Comment ID found.'); } if (isset($match[1])) { return entity_load('comment', $match[1]); } }
/** * Tests creating a content type during config import. */ public function testImportCreate() { $node_type_id = 'import'; $node_type_config_name = "node.type.{$node_type_id}"; // Simulate config data to import. $active = $this->container->get('config.storage'); $staging = $this->container->get('config.storage.staging'); $this->copyConfig($active, $staging); // Manually add new node type. $src_dir = drupal_get_path('module', 'node_test_config') . '/staging'; $target_dir = $this->configDirectories[CONFIG_STAGING_DIRECTORY]; $this->assertTrue(file_unmanaged_copy("{$src_dir}/{$node_type_config_name}.yml", "{$target_dir}/{$node_type_config_name}.yml")); // Import the content of the staging directory. $this->configImporter()->import(); // Check that the content type was created. $node_type = entity_load('node_type', $node_type_id); $this->assertTrue($node_type, 'Import node type from staging was created.'); $this->assertFalse(FieldInstanceConfig::loadByName('node', $node_type_id, 'body')); }
/** * Tests editing a comment type using the UI. */ public function testCommentTypeEditing() { $this->drupalLogin($this->adminUser); $instance = FieldInstanceConfig::loadByName('comment', 'comment', 'comment_body'); $this->assertEqual($instance->getLabel(), 'Comment', 'Comment body field was found.'); // Change the comment type name. $this->drupalGet('admin/structure/comment'); $edit = array('label' => 'Bar'); $this->drupalPostForm('admin/structure/comment/manage/comment', $edit, t('Save')); $this->drupalGet('admin/structure/comment'); $this->assertRaw('Bar', 'New name was displayed.'); $this->clickLink('Manage fields'); $this->assertEqual(url('admin/structure/comment/manage/comment/fields', array('absolute' => TRUE)), $this->getUrl(), 'Original machine name was used in URL.'); // Remove the body field. $this->drupalPostForm('admin/structure/comment/manage/comment/fields/comment.comment.comment_body/delete', array(), t('Delete')); // Resave the settings for this type. $this->drupalPostForm('admin/structure/comment/manage/comment', array(), t('Save')); // Check that the body field doesn't exist. $this->drupalGet('admin/structure/comment/manage/comment/fields'); $this->assertNoRaw('comment_body', 'Body field was not found.'); }
/** * {@inheritdoc} */ public function addBodyField($comment_type_id) { // Create the field if needed. $field_storage = FieldStorageConfig::loadByName('comment', 'comment_body'); if (!$field_storage) { $field_storage = $this->entityManager->getStorage('field_storage_config')->create(array('name' => 'comment_body', 'type' => 'text_long', 'entity_type' => 'comment')); $field_storage->save(); } if (!FieldInstanceConfig::loadByName('comment', $comment_type_id, 'comment_body')) { // Attaches the body field by default. $field_instance = $this->entityManager->getStorage('field_instance_config')->create(array('field_name' => 'comment_body', 'label' => 'Comment', 'entity_type' => 'comment', 'bundle' => $comment_type_id, 'settings' => array('text_processing' => 1), 'required' => TRUE)); $field_instance->save(); // Assign widget settings for the 'default' form mode. entity_get_form_display('comment', $comment_type_id, 'default')->setComponent('comment_body', array('type' => 'text_textarea'))->save(); // Assign display settings for the 'default' view mode. entity_get_display('comment', $comment_type_id, 'default')->setComponent('comment_body', array('label' => 'hidden', 'type' => 'text_default', 'weight' => 0))->save(); } }
/** * Test entity_bundle_create() and entity_bundle_rename(). */ function testEntityCreateRenameBundle() { $entity_type = 'entity_test_rev'; $this->createFieldWithInstance('', $entity_type); $cardinality = $this->field_storage->getCardinality(); // Create a new bundle. $new_bundle = 'test_bundle_' . drupal_strtolower($this->randomName()); entity_test_create_bundle($new_bundle, NULL, $entity_type); // Add an instance to that bundle. $this->instance_definition['bundle'] = $new_bundle; entity_create('field_instance_config', $this->instance_definition)->save(); // Save an entity with data in the field. $entity = entity_create($entity_type, array('type' => $this->instance->bundle)); $values = $this->_generateTestFieldValues($cardinality); $entity->{$this->field_name} = $values; // Verify the field data is present on load. $entity = $this->entitySaveReload($entity); $this->assertEqual(count($entity->{$this->field_name}), $cardinality, "Data is retrieved for the new bundle"); // Rename the bundle. $new_bundle = 'test_bundle_' . drupal_strtolower($this->randomName()); entity_test_rename_bundle($this->instance_definition['bundle'], $new_bundle, $entity_type); // Check that the instance definition has been updated. $this->instance = FieldInstanceConfig::loadByName($entity_type, $new_bundle, $this->field_name); $this->assertIdentical($this->instance->bundle, $new_bundle, "Bundle name has been updated in the instance."); // Verify the field data is present on load. $controller = $this->container->get('entity.manager')->getStorage($entity->getEntityTypeId()); $controller->resetCache(); $entity = $controller->load($entity->id()); $this->assertEqual(count($entity->{$this->field_name}), $cardinality, "Bundle name has been updated in the field storage"); }
/** * Tests that the settings UI works as expected. */ function testSettingsUI() { // Check for the content_translation_menu_links_discovered_alter() changes. $this->drupalGet('admin/config'); $this->assertLink('Content language and translation'); $this->assertText('Configure language and translation support for content.'); // Test that the translation settings are ignored if the bundle is marked // translatable but the entity type is not. $edit = array('settings[comment][comment_article][translatable]' => TRUE); $this->assertSettings('comment', NULL, FALSE, $edit); // Test that the translation settings are ignored if only a field is marked // as translatable and not the related entity type and bundle. $edit = array('settings[comment][comment_article][fields][comment_body]' => TRUE); $this->assertSettings('comment', NULL, FALSE, $edit); // Test that the translation settings are not stored if an entity type and // bundle are marked as translatable but no field is. $edit = array('entity_types[comment]' => TRUE, 'settings[comment][comment_article][translatable]' => TRUE, 'settings[comment][comment_article][fields][changed]' => FALSE, 'settings[comment][comment_article][fields][created]' => FALSE, 'settings[comment][comment_article][fields][homepage]' => FALSE, 'settings[comment][comment_article][fields][hostname]' => FALSE, 'settings[comment][comment_article][fields][mail]' => FALSE, 'settings[comment][comment_article][fields][name]' => FALSE, 'settings[comment][comment_article][fields][status]' => FALSE, 'settings[comment][comment_article][fields][subject]' => FALSE, 'settings[comment][comment_article][fields][uid]' => FALSE); $this->assertSettings('comment', 'comment_article', FALSE, $edit); $xpath_err = '//div[contains(@class, "error")]'; $this->assertTrue($this->xpath($xpath_err), 'Enabling translation only for entity bundles generates a form error.'); // Test that the translation settings are not stored if a non-configurable // language is set as default and the language selector is hidden. $edit = array('entity_types[comment]' => TRUE, 'settings[comment][comment_article][settings][language][langcode]' => Language::LANGCODE_NOT_SPECIFIED, 'settings[comment][comment_article][settings][language][language_show]' => FALSE, 'settings[comment][comment_article][translatable]' => TRUE, 'settings[comment][comment_article][fields][comment_body]' => TRUE); $this->assertSettings('comment', 'comment_article', FALSE, $edit); $this->assertTrue($this->xpath($xpath_err), 'Enabling translation with a fixed non-configurable language generates a form error.'); // Test that a field shared among different bundles can be enabled without // needing to make all the related bundles translatable. $edit = array('entity_types[comment]' => TRUE, 'settings[comment][comment_article][settings][language][langcode]' => 'current_interface', 'settings[comment][comment_article][settings][language][language_show]' => TRUE, 'settings[comment][comment_article][translatable]' => TRUE, 'settings[comment][comment_article][fields][comment_body]' => TRUE, 'settings[comment][comment_article][fields][subject]' => FALSE, 'settings[comment][comment][fields][subject]' => FALSE); $this->assertSettings('comment', 'comment_article', TRUE, $edit); $definition = $this->entityManager()->getFieldDefinitions('comment', 'comment_article')['comment_body']; $this->assertTrue($definition->isTranslatable(), 'Article comment body is translatable.'); $definition = $this->entityManager()->getFieldDefinitions('comment', 'comment_article')['subject']; $this->assertFalse($definition->isTranslatable(), 'Article comment subject is not translatable.'); $definition = $this->entityManager()->getFieldDefinitions('comment', 'comment')['comment_body']; $this->assertFalse($definition->isTranslatable(), 'Page comment body is not translatable.'); $definition = $this->entityManager()->getFieldDefinitions('comment', 'comment')['subject']; $this->assertFalse($definition->isTranslatable(), 'Page comment subject is not translatable.'); $settings = content_translation_get_config('comment', 'comment_article', 'fields'); $this->assertFalse(isset($settings['comment_body']), 'Configurable fields are not saved to content_translation.settings.'); $this->assertTrue(isset($settings['subject']), 'Base fields are saved to content_translation.settings.'); // Test that translation can be enabled for base fields. $edit = array('entity_types[entity_test_mul]' => TRUE, 'settings[entity_test_mul][entity_test_mul][translatable]' => TRUE, 'settings[entity_test_mul][entity_test_mul][fields][name]' => TRUE, 'settings[entity_test_mul][entity_test_mul][fields][user_id]' => FALSE); $this->assertSettings('entity_test_mul', 'entity_test_mul', TRUE, $edit); $settings = content_translation_get_config('entity_test_mul', 'entity_test_mul', 'fields'); $this->assertTrue($settings['name'] && !$settings['user_id'], 'Base fields are saved to content_translation.settings.'); $definitions = $this->entityManager()->getFieldDefinitions('entity_test_mul', 'entity_test_mul'); $this->assertTrue($definitions['name']->isTranslatable() && !$definitions['user_id']->isTranslatable(), 'Bundle field definitions were correctly altered.'); // Test that language settings are correctly stored. $language_configuration = language_get_default_configuration('comment', 'comment_article'); $this->assertEqual($language_configuration['langcode'], 'current_interface', 'The default language for article comments is set to the current interface language.'); $this->assertTrue($language_configuration['language_show'], 'The language selector for article comments is shown.'); // Verify language widget appears on comment type form. $this->drupalGet('admin/structure/comment/manage/comment_article'); $this->assertField('language_configuration[content_translation]'); $this->assertFieldChecked('edit-language-configuration-content-translation'); // Verify that translation may be enabled for the article content type. $edit = array('language_configuration[content_translation]' => TRUE); // Make sure the checkbox is available and not checked by default. $this->drupalGet('admin/structure/types/manage/article'); $this->assertField('language_configuration[content_translation]'); $this->assertNoFieldChecked('edit-language-configuration-content-translation'); $this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type')); $this->drupalGet('admin/structure/types/manage/article'); $this->assertFieldChecked('edit-language-configuration-content-translation'); // Test that the title field of nodes is available in the settings form. $edit = array('entity_types[node]' => TRUE, 'settings[node][article][settings][language][langcode]' => 'current_interface', 'settings[node][article][settings][language][language_show]' => TRUE, 'settings[node][article][translatable]' => TRUE, 'settings[node][article][fields][title]' => TRUE); $this->assertSettings('node', NULL, TRUE, $edit); foreach (array(TRUE, FALSE) as $translatable) { // Test that configurable field translatability is correctly switched. $edit = array('settings[node][article][fields][body]' => $translatable); $this->assertSettings('node', 'article', TRUE, $edit); $instance = FieldInstanceConfig::loadByName('node', 'article', 'body'); $definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'article'); $this->assertEqual($definitions['body']->isTranslatable(), $translatable, 'Field translatability correctly switched.'); $this->assertEqual($instance->isTranslatable(), $definitions['body']->isTranslatable(), 'Configurable field translatability correctly switched.'); // Test that also the Field UI form behaves correctly. $translatable = !$translatable; $edit = array('instance[translatable]' => $translatable); $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.body', $edit, t('Save settings')); \Drupal::entityManager()->clearCachedFieldDefinitions(); $instance = FieldInstanceConfig::loadByName('node', 'article', 'body'); $definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'article'); $this->assertEqual($definitions['body']->isTranslatable(), $translatable, 'Field translatability correctly switched.'); $this->assertEqual($instance->isTranslatable(), $definitions['body']->isTranslatable(), 'Configurable field translatability correctly switched.'); } }
/** * Updates an existing file field with new settings. */ function updateFileField($name, $type_name, $instance_settings = array(), $widget_settings = array()) { $instance = FieldInstanceConfig::loadByName('node', $type_name, $name); $instance->settings = array_merge($instance->settings, $instance_settings); $instance->save(); entity_get_form_display('node', $type_name, 'default')->setComponent($name, array('settings' => $widget_settings))->save(); }
/** * Verify that field storages are preserved and purged correctly as multiple * instances are deleted and purged. */ function testPurgeFieldStorage() { // Start recording hook invocations. field_test_memorize(); $field_storage = reset($this->fieldStorages); // Delete the first instance. $bundle = reset($this->bundles); $instance = FieldInstanceConfig::loadByName($this->entity_type, $bundle, $field_storage->name); $instance->delete(); // Assert that FieldItemInterface::delete() was not called yet. $mem = field_test_memorize(); $this->assertEqual(count($mem), 0, 'No field hooks were called.'); // Purge the data. field_purge_batch(10); // Check hooks invocations. // FieldItemInterface::delete() should have been called once for each entity in the // bundle. $actual_hooks = field_test_memorize(); $hooks = array(); $entities = $this->entities_by_bundles[$bundle]; foreach ($entities as $id => $entity) { $hooks['field_test_field_delete'][] = $entity; } $this->checkHooksInvocations($hooks, $actual_hooks); // The instance still exists, deleted. $instances = entity_load_multiple_by_properties('field_instance_config', array('uuid' => $instance->uuid(), 'include_deleted' => TRUE)); $this->assertTrue(isset($instances[$instance->uuid()]) && $instances[$instance->uuid()]->deleted, 'The instance exists and is deleted'); // Purge again to purge the instance. field_purge_batch(0); // The instance is gone. $instances = entity_load_multiple_by_properties('field_instance_config', array('uuid' => $instance->uuid(), 'include_deleted' => TRUE)); $this->assertEqual(count($instances), 0, 'The instance is purged.'); // The field storage still exists, not deleted. $storages = entity_load_multiple_by_properties('field_storage_config', array('uuid' => $field_storage->uuid(), 'include_deleted' => TRUE)); $this->assertTrue(isset($storages[$field_storage->uuid()]) && !$storages[$field_storage->uuid()]->deleted, 'The field storage exists and is not deleted'); // Delete the second instance. $bundle = next($this->bundles); $instance = FieldInstanceConfig::loadByName($this->entity_type, $bundle, $field_storage->name); $instance->delete(); // Assert that FieldItemInterface::delete() was not called yet. $mem = field_test_memorize(); $this->assertEqual(count($mem), 0, 'No field hooks were called.'); // Purge the data. field_purge_batch(10); // Check hooks invocations (same as above, for the 2nd bundle). $actual_hooks = field_test_memorize(); $hooks = array(); $entities = $this->entities_by_bundles[$bundle]; foreach ($entities as $id => $entity) { $hooks['field_test_field_delete'][] = $entity; } $this->checkHooksInvocations($hooks, $actual_hooks); // The field storage and instance still exist, deleted. $instances = entity_load_multiple_by_properties('field_instance_config', array('uuid' => $instance->uuid(), 'include_deleted' => TRUE)); $this->assertTrue(isset($instances[$instance->uuid()]) && $instances[$instance->uuid()]->deleted, 'The instance exists and is deleted'); $storages = entity_load_multiple_by_properties('field_storage_config', array('uuid' => $field_storage->uuid(), 'include_deleted' => TRUE)); $this->assertTrue(isset($storages[$field_storage->uuid()]) && $storages[$field_storage->uuid()]->deleted, 'The field storage exists and is deleted'); // Purge again to purge the instance and the field storage. field_purge_batch(0); // The field storage and instance are gone. $instances = entity_load_multiple_by_properties('field_instance_config', array('uuid' => $instance->uuid(), 'include_deleted' => TRUE)); $this->assertEqual(count($instances), 0, 'The instance is purged.'); $storages = entity_load_multiple_by_properties('field_storage_config', array('uuid' => $field_storage->uuid(), 'include_deleted' => TRUE)); $this->assertEqual(count($storages), 0, 'The field storage is purged.'); }
/** * Tests the cross deletion behavior between fields and instances. */ function testDeleteFieldInstanceCrossDeletion() { $instance_definition_2 = $this->instanceDefinition; $instance_definition_2['bundle'] .= '_another_bundle'; entity_test_create_bundle($instance_definition_2['bundle']); // Check that deletion of a field deletes its instances. $field_storage = $this->fieldStorage; entity_create('field_instance_config', $this->instanceDefinition)->save(); entity_create('field_instance_config', $instance_definition_2)->save(); $field_storage->delete(); $this->assertFalse(FieldInstanceConfig::loadByName('entity_test', $this->instanceDefinition['bundle'], $field_storage->name)); $this->assertFalse(FieldInstanceConfig::loadByName('entity_test', $instance_definition_2['bundle'], $field_storage->name)); // Chack that deletion of the last instance deletes the field. $field_storage = entity_create('field_storage_config', $this->fieldStorageDefinition); $field_storage->save(); $instance = entity_create('field_instance_config', $this->instanceDefinition); $instance->save(); $instance_2 = entity_create('field_instance_config', $instance_definition_2); $instance_2->save(); $instance->delete(); $this->assertTrue(FieldStorageConfig::loadByName('entity_test', $field_storage->name)); $instance_2->delete(); $this->assertFalse(FieldStorageConfig::loadByName('entity_test', $field_storage->name)); // Check that deletion of all instances of the same field simultaneously // deletes the field. $field_storage = entity_create('field_storage_config', $this->fieldStorageDefinition); $field_storage->save(); $instance = entity_create('field_instance_config', $this->instanceDefinition); $instance->save(); $instance_2 = entity_create('field_instance_config', $instance_definition_2); $instance_2->save(); $this->container->get('entity.manager')->getStorage('field_instance_config')->delete(array($instance, $instance_2)); $this->assertFalse(FieldStorageConfig::loadByName('entity_test', $field_storage->name)); }
/** * Toggles field storage translatability. * * @param string $entity_type * The type of the entity fields are attached to. */ protected function toggleFieldTranslatability($entity_type, $bundle) { $fields = array($this->field_name, $this->untranslatable_field_name); foreach ($fields as $field_name) { $instance = FieldInstanceConfig::loadByName($entity_type, $bundle, $field_name); $translatable = !$instance->isTranslatable(); $instance->set('translatable', $translatable); $instance->save(); $instance = FieldInstanceConfig::loadByName($entity_type, $bundle, $field_name); $this->assertEqual($instance->isTranslatable(), $translatable, 'Field translatability changed.'); } \Drupal::cache('entity')->deleteAll(); }
/** * {@inheritdoc} */ public function calculateDependencies() { parent::calculateDependencies(); $target_entity_type = \Drupal::entityManager()->getDefinition($this->targetEntityType); $bundle_entity_type_id = $target_entity_type->getBundleEntityType(); if ($bundle_entity_type_id != 'bundle') { // If the target entity type uses entities to manage its bundles then // depend on the bundle entity. $bundle_entity = \Drupal::entityManager()->getStorage($bundle_entity_type_id)->load($this->bundle); $this->addDependency('entity', $bundle_entity->getConfigDependencyName()); } else { // Depend on the provider of the entity type. $this->addDependency('module', $target_entity_type->getProvider()); } // Create dependencies on both hidden and visible fields. $fields = $this->content + $this->hidden; foreach ($fields as $field_name => $component) { $field_instance = FieldInstanceConfig::loadByName($this->targetEntityType, $this->bundle, $field_name); if ($field_instance) { $this->addDependency('entity', $field_instance->getConfigDependencyName()); } // Create a dependency on the module that provides the formatter or // widget. if (isset($component['type']) && ($definition = $this->pluginManager->getDefinition($component['type'], FALSE))) { $this->addDependency('module', $definition['provider']); } // Create dependencies on any modules providing third party settings. if (isset($component['third_party_settings'])) { foreach ($component['third_party_settings'] as $module => $settings) { $this->addDependency('module', $module); } } } // Depend on configured modes. if ($this->mode != 'default') { $mode_entity = \Drupal::entityManager()->getStorage($this->displayContext . '_mode')->load($target_entity_type->id() . '.' . $this->mode); $this->addDependency('entity', $mode_entity->getConfigDependencyName()); } return $this->dependencies; }
/** * Verify access rules for comment indexing with different permissions. */ function testSearchResultsCommentAccess() { $comment_body = 'Test comment body'; $this->comment_subject = 'Test comment subject'; $roles = $this->admin_user->getRoles(); $this->admin_role = $roles[0]; // Create a node. // Make preview optional. $instance = FieldInstanceConfig::loadByName('node', 'article', 'comment'); $instance->settings['preview'] = DRUPAL_OPTIONAL; $instance->save(); $this->node = $this->drupalCreateNode(array('type' => 'article')); // Post a comment using 'Full HTML' text format. $edit_comment = array(); $edit_comment['subject[0][value]'] = $this->comment_subject; $edit_comment['comment_body[0][value]'] = '<h1>' . $comment_body . '</h1>'; $this->drupalPostForm('comment/reply/node/' . $this->node->id() . '/comment', $edit_comment, t('Save')); $this->drupalLogout(); $this->setRolePermissions(DRUPAL_ANONYMOUS_RID); $this->assertCommentAccess(FALSE, 'Anon user has search permission but no access comments permission, comments should not be indexed'); $this->setRolePermissions(DRUPAL_ANONYMOUS_RID, TRUE); $this->assertCommentAccess(TRUE, 'Anon user has search permission and access comments permission, comments should be indexed'); $this->drupalLogin($this->admin_user); $this->drupalGet('admin/people/permissions'); // Disable search access for authenticated user to test admin user. $this->setRolePermissions(DRUPAL_AUTHENTICATED_RID, FALSE, FALSE); $this->setRolePermissions($this->admin_role); $this->assertCommentAccess(FALSE, 'Admin user has search permission but no access comments permission, comments should not be indexed'); $this->drupalGet('node/' . $this->node->id()); $this->setRolePermissions($this->admin_role, TRUE); $this->assertCommentAccess(TRUE, 'Admin user has search permission and access comments permission, comments should be indexed'); $this->setRolePermissions(DRUPAL_AUTHENTICATED_RID); $this->assertCommentAccess(FALSE, 'Authenticated user has search permission but no access comments permission, comments should not be indexed'); $this->setRolePermissions(DRUPAL_AUTHENTICATED_RID, TRUE); $this->assertCommentAccess(TRUE, 'Authenticated user has search permission and access comments permission, comments should be indexed'); // Verify that access comments permission is inherited from the // authenticated role. $this->setRolePermissions(DRUPAL_AUTHENTICATED_RID, TRUE, FALSE); $this->setRolePermissions($this->admin_role); $this->assertCommentAccess(TRUE, 'Admin user has search permission and no access comments permission, but comments should be indexed because admin user inherits authenticated user\'s permission to access comments'); // Verify that search content permission is inherited from the authenticated // role. $this->setRolePermissions(DRUPAL_AUTHENTICATED_RID, TRUE, TRUE); $this->setRolePermissions($this->admin_role, TRUE, FALSE); $this->assertCommentAccess(TRUE, 'Admin user has access comments permission and no search permission, but comments should be indexed because admin user inherits authenticated user\'s permission to search'); }
/** * Tests a file field with a "Private files" upload destination setting. */ function testPrivateFileSetting() { // Grant the admin user required permissions. user_role_grant_permissions($this->admin_user->roles[0]->value, array('administer node fields')); $type_name = 'article'; $field_name = strtolower($this->randomMachineName()); $this->createFileField($field_name, 'node', $type_name); $instance = FieldInstanceConfig::loadByName('node', $type_name, $field_name); $test_file = $this->getTestFile('text'); // Change the field setting to make its files private, and upload a file. $edit = array('field[settings][uri_scheme]' => 'private'); $this->drupalPostForm("admin/structure/types/manage/{$type_name}/fields/{$instance->id}/storage", $edit, t('Save field settings')); $nid = $this->uploadNodeFile($test_file, $field_name, $type_name); $node = node_load($nid, TRUE); $node_file = file_load($node->{$field_name}->target_id); $this->assertFileExists($node_file, 'New file saved to disk on node creation.'); // Ensure the private file is available to the user who uploaded it. $this->drupalGet(file_create_url($node_file->getFileUri())); $this->assertResponse(200, 'Confirmed that the generated URL is correct by downloading the shipped file.'); // Ensure we can't change 'uri_scheme' field settings while there are some // entities with uploaded files. $this->drupalGet("admin/structure/types/manage/{$type_name}/fields/{$instance->id}/storage"); $this->assertFieldByXpath('//input[@id="edit-field-settings-uri-scheme-public" and @disabled="disabled"]', 'public', 'Upload destination setting disabled.'); // Delete node and confirm that setting could be changed. $node->delete(); $this->drupalGet("admin/structure/types/manage/{$type_name}/fields/{$instance->id}/storage"); $this->assertFieldByXpath('//input[@id="edit-field-settings-uri-scheme-public" and not(@disabled)]', 'public', 'Upload destination setting enabled.'); }
/** * Tests that deletion removes fields and instances as expected for a term. */ function testDeleteTaxonomyField() { // Create a new field. $bundle_path = 'admin/structure/taxonomy/manage/tags/overview'; $edit1 = array('fields[_add_new_field][label]' => $this->field_label, 'fields[_add_new_field][field_name]' => $this->field_name_input); $this->fieldUIAddNewField($bundle_path, $edit1); // Delete the field. $this->fieldUIDeleteField($bundle_path, "taxonomy_term.tags.{$this->field_name}", $this->field_label, 'Tags'); // Check that the field instance was deleted. $this->assertNull(FieldInstanceConfig::loadByName('taxonomy_term', 'tags', $this->field_name), 'Field instance was deleted.'); // Check that the field storage was deleted too. $this->assertNull(FieldStorageConfig::loadByName('taxonomy_term', $this->field_name), 'Field storage was deleted.'); }
/** * Tests that machine name changes are properly reflected. */ function testTaxonomyVocabularyChangeMachineName() { // Add a field instance to the vocabulary. entity_create('field_storage_config', array('name' => 'field_test', 'entity_type' => 'taxonomy_term', 'type' => 'test_field'))->save(); entity_create('field_instance_config', array('field_name' => 'field_test', 'entity_type' => 'taxonomy_term', 'bundle' => $this->vocabulary->id()))->save(); // Change the machine name. $old_name = $this->vocabulary->id(); $new_name = drupal_strtolower($this->randomName()); $this->vocabulary->vid = $new_name; $this->vocabulary->save(); // Check that entity bundles are properly updated. $info = entity_get_bundles('taxonomy_term'); $this->assertFalse(isset($info[$old_name]), 'The old bundle name does not appear in entity_get_bundles().'); $this->assertTrue(isset($info[$new_name]), 'The new bundle name appears in entity_get_bundles().'); // Check that the field instance is still attached to the vocabulary. $this->assertTrue(FieldInstanceConfig::loadByName('taxonomy_term', $new_name, 'field_test'), 'The bundle name was updated correctly.'); }
/** * Executes the computed properties tests for the given entity type. * * @param string $entity_type * The entity type to run the tests with. */ protected function assertComputedProperties($entity_type) { // Make the test text field processed. $instance = FieldInstanceConfig::loadByName($entity_type, $entity_type, 'field_test_text'); $instance->settings['text_processing'] = 1; $instance->save(); $entity = $this->createTestEntity($entity_type); $entity->field_test_text->value = "The <strong>text</strong> text to filter."; $entity->field_test_text->format = filter_default_format(); $target = "<p>The <strong>text</strong> text to filter.</p>\n"; $this->assertEqual($entity->field_test_text->processed, $target, format_string('%entity_type: Text is processed with the default filter.', array('%entity_type' => $entity_type))); // Save and load entity and make sure it still works. $entity->save(); $entity = entity_load($entity_type, $entity->id()); $this->assertEqual($entity->field_test_text->processed, $target, format_string('%entity_type: Text is processed with the default filter.', array('%entity_type' => $entity_type))); }
/** * Sets a comment settings variable for the article content type. * * @param string $name * Name of variable. * @param string $value * Value of variable. * @param string $message * Status message to display. * @param string $field_name * (optional) Field name through which the comment should be posted. * Defaults to 'comment'. */ public function setCommentSettings($name, $value, $message, $field_name = 'comment') { $instance = FieldInstanceConfig::loadByName('node', 'article', $field_name); $instance->settings[$name] = $value; $instance->save(); // Display status message. $this->pass($message); }
/** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { $options = array(); $types = NodeType::loadMultiple(); $comment_fields = $this->commentManager ? $this->commentManager->getFields('node') : array(); $map = array(t('Hidden'), t('Closed'), t('Open')); foreach ($types as $type) { $options[$type->type] = array('type' => array('#markup' => t($type->name))); if ($this->commentManager) { $fields = array(); foreach ($comment_fields as $field_name => $info) { // Find all comment fields for the bundle. if (in_array($type->type, $info['bundles'])) { $instance = FieldInstanceConfig::loadByName('node', $type->type, $field_name); $default_mode = reset($instance->default_value); $fields[] = String::format('@field: !state', array('@field' => $instance->label(), '!state' => $map[$default_mode['status']])); } } // @todo Refactor display of comment fields. if (!empty($fields)) { $options[$type->type]['comments'] = array('data' => array('#theme' => 'item_list', '#items' => $fields)); } else { $options[$type->type]['comments'] = t('No comment fields'); } } } if (empty($options)) { $this->setMessage(t('You do not have any content types that can be generated. <a href="@create-type">Go create a new content type</a> already!</a>', array('@create-type' => url('admin/structure/types/add'))), 'error', FALSE); return; } $header = array('type' => t('Content type')); if ($this->commentManager) { $header['comments'] = array('data' => t('Comments'), 'class' => array(RESPONSIVE_PRIORITY_MEDIUM)); } $form['node_types'] = array('#type' => 'tableselect', '#header' => $header, '#options' => $options); $form['kill'] = array('#type' => 'checkbox', '#title' => t('<strong>Delete all content</strong> in these content types before generating new content.'), '#default_value' => $this->getSetting('kill')); $form['num'] = array('#type' => 'textfield', '#title' => t('How many nodes would you like to generate?'), '#default_value' => $this->getSetting('num'), '#size' => 10); $options = array(1 => t('Now')); foreach (array(3600, 86400, 604800, 2592000, 31536000) as $interval) { $options[$interval] = \Drupal::service('date.formatter')->formatInterval($interval, 1) . ' ' . t('ago'); } $form['time_range'] = array('#type' => 'select', '#title' => t('How far back in time should the nodes be dated?'), '#description' => t('Node creation dates will be distributed randomly from the current time, back to the selected time.'), '#options' => $options, '#default_value' => 604800); $form['max_comments'] = array('#type' => $this->moduleHandler->moduleExists('comment') ? 'textfield' : 'value', '#title' => t('Maximum number of comments per node.'), '#description' => t('You must also enable comments for the content types you are generating. Note that some nodes will randomly receive zero comments. Some will receive the max.'), '#default_value' => $this->getSetting('max_comments'), '#size' => 3, '#access' => $this->moduleHandler->moduleExists('comment')); $form['title_length'] = array('#type' => 'textfield', '#title' => t('Maximum number of words in titles'), '#default_value' => $this->getSetting('title_length'), '#size' => 10); $form['add_alias'] = array('#type' => 'checkbox', '#disabled' => !$this->moduleHandler->moduleExists('path'), '#description' => t('Requires path.module'), '#title' => t('Add an url alias for each node.'), '#default_value' => FALSE); $form['add_statistics'] = array('#type' => 'checkbox', '#title' => t('Add statistics for each node (node_counter table).'), '#default_value' => TRUE, '#access' => $this->moduleHandler->moduleExists('statistics')); $options = array(Language::LANGCODE_NOT_SPECIFIED => t('Language neutral')); if ($this->moduleHandler->moduleExists('locale')) { $languages = language_list(); foreach ($languages as $langcode => $language) { $options[$langcode] = $language->name; } } $form['add_language'] = array('#type' => 'select', '#title' => t('Set language on nodes'), '#multiple' => TRUE, '#disabled' => !$this->moduleHandler->moduleExists('locale'), '#description' => t('Requires locale.module'), '#options' => $options, '#default_value' => array(Language::LANGCODE_NOT_SPECIFIED)); $form['submit'] = array('#type' => 'submit', '#value' => t('Generate'), '#tableselect' => TRUE); $form['#redirect'] = FALSE; return $form; }