Example #1
0
 /**
  * Ensures that post update functions are removed on uninstall.
  */
 public function testUninstallPostUpdateFunctions()
 {
     \Drupal::service('module_installer')->uninstall(['module_test']);
     $post_update_key_value = \Drupal::keyValue('post_update');
     $existing_updates = $post_update_key_value->get('existing_updates', []);
     $this->assertFalse(in_array('module_test_post_update_test', $existing_updates));
 }
Example #2
0
 /**
  * Tests hook_post_update_NAME().
  */
 public function testPostUpdate()
 {
     $this->runUpdates();
     $this->assertRaw('<h3>Update first</h3>');
     $this->assertRaw('First update');
     $this->assertRaw('<h3>Update second</h3>');
     $this->assertRaw('Second update');
     $this->assertRaw('<h3>Update test1</h3>');
     $this->assertRaw('Test1 update');
     $this->assertRaw('<h3>Update test0</h3>');
     $this->assertRaw('Test0 update');
     $this->assertRaw('<h3>Update test_batch</h3>');
     $this->assertRaw('Test post update batches');
     // Test state value set by each post update.
     $updates = ['update_test_postupdate_post_update_first', 'update_test_postupdate_post_update_second', 'update_test_postupdate_post_update_test1', 'update_test_postupdate_post_update_test0', 'update_test_postupdate_post_update_test_batch-1', 'update_test_postupdate_post_update_test_batch-2', 'update_test_postupdate_post_update_test_batch-3'];
     $this->assertIdentical($updates, \Drupal::state()->get('post_update_test_execution', []));
     // Test post_update key value stores contains a list of the update functions
     // that have run.
     $existing_updates = array_count_values(\Drupal::keyValue('post_update')->get('existing_updates'));
     $expected_updates = ['update_test_postupdate_post_update_first', 'update_test_postupdate_post_update_second', 'update_test_postupdate_post_update_test1', 'update_test_postupdate_post_update_test0', 'update_test_postupdate_post_update_test_batch'];
     foreach ($expected_updates as $expected_update) {
         $this->assertEqual($existing_updates[$expected_update], 1, new FormattableMarkup("@expected_update exists in 'existing_updates' key and only appears once.", ['@expected_update' => $expected_update]));
     }
     $this->drupalGet('update.php/selection');
     $this->assertText('No pending updates.');
 }
 /**
  * Tests hook_post_update_NAME().
  */
 public function testPostUpdate()
 {
     // There are expected to be failed updates.
     $this->checkFailedUpdates = FALSE;
     $this->runUpdates();
     // There should be no post update hooks registered as being run.
     $this->assertIdentical([], \Drupal::state()->get('post_update_test_execution', []));
     $key_value = \Drupal::keyValue('update__post_update');
     $this->assertEqual([], $key_value->get('existing_updates'));
 }
Example #4
0
/**
 * Disable all blocks with missing context IDs in block_update_8001().
 */
function block_post_update_disable_blocks_with_missing_contexts()
{
    // Don't execute the function if block_update_8002() got executed already,
    // which used to do the same. Note: Its okay to check here, because
    // update_do_one() does not update the installed schema version until the
    // batch is finished.
    $module_schema = drupal_get_installed_schema_version('block');
    // The state entry 'block_update_8002_placeholder' is used in order to
    // indicate that the placeholder block_update_8002() function has been
    // executed, so this function needs to be executed as well. If the non
    // placeholder version of block_update_8002() got executed already, the state
    // won't be set and we skip this update.
    if ($module_schema >= 8002 && !\Drupal::state()->get('block_update_8002_placeholder', FALSE)) {
        return;
    }
    // Cleanup the state entry as its no longer needed.
    \Drupal::state()->delete('block_update_8002');
    $block_update_8001 = \Drupal::keyValue('update_backup')->get('block_update_8001', []);
    $block_ids = array_keys($block_update_8001);
    $block_storage = \Drupal::entityManager()->getStorage('block');
    $blocks = $block_storage->loadMultiple($block_ids);
    /** @var $blocks \Drupal\block\BlockInterface[] */
    foreach ($blocks as $block) {
        // This block has had conditions removed due to an inability to resolve
        // contexts in block_update_8001() so disable it.
        // Disable currently enabled blocks.
        if ($block_update_8001[$block->id()]['status']) {
            $block->setStatus(FALSE);
            $block->save();
        }
    }
    // Provides a list of plugin labels, keyed by plugin ID.
    $condition_plugin_id_label_map = array_column(\Drupal::service('plugin.manager.condition')->getDefinitions(), 'label', 'id');
    // Override with the UI labels we are aware of. Sadly they are not machine
    // accessible, see
    // \Drupal\node\Plugin\Condition\NodeType::buildConfigurationForm().
    $condition_plugin_id_label_map['node_type'] = t('Content types');
    $condition_plugin_id_label_map['request_path'] = t('Pages');
    $condition_plugin_id_label_map['user_role'] = t('Roles');
    if (count($block_ids) > 0) {
        $message = t('Encountered an unknown context mapping key coming probably from a contributed or custom module: One or more mappings could not be updated. Please manually review your visibility settings for the following blocks, which are disabled now:');
        $message .= '<ul>';
        foreach ($blocks as $disabled_block_id => $disabled_block) {
            $message .= '<li>' . t('@label (Visibility: @plugin_ids)', array('@label' => $disabled_block->get('settings')['label'], '@plugin_ids' => implode(', ', array_intersect_key($condition_plugin_id_label_map, array_flip(array_keys($block_update_8001[$disabled_block_id]['missing_context_ids'])))))) . '</li>';
        }
        $message .= '</ul>';
        return $message;
    }
}
 /**
  * Tests that column-level schema changes are detected for fields with data.
  */
 public function testColumnUpdate()
 {
     // Change the field type in the stored schema.
     $schema = \Drupal::keyValue('entity.storage_schema.sql')->get('entity_test_rev.field_schema_data.test');
     $schema['entity_test_rev__test']['fields']['test_value']['type'] = 'varchar_ascii';
     \Drupal::keyValue('entity.storage_schema.sql')->set('entity_test_rev.field_schema_data.test', $schema);
     // Now attempt to run automatic updates. An exception should be thrown
     // since there is data in the table.
     try {
         \Drupal::service('entity.definition_update_manager')->applyUpdates();
         $this->fail('Failed to detect a schema change in a field with data.');
     } catch (FieldStorageDefinitionUpdateForbiddenException $e) {
         $this->pass('Detected a schema change in a field with data.');
     }
 }
