diff --git a/core/modules/book/book.install b/core/modules/book/book.install index 76ddc81..87d2361 100644 --- a/core/modules/book/book.install +++ b/core/modules/book/book.install @@ -6,14 +6,6 @@ */ /** - * Implements hook_uninstall(). - */ -function book_uninstall() { - // Clear book data out of the cache. - \Drupal::cache('data')->deleteAll(); -} - -/** * Implements hook_schema(). */ function book_schema() { @@ -133,3 +125,11 @@ function book_schema() { return $schema; } + +/** + * Implements hook_uninstall(). + */ +function book_uninstall() { + // Clear book data out of the cache. + \Drupal::cache('data')->deleteAll(); +} diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install index b67825e..f87048a 100644 --- a/core/modules/comment/comment.install +++ b/core/modules/comment/comment.install @@ -9,29 +9,6 @@ use Drupal\field\Entity\FieldStorageConfig; /** - * Implements hook_uninstall(). - */ -function comment_uninstall() { - // Remove the comment fields. - $fields = entity_load_multiple_by_properties('field_storage_config', array('type' => 'comment')); - foreach ($fields as $field) { - $field->delete(); - } - - // Remove state setting. - \Drupal::state()->delete('comment.node_comment_statistics_scale'); -} - -/** - * Implements hook_install(). - */ -function comment_install() { - // By default, maintain entity statistics for comments. - // @see \Drupal\comment\CommentStatisticsInterface - \Drupal::state()->set('comment.maintain_entity_statistics', TRUE); -} - -/** * Implements hook_schema(). */ function comment_schema() { @@ -112,6 +89,29 @@ function comment_schema() { } /** + * Implements hook_install(). + */ +function comment_install() { + // By default, maintain entity statistics for comments. + // @see \Drupal\comment\CommentStatisticsInterface + \Drupal::state()->set('comment.maintain_entity_statistics', TRUE); +} + +/** + * Implements hook_uninstall(). + */ +function comment_uninstall() { + // Remove the comment fields. + $fields = entity_load_multiple_by_properties('field_storage_config', array('type' => 'comment')); + foreach ($fields as $field) { + $field->delete(); + } + + // Remove state setting. + \Drupal::state()->delete('comment.node_comment_statistics_scale'); +} + +/** * @addtogroup updates-8.0.0-rc * @{ */ diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install index 36c71e4..e9bd80e 100644 --- a/core/modules/forum/forum.install +++ b/core/modules/forum/forum.install @@ -9,55 +9,6 @@ use Drupal\taxonomy\Entity\Term; /** - * Implements hook_install(). - */ -function forum_install() { - // Set the weight of the forum.module to 1 so it is loaded after the taxonomy.module. - module_set_weight('forum', 1); - // Do not allow to delete the forum's node type machine name. - $locked = \Drupal::state()->get('node.type.locked'); - $locked['forum'] = 'forum'; - \Drupal::state()->set('node.type.locked', $locked); - - if (!\Drupal::service('config.installer')->isSyncing()) { - // Create a default forum so forum posts can be created. - $term = Term::create(array( - 'name' => t('General discussion'), - 'description' => '', - 'parent' => array(0), - 'vid' => 'forums', - 'forum_container' => 0, - )); - $term->save(); - } -} - -/** - * Implements hook_uninstall(). - */ -function forum_uninstall() { - if ($field_storage = FieldStorageConfig::loadByName('node', 'taxonomy_forums')) { - $field_storage->delete(); - } - - if ($field_storage = FieldStorageConfig::loadByName('node', 'comment_forum')) { - $field_storage->delete(); - } - - if ($field_storage = FieldStorageConfig::loadByName('taxonomy_term', 'forum_container')) { - $field_storage->delete(); - } - - // Purge field data now to allow taxonomy and options module to be uninstalled - // if this is the only field remaining. - field_purge_batch(10); - // Allow to delete a forum's node type. - $locked = \Drupal::state()->get('node.type.locked'); - unset($locked['forum']); - \Drupal::state()->set('node.type.locked', $locked); -} - -/** * Implements hook_schema(). */ function forum_schema() { @@ -175,3 +126,52 @@ function forum_schema() { return $schema; } + +/** + * Implements hook_install(). + */ +function forum_install() { + // Set the weight of the forum.module to 1 so it is loaded after the taxonomy.module. + module_set_weight('forum', 1); + // Do not allow to delete the forum's node type machine name. + $locked = \Drupal::state()->get('node.type.locked'); + $locked['forum'] = 'forum'; + \Drupal::state()->set('node.type.locked', $locked); + + if (!\Drupal::service('config.installer')->isSyncing()) { + // Create a default forum so forum posts can be created. + $term = Term::create(array( + 'name' => t('General discussion'), + 'description' => '', + 'parent' => array(0), + 'vid' => 'forums', + 'forum_container' => 0, + )); + $term->save(); + } +} + +/** + * Implements hook_uninstall(). + */ +function forum_uninstall() { + if ($field_storage = FieldStorageConfig::loadByName('node', 'taxonomy_forums')) { + $field_storage->delete(); + } + + if ($field_storage = FieldStorageConfig::loadByName('node', 'comment_forum')) { + $field_storage->delete(); + } + + if ($field_storage = FieldStorageConfig::loadByName('taxonomy_term', 'forum_container')) { + $field_storage->delete(); + } + + // Purge field data now to allow taxonomy and options module to be uninstalled + // if this is the only field remaining. + field_purge_batch(10); + // Allow to delete a forum's node type. + $locked = \Drupal::state()->get('node.type.locked'); + unset($locked['forum']); + \Drupal::state()->set('node.type.locked', $locked); +} diff --git a/core/modules/image/image.install b/core/modules/image/image.install index fd14d03..dbc91f9 100644 --- a/core/modules/image/image.install +++ b/core/modules/image/image.install @@ -6,23 +6,6 @@ */ /** - * Implements hook_install(). - */ -function image_install() { - // Create the styles directory and ensure it's writable. - $directory = file_default_scheme() . '://styles'; - file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); -} - -/** - * Implements hook_uninstall(). - */ -function image_uninstall() { - // Remove the styles directory and generated images. - file_unmanaged_delete_recursive(file_default_scheme() . '://styles'); -} - -/** * Implements hook_requirements() to check the PHP GD Library. * * @param $phase @@ -61,3 +44,20 @@ function image_requirements($phase) { return $requirements; } + +/** + * Implements hook_install(). + */ +function image_install() { + // Create the styles directory and ensure it's writable. + $directory = file_default_scheme() . '://styles'; + file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); +} + +/** + * Implements hook_uninstall(). + */ +function image_uninstall() { + // Remove the styles directory and generated images. + file_unmanaged_delete_recursive(file_default_scheme() . '://styles'); +} diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install index 0755104..5c99587 100644 --- a/core/modules/locale/locale.install +++ b/core/modules/locale/locale.install @@ -8,46 +8,6 @@ use Drupal\Core\Url; /** - * Implements hook_install(). - */ -function locale_install() { - // Create the interface translations directory and ensure it's writable. - if (!$directory = \Drupal::config('locale.settings')->get('translation.path')) { - $site_path = \Drupal::service('site.path'); - $directory = $site_path . '/files/translations'; - \Drupal::configFactory()->getEditable('locale.settings')->set('translation.path', $directory)->save(); - } - file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); -} - -/** - * Implements hook_uninstall(). - */ -function locale_uninstall() { - $config = \Drupal::config('locale.settings'); - // Delete all JavaScript translation files. - $locale_js_directory = 'public://' . $config->get('javascript.directory'); - - if (is_dir($locale_js_directory)) { - $locale_javascripts = \Drupal::state()->get('locale.translation.javascript') ?: array(); - foreach ($locale_javascripts as $langcode => $file_suffix) { - if (!empty($file_suffix)) { - file_unmanaged_delete($locale_js_directory . '/' . $langcode . '_' . $file_suffix . '.js'); - } - } - // Delete the JavaScript translations directory if empty. - if (!file_scan_directory($locale_js_directory, '/.*/')) { - drupal_rmdir($locale_js_directory); - } - } - - // Clear variables. - \Drupal::state()->delete('system.javascript_parsed'); - \Drupal::state()->delete('locale.translation.plurals'); - \Drupal::state()->delete('locale.translation.javascript'); -} - -/** * Implements hook_schema(). */ function locale_schema() { @@ -294,3 +254,43 @@ function locale_requirements($phase) { } return $requirements; } + +/** + * Implements hook_install(). + */ +function locale_install() { + // Create the interface translations directory and ensure it's writable. + if (!$directory = \Drupal::config('locale.settings')->get('translation.path')) { + $site_path = \Drupal::service('site.path'); + $directory = $site_path . '/files/translations'; + \Drupal::configFactory()->getEditable('locale.settings')->set('translation.path', $directory)->save(); + } + file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); +} + +/** + * Implements hook_uninstall(). + */ +function locale_uninstall() { + $config = \Drupal::config('locale.settings'); + // Delete all JavaScript translation files. + $locale_js_directory = 'public://' . $config->get('javascript.directory'); + + if (is_dir($locale_js_directory)) { + $locale_javascripts = \Drupal::state()->get('locale.translation.javascript') ?: array(); + foreach ($locale_javascripts as $langcode => $file_suffix) { + if (!empty($file_suffix)) { + file_unmanaged_delete($locale_js_directory . '/' . $langcode . '_' . $file_suffix . '.js'); + } + } + // Delete the JavaScript translations directory if empty. + if (!file_scan_directory($locale_js_directory, '/.*/')) { + drupal_rmdir($locale_js_directory); + } + } + + // Clear variables. + \Drupal::state()->delete('system.javascript_parsed'); + \Drupal::state()->delete('locale.translation.plurals'); + \Drupal::state()->delete('locale.translation.javascript'); +} diff --git a/core/modules/node/node.install b/core/modules/node/node.install index c754880..ab56cc7 100644 --- a/core/modules/node/node.install +++ b/core/modules/node/node.install @@ -9,34 +9,6 @@ use Drupal\user\RoleInterface; /** - * Implements hook_requirements(). - */ -function node_requirements($phase) { - $requirements = array(); - if ($phase === 'runtime') { - // Only show rebuild button if there are either 0, or 2 or more, rows - // in the {node_access} table, or if there are modules that - // implement hook_node_grants(). - $grant_count = \Drupal::entityManager()->getAccessControlHandler('node')->countGrants(); - if ($grant_count != 1 || count(\Drupal::moduleHandler()->getImplementations('node_grants')) > 0) { - $value = \Drupal::translation()->formatPlural($grant_count, 'One permission in use', '@count permissions in use', array('@count' => $grant_count)); - } - else { - $value = t('Disabled'); - } - - $requirements['node_access'] = array( - 'title' => t('Node Access Permissions'), - 'value' => $value, - 'description' => t('If the site is experiencing problems with permissions to content, you may have to rebuild the permissions cache. Rebuilding will remove all privileges to content and replace them with permissions based on the current modules and settings. Rebuilding may take some time if there is a lot of content or complex permission settings. After rebuilding has completed, content will automatically use the new permissions. Rebuild permissions', array( - ':rebuild' => \Drupal::url('node.configure_rebuild_confirm'), - )), - ); - } - return $requirements; -} - -/** * Implements hook_schema(). */ function node_schema() { @@ -116,6 +88,34 @@ function node_schema() { } /** + * Implements hook_requirements(). + */ +function node_requirements($phase) { + $requirements = array(); + if ($phase === 'runtime') { + // Only show rebuild button if there are either 0, or 2 or more, rows + // in the {node_access} table, or if there are modules that + // implement hook_node_grants(). + $grant_count = \Drupal::entityManager()->getAccessControlHandler('node')->countGrants(); + if ($grant_count != 1 || count(\Drupal::moduleHandler()->getImplementations('node_grants')) > 0) { + $value = \Drupal::translation()->formatPlural($grant_count, 'One permission in use', '@count permissions in use', array('@count' => $grant_count)); + } + else { + $value = t('Disabled'); + } + + $requirements['node_access'] = array( + 'title' => t('Node Access Permissions'), + 'value' => $value, + 'description' => t('If the site is experiencing problems with permissions to content, you may have to rebuild the permissions cache. Rebuilding will remove all privileges to content and replace them with permissions based on the current modules and settings. Rebuilding may take some time if there is a lot of content or complex permission settings. After rebuilding has completed, content will automatically use the new permissions. Rebuild permissions', array( + ':rebuild' => \Drupal::url('node.configure_rebuild_confirm'), + )), + ); + } + return $requirements; +} + +/** * Implements hook_install(). */ function node_install() { diff --git a/core/modules/simpletest/simpletest.install b/core/modules/simpletest/simpletest.install index e5eb9a3..d601bc3 100644 --- a/core/modules/simpletest/simpletest.install +++ b/core/modules/simpletest/simpletest.install @@ -13,69 +13,6 @@ const SIMPLETEST_MINIMUM_PHP_MEMORY_LIMIT = '128M'; /** - * Implements hook_requirements(). - */ -function simpletest_requirements($phase) { - $requirements = array(); - - $has_curl = function_exists('curl_init'); - $open_basedir = ini_get('open_basedir'); - - $requirements['curl'] = array( - 'title' => t('cURL'), - 'value' => $has_curl ? t('Enabled') : t('Not found'), - ); - if (!$has_curl) { - $requirements['curl']['severity'] = REQUIREMENT_ERROR; - $requirements['curl']['description'] = t('The testing framework could not be installed because the PHP cURL library is not available.'); - } - - // SimpleTest currently needs 2 cURL options which are incompatible with - // having PHP's open_basedir restriction set. - // See https://www.drupal.org/node/674304. - $requirements['php_open_basedir'] = array( - 'title' => t('PHP open_basedir restriction'), - 'value' => $open_basedir ? t('Enabled') : t('Disabled'), - ); - if ($open_basedir) { - $requirements['php_open_basedir']['severity'] = REQUIREMENT_ERROR; - $requirements['php_open_basedir']['description'] = t('The testing framework requires the PHP open_basedir restriction to be disabled. Check your webserver configuration or contact your web host.'); - } - - // Check the current memory limit. If it is set too low, SimpleTest will fail - // to load all tests and throw a fatal error. - $memory_limit = ini_get('memory_limit'); - if (!Environment::checkMemoryLimit(SIMPLETEST_MINIMUM_PHP_MEMORY_LIMIT, $memory_limit)) { - $requirements['php_memory_limit']['severity'] = REQUIREMENT_WARNING; - $requirements['php_memory_limit']['description'] = t('The testing framework requires the PHP memory limit to be at least %memory_minimum_limit. The current value is %memory_limit. Follow these steps to continue.', array('%memory_limit' => $memory_limit, '%memory_minimum_limit' => SIMPLETEST_MINIMUM_PHP_MEMORY_LIMIT, ':url' => 'https://www.drupal.org/node/207036')); - } - - $site_directory = 'sites/simpletest'; - if (!drupal_verify_install_file(\Drupal::root() . '/' . $site_directory, FILE_EXIST|FILE_READABLE|FILE_WRITABLE|FILE_EXECUTABLE, 'dir')) { - $requirements['simpletest_site_directory'] = array( - 'title' => t('Simpletest site directory'), - 'value' => is_dir(\Drupal::root() . '/' . $site_directory) ? t('Not writable') : t('Missing'), - 'severity' => REQUIREMENT_ERROR, - 'description' => t('The testing framework requires the %sites-simpletest directory to exist and be writable in order to run tests.', array( - '%sites-simpletest' => $site_directory, - )), - ); - } - elseif (!file_save_htaccess(\Drupal::root() . '/' . $site_directory, FALSE)) { - $requirements['simpletest_site_directory'] = array( - 'title' => t('Simpletest site directory'), - 'value' => t('Not protected'), - 'severity' => REQUIREMENT_ERROR, - 'description' => t('The file %file does not exist and could not be created automatically, which poses a security risk. Ensure that the directory is writable.', array( - '%file' => $site_directory . '/.htaccess', - )), - ); - } - - return $requirements; -} - -/** * Implements hook_schema(). */ function simpletest_schema() { @@ -168,6 +105,69 @@ function simpletest_schema() { } /** + * Implements hook_requirements(). + */ +function simpletest_requirements($phase) { + $requirements = array(); + + $has_curl = function_exists('curl_init'); + $open_basedir = ini_get('open_basedir'); + + $requirements['curl'] = array( + 'title' => t('cURL'), + 'value' => $has_curl ? t('Enabled') : t('Not found'), + ); + if (!$has_curl) { + $requirements['curl']['severity'] = REQUIREMENT_ERROR; + $requirements['curl']['description'] = t('The testing framework could not be installed because the PHP cURL library is not available.'); + } + + // SimpleTest currently needs 2 cURL options which are incompatible with + // having PHP's open_basedir restriction set. + // See https://www.drupal.org/node/674304. + $requirements['php_open_basedir'] = array( + 'title' => t('PHP open_basedir restriction'), + 'value' => $open_basedir ? t('Enabled') : t('Disabled'), + ); + if ($open_basedir) { + $requirements['php_open_basedir']['severity'] = REQUIREMENT_ERROR; + $requirements['php_open_basedir']['description'] = t('The testing framework requires the PHP open_basedir restriction to be disabled. Check your webserver configuration or contact your web host.'); + } + + // Check the current memory limit. If it is set too low, SimpleTest will fail + // to load all tests and throw a fatal error. + $memory_limit = ini_get('memory_limit'); + if (!Environment::checkMemoryLimit(SIMPLETEST_MINIMUM_PHP_MEMORY_LIMIT, $memory_limit)) { + $requirements['php_memory_limit']['severity'] = REQUIREMENT_WARNING; + $requirements['php_memory_limit']['description'] = t('The testing framework requires the PHP memory limit to be at least %memory_minimum_limit. The current value is %memory_limit. Follow these steps to continue.', array('%memory_limit' => $memory_limit, '%memory_minimum_limit' => SIMPLETEST_MINIMUM_PHP_MEMORY_LIMIT, ':url' => 'https://www.drupal.org/node/207036')); + } + + $site_directory = 'sites/simpletest'; + if (!drupal_verify_install_file(\Drupal::root() . '/' . $site_directory, FILE_EXIST|FILE_READABLE|FILE_WRITABLE|FILE_EXECUTABLE, 'dir')) { + $requirements['simpletest_site_directory'] = array( + 'title' => t('Simpletest site directory'), + 'value' => is_dir(\Drupal::root() . '/' . $site_directory) ? t('Not writable') : t('Missing'), + 'severity' => REQUIREMENT_ERROR, + 'description' => t('The testing framework requires the %sites-simpletest directory to exist and be writable in order to run tests.', array( + '%sites-simpletest' => $site_directory, + )), + ); + } + elseif (!file_save_htaccess(\Drupal::root() . '/' . $site_directory, FALSE)) { + $requirements['simpletest_site_directory'] = array( + 'title' => t('Simpletest site directory'), + 'value' => t('Not protected'), + 'severity' => REQUIREMENT_ERROR, + 'description' => t('The file %file does not exist and could not be created automatically, which poses a security risk. Ensure that the directory is writable.', array( + '%file' => $site_directory . '/.htaccess', + )), + ); + } + + return $requirements; +} + +/** * Implements hook_uninstall(). */ function simpletest_uninstall() { diff --git a/core/modules/statistics/statistics.install b/core/modules/statistics/statistics.install index 11c72f4..5d493f3 100644 --- a/core/modules/statistics/statistics.install +++ b/core/modules/statistics/statistics.install @@ -6,15 +6,6 @@ */ /** - * Implements hook_uninstall(). - */ -function statistics_uninstall() { - // Remove states. - \Drupal::state()->delete('statistics.node_counter_scale'); - \Drupal::state()->delete('statistics.day_timestamp'); -} - -/** * Implements hook_schema(). */ function statistics_schema() { @@ -59,6 +50,15 @@ function statistics_schema() { } /** + * Implements hook_uninstall(). + */ +function statistics_uninstall() { + // Remove states. + \Drupal::state()->delete('statistics.node_counter_scale'); + \Drupal::state()->delete('statistics.day_timestamp'); +} + +/** * Disable the Statistics module if the node module is not enabled. */ function statistics_update_8001() { diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 49b5ff3..05e466a 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -17,81 +17,412 @@ use Symfony\Component\HttpFoundation\Request; /** - * Implements hook_requirements(). + * Implements hook_schema(). */ -function system_requirements($phase) { - global $install_state; - $requirements = array(); - - // Report Drupal version - if ($phase == 'runtime') { - $requirements['drupal'] = array( - 'title' => t('Drupal'), - 'value' => \Drupal::VERSION, - 'severity' => REQUIREMENT_INFO, - 'weight' => -10, - ); +function system_schema() { + $schema['batch'] = array( + 'description' => 'Stores details about batches (processes that run in multiple HTTP requests).', + 'fields' => array( + 'bid' => array( + 'description' => 'Primary Key: Unique batch ID.', + // This is not a serial column, to allow both progressive and + // non-progressive batches. See batch_process(). + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'token' => array( + 'description' => "A string token generated against the current user's session id and the batch id, used to ensure that only the user who submitted the batch can effectively access it.", + 'type' => 'varchar_ascii', + 'length' => 64, + 'not null' => TRUE, + ), + 'timestamp' => array( + 'description' => 'A Unix timestamp indicating when this batch was submitted for processing. Stale batches are purged at cron time.', + 'type' => 'int', + 'not null' => TRUE, + ), + 'batch' => array( + 'description' => 'A serialized array containing the processing data for the batch.', + 'type' => 'blob', + 'not null' => FALSE, + 'size' => 'big', + ), + ), + 'primary key' => array('bid'), + 'indexes' => array( + 'token' => array('token'), + ), + ); - // Display the currently active installation profile, if the site - // is not running the default installation profile. - $profile = drupal_get_profile(); - if ($profile != 'standard') { - $info = system_get_info('module', $profile); - $requirements['install_profile'] = array( - 'title' => t('Installation profile'), - 'value' => t('%profile_name (%profile-%version)', array( - '%profile_name' => $info['name'], - '%profile' => $profile, - '%version' => $info['version'] - )), - 'severity' => REQUIREMENT_INFO, - 'weight' => -9 - ); - } + $schema['key_value'] = array( + 'description' => 'Generic key-value storage table. See the state system for an example.', + 'fields' => array( + 'collection' => array( + 'description' => 'A named collection of key and value pairs.', + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + 'name' => array( + 'description' => 'The key of the key-value pair. As KEY is a SQL reserved keyword, name was chosen instead.', + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + 'value' => array( + 'description' => 'The value.', + 'type' => 'blob', + 'not null' => TRUE, + 'size' => 'big', + ), + ), + 'primary key' => array('collection', 'name'), + ); - // Warn if any experimental modules are installed. - $experimental = array(); - $enabled_modules = \Drupal::moduleHandler()->getModuleList(); - foreach ($enabled_modules as $module => $data) { - $info = system_get_info('module', $module); - if ($info['package'] === 'Core (Experimental)') { - $experimental[$module] = $info['name']; - } - } - if (!empty($experimental)) { - $requirements['experimental'] = array( - 'title' => t('Experimental modules enabled'), - 'value' => t('Experimental modules found: %module_list. Experimental modules are provided for testing purposes only. Use at your own risk.', array('%module_list' => implode(', ', $experimental), ':url' => 'https://www.drupal.org/core/experimental')), - 'severity' => REQUIREMENT_WARNING, - ); - } - } + $schema['key_value_expire'] = array( + 'description' => 'Generic key/value storage table with an expiration.', + 'fields' => array( + 'collection' => array( + 'description' => 'A named collection of key and value pairs.', + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + 'name' => array( + // KEY is an SQL reserved word, so use 'name' as the key's field name. + 'description' => 'The key of the key/value pair.', + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + 'value' => array( + 'description' => 'The value of the key/value pair.', + 'type' => 'blob', + 'not null' => TRUE, + 'size' => 'big', + ), + 'expire' => array( + 'description' => 'The time since Unix epoch in seconds when this item expires. Defaults to the maximum possible time.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 2147483647, + ), + ), + 'primary key' => array('collection', 'name'), + 'indexes' => array( + 'all' => array('name', 'collection', 'expire'), + 'expire' => array('expire'), + ), + ); - // Web server information. - $software = \Drupal::request()->server->get('SERVER_SOFTWARE'); - $requirements['webserver'] = array( - 'title' => t('Web server'), - 'value' => $software, + $schema['queue'] = array( + 'description' => 'Stores items in queues.', + 'fields' => array( + 'item_id' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'Primary Key: Unique item ID.', + ), + 'name' => array( + 'type' => 'varchar_ascii', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The queue name.', + ), + 'data' => array( + 'type' => 'blob', + 'not null' => FALSE, + 'size' => 'big', + 'serialize' => TRUE, + 'description' => 'The arbitrary data for the item.', + ), + 'expire' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Timestamp when the claim lease expires on the item.', + ), + 'created' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Timestamp when the item was created.', + ), + ), + 'primary key' => array('item_id'), + 'indexes' => array( + 'name_created' => array('name', 'created'), + 'expire' => array('expire'), + ), ); - // Tests clean URL support. - if ($phase == 'install' && $install_state['interactive'] && !isset($_GET['rewrite']) && strpos($software, 'Apache') !== FALSE) { - // If the Apache rewrite module is not enabled, Apache version must be >= - // 2.2.16 because of the FallbackResource directive in the root .htaccess - // file. Since the Apache version reported by the server is dependent on the - // ServerTokens setting in httpd.conf, we may not be able to determine if a - // given config is valid. Thus we are unable to use version_compare() as we - // need have three possible outcomes: the version of Apache is greater than - // 2.2.16, is less than 2.2.16, or cannot be determined accurately. In the - // first case, we encourage the use of mod_rewrite; in the second case, we - // raise an error regarding the minimum Apache version; in the third case, - // we raise a warning that the current version of Apache may not be - // supported. - $rewrite_warning = FALSE; - $rewrite_error = FALSE; - $apache_version_string = 'Apache'; + $schema['router'] = array( + 'description' => 'Maps paths to various callbacks (access, page and title)', + 'fields' => array( + 'name' => array( + 'description' => 'Primary Key: Machine name of this route', + 'type' => 'varchar_ascii', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'path' => array( + 'description' => 'The path for this URI', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'pattern_outline' => array( + 'description' => 'The pattern', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'fit' => array( + 'description' => 'A numeric representation of how specific the path is.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'route' => array( + 'description' => 'A serialized Route object', + 'type' => 'blob', + 'size' => 'big', + ), + 'number_parts' => array( + 'description' => 'Number of parts in this router path.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'size' => 'small', + ), + ), + 'indexes' => array( + 'pattern_outline_parts' => array('pattern_outline', 'number_parts'), + ), + 'primary key' => array('name'), + ); - // Determine the Apache version number: major, minor and revision. + $schema['semaphore'] = array( + 'description' => 'Table for holding semaphores, locks, flags, etc. that cannot be stored as state since they must not be cached.', + 'fields' => array( + 'name' => array( + 'description' => 'Primary Key: Unique name.', + 'type' => 'varchar_ascii', + 'length' => 255, + 'not null' => TRUE, + 'default' => '' + ), + 'value' => array( + 'description' => 'A value for the semaphore.', + 'type' => 'varchar_ascii', + 'length' => 255, + 'not null' => TRUE, + 'default' => '' + ), + 'expire' => array( + 'description' => 'A Unix timestamp with microseconds indicating when the semaphore should expire.', + 'type' => 'float', + 'size' => 'big', + 'not null' => TRUE + ), + ), + 'indexes' => array( + 'value' => array('value'), + 'expire' => array('expire'), + ), + 'primary key' => array('name'), + ); + + $schema['sequences'] = array( + 'description' => 'Stores IDs.', + 'fields' => array( + 'value' => array( + 'description' => 'The value of the sequence.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + ), + 'primary key' => array('value'), + ); + + $schema['sessions'] = array( + 'description' => "Drupal's session handlers read and write into the sessions table. Each record represents a user session, either anonymous or authenticated.", + 'fields' => array( + 'uid' => array( + 'description' => 'The {users}.uid corresponding to a session, or 0 for anonymous user.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'sid' => array( + 'description' => "A session ID (hashed). The value is generated by Drupal's session handlers.", + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + ), + 'hostname' => array( + 'description' => 'The IP address that last used this session ID (sid).', + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + 'timestamp' => array( + 'description' => 'The Unix timestamp when this session last requested a page. Old records are purged by PHP automatically.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'session' => array( + 'description' => 'The serialized contents of $_SESSION, an array of name/value pairs that persists across page requests by this session ID. Drupal loads $_SESSION from here at the start of each request and saves it at the end.', + 'type' => 'blob', + 'not null' => FALSE, + 'size' => 'big', + ), + ), + 'primary key' => array( + 'sid', + ), + 'indexes' => array( + 'timestamp' => array('timestamp'), + 'uid' => array('uid'), + ), + 'foreign keys' => array( + 'session_user' => array( + 'table' => 'users', + 'columns' => array('uid' => 'uid'), + ), + ), + ); + + $schema['url_alias'] = array( + 'description' => 'A list of URL aliases for Drupal paths; a user may visit either the source or destination path.', + 'fields' => array( + 'pid' => array( + 'description' => 'A unique path alias identifier.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'source' => array( + 'description' => 'The Drupal path this alias is for; e.g. node/12.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'alias' => array( + 'description' => 'The alias for this path; e.g. title-of-the-story.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'langcode' => array( + 'description' => "The language code this alias is for; if 'und', the alias will be used for unknown languages. Each Drupal path can have an alias for each supported language.", + 'type' => 'varchar_ascii', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), + ), + 'primary key' => array('pid'), + 'indexes' => array( + 'alias_langcode_pid' => array('alias', 'langcode', 'pid'), + 'source_langcode_pid' => array('source', 'langcode', 'pid'), + ), + ); + + return $schema; +} + +/** + * Implements hook_requirements(). + */ +function system_requirements($phase) { + global $install_state; + $requirements = array(); + + // Report Drupal version + if ($phase == 'runtime') { + $requirements['drupal'] = array( + 'title' => t('Drupal'), + 'value' => \Drupal::VERSION, + 'severity' => REQUIREMENT_INFO, + 'weight' => -10, + ); + + // Display the currently active installation profile, if the site + // is not running the default installation profile. + $profile = drupal_get_profile(); + if ($profile != 'standard') { + $info = system_get_info('module', $profile); + $requirements['install_profile'] = array( + 'title' => t('Installation profile'), + 'value' => t('%profile_name (%profile-%version)', array( + '%profile_name' => $info['name'], + '%profile' => $profile, + '%version' => $info['version'] + )), + 'severity' => REQUIREMENT_INFO, + 'weight' => -9 + ); + } + + // Warn if any experimental modules are installed. + $experimental = array(); + $enabled_modules = \Drupal::moduleHandler()->getModuleList(); + foreach ($enabled_modules as $module => $data) { + $info = system_get_info('module', $module); + if ($info['package'] === 'Core (Experimental)') { + $experimental[$module] = $info['name']; + } + } + if (!empty($experimental)) { + $requirements['experimental'] = array( + 'title' => t('Experimental modules enabled'), + 'value' => t('Experimental modules found: %module_list. Experimental modules are provided for testing purposes only. Use at your own risk.', array('%module_list' => implode(', ', $experimental), ':url' => 'https://www.drupal.org/core/experimental')), + 'severity' => REQUIREMENT_WARNING, + ); + } + } + + // Web server information. + $software = \Drupal::request()->server->get('SERVER_SOFTWARE'); + $requirements['webserver'] = array( + 'title' => t('Web server'), + 'value' => $software, + ); + + // Tests clean URL support. + if ($phase == 'install' && $install_state['interactive'] && !isset($_GET['rewrite']) && strpos($software, 'Apache') !== FALSE) { + // If the Apache rewrite module is not enabled, Apache version must be >= + // 2.2.16 because of the FallbackResource directive in the root .htaccess + // file. Since the Apache version reported by the server is dependent on the + // ServerTokens setting in httpd.conf, we may not be able to determine if a + // given config is valid. Thus we are unable to use version_compare() as we + // need have three possible outcomes: the version of Apache is greater than + // 2.2.16, is less than 2.2.16, or cannot be determined accurately. In the + // first case, we encourage the use of mod_rewrite; in the second case, we + // raise an error regarding the minimum Apache version; in the third case, + // we raise a warning that the current version of Apache may not be + // supported. + $rewrite_warning = FALSE; + $rewrite_error = FALSE; + $apache_version_string = 'Apache'; + + // Determine the Apache version number: major, minor and revision. if (preg_match('/Apache\/(\d+)\.?(\d+)?\.?(\d+)?/', $software, $matches)) { $apache_version_string = $matches[0]; @@ -851,337 +1182,6 @@ function system_install() { } /** - * Implements hook_schema(). - */ -function system_schema() { - $schema['batch'] = array( - 'description' => 'Stores details about batches (processes that run in multiple HTTP requests).', - 'fields' => array( - 'bid' => array( - 'description' => 'Primary Key: Unique batch ID.', - // This is not a serial column, to allow both progressive and - // non-progressive batches. See batch_process(). - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'token' => array( - 'description' => "A string token generated against the current user's session id and the batch id, used to ensure that only the user who submitted the batch can effectively access it.", - 'type' => 'varchar_ascii', - 'length' => 64, - 'not null' => TRUE, - ), - 'timestamp' => array( - 'description' => 'A Unix timestamp indicating when this batch was submitted for processing. Stale batches are purged at cron time.', - 'type' => 'int', - 'not null' => TRUE, - ), - 'batch' => array( - 'description' => 'A serialized array containing the processing data for the batch.', - 'type' => 'blob', - 'not null' => FALSE, - 'size' => 'big', - ), - ), - 'primary key' => array('bid'), - 'indexes' => array( - 'token' => array('token'), - ), - ); - - $schema['key_value'] = array( - 'description' => 'Generic key-value storage table. See the state system for an example.', - 'fields' => array( - 'collection' => array( - 'description' => 'A named collection of key and value pairs.', - 'type' => 'varchar_ascii', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - ), - 'name' => array( - 'description' => 'The key of the key-value pair. As KEY is a SQL reserved keyword, name was chosen instead.', - 'type' => 'varchar_ascii', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - ), - 'value' => array( - 'description' => 'The value.', - 'type' => 'blob', - 'not null' => TRUE, - 'size' => 'big', - ), - ), - 'primary key' => array('collection', 'name'), - ); - - $schema['key_value_expire'] = array( - 'description' => 'Generic key/value storage table with an expiration.', - 'fields' => array( - 'collection' => array( - 'description' => 'A named collection of key and value pairs.', - 'type' => 'varchar_ascii', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - ), - 'name' => array( - // KEY is an SQL reserved word, so use 'name' as the key's field name. - 'description' => 'The key of the key/value pair.', - 'type' => 'varchar_ascii', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - ), - 'value' => array( - 'description' => 'The value of the key/value pair.', - 'type' => 'blob', - 'not null' => TRUE, - 'size' => 'big', - ), - 'expire' => array( - 'description' => 'The time since Unix epoch in seconds when this item expires. Defaults to the maximum possible time.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 2147483647, - ), - ), - 'primary key' => array('collection', 'name'), - 'indexes' => array( - 'all' => array('name', 'collection', 'expire'), - 'expire' => array('expire'), - ), - ); - - $schema['queue'] = array( - 'description' => 'Stores items in queues.', - 'fields' => array( - 'item_id' => array( - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'description' => 'Primary Key: Unique item ID.', - ), - 'name' => array( - 'type' => 'varchar_ascii', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => 'The queue name.', - ), - 'data' => array( - 'type' => 'blob', - 'not null' => FALSE, - 'size' => 'big', - 'serialize' => TRUE, - 'description' => 'The arbitrary data for the item.', - ), - 'expire' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Timestamp when the claim lease expires on the item.', - ), - 'created' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Timestamp when the item was created.', - ), - ), - 'primary key' => array('item_id'), - 'indexes' => array( - 'name_created' => array('name', 'created'), - 'expire' => array('expire'), - ), - ); - - $schema['router'] = array( - 'description' => 'Maps paths to various callbacks (access, page and title)', - 'fields' => array( - 'name' => array( - 'description' => 'Primary Key: Machine name of this route', - 'type' => 'varchar_ascii', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - ), - 'path' => array( - 'description' => 'The path for this URI', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - ), - 'pattern_outline' => array( - 'description' => 'The pattern', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - ), - 'fit' => array( - 'description' => 'A numeric representation of how specific the path is.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'route' => array( - 'description' => 'A serialized Route object', - 'type' => 'blob', - 'size' => 'big', - ), - 'number_parts' => array( - 'description' => 'Number of parts in this router path.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'size' => 'small', - ), - ), - 'indexes' => array( - 'pattern_outline_parts' => array('pattern_outline', 'number_parts'), - ), - 'primary key' => array('name'), - ); - - $schema['semaphore'] = array( - 'description' => 'Table for holding semaphores, locks, flags, etc. that cannot be stored as state since they must not be cached.', - 'fields' => array( - 'name' => array( - 'description' => 'Primary Key: Unique name.', - 'type' => 'varchar_ascii', - 'length' => 255, - 'not null' => TRUE, - 'default' => '' - ), - 'value' => array( - 'description' => 'A value for the semaphore.', - 'type' => 'varchar_ascii', - 'length' => 255, - 'not null' => TRUE, - 'default' => '' - ), - 'expire' => array( - 'description' => 'A Unix timestamp with microseconds indicating when the semaphore should expire.', - 'type' => 'float', - 'size' => 'big', - 'not null' => TRUE - ), - ), - 'indexes' => array( - 'value' => array('value'), - 'expire' => array('expire'), - ), - 'primary key' => array('name'), - ); - - $schema['sequences'] = array( - 'description' => 'Stores IDs.', - 'fields' => array( - 'value' => array( - 'description' => 'The value of the sequence.', - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - ), - 'primary key' => array('value'), - ); - - $schema['sessions'] = array( - 'description' => "Drupal's session handlers read and write into the sessions table. Each record represents a user session, either anonymous or authenticated.", - 'fields' => array( - 'uid' => array( - 'description' => 'The {users}.uid corresponding to a session, or 0 for anonymous user.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'sid' => array( - 'description' => "A session ID (hashed). The value is generated by Drupal's session handlers.", - 'type' => 'varchar_ascii', - 'length' => 128, - 'not null' => TRUE, - ), - 'hostname' => array( - 'description' => 'The IP address that last used this session ID (sid).', - 'type' => 'varchar_ascii', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - ), - 'timestamp' => array( - 'description' => 'The Unix timestamp when this session last requested a page. Old records are purged by PHP automatically.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'session' => array( - 'description' => 'The serialized contents of $_SESSION, an array of name/value pairs that persists across page requests by this session ID. Drupal loads $_SESSION from here at the start of each request and saves it at the end.', - 'type' => 'blob', - 'not null' => FALSE, - 'size' => 'big', - ), - ), - 'primary key' => array( - 'sid', - ), - 'indexes' => array( - 'timestamp' => array('timestamp'), - 'uid' => array('uid'), - ), - 'foreign keys' => array( - 'session_user' => array( - 'table' => 'users', - 'columns' => array('uid' => 'uid'), - ), - ), - ); - - $schema['url_alias'] = array( - 'description' => 'A list of URL aliases for Drupal paths; a user may visit either the source or destination path.', - 'fields' => array( - 'pid' => array( - 'description' => 'A unique path alias identifier.', - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'source' => array( - 'description' => 'The Drupal path this alias is for; e.g. node/12.', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - ), - 'alias' => array( - 'description' => 'The alias for this path; e.g. title-of-the-story.', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - ), - 'langcode' => array( - 'description' => "The language code this alias is for; if 'und', the alias will be used for unknown languages. Each Drupal path can have an alias for each supported language.", - 'type' => 'varchar_ascii', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - ), - 'primary key' => array('pid'), - 'indexes' => array( - 'alias_langcode_pid' => array('alias', 'langcode', 'pid'), - 'source_langcode_pid' => array('source', 'langcode', 'pid'), - ), - ); - - return $schema; -} - -/** * @addtogroup updates-8.0.0-beta * @{ */ diff --git a/core/modules/system/tests/modules/entity_test/entity_test.install b/core/modules/system/tests/modules/entity_test/entity_test.install index b6369da..8aa1b39 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.install +++ b/core/modules/system/tests/modules/entity_test/entity_test.install @@ -9,6 +9,25 @@ use Drupal\field\Entity\FieldStorageConfig; /** + * Implements hook_schema(). + */ +function entity_test_schema() { + // Schema for simple entity. + $schema['entity_test_example'] = array( + 'description' => 'Stores entity_test items.', + 'fields' => array( + 'id' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'description' => 'Primary Key: Unique entity-test item ID.', + ), + ), + 'primary key' => array('id'), + ); + return $schema; +} + +/** * Implements hook_install(). */ function entity_test_install() { @@ -34,24 +53,5 @@ function entity_test_install() { } } -/** - * Implements hook_schema(). - */ -function entity_test_schema() { - // Schema for simple entity. - $schema['entity_test_example'] = array( - 'description' => 'Stores entity_test items.', - 'fields' => array( - 'id' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'description' => 'Primary Key: Unique entity-test item ID.', - ), - ), - 'primary key' => array('id'), - ); - return $schema; -} - DbUpdatesTrait::includeUpdates('entity_test', 'entity_definition_updates'); DbUpdatesTrait::includeUpdates('entity_test', 'status_report'); diff --git a/core/modules/system/tests/modules/update_test_with_7x/update_test_with_7x.install b/core/modules/system/tests/modules/update_test_with_7x/update_test_with_7x.install index fd5c65b..bececb5 100644 --- a/core/modules/system/tests/modules/update_test_with_7x/update_test_with_7x.install +++ b/core/modules/system/tests/modules/update_test_with_7x/update_test_with_7x.install @@ -6,20 +6,20 @@ */ /** - * Dummy update_test_with_7x update 7200. + * Implements hook_update_last_removed(). */ -function update_test_with_7x_update_7200() { +function update_test_with_7x_update_last_removed() { + return 7110; } /** - * Dummy update_test_with_7x update 7201. + * Dummy update_test_with_7x update 7200. */ -function update_test_with_7x_update_7201() { +function update_test_with_7x_update_7200() { } /** - * Implements hook_update_last_removed(). + * Dummy update_test_with_7x update 7201. */ -function update_test_with_7x_update_last_removed() { - return 7110; +function update_test_with_7x_update_7201() { } diff --git a/core/modules/tracker/tracker.install b/core/modules/tracker/tracker.install index 5f3e5a0..a3a77ed 100644 --- a/core/modules/tracker/tracker.install +++ b/core/modules/tracker/tracker.install @@ -6,26 +6,6 @@ */ /** - * Implements hook_uninstall(). - */ -function tracker_uninstall() { - \Drupal::state()->delete('tracker.index_nid'); -} - -/** - * Implements hook_install(). - */ -function tracker_install() { - $max_nid = db_query('SELECT MAX(nid) FROM {node}')->fetchField(); - if ($max_nid != 0) { - \Drupal::state()->set('tracker.index_nid', $max_nid); - // To avoid timing out while attempting to do a complete indexing, we - // simply call our cron job to remove stale records and begin the process. - tracker_cron(); - } -} - -/** * Implements hook_schema(). */ function tracker_schema() { @@ -116,3 +96,23 @@ function tracker_schema() { return $schema; } + +/** + * Implements hook_install(). + */ +function tracker_install() { + $max_nid = db_query('SELECT MAX(nid) FROM {node}')->fetchField(); + if ($max_nid != 0) { + \Drupal::state()->set('tracker.index_nid', $max_nid); + // To avoid timing out while attempting to do a complete indexing, we + // simply call our cron job to remove stale records and begin the process. + tracker_cron(); + } +} + +/** + * Implements hook_uninstall(). + */ +function tracker_uninstall() { + \Drupal::state()->delete('tracker.index_nid'); +}