Example #6
0
 /**
  * Tests state listing.
  */
 public function testStateListing()
 {
     // Ensure that state listing page is accessible only by users with the
     // adequate permissions.
     $this->drupalGet('devel/state');
     $this->assertResponse(403);
     $this->drupalLogin($this->develUser);
     $this->drupalGet('devel/state');
     $this->assertResponse(200);
     $this->assertText(t('State editor'));
     // Ensure that the state variables table is visible.
     $table = $this->xpath('//table[contains(@class, "devel-state-list")]');
     $this->assertTrue($table, 'State list table found.');
     // Ensure that all state variables are listed in the table.
     $states = \Drupal::keyValue('state')->getAll();
     $rows = $this->xpath('//table[contains(@class, "devel-state-list")]//tbody//tr');
     $this->assertEqual(count($rows), count($states), 'All states are listed in the table.');
     // Ensure that the added state variables are listed in the table.
     $this->state->set('devel.simple', 'Hello!');
     $this->drupalGet('devel/state');
     $this->assertFieldByXpath('//table[contains(@class, "devel-state-list")]//tbody//td', 'devel.simple', 'Label found for the added state.');
     $thead_xpath = '//table[contains(@class, "devel-state-list")]/thead/tr/th';
     $action_xpath = '//table[contains(@class, "devel-state-list")]//ul[@class="dropbutton"]/li/a';
     // Ensure that the operations column and the actions buttons are not
     // available for user without 'administer site configuration' permission.
     $elements = $this->xpath($thead_xpath);
     $this->assertEqual(count($elements), 2, 'Correct number of table header cells found.');
     $expected_items = ['Name', 'Value'];
     foreach ($elements as $key => $element) {
         $this->assertIdentical((string) $element[0], $expected_items[$key]);
     }
     $this->assertFalse($this->xpath($action_xpath), 'Action buttons are not visible.');
     // Ensure that the operations column and the actions buttons are
     // available for user with 'administer site configuration' permission.
     $this->drupalLogin($this->adminUser);
     $this->drupalGet('devel/state');
     $elements = $this->xpath($thead_xpath);
     $this->assertEqual(count($elements), 3, 'Correct number of table header cells found.');
     $expected_items = ['Name', 'Value', 'Operations'];
     foreach ($elements as $key => $element) {
         $this->assertIdentical((string) $element[0], $expected_items[$key]);
     }
     $this->assertTrue($this->xpath($action_xpath), 'Action buttons are visible.');
     // Test that the edit button works properly.
     $this->clickLink(t('Edit'));
     $this->assertResponse(200);
 }
 /**
  * Tests that block context mapping is updated properly.
  */
 public function testUpdateHookN()
 {
     $this->runUpdates();
     $this->assertRaw('Encountered an unknown context mapping key coming probably from a contributed or custom module: One or more mappings could not be updated. Please manually review your visibility settings for the following blocks, which are disabled now:<ul><li>User login (Visibility: Baloney spam)</li></ul>');
     // Disable maintenance mode.
     \Drupal::state()->set('system.maintenance_mode', FALSE);
     // We finished updating so we can login the user now.
     $this->drupalLogin($this->rootUser);
     // The block that we are testing has the following visibility rules:
     // - only visible on node pages
     // - only visible to authenticated users.
     $block_title = 'Test for 2354889';
     // Create two nodes, a page and an article.
     $page = Node::create(['type' => 'page', 'title' => 'Page node']);
     $page->save();
     $article = Node::create(['type' => 'article', 'title' => 'Article node']);
     $article->save();
     // Check that the block appears only on Page nodes for authenticated users.
     $this->drupalGet('node/' . $page->id());
     $this->assertRaw($block_title, 'Test block is visible on a Page node as an authenticated user.');
     $this->drupalGet('node/' . $article->id());
     $this->assertNoRaw($block_title, 'Test block is not visible on a Article node as an authenticated user.');
     $this->drupalLogout();
     // Check that the block does not appear on any page for anonymous users.
     $this->drupalGet('node/' . $page->id());
     $this->assertNoRaw($block_title, 'Test block is not visible on a Page node as an anonymous user.');
     $this->drupalGet('node/' . $article->id());
     $this->assertNoRaw($block_title, 'Test block is not visible on a Article node as an anonymous user.');
     // Ensure that all the context mappings got updated properly.
     $block = Block::load('testfor2354889');
     $visibility = $block->get('visibility');
     $this->assertEqual('@node.node_route_context:node', $visibility['node_type']['context_mapping']['node']);
     $this->assertEqual('@user.current_user_context:current_user', $visibility['user_role']['context_mapping']['user']);
     $this->assertEqual('@language.current_language_context:language_interface', $visibility['language']['context_mapping']['language']);
     // Check that a block with invalid context is being disabled and that it can
     // still be edited afterward.
     $disabled_block = Block::load('thirdtestfor2354889');
     $this->assertFalse($disabled_block->status(), 'Block with invalid context is disabled');
     $this->assertEqual(['thirdtestfor2354889' => ['missing_context_ids' => ['baloney.spam' => ['node_type']], 'status' => TRUE]], \Drupal::keyValue('update_backup')->get('block_update_8001'));
     $disabled_block_visibility = $disabled_block->get('visibility');
     $this->assertTrue(!isset($disabled_block_visibility['node_type']), 'The problematic visibility condition has been removed.');
     $admin_user = $this->drupalCreateUser(['administer blocks']);
     $this->drupalLogin($admin_user);
     $this->drupalGet('admin/structure/block/manage/thirdtestfor2354889');
     $this->assertResponse('200');
 }
 /**
  * Tests that the database was properly loaded.
  */
 public function testDatabaseLoaded()
 {
     $hook_updates = ['user' => '8000', 'node' => '8003', 'system' => '8013'];
     foreach ($hook_updates as $module => $schema) {
         $this->assertEqual(drupal_get_installed_schema_version($module), $schema, new FormattableMarkup('Module @module schema is @schema', ['@module' => $module, '@schema' => $schema]));
     }
     // Test post_update key value stores contains a list of the update functions
     // that have run.
     $existing_updates = array_count_values(\Drupal::keyValue('post_update')->get('existing_updates'));
     $expected_updates = ['system_post_update_recalculate_configuration_entity_dependencies', 'field_post_update_save_custom_storage_property', 'field_post_update_entity_reference_handler_setting', 'block_post_update_disable_blocks_with_missing_contexts', 'views_post_update_update_cacheability_metadata'];
     foreach ($expected_updates as $expected_update) {
         $this->assertEqual($existing_updates[$expected_update], 1, new FormattableMarkup("@expected_update exists in 'existing_updates' key and only appears once.", ['@expected_update' => $expected_update]));
     }
     // @todo there are no updates to run.
     // $this->runUpdates();
     $this->assertEqual(\Drupal::config('system.site')->get('name'), 'Site-Install');
     $this->drupalGet('<front>');
     $this->assertText('Site-Install');
 }
 /**
  * Tests hook_post_update_NAME().
  */
 public function testPostUpdate()
 {
     $this->runUpdates();
     $this->assertRaw('<h3>Update first</h3>');
     $this->assertRaw('First update');
     $this->assertRaw('<h3>Update second</h3>');
     $this->assertRaw('Second update');
     $this->assertRaw('<h3>Update test1</h3>');
     $this->assertRaw('Test1 update');
     $this->assertRaw('<h3>Update test0</h3>');
     $this->assertRaw('Test0 update');
     $updates = ['update_test_postupdate_post_update_first', 'update_test_postupdate_post_update_second', 'update_test_postupdate_post_update_test1', 'update_test_postupdate_post_update_test0'];
     $this->assertIdentical($updates, \Drupal::state()->get('post_update_test_execution', []));
     $key_value = \Drupal::keyValue('post_update');
     $updates = array_merge(['block_post_update_disable_blocks_with_missing_contexts', 'field_post_update_save_custom_storage_property', 'field_post_update_entity_reference_handler_setting', 'system_post_update_recalculate_configuration_entity_dependencies', 'views_post_update_update_cacheability_metadata'], $updates);
     $this->assertEqual($updates, $key_value->get('existing_updates'));
     $this->drupalGet('update.php/selection');
     $this->assertText('No pending updates.');
 }
 /**
  * Tests hook_post_update_NAME().
  */
 public function testPostUpdate()
 {
     $this->runUpdates();
     $this->assertRaw('<h3>Update first</h3>');
     $this->assertRaw('First update');
     $this->assertRaw('<h3>Update second</h3>');
     $this->assertRaw('Second update');
     $this->assertRaw('<h3>Update test1</h3>');
     $this->assertRaw('Test1 update');
     $this->assertRaw('<h3>Update test0</h3>');
     $this->assertRaw('Test0 update');
     $updates = ['update_test_postupdate_post_update_first', 'update_test_postupdate_post_update_second', 'update_test_postupdate_post_update_test1', 'update_test_postupdate_post_update_test0'];
     $this->assertIdentical($updates, \Drupal::state()->get('post_update_test_execution', []));
     $key_value = \Drupal::keyValue('post_update');
     array_unshift($updates, 'block_post_update_disable_blocks_with_missing_contexts');
     $this->assertEqual($updates, $key_value->get('existing_updates'));
     $this->drupalGet('update.php/selection');
     $this->assertText('No pending updates.');
 }
 /**
  * Tests that the database was properly loaded.
  */
 public function testDatabaseLoaded()
 {
     $extensions = \Drupal::service('config.storage')->read('core.extension');
     $this->assertFalse(isset($extensions['theme']['stable']), 'Stable is not installed before updating.');
     $hook_updates = ['user' => '8000', 'node' => '8003', 'system' => '8013'];
     foreach ($hook_updates as $module => $schema) {
         $this->assertEqual(drupal_get_installed_schema_version($module), $schema, new FormattableMarkup('Module @module schema is @schema', ['@module' => $module, '@schema' => $schema]));
     }
     // Test post_update key value stores contains a list of the update functions
     // that have run.
     $existing_updates = array_count_values(\Drupal::keyValue('post_update')->get('existing_updates'));
     $expected_updates = ['system_post_update_recalculate_configuration_entity_dependencies', 'field_post_update_save_custom_storage_property', 'field_post_update_entity_reference_handler_setting', 'block_post_update_disable_blocks_with_missing_contexts', 'views_post_update_update_cacheability_metadata'];
     foreach ($expected_updates as $expected_update) {
         $this->assertEqual($existing_updates[$expected_update], 1, new FormattableMarkup("@expected_update exists in 'existing_updates' key and only appears once.", ['@expected_update' => $expected_update]));
     }
     $this->runUpdates();
     $this->assertEqual(\Drupal::config('system.site')->get('name'), 'Site-Install');
     $this->drupalGet('<front>');
     $this->assertText('Site-Install');
     $extensions = \Drupal::service('config.storage')->read('core.extension');
     $this->assertTrue(isset($extensions['theme']['stable']), 'Stable is installed after updating.');
     $blocks = \Drupal::entityManager()->getStorage('block')->loadByProperties(['theme' => 'stable']);
     $this->assertTrue(empty($blocks), 'No blocks have been placed for Stable.');
 }
 /**
  * Builds a row for an entity in the entity listing.
  *
  * @param \Drupal\migrate\Entity\EntityInterface $migration
  *   The entity for which to build the row.
  *
  * @return array
  *   A render array of the table row for displaying the entity.
  *
  * @see Drupal\Core\Entity\EntityListController::render()
  */
 public function buildRow(EntityInterface $migration)
 {
     $row['label'] = $migration->label();
     $row['machine_name'] = $migration->id();
     $row['status'] = $migration->getStatusLabel();
     // Derive the stats
     $source_plugin = $migration->getSourcePlugin();
     $row['total'] = $source_plugin->count();
     $map = $migration->getIdMap();
     $row['imported'] = $map->importedCount();
     // -1 indicates uncountable sources.
     if ($row['total'] == -1) {
         $row['total'] = $this->t('N/A');
         $row['unprocessed'] = $this->t('N/A');
     } else {
         $row['unprocessed'] = $row['total'] - $map->processedCount();
     }
     $migration_group = $migration->getThirdPartySetting('migrate_plus', 'migration_group');
     if (!$migration_group) {
         $migration_group = 'default';
     }
     $route_parameters = array('migration_group' => $migration_group, 'migration' => $migration->id());
     $row['messages'] = array('data' => array('#type' => 'link', '#title' => $map->messageCount(), '#url' => Url::fromRoute("migrate_tools.messages", $route_parameters)));
     $migrate_last_imported_store = \Drupal::keyValue('migrate_last_imported');
     $last_imported = $migrate_last_imported_store->get($migration->id(), FALSE);
     if ($last_imported) {
         /** @var DateFormatter $date_formatter */
         $date_formatter = \Drupal::service('date.formatter');
         $row['last_imported'] = $date_formatter->format($last_imported / 1000, 'custom', 'Y-m-d H:i:s');
     } else {
         $row['last_imported'] = '';
     }
     return $row;
     // + parent::buildRow($migration);
 }
Example #13
0
 /**
  * {@inheritdoc}
  */
 public function interruptMigration($result)
 {
     $this->setStatus(MigrationInterface::STATUS_STOPPING);
     \Drupal::keyValue('migrate_interruption_result')->set($this->id(), $result);
 }
Example #14
0
 /**
  * Retrieves the database information for the test index.
  *
  * @return array
  *   The database information stored by the backend for the test index.
  */
 protected function getIndexDbInfo()
 {
     return \Drupal::keyValue(BackendDatabase::INDEXES_KEY_VALUE_STORE_ID)->get($this->indexId);
 }
 /**
  * Adds entity autocomplete functionality to a form element.
  *
  * @param array $element
  *   The form element to process. Properties used:
  *   - #target_type: The ID of the target entity type.
  *   - #selection_handler: The plugin ID of the entity reference selection
  *     handler.
  *   - #selection_settings: An array of settings that will be passed to the
  *     selection handler.
  * @param \Drupal\Core\Form\FormStateInterface $form_state
  *   The current state of the form.
  * @param array $complete_form
  *   The complete form structure.
  *
  * @return array
  *   The form element.
  *
  * @throws \InvalidArgumentException
  *   Exception thrown when the #target_type or #autocreate['bundle'] are
  *   missing.
  */
 public static function processEntityAutocomplete(array &$element, FormStateInterface $form_state, array &$complete_form)
 {
     // Nothing to do if there is no target entity type.
     if (empty($element['#target_type'])) {
         throw new \InvalidArgumentException('Missing required #target_type parameter.');
     }
     // Provide default values and sanity checks for the #autocreate parameter.
     if ($element['#autocreate']) {
         if (!isset($element['#autocreate']['bundle'])) {
             throw new \InvalidArgumentException("Missing required #autocreate['bundle'] parameter.");
         }
         // Default the autocreate user ID to the current user.
         $element['#autocreate']['uid'] = isset($element['#autocreate']['uid']) ? $element['#autocreate']['uid'] : \Drupal::currentUser()->id();
     }
     // Store the selection settings in the key/value store and pass a hashed key
     // in the route parameters.
     $selection_settings = isset($element['#selection_settings']) ? $element['#selection_settings'] : [];
     $data = serialize($selection_settings) . $element['#target_type'] . $element['#selection_handler'];
     $selection_settings_key = Crypt::hmacBase64($data, Settings::getHashSalt());
     $key_value_storage = \Drupal::keyValue('entity_autocomplete');
     if (!$key_value_storage->has($selection_settings_key)) {
         $key_value_storage->set($selection_settings_key, $selection_settings);
     }
     $element['#autocomplete_route_name'] = 'system.entity_autocomplete';
     $element['#autocomplete_route_parameters'] = array('target_type' => $element['#target_type'], 'selection_handler' => $element['#selection_handler'], 'selection_settings_key' => $selection_settings_key);
     return $element;
 }
Example #16
0
 /**
  * Deletes the stored state.
  */
 public function purge()
 {
     \Drupal::keyValue($this->getCollection())->delete($this->parent->getEntity()->id());
 }
 /**
  * {@inheritdoc}
  */
 public function uninstall(array $module_list, $uninstall_dependents = TRUE)
 {
     // Get all module data so we can find dependencies and sort.
     $module_data = system_rebuild_module_data();
     $module_list = $module_list ? array_combine($module_list, $module_list) : array();
     if (array_diff_key($module_list, $module_data)) {
         // One or more of the given modules doesn't exist.
         return FALSE;
     }
     // Only process currently installed modules.
     $extension_config = \Drupal::config('core.extension');
     $installed_modules = $extension_config->get('module') ?: array();
     if (!($module_list = array_intersect_key($module_list, $installed_modules))) {
         // Nothing to do. All modules already uninstalled.
         return TRUE;
     }
     if ($uninstall_dependents) {
         // Add dependent modules to the list. The new modules will be processed as
         // the while loop continues.
         $profile = drupal_get_profile();
         while (list($module) = each($module_list)) {
             foreach (array_keys($module_data[$module]->required_by) as $dependent) {
                 if (!isset($module_data[$dependent])) {
                     // The dependent module does not exist.
                     return FALSE;
                 }
                 // Skip already uninstalled modules.
                 if (isset($installed_modules[$dependent]) && !isset($module_list[$dependent]) && $dependent != $profile) {
                     $module_list[$dependent] = $dependent;
                 }
             }
         }
     }
     // Set the actual module weights.
     $module_list = array_map(function ($module) use($module_data) {
         return $module_data[$module]->sort;
     }, $module_list);
     // Sort the module list by their weights.
     asort($module_list);
     $module_list = array_keys($module_list);
     // Only process modules that are enabled. A module is only enabled if it is
     // configured as enabled. Custom or overridden module handlers might contain
     // the module already, which means that it might be loaded, but not
     // necessarily installed.
     $schema_store = \Drupal::keyValue('system.schema');
     $entity_manager = \Drupal::entityManager();
     foreach ($module_list as $module) {
         // Clean up all entity bundles (including fields) of every entity type
         // provided by the module that is being uninstalled.
         foreach ($entity_manager->getDefinitions() as $entity_type_id => $entity_type) {
             if ($entity_type->getProvider() == $module) {
                 foreach (array_keys($entity_manager->getBundleInfo($entity_type_id)) as $bundle) {
                     $entity_manager->onBundleDelete($bundle, $entity_type_id);
                 }
             }
         }
         // Allow modules to react prior to the uninstallation of a module.
         $this->invokeAll('module_preuninstall', array($module));
         // Uninstall the module.
         module_load_install($module);
         $this->invoke($module, 'uninstall');
         // Remove all configuration belonging to the module.
         \Drupal::service('config.manager')->uninstall('module', $module);
         // Notify the entity manager that this module's entity types are being
         // deleted, so that it can notify all interested handlers. For example,
         // a SQL-based storage handler can use this as an opportunity to drop
         // the corresponding database tables.
         foreach ($entity_manager->getDefinitions() as $entity_type) {
             if ($entity_type->getProvider() == $module) {
                 $entity_manager->onEntityTypeDelete($entity_type);
             }
         }
         // Remove the schema.
         drupal_uninstall_schema($module);
         // Remove the module's entry from the config.
         $extension_config->clear("module.{$module}")->save();
         // Update the module handler to remove the module.
         // The current ModuleHandler instance is obsolete with the kernel rebuild
         // below.
         $module_filenames = $this->getModuleList();
         unset($module_filenames[$module]);
         $this->setModuleList($module_filenames);
         // Remove any potential cache bins provided by the module.
         $this->removeCacheBins($module);
         // Clear the static cache of system_rebuild_module_data() to pick up the
         // new module, since it merges the installation status of modules into
         // its statically cached list.
         drupal_static_reset('system_rebuild_module_data');
         // Clear plugin manager caches and flag router to rebuild if requested.
         \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions();
         \Drupal::service('router.builder_indicator')->setRebuildNeeded();
         // Update the kernel to exclude the uninstalled modules.
         \Drupal::service('kernel')->updateModules($module_filenames, $module_filenames);
         // Update the theme registry to remove the newly uninstalled module.
         drupal_theme_rebuild();
         // Modules can alter theme info, so refresh theme data.
         // @todo ThemeHandler cannot be injected into ModuleHandler, since that
         //   causes a circular service dependency.
         // @see https://drupal.org/node/2208429
         \Drupal::service('theme_handler')->refreshInfo();
         \Drupal::logger('system')->info('%module module uninstalled.', array('%module' => $module));
         $schema_store->delete($module);
     }
     drupal_get_installed_schema_version(NULL, TRUE);
     // Let other modules react.
     $this->invokeAll('modules_uninstalled', array($module_list));
     return TRUE;
 }
Example #18
0
/**
 * Executes an update which is intended to update data, like entities.
 *
 * These implementations have to be placed in a MODULE.post_update.php file.
 *
 * These updates are executed after all hook_update_N() implementations. At this
 * stage Drupal is already fully repaired so you can use any API as you wish.
 *
 * NAME can be arbitrary machine names. In contrast to hook_update_N() the order
 * of functions in the file is the only thing which ensures the execution order
 * of those functions.
 *
 * Drupal also ensures to not execute the same hook_post_update_NAME() function
 * twice.
 *
 * @param array $sandbox
 *   Stores information for batch updates. See above for more information.
 *
 * @throws \Drupal\Core\Utility\UpdateException|PDOException
 *   In case of error, update hooks should throw an instance of
 *   \Drupal\Core\Utility\UpdateException with a meaningful message for the
 *   user. If a database query fails for whatever reason, it will throw a
 *   PDOException.
 *
 * @return string|null
 *   Optionally, hook_post_update_NAME() hooks may return a translated string
 *   that will be displayed to the user after the update has completed. If no
 *   message is returned, no message will be presented to the user.
 *
 * @ingroup update_api
 *
 * @see hook_update_N()
 */
function hook_post_update_NAME(&$sandbox)
{
    // Example of updating some content.
    $node = \Drupal\node\Entity\Node::load(123);
    $node->setTitle('foo');
    $node->save();
    $result = t('Node %nid saved', ['%nid' => $node->id()]);
    // Example of disabling blocks with missing condition contexts. Note: The
    // block itself is in a state which is valid at that point.
    // @see block_update_8001()
    // @see block_post_update_disable_blocks_with_missing_contexts()
    $block_update_8001 = \Drupal::keyValue('update_backup')->get('block_update_8001', []);
    $block_ids = array_keys($block_update_8001);
    $block_storage = \Drupal::entityManager()->getStorage('block');
    $blocks = $block_storage->loadMultiple($block_ids);
    /** @var $blocks \Drupal\block\BlockInterface[] */
    foreach ($blocks as $block) {
        // This block has had conditions removed due to an inability to resolve
        // contexts in block_update_8001() so disable it.
        // Disable currently enabled blocks.
        if ($block_update_8001[$block->id()]['status']) {
            $block->setStatus(FALSE);
            $block->save();
        }
    }
    return $result;
}
Example #19
0
 /**
  * Tests the keyValue() method.
  *
  * @covers ::keyValue
  */
 public function testKeyValue()
 {
     $keyvalue = $this->getMockBuilder('Drupal\\Core\\KeyValueStore\\KeyValueFactory')->disableOriginalConstructor()->getMock();
     $keyvalue->expects($this->once())->method('get')->with('test_collection')->will($this->returnValue(TRUE));
     $this->setMockContainerService('keyvalue', $keyvalue);
     $this->assertNotNull(\Drupal::keyValue('test_collection'));
 }
Example #20
0
 /**
  * Retrieves the key-value store to use.
  *
  * @return \Drupal\Core\KeyValueStore\KeyValueStoreInterface
  *   The key-value store.
  */
 public function getKeyValueStore() {
   return $this->keyValueStore ? : \Drupal::keyValue(self::INDEXES_KEY_VALUE_STORE_ID);
 }
 /**
  * {@inheritdoc}
  */
 public function getMigrationResult()
 {
     $migrate_result_store = \Drupal::keyValue('migrate_result');
     return $migrate_result_store->get($this->id(), static::RESULT_INCOMPLETE);
 }
Example #22
0
 /**
  * Get the highwater storage object.
  *
  * @return \Drupal\Core\KeyValueStore\KeyValueStoreInterface
  *   The storage object.
  */
 protected function getHighWaterStorage()
 {
     if (!isset($this->highwaterStorage)) {
         $this->highwaterStorage = \Drupal::keyValue('migrate:highwater');
     }
     return $this->highwaterStorage;
 }
 /**
  * Gets the keyvalue collection for tracking the installed schema.
  *
  * @return \Drupal\Core\KeyValueStore\KeyValueStoreInterface
  *
  * @todo Inject this dependency in the constructor once this class can be
  *   instantiated as a regular entity handler:
  *   https://www.drupal.org/node/2332857.
  */
 protected function installedStorageSchema()
 {
     if (!isset($this->installedStorageSchema)) {
         $this->installedStorageSchema = \Drupal::keyValue('entity.storage_schema.sql');
     }
     return $this->installedStorageSchema;
 }
Example #24
0
 /**
  * Tests whether removing the configuration again works as it should.
  */
 protected function checkModuleUninstall()
 {
     $db_info = \Drupal::keyValue(BackendDatabase::INDEXES_KEY_VALUE_STORE_ID)->get($this->indexId);
     $normalized_storage_table = $db_info['index_table'];
     $field_tables = $db_info['field_tables'];
     // See whether clearing the server works.
     // Regression test for #2156151.
     $server = $this->getServer();
     $index = $this->getIndex();
     $server->deleteAllIndexItems($index);
     $query = $this->buildSearch();
     $results = $query->execute();
     $this->assertEquals(0, $results->getResultCount(), 'Clearing the server worked correctly.');
     $this->assertTrue(Database::getConnection()->schema()->tableExists($normalized_storage_table), 'The index tables were left in place.');
     // Remove first the index and then the server.
     $index->setServer();
     $index->save();
     $db_info = \Drupal::keyValue(BackendDatabase::INDEXES_KEY_VALUE_STORE_ID)->get($this->indexId);
     $this->assertNull($db_info, 'The index was successfully removed from the server.');
     $this->assertFalse(Database::getConnection()->schema()->tableExists($normalized_storage_table), 'The index tables were deleted.');
     foreach ($field_tables as $field_table) {
         $this->assertFalse(\Drupal::database()->schema()->tableExists($field_table['table']), new FormattableMarkup('Field table %table exists', array('%table' => $field_table['table'])));
     }
     // Re-add the index to see if the associated tables are also properly
     // removed when the server is deleted.
     $index->setServer($server);
     $index->save();
     $server->delete();
     $db_info = \Drupal::keyValue(BackendDatabase::INDEXES_KEY_VALUE_STORE_ID)->get($this->indexId);
     $this->assertNull($db_info, 'The index was successfully removed from the server.');
     $this->assertFalse(Database::getConnection()->schema()->tableExists($normalized_storage_table), 'The index tables were deleted.');
     foreach ($field_tables as $field_table) {
         $this->assertFalse(\Drupal::database()->schema()->tableExists($field_table['table']), new FormattableMarkup('Field table %table exists', array('%table' => $field_table['table'])));
     }
     // Uninstall the module.
     \Drupal::service('module_installer')->uninstall(array('search_api_db'), FALSE);
     $this->assertFalse(\Drupal::moduleHandler()->moduleExists('search_api_db'), 'The Database Search module was successfully uninstalled.');
     $tables = \Drupal::database()->schema()->findTables('search_api_db_%');
     $this->assertEquals(array(), $tables, 'All the tables of the the Database Search module have been removed.');
 }
Example #25
0
 /**
  * Tests fields from an uninstalled module are removed from the schema.
  */
 public function testCleanUpStorageDefinition()
 {
     // Find all the entity types provided by the entity_test module and install
     // the schema for them.
     $entity_type_ids = [];
     $entities = \Drupal::entityManager()->getDefinitions();
     foreach ($entities as $entity_type_id => $definition) {
         if ($definition->getProvider() == 'entity_test') {
             $this->installEntitySchema($entity_type_id);
             $entity_type_ids[] = $entity_type_id;
         }
     }
     // Get a list of all the entities in the schema.
     $key_value_store = \Drupal::keyValue('entity.storage_schema.sql');
     $schema = $key_value_store->getAll();
     // Count the storage definitions provided by the entity_test module, so that
     // after uninstall we can be sure there were some to be deleted.
     $entity_type_id_count = 0;
     foreach (array_keys($schema) as $storage_definition_name) {
         list($entity_type_id, , ) = explode('.', $storage_definition_name);
         if (in_array($entity_type_id, $entity_type_ids)) {
             $entity_type_id_count++;
         }
     }
     // Ensure that there are storage definitions from the entity_test module.
     $this->assertNotEqual($entity_type_id_count, 0, 'There are storage definitions provided by the entity_test module in the schema.');
     // Uninstall the entity_test module.
     $this->container->get('module_installer')->uninstall(array('entity_test'));
     // Get a list of all the entities in the schema.
     $key_value_store = \Drupal::keyValue('entity.storage_schema.sql');
     $schema = $key_value_store->getAll();
     // Count the storage definitions that come from entity types provided by
     // the entity_test module.
     $entity_type_id_count = 0;
     foreach (array_keys($schema) as $storage_definition_name) {
         list($entity_type_id, , ) = explode('.', $storage_definition_name);
         if (in_array($entity_type_id, $entity_type_ids)) {
             $entity_type_id_count++;
         }
     }
     // Ensure that all storage definitions have been removed from the schema.
     $this->assertEqual($entity_type_id_count, 0, 'After uninstalling entity_test module the schema should not contains fields from entities provided by the module.');
 }
Example #26
0
 /**
  * {@inheritdoc}
  */
 public function uninstall(array $module_list, $uninstall_dependents = TRUE)
 {
     // Get all module data so we can find dependencies and sort.
     $module_data = system_rebuild_module_data();
     $module_list = $module_list ? array_combine($module_list, $module_list) : array();
     if (array_diff_key($module_list, $module_data)) {
         // One or more of the given modules doesn't exist.
         return FALSE;
     }
     $extension_config = \Drupal::configFactory()->getEditable('core.extension');
     $installed_modules = $extension_config->get('module') ?: array();
     if (!($module_list = array_intersect_key($module_list, $installed_modules))) {
         // Nothing to do. All modules already uninstalled.
         return TRUE;
     }
     if ($uninstall_dependents) {
         // Add dependent modules to the list. The new modules will be processed as
         // the while loop continues.
         $profile = drupal_get_profile();
         while (list($module) = each($module_list)) {
             foreach (array_keys($module_data[$module]->required_by) as $dependent) {
                 if (!isset($module_data[$dependent])) {
                     // The dependent module does not exist.
                     return FALSE;
                 }
                 // Skip already uninstalled modules.
                 if (isset($installed_modules[$dependent]) && !isset($module_list[$dependent]) && $dependent != $profile) {
                     $module_list[$dependent] = $dependent;
                 }
             }
         }
     }
     // Use the validators and throw an exception with the reasons.
     if ($reasons = $this->validateUninstall($module_list)) {
         foreach ($reasons as $reason) {
             $reason_message[] = implode(', ', $reason);
         }
         throw new ModuleUninstallValidatorException('The following reasons prevent the modules from being uninstalled: ' . implode('; ', $reason_message));
     }
     // Set the actual module weights.
     $module_list = array_map(function ($module) use($module_data) {
         return $module_data[$module]->sort;
     }, $module_list);
     // Sort the module list by their weights.
     asort($module_list);
     $module_list = array_keys($module_list);
     // Only process modules that are enabled. A module is only enabled if it is
     // configured as enabled. Custom or overridden module handlers might contain
     // the module already, which means that it might be loaded, but not
     // necessarily installed.
     foreach ($module_list as $module) {
         // Clean up all entity bundles (including fields) of every entity type
         // provided by the module that is being uninstalled.
         // @todo Clean this up in https://www.drupal.org/node/2350111.
         $entity_manager = \Drupal::entityManager();
         foreach ($entity_manager->getDefinitions() as $entity_type_id => $entity_type) {
             if ($entity_type->getProvider() == $module) {
                 foreach (array_keys($entity_manager->getBundleInfo($entity_type_id)) as $bundle) {
                     $entity_manager->onBundleDelete($bundle, $entity_type_id);
                 }
             }
         }
         // Allow modules to react prior to the uninstallation of a module.
         $this->moduleHandler->invokeAll('module_preuninstall', array($module));
         // Uninstall the module.
         module_load_install($module);
         $this->moduleHandler->invoke($module, 'uninstall');
         // Remove all configuration belonging to the module.
         \Drupal::service('config.manager')->uninstall('module', $module);
         // In order to make uninstalling transactional if anything uses routes.
         \Drupal::getContainer()->set('router.route_provider.old', \Drupal::service('router.route_provider'));
         \Drupal::getContainer()->set('router.route_provider', \Drupal::service('router.route_provider.lazy_builder'));
         // Notify interested components that this module's entity types are being
         // deleted. For example, a SQL-based storage handler can use this as an
         // opportunity to drop the corresponding database tables.
         // @todo Clean this up in https://www.drupal.org/node/2350111.
         $update_manager = \Drupal::entityDefinitionUpdateManager();
         foreach ($entity_manager->getDefinitions() as $entity_type) {
             if ($entity_type->getProvider() == $module) {
                 $update_manager->uninstallEntityType($entity_type);
             } elseif ($entity_type->isSubclassOf(FieldableEntityInterface::CLASS)) {
                 // The module being installed may be adding new fields to existing
                 // entity types. Field definitions for any entity type defined by
                 // the module are handled in the if branch.
                 $entity_type_id = $entity_type->id();
                 /** @var \Drupal\Core\Entity\FieldableEntityStorageInterface $storage */
                 $storage = $entity_manager->getStorage($entity_type_id);
                 foreach ($entity_manager->getFieldStorageDefinitions($entity_type_id) as $storage_definition) {
                     // @todo We need to trigger field purging here.
                     //   See https://www.drupal.org/node/2282119.
                     if ($storage_definition->getProvider() == $module && !$storage->countFieldData($storage_definition, TRUE)) {
                         $update_manager->uninstallFieldStorageDefinition($storage_definition);
                     }
                 }
             }
         }
         // Remove the schema.
         drupal_uninstall_schema($module);
         // Remove the module's entry from the config. Don't check schema when
         // uninstalling a module since we are only clearing a key.
         \Drupal::configFactory()->getEditable('core.extension')->clear("module.{$module}")->save(TRUE);
         // Update the module handler to remove the module.
         // The current ModuleHandler instance is obsolete with the kernel rebuild
         // below.
         $module_filenames = $this->moduleHandler->getModuleList();
         unset($module_filenames[$module]);
         $this->moduleHandler->setModuleList($module_filenames);
         // Remove any potential cache bins provided by the module.
         $this->removeCacheBins($module);
         // Clear the static cache of system_rebuild_module_data() to pick up the
         // new module, since it merges the installation status of modules into
         // its statically cached list.
         drupal_static_reset('system_rebuild_module_data');
         // Clear plugin manager caches.
         \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions();
         // Update the kernel to exclude the uninstalled modules.
         $this->updateKernel($module_filenames);
         // Update the theme registry to remove the newly uninstalled module.
         drupal_theme_rebuild();
         // Modules can alter theme info, so refresh theme data.
         // @todo ThemeHandler cannot be injected into ModuleHandler, since that
         //   causes a circular service dependency.
         // @see https://www.drupal.org/node/2208429
         \Drupal::service('theme_handler')->refreshInfo();
         \Drupal::logger('system')->info('%module module uninstalled.', array('%module' => $module));
         $schema_store = \Drupal::keyValue('system.schema');
         $schema_store->delete($module);
         /** @var \Drupal\Core\Update\UpdateRegistry $post_update_registry */
         $post_update_registry = \Drupal::service('update.post_update_registry');
         $post_update_registry->filterOutInvokedUpdatesByModule($module);
     }
     // Rebuild routes after installing module. This is done here on top of
     // \Drupal\Core\Routing\RouteBuilder::destruct to not run into errors on
     // fastCGI which executes ::destruct() after the Module uninstallation page
     // was sent already.
     \Drupal::service('router.builder')->rebuild();
     drupal_get_installed_schema_version(NULL, TRUE);
     // Let other modules react.
     $this->moduleHandler->invokeAll('modules_uninstalled', array($module_list));
     // Flush all persistent caches.
     // Any cache entry might implicitly depend on the uninstalled modules,
     // so clear all of them explicitly.
     $this->moduleHandler->invokeAll('cache_flush');
     foreach (Cache::getBins() as $service_id => $cache_backend) {
         $cache_backend->deleteAll();
     }
     return TRUE;
 }
Example #27
0
 /**
  * Returns the result of an Entity reference autocomplete request.
  *
  * @param string $input
  *   The label of the entity to query by.
  *
  * @return mixed
  *  The JSON value encoded in its appropriate PHP type.
  */
 protected function getAutocompleteResult($input)
 {
     $request = Request::create('entity_reference_autocomplete/' . $this->entityType . '/default');
     $request->query->set('q', $input);
     $selection_settings = [];
     $selection_settings_key = Crypt::hmacBase64(serialize($selection_settings) . $this->entityType . 'default', Settings::getHashSalt());
     \Drupal::keyValue('entity_autocomplete')->set($selection_settings_key, $selection_settings);
     $entity_reference_controller = EntityAutocompleteController::create($this->container);
     $result = $entity_reference_controller->handleAutocomplete($request, $this->entityType, 'default', $selection_settings_key)->getContent();
     return Json::decode($result);
 }
 /**
  * Builds a row for an entity in the entity listing.
  *
  * @param EntityInterface $migration
  *   The entity for which to build the row.
  *
  * @return array
  *   A render array of the table row for displaying the entity.
  *
  * @see Drupal\Core\Entity\EntityListController::render()
  */
 public function buildRow(MigrationInterface $migration)
 {
     $row['label'] = $migration->label();
     $row['machine_name'] = $migration->id();
     $row['status'] = $migration->getStatusLabel();
     // Derive the stats
     $source_plugin = $migration->getSourcePlugin();
     $row['total'] = $source_plugin->count();
     $map = $migration->getIdMap();
     $row['imported'] = $map->importedCount();
     // -1 indicates uncountable sources.
     if ($row['total'] == -1) {
         $row['total'] = $this->t('N/A');
         $row['unprocessed'] = $this->t('N/A');
     } else {
         $row['unprocessed'] = $row['total'] - $map->processedCount();
     }
     $group = $migration->get('migration_group');
     if (!$group) {
         $group = 'default';
     }
     // @todo: This is most likely not a Best Practice (tm).
     $row['messages']['data']['#markup'] = '<a href="/admin/structure/migrate/manage/' . $group . '/migrations/' . $migration->id() . '/messages">' . $map->messageCount() . '</a>';
     $migrate_last_imported_store = \Drupal::keyValue('migrate_last_imported');
     $last_imported = $migrate_last_imported_store->get($migration->id(), FALSE);
     if ($last_imported) {
         /** @var DateFormatter $date_formatter */
         $date_formatter = \Drupal::service('date.formatter');
         $row['last_imported'] = $date_formatter->format($last_imported / 1000, 'custom', 'Y-m-d H:i:s');
     } else {
         $row['last_imported'] = '';
     }
     return $row;
     // + parent::buildRow($migration);
 }
 /**
  * Asserts the module post update functions after uninstall.
  *
  * @param string $module
  *   The module that got installed.
  */
 protected function assertUninstallModuleUpdates($module)
 {
     /** @var \Drupal\Core\Update\UpdateRegistry $post_update_registry */
     $post_update_registry = \Drupal::service('update.post_update_registry');
     $all_update_functions = $post_update_registry->getPendingUpdateFunctions();
     switch ($module) {
         case 'block':
             $this->assertFalse(array_intersect(['block_post_update_disable_blocks_with_missing_contexts'], $all_update_functions), 'Asserts that no pending post update functions are available.');
             $existing_updates = \Drupal::keyValue('post_update')->get('existing_updates', []);
             $this->assertFalse(array_intersect(['block_post_update_disable_blocks_with_missing_contexts'], $existing_updates), 'Asserts that no post update functions are stored in keyvalue store.');
             break;
     }
 }
Example #30
0
 /**
  * @todo Merge this with existing node test methods?
  */
 public function testNodeState()
 {
     $nodeNoAliasUser = $this->drupalCreateUser(array('bypass node access'));
     $nodeAliasUser = $this->drupalCreateUser(array('bypass node access', 'create url aliases'));
     $node = $this->drupalCreateNode(array('title' => 'Node version one', 'type' => 'page', 'path' => array('pathauto' => PathautoState::SKIP)));
     $this->assertNoEntityAlias($node);
     // Set a manual path alias for the node.
     $node->path->alias = '/test-alias';
     $node->save();
     // Ensure that the pathauto field was saved to the database.
     \Drupal::entityManager()->getStorage('node')->resetCache();
     $node = Node::load($node->id());
     $this->assertIdentical($node->path->pathauto, PathautoState::SKIP);
     // Ensure that the manual path alias was saved and an automatic alias was not generated.
     $this->assertEntityAlias($node, '/test-alias');
     $this->assertNoEntityAliasExists($node, '/content/node-version-one');
     // Save the node as a user who does not have access to path fieldset.
     $this->drupalLogin($nodeNoAliasUser);
     $this->drupalGet('node/' . $node->id() . '/edit');
     $this->assertNoFieldByName('path[0][pathauto]');
     $edit = array('title[0][value]' => 'Node version two');
     $this->drupalPostForm(NULL, $edit, 'Save');
     $this->assertText('Basic page Node version two has been updated.');
     $this->assertEntityAlias($node, '/test-alias');
     $this->assertNoEntityAliasExists($node, '/content/node-version-one');
     $this->assertNoEntityAliasExists($node, '/content/node-version-two');
     // Load the edit node page and check that the Pathauto checkbox is unchecked.
     $this->drupalLogin($nodeAliasUser);
     $this->drupalGet('node/' . $node->id() . '/edit');
     $this->assertNoFieldChecked('edit-path-0-pathauto');
     // Edit the manual alias and save the node.
     $edit = array('title[0][value]' => 'Node version three', 'path[0][alias]' => '/manually-edited-alias');
     $this->drupalPostForm(NULL, $edit, 'Save');
     $this->assertText('Basic page Node version three has been updated.');
     $this->assertEntityAlias($node, '/manually-edited-alias');
     $this->assertNoEntityAliasExists($node, '/test-alias');
     $this->assertNoEntityAliasExists($node, '/content/node-version-one');
     $this->assertNoEntityAliasExists($node, '/content/node-version-two');
     $this->assertNoEntityAliasExists($node, '/content/node-version-three');
     // Programatically save the node with an automatic alias.
     \Drupal::entityManager()->getStorage('node')->resetCache();
     $node = Node::load($node->id());
     $node->path->pathauto = PathautoState::CREATE;
     $node->save();
     // Ensure that the pathauto field was saved to the database.
     \Drupal::entityManager()->getStorage('node')->resetCache();
     $node = Node::load($node->id());
     $this->assertIdentical($node->path->pathauto, PathautoState::CREATE);
     $this->assertEntityAlias($node, '/content/node-version-three');
     $this->assertNoEntityAliasExists($node, '/manually-edited-alias');
     $this->assertNoEntityAliasExists($node, '/test-alias');
     $this->assertNoEntityAliasExists($node, '/content/node-version-one');
     $this->assertNoEntityAliasExists($node, '/content/node-version-two');
     $node->delete();
     $this->assertNull(\Drupal::keyValue('pathauto_state.node')->get($node->id()), 'Pathauto state was deleted');
 }