diff --git a/.htaccess b/.htaccess index 07cf7e4..c29b0d5 100644 --- a/.htaccess +++ b/.htaccess @@ -97,14 +97,14 @@ AddEncoding gzip svgz # URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option: # # To redirect all users to access the site WITH the 'www.' prefix, - # (http://example.com/foo will be redirected to http://www.example.com/foo) + # (http://example.com/... will be redirected to http://www.example.com/...) # uncomment the following: # RewriteCond %{HTTP_HOST} . # RewriteCond %{HTTP_HOST} !^www\. [NC] # RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301] # # To redirect all users to access the site WITHOUT the 'www.' prefix, - # (http://www.example.com/foo will be redirected to http://example.com/foo) + # (http://www.example.com/... will be redirected to http://example.com/...) # uncomment the following: # RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] # RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301] diff --git a/core/CHANGELOG.txt b/core/CHANGELOG.txt index e9fec1d..3420ece 100644 --- a/core/CHANGELOG.txt +++ b/core/CHANGELOG.txt @@ -96,7 +96,7 @@ Drupal 8.0, xxxx-xx-xx (development version) * Added language selectors to most configuration options (views, menus, etc.) * Added a configuration translation user interface that works with any - configuration with translatable values (blocks, views, fields, etc.). + configuration with translatable values (blocks, views, fields, etc). * Added language options to block visibility. * Much improved language APIs for developers: * Added simple APIs and hooks to save/delete/update languages. @@ -682,7 +682,7 @@ Drupal 4.7.0, 2006-05-01 - Added support for PHP5's 'mysqli' extension. - Search module: * Made indexer smarter and more robust. - * Added advanced search operators (e.g., phrase, node type, etc.). + * Added advanced search operators (e.g. phrase, node type, ...). * Added customizable result ranking. - PostgreSQL support: * Removed dependency on PL/pgSQL procedural language. @@ -1059,7 +1059,7 @@ Drupal 4.0.0, 2002-06-15 * Made each cloud site have its own settings. * Modules and themes can now be enabled/disabled using the administration pages. * Added URL abstraction for links. - * Usability changes (renamed links, better UI, etc.). + * Usability changes (renamed links, better UI, etc). - Collaboratively revised and expanded the Drupal documentation. Drupal 3.0.1, 2001-10-15 diff --git a/core/core.services.yml b/core/core.services.yml index 589c5f6..7b41a1d 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -136,7 +136,7 @@ services: arguments: ['@database', '@cache_tags.invalidator.checksum'] cache.backend.apcu: class: Drupal\Core\Cache\ApcuBackendFactory - arguments: ['@app.root', '@site.path', '@cache_tags.invalidator.checksum'] + arguments: ['@app.root', '@cache_tags.invalidator.checksum'] cache.backend.php: class: Drupal\Core\Cache\PhpBackendFactory arguments: ['@cache_tags.invalidator.checksum'] @@ -418,12 +418,6 @@ services: - { name: module_install.uninstall_validator } arguments: ['@entity.manager', '@string_translation'] lazy: true - required_module_uninstall_validator: - class: Drupal\Core\Extension\RequiredModuleUninstallValidator - tags: - - { name: module_install.uninstall_validator } - arguments: ['@string_translation'] - lazy: true theme_handler: class: Drupal\Core\Extension\ThemeHandler arguments: ['@app.root', '@config.factory', '@module_handler', '@state', '@info_parser'] @@ -498,7 +492,7 @@ services: arguments: ['@controller_resolver', '@request_stack', '@current_route_match', '@router.route_provider', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user'] plugin.manager.menu.local_task: class: Drupal\Core\Menu\LocalTaskManager - arguments: ['@controller_resolver', '@request_stack', '@current_route_match', '@router.route_provider', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user'] + arguments: ['@controller_resolver', '@request_stack', '@current_route_match', '@router.route_provider', '@router.builder', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user'] plugin.manager.menu.contextual_link: class: Drupal\Core\Menu\ContextualLinkManager arguments: ['@controller_resolver', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user', '@request_stack'] @@ -545,15 +539,6 @@ services: class: Drupal\Core\AppRootFactory arguments: ['@kernel'] public: false - site.path: - class: SplString - factory: site.path.factory:get - tags: - - { name: parameter_service } - site.path.factory: - class: Drupal\Core\SitePathFactory - arguments: ['@kernel'] - public: false controller_resolver: class: Drupal\Core\Controller\ControllerResolver arguments: ['@class_resolver'] @@ -575,6 +560,10 @@ services: http_middleware.negotiation: class: Drupal\Core\StackMiddleware\NegotiationMiddleware arguments: ['@http_negotiation.format_negotiator'] + calls: + - [registerFormat, ['drupal_ajax', ['application/vnd.drupal-ajax']]] + - [registerFormat, ['drupal_dialog', ['application/vnd.drupal-dialog']]] + - [registerFormat, ['drupal_modal', ['application/vnd.drupal-modal']]] tags: - { name: http_middleware, priority: 400 } http_middleware.reverse_proxy: @@ -769,8 +758,8 @@ services: password: class: Drupal\Core\Password\PhpassHashedPassword arguments: [16] - request_format_route_filter: - class: Drupal\Core\Routing\RequestFormatRouteFilter + accept_header_matcher: + class: Drupal\Core\Routing\AcceptHeaderMatcher tags: - { name: route_filter } content_type_header_matcher: @@ -1143,7 +1132,7 @@ services: arguments: ['@module_handler'] date.formatter: class: Drupal\Core\Datetime\DateFormatter - arguments: ['@entity.manager', '@language_manager', '@string_translation', '@config.factory', '@request_stack'] + arguments: ['@entity.manager', '@language_manager', '@string_translation', '@config.factory'] feed.bridge.reader: class: Drupal\Component\Bridge\ZfExtensionManagerSfContainer calls: diff --git a/core/includes/entity.inc b/core/includes/entity.inc index 31bbf42..463dcd0 100644 --- a/core/includes/entity.inc +++ b/core/includes/entity.inc @@ -213,11 +213,6 @@ function entity_delete_multiple($entity_type, array $ids) { * * @return \Drupal\Core\Entity\EntityInterface * A new entity object. - * - * @deprecated in Drupal 8.x-dev, will be removed before Drupal 9.0.0. Use - * the ::create($values) method if the entity type is known or - * \Drupal::entityManager()->getStorage($entity_type)->create($values) if the - * entity type is variable. */ function entity_create($entity_type, array $values = array()) { return \Drupal::entityManager() diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 402d41e..6f1add0 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -367,7 +367,7 @@ function install_begin_request($class_loader, &$install_state) { // Determine whether base system services are ready to operate. $install_state['config_verified'] = install_ensure_config_directory(CONFIG_ACTIVE_DIRECTORY) && install_ensure_config_directory(CONFIG_STAGING_DIRECTORY); - $install_state['database_verified'] = install_verify_database_settings($site_path); + $install_state['database_verified'] = install_verify_database_settings(); $install_state['settings_verified'] = $install_state['config_verified'] && $install_state['database_verified']; // Install factory tables only after checking the database. @@ -1077,17 +1077,11 @@ function install_verify_completed_task() { /** * Verifies that settings.php specifies a valid database connection. - * - * @param string $site_path - * The site path. - * - * @return bool - * TRUE if there are no database errors. */ -function install_verify_database_settings($site_path) { +function install_verify_database_settings() { if ($database = Database::getConnectionInfo()) { $database = $database['default']; - $settings_file = './' . $site_path . '/settings.php'; + $settings_file = './' . conf_path(FALSE) . '/settings.php'; $errors = install_database_errors($database, $settings_file); if (empty($errors)) { return TRUE; @@ -1908,9 +1902,8 @@ function install_check_translations($langcode, $server_pattern) { $readable = FALSE; $writable = FALSE; // @todo: Make this configurable. - $site_path = \Drupal::service('site.path'); - $files_directory = $site_path . '/files'; - $translations_directory = $site_path . '/files/translations'; + $files_directory = conf_path() . '/files'; + $translations_directory = conf_path() . '/files/translations'; $translations_directory_exists = FALSE; $translation_available = FALSE; $online = FALSE; @@ -2088,12 +2081,12 @@ function install_check_requirements($install_state) { foreach ($default_files as $default_file_info) { $readable = FALSE; $writable = FALSE; - $site_path = './' . \Drupal::service('site.path'); - $file = $site_path . "/{$default_file_info['file']}"; + $conf_path = './' . conf_path(FALSE); + $file = $conf_path . "/{$default_file_info['file']}"; $default_file = "./sites/default/{$default_file_info['file_default']}"; $exists = FALSE; // Verify that the directory exists. - if (drupal_verify_install_file($site_path, FILE_EXIST, 'dir')) { + if (drupal_verify_install_file($conf_path, FILE_EXIST, 'dir')) { if (drupal_verify_install_file($file, FILE_EXIST)) { // If it does, make sure it is writable. $readable = drupal_verify_install_file($file, FILE_READABLE); @@ -2118,7 +2111,7 @@ function install_check_requirements($install_state) { // Otherwise, if $file does not exist yet, we can try to copy // $default_file to create it. elseif (!$exists) { - $copied = drupal_verify_install_file($site_path, FILE_EXIST | FILE_WRITABLE, 'dir') && @copy($default_file, $file); + $copied = drupal_verify_install_file($conf_path, FILE_EXIST | FILE_WRITABLE, 'dir') && @copy($default_file, $file); if ($copied) { // If the new $file file has the same owner as $default_file this means // $default_file is owned by the webserver user. This is an inherent diff --git a/core/includes/install.inc b/core/includes/install.inc index 01d6166..6f7c8c7 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -197,7 +197,7 @@ function drupal_get_database_types() { */ function drupal_rewrite_settings($settings = array(), $settings_file = NULL) { if (!isset($settings_file)) { - $settings_file = \Drupal::service('site.path') . '/settings.php'; + $settings_file = conf_path(FALSE) . '/settings.php'; } // Build list of setting names and insert the values into the global namespace. $variable_names = array(); @@ -470,13 +470,13 @@ function drupal_install_config_directories() { $config_directories_hash = Crypt::randomBytesBase64(55); if (empty($config_directories[CONFIG_ACTIVE_DIRECTORY])) { $settings['config_directories'][CONFIG_ACTIVE_DIRECTORY] = (object) [ - 'value' => \Drupal::service('site.path') . '/files/config_' . $config_directories_hash . '/active', + 'value' => conf_path() . '/files/config_' . $config_directories_hash . '/active', 'required' => TRUE, ]; } if (empty($config_directories[CONFIG_STAGING_DIRECTORY])) { $settings['config_directories'][CONFIG_STAGING_DIRECTORY] = (object) [ - 'value' => \Drupal::service('site.path') . '/files/config_' . $config_directories_hash . '/staging', + 'value' => conf_path() . '/files/config_' . $config_directories_hash . '/staging', 'required' => TRUE, ]; } diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 121da17..fa83a1b 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1362,9 +1362,9 @@ function template_preprocess_page(&$variables) { // Move some variables to the top level for themer convenience and template cleanliness. $variables['title'] = $variables['page']['#title']; - foreach (\Drupal::theme()->getActiveTheme()->getRegions() as $region) { - if (!isset($variables['page'][$region])) { - $variables['page'][$region] = array(); + foreach (system_region_list(\Drupal::theme()->getActiveTheme()->getName()) as $region_key => $region_name) { + if (!isset($variables['page'][$region_key])) { + $variables['page'][$region_key] = array(); } } diff --git a/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php b/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php index a10d0e8..a5ef64d 100644 --- a/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php +++ b/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php @@ -33,12 +33,11 @@ class HWLDFWordAccumulator { protected function _flushGroup($new_tag) { if ($this->group !== '') { if ($this->tag == 'mark') { - $format_string = '@original_line@group'; + $this->line .= '' . SafeMarkup::checkPlain($this->group) . ''; } else { - $format_string = '@original_line@group'; + $this->line .= SafeMarkup::checkPlain($this->group); } - $this->line = SafeMarkup::format($format_string, ['@original_line' => $this->line, '@group' => $this->group]); } $this->group = ''; $this->tag = $new_tag; @@ -47,7 +46,9 @@ protected function _flushGroup($new_tag) { protected function _flushLine($new_tag) { $this->_flushGroup($new_tag); if ($this->line != '') { - array_push($this->lines, $this->line); + // @todo This is probably not the right place to do this. To be + // addressed in https://www.drupal.org/node/2280963. + array_push($this->lines, SafeMarkup::set($this->line)); } else { // make empty lines visible by inserting an NBSP diff --git a/core/lib/Drupal/Component/Utility/NestedArray.php b/core/lib/Drupal/Component/Utility/NestedArray.php index 8829fc8..e123b4a 100644 --- a/core/lib/Drupal/Component/Utility/NestedArray.php +++ b/core/lib/Drupal/Component/Utility/NestedArray.php @@ -42,7 +42,7 @@ class NestedArray { * $key_exists = NULL; * $value = NestedArray::getValue($form, $parents, $key_exists); * if ($key_exists) { - * // Do something with $value. + * // ... do something with $value ... * } * @endcode * diff --git a/core/lib/Drupal/Core/Action/ActionBase.php b/core/lib/Drupal/Core/Action/ActionBase.php index 9278deb..89e184a 100644 --- a/core/lib/Drupal/Core/Action/ActionBase.php +++ b/core/lib/Drupal/Core/Action/ActionBase.php @@ -8,6 +8,7 @@ namespace Drupal\Core\Action; use Drupal\Core\Plugin\PluginBase; +use Drupal\Core\Action\ActionInterface; /** * Provides a base implementation for an Action plugin. diff --git a/core/lib/Drupal/Core/Asset/CssOptimizer.php b/core/lib/Drupal/Core/Asset/CssOptimizer.php index 6e32fbd..4b96888 100644 --- a/core/lib/Drupal/Core/Asset/CssOptimizer.php +++ b/core/lib/Drupal/Core/Asset/CssOptimizer.php @@ -176,7 +176,8 @@ protected function loadNestedFile($matches) { $directory = $directory == '.' ? '' : $directory .'/'; // Alter all internal url() paths. Leave external paths alone. We don't need - // to normalize absolute paths here because that will be done later. + // to normalize absolute paths here (i.e. remove folder/... segments) + // because that will be done later. return preg_replace('/url\(\s*([\'"]?)(?![a-z]+:|\/+)([^\'")]+)([\'"]?)\s*\)/i', 'url(\1' . $directory . '\2\3)', $file); } diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php index e6a4376..1c08bc9 100644 --- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php @@ -213,7 +213,7 @@ public function buildByExtension($extension) { } /** - * Parses a given library file and allows modules and themes to alter it. + * Parses a given library file and allows module to alter it. * * This method sets the parsed information onto the library property. * diff --git a/core/lib/Drupal/Core/Cache/ApcuBackendFactory.php b/core/lib/Drupal/Core/Cache/ApcuBackendFactory.php index f744edc..97a201b 100644 --- a/core/lib/Drupal/Core/Cache/ApcuBackendFactory.php +++ b/core/lib/Drupal/Core/Cache/ApcuBackendFactory.php @@ -30,13 +30,11 @@ class ApcuBackendFactory implements CacheFactoryInterface { * * @param string $root * The app root. - * @param string $site_path - * The site path. * @param \Drupal\Core\Cache\CacheTagsChecksumInterface $checksum_provider * The cache tags checksum provider. */ - public function __construct($root, $site_path, CacheTagsChecksumInterface $checksum_provider) { - $this->sitePrefix = Settings::getApcuPrefix('apcu_backend', $root, $site_path); + public function __construct($root, CacheTagsChecksumInterface $checksum_provider) { + $this->sitePrefix = Settings::getApcuPrefix('apcu_backend', $root, conf_path()); $this->checksumProvider = $checksum_provider; } diff --git a/core/lib/Drupal/Core/Command/DbDumpApplication.php b/core/lib/Drupal/Core/Command/DbDumpApplication.php deleted file mode 100644 index 080e20f..0000000 --- a/core/lib/Drupal/Core/Command/DbDumpApplication.php +++ /dev/null @@ -1,78 +0,0 @@ -connection = $connection; - $this->moduleHandler = $module_handler; - parent::__construct(); - } - - /** - * {@inheritdoc} - */ - protected function getCommandName(InputInterface $input) { - return 'dump-database-d8-mysql'; - } - - /** - * {@inheritdoc} - */ - protected function getDefaultCommands() { - // Even though this is a single command, keep the HelpCommand (--help). - $default_commands = parent::getDefaultCommands(); - $default_commands[] = new DbDumpCommand($this->connection, $this->moduleHandler); - return $default_commands; - } - - /** - * {@inheritdoc} - * - * Overridden so the application doesn't expect the command name as the first - * argument. - */ - public function getDefinition() { - $definition = parent::getDefinition(); - // Clears the normal first argument (the command name). - $definition->setArguments(); - return $definition; - } - -} diff --git a/core/lib/Drupal/Core/Command/DbDumpCommand.php b/core/lib/Drupal/Core/Command/DbDumpCommand.php deleted file mode 100644 index d71bb37..0000000 --- a/core/lib/Drupal/Core/Command/DbDumpCommand.php +++ /dev/null @@ -1,434 +0,0 @@ -databaseType() !== 'mysql') { - throw new \RuntimeException('This script can only be used with MySQL database backends.'); - } - - $this->connection = $connection; - $this->moduleHandler = $module_handler; - parent::__construct(); - } - - /** - * {@inheritdoc} - */ - protected function configure() { - $this->setName('dump-database-d8-mysql') - ->setDescription('Dump the current database to a generation script'); - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) { - // If not explicitly set, disable ANSI which will break generated php. - if ($input->hasParameterOption(['--ansi']) !== TRUE) { - $output->setDecorated(FALSE); - } - - $output->writeln($this->generateScript()); - } - - /** - * Generates the database script. - * - * @return string - * The PHP script. - */ - protected function generateScript() { - $tables = ''; - foreach ($this->getTables() as $table) { - $schema = $this->getTableSchema($table); - $data = $this->getTableData($table); - $tables .= $this->getTableScript($table, $schema, $data); - } - $script = $this->getTemplate(); - // Substitute in the tables. - $script = str_replace('{{TABLES}}', trim($tables), $script); - // Modules. - $script = str_replace('{{MODULES}}', $this->getModulesScript(), $script); - return trim($script); - } - - /** - * Returns a list of tables, not including those set to be excluded. - * - * @return array - * An array of table names. - */ - protected function getTables() { - $pattern = $this->connection->tablePrefix() . '%'; - $tables = array_values($this->connection->schema()->findTables($pattern)); - foreach ($tables as $key => $table) { - // The prefix is removed for the resultant script. - $table = $tables[$key] = str_replace($this->connection->tablePrefix(), '', $table); - - // Remove any explicitly excluded tables. - foreach ($this->excludeTables as $pattern) { - if (preg_match('/^' . $pattern . '$/', $table)) { - unset($tables[$key]); - } - } - } - return $tables; - } - - /** - * Returns a schema array for a given table. - * - * @param string $table - * The table name. - * - * @return array - * A schema array (as defined by hook_schema()). - * - * @todo This implementation is hard-coded for MySQL. - */ - protected function getTableSchema($table) { - $query = $this->connection->query("SHOW FULL COLUMNS FROM {" . $table . "}"); - $definition = []; - while (($row = $query->fetchAssoc()) !== FALSE) { - $name = $row['Field']; - // Parse out the field type and meta information. - preg_match('@([a-z]+)(?:\((\d+)(?:,(\d+))?\))?\s*(unsigned)?@', $row['Type'], $matches); - $type = $this->fieldTypeMap($matches[1]); - if ($row['Extra'] === 'auto_increment') { - // If this is an auto increment, then the type is 'serial'. - $type = 'serial'; - } - $definition['fields'][$name] = [ - 'type' => $type, - 'not null' => $row['Null'] === 'NO', - ]; - if ($size = $this->fieldSizeMap($matches[1])) { - $definition['fields'][$name]['size'] = $size; - } - if (isset($matches[2]) && $type === 'numeric') { - // Add precision and scale. - $definition['fields'][$name]['precision'] = $matches[2]; - $definition['fields'][$name]['scale'] = $matches[3]; - } - elseif ($type === 'time' || $type === 'datetime') { - // @todo Core doesn't support these, but copied from `migrate-db.sh` for now. - // Convert to varchar. - $definition['fields'][$name]['type'] = 'varchar'; - $definition['fields'][$name]['length'] = '100'; - } - elseif (!isset($definition['fields'][$name]['size'])) { - // Try use the provided length, if it doesn't exist default to 100. It's - // not great but good enough for our dumps at this point. - $definition['fields'][$name]['length'] = isset($matches[2]) ? $matches[2] : 100; - } - - if (isset($row['Default'])) { - $definition['fields'][$name]['default'] = $row['Default']; - } - - if (isset($matches[4])) { - $definition['fields'][$name]['unsigned'] = TRUE; - } - - // Check for the 'varchar_ascii' type that should be 'binary'. - if (isset($row['Collation']) && $row['Collation'] == 'ascii_bin') { - $definition['fields'][$name]['type'] = 'varchar_ascii'; - $definition['fields'][$name]['binary'] = TRUE; - } - - // Check for the non-binary 'varchar_ascii'. - if (isset($row['Collation']) && $row['Collation'] == 'ascii_general_ci') { - $definition['fields'][$name]['type'] = 'varchar_ascii'; - } - - // Check for the 'utf8_bin' collation. - if (isset($row['Collation']) && $row['Collation'] == 'utf8_bin') { - $definition['fields'][$name]['binary'] = TRUE; - } - } - - // Set primary key, unique keys, and indexes. - $this->getTableIndexes($table, $definition); - - return $definition; - } - - /** - * Adds primary key, unique keys, and index information to the schema. - * - * @param string $table - * The table to find indexes for. - * @param array &$definition - * The schema definition to modify. - */ - protected function getTableIndexes($table, &$definition) { - // Note, this query doesn't support ordering, so that is worked around - // below by keying the array on Seq_in_index. - $query = $this->connection->query("SHOW INDEX FROM {" . $table . "}"); - $indexes = []; - while (($row = $query->fetchAssoc()) !== FALSE) { - $index_name = $row['Key_name']; - $column = $row['Column_name']; - // Key the arrays by the index sequence for proper ordering (start at 0). - $order = $row['Seq_in_index'] - 1; - - // If specified, add length to the index. - if ($row['Sub_part']) { - $column = [$column, $row['Sub_part']]; - } - - if ($index_name === 'PRIMARY') { - $definition['primary key'][$order] = $column; - } - elseif ($row['Non_unique'] == 0) { - $definition['unique keys'][$index_name][$order] = $column; - } - else { - $definition['indexes'][$index_name][$order] = $column; - } - } - } - - /** - * Gets all data from a given table. - * - * If a table is set to be schema only, and empty array is returned. - * - * @param string $table - * The table to query. - * - * @return array - * The data from the table as an array. - */ - protected function getTableData($table) { - // Check for schema only. - foreach ($this->schemaOnly as $schema_only) { - if (preg_match('/^' . $schema_only . '$/', $table)) { - return []; - } - } - $order = $this->getFieldOrder($table); - $query = $this->connection->query("SELECT * FROM {" . $table . "} " . $order ); - $results = []; - while (($row = $query->fetchAssoc()) !== FALSE) { - $results[] = $row; - } - return $results; - } - - /** - * Given a database field type, return a Drupal type. - * - * @param string $type - * The MySQL field type. - * - * @return string - * The Drupal schema field type. If there is no mapping, the original field - * type is returned. - */ - protected function fieldTypeMap($type) { - // Convert everything to lowercase. - $map = array_map('strtolower', $this->connection->schema()->getFieldTypeMap()); - $map = array_flip($map); - - // The MySql map contains type:size. Remove the size part. - return isset($map[$type]) ? explode(':', $map[$type])[0] : $type; - } - - /** - * Given a database field type, return a Drupal size. - * - * @param string $type - * The MySQL field type. - * - * @return string - * The Drupal schema field size. - */ - protected function fieldSizeMap($type) { - // Convert everything to lowercase. - $map = array_map('strtolower', $this->connection->schema()->getFieldTypeMap()); - $map = array_flip($map); - - $schema_type = explode(':', $map[$type])[0]; - // Only specify size on these types. - if (in_array($schema_type, ['blob', 'float', 'int', 'text'])) { - // The MySql map contains type:size. Remove the type part. - return explode(':', $map[$type])[1]; - } - } - - /** - * Gets field ordering for a given table. - * - * @param string $table - * The table name. - * - * @return string - * The order string to append to the query. - */ - protected function getFieldOrder($table) { - // @todo this is MySQL only since there are no Database API functions for - // table column data. - // @todo this code is duplicated in `core/scripts/migrate-db.sh`. - $connection_info = $this->connection->getConnectionOptions(); - // Order by primary keys. - $order = ''; - $query = "SELECT `COLUMN_NAME` FROM `information_schema`.`COLUMNS` - WHERE (`TABLE_SCHEMA` = '" . $connection_info['database'] . "') - AND (`TABLE_NAME` = '{" . $table . "}') AND (`COLUMN_KEY` = 'PRI') - ORDER BY COLUMN_NAME"; - $results = $this->connection->query($query); - while (($row = $results->fetchAssoc()) !== FALSE) { - $order .= $row['COLUMN_NAME'] . ', '; - } - if (!empty($order)) { - $order = ' ORDER BY ' . rtrim($order, ', '); - } - return $order; - } - - /** - * The script template. - * - * @return string - * The template for the generated PHP script. - */ - protected function getTemplate() { - $script = <<<'ENDOFSCRIPT' -schema()->createTable('" . $table . "', " . Variable::export($schema) . ");\n\n"; - if (!empty($data)) { - $insert = ''; - foreach ($data as $record) { - $insert .= "->values(" . Variable::export($record) . ")\n"; - } - $output .= "\$connection->insert('" . $table . "')\n" - . "->fields(" . Variable::export(array_keys($schema['fields'])) . ")\n" - . $insert - . "->execute();\n\n"; - } - return $output; - } - - /** - * List of modules enabled for insertion into the script docblock. - * - * @return string - * The formatted list of enabled modules. - */ - protected function getModulesScript() { - $output = ''; - $modules = $this->moduleHandler->getModuleList(); - ksort($modules); - foreach ($modules as $module => $filename) { - $output .= " * - $module\n"; - } - return rtrim($output, "\n"); - } - -} diff --git a/core/lib/Drupal/Core/Condition/ConditionPluginBase.php b/core/lib/Drupal/Core/Condition/ConditionPluginBase.php index 5237d0d..4b4a07b 100644 --- a/core/lib/Drupal/Core/Condition/ConditionPluginBase.php +++ b/core/lib/Drupal/Core/Condition/ConditionPluginBase.php @@ -7,7 +7,6 @@ namespace Drupal\Core\Condition; -use Drupal\Core\Executable\ExecutableManagerInterface; use Drupal\Core\Executable\ExecutablePluginBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContextAwarePluginAssignmentTrait; @@ -26,13 +25,6 @@ use ContextAwarePluginAssignmentTrait; /** - * The condition manager to proxy execute calls through. - * - * @var \Drupal\Core\Executable\ExecutableInterface - */ - protected $executableManager; - - /** * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, $plugin_definition) { @@ -115,12 +107,4 @@ public function calculateDependencies() { return array(); } - /** - * {@inheritdoc} - */ - public function setExecutableManager(ExecutableManagerInterface $executableManager) { - $this->executableManager = $executableManager; - return $this; - } - } diff --git a/core/lib/Drupal/Core/Config/ConfigImporter.php b/core/lib/Drupal/Core/Config/ConfigImporter.php index ed50735..bae7618 100644 --- a/core/lib/Drupal/Core/Config/ConfigImporter.php +++ b/core/lib/Drupal/Core/Config/ConfigImporter.php @@ -755,7 +755,7 @@ protected function validate() { protected function processConfiguration($collection, $op, $name) { try { $processed = FALSE; - if ($collection == StorageInterface::DEFAULT_COLLECTION) { + if ($this->configManager->supportsConfigurationEntities($collection)) { $processed = $this->importInvokeOwner($collection, $op, $name); } if (!$processed) { diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php index 929731b..0ac79c0 100644 --- a/core/lib/Drupal/Core/Config/ConfigInstaller.php +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php @@ -175,39 +175,49 @@ public function installOptionalConfig(StorageInterface $storage = NULL, $depende $profile_storage = NULL; } + $collection_info = $this->configManager->getConfigCollectionInfo(); $enabled_extensions = $this->getEnabledExtensions(); - $existing_config = $this->getActiveStorages()->listAll(); - $list = array_filter($storage->listAll(), function($config_name) use ($existing_config) { - // Only list configuration that: - // - does not already exist - // - is a configuration entity (this also excludes config that has an - // implicit dependency on modules that are not yet installed) - return !in_array($config_name, $existing_config) && $this->configManager->getEntityTypeIdByName($config_name); - }); - - $all_config = array_merge($existing_config, $list); - $config_to_create = $storage->readMultiple($list); - // Check to see if the corresponding override storage has any overrides. - if ($profile_storage) { - $config_to_create = $profile_storage->readMultiple($list) + $config_to_create; - } - foreach ($config_to_create as $config_name => $data) { - // Exclude configuration where its dependencies cannot be met. - if (!$this->validateDependencies($config_name, $data, $enabled_extensions, $all_config)) { - unset($config_to_create[$config_name]); + foreach ($collection_info->getCollectionNames() as $collection) { + if (!$this->configManager->supportsConfigurationEntities($collection)) { + continue; } - // Exclude configuration that does not have a matching dependency. - elseif (!empty($dependency)) { - // Create a light weight dependency object to check dependencies. - $config_entity = new ConfigEntityDependency($config_name, $data); - if (!$config_entity->hasDependency(key($dependency), reset($dependency))) { + $existing_config = $this->getActiveStorages($collection)->listAll(); + + $list = array_filter($storage->listAll(), function($config_name) use ($existing_config) { + // Only list configuration that: + // - does not already exist + // - is a configuration entity (this also excludes config that has an + // implicit dependency on modules that are not yet installed) + return !in_array($config_name, $existing_config) && $this->configManager->getEntityTypeIdByName($config_name); + }); + + $all_config = array_merge($existing_config, $list); + $config_to_create = $storage->readMultiple($list); + // Check to see if the corresponding override storage has any overrides. + if ($profile_storage) { + if ($profile_storage->getCollectionName() != $collection) { + $profile_storage = $profile_storage->createCollection($collection); + } + $config_to_create = $profile_storage->readMultiple($list) + $config_to_create; + } + foreach ($config_to_create as $config_name => $data) { + // Exclude configuration where its dependencies cannot be met. + if (!$this->validateDependencies($config_name, $data, $enabled_extensions, $all_config)) { unset($config_to_create[$config_name]); } + // Exclude configuration that does not have a matching dependency. + elseif (!empty($dependency)) { + // Create a light weight dependency object to check dependencies. + $config_entity = new ConfigEntityDependency($config_name, $data); + if (!$config_entity->hasDependency(key($dependency), reset($dependency))) { + unset($config_to_create[$config_name]); + } + } + } + if (!empty($config_to_create)) { + $this->createConfiguration($collection, $config_to_create, TRUE); } - } - if (!empty($config_to_create)) { - $this->createConfiguration(StorageInterface::DEFAULT_COLLECTION, $config_to_create, TRUE); } } @@ -251,7 +261,8 @@ protected function getConfigToCreate(StorageInterface $storage, $collection, $pr */ protected function createConfiguration($collection, array $config_to_create) { // Order the configuration to install in the order of dependencies. - if ($collection == StorageInterface::DEFAULT_COLLECTION) { + $config_entity_support = $this->configManager->supportsConfigurationEntities($collection); + if ($config_entity_support) { $dependency_manager = new ConfigDependencyManager(); $config_names = $dependency_manager ->setData($config_to_create) @@ -274,7 +285,7 @@ protected function createConfiguration($collection, array $config_to_create) { if ($config_to_create[$name] !== FALSE) { $new_config->setData($config_to_create[$name]); } - if ($collection == StorageInterface::DEFAULT_COLLECTION && $entity_type = $this->configManager->getEntityTypeIdByName($name)) { + if ($config_entity_support && $entity_type = $this->configManager->getEntityTypeIdByName($name)) { // If we are syncing do not create configuration entities. Pluggable // configuration entities can have dependencies on modules that are // not yet enabled. This approach means that any code that expects diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php index fb8f658..c70dd4c 100644 --- a/core/lib/Drupal/Core/Config/ConfigManager.php +++ b/core/lib/Drupal/Core/Config/ConfigManager.php @@ -355,6 +355,13 @@ public function getConfigEntitiesToChangeOnDependencyRemoval($type, array $names /** * {@inheritdoc} */ + public function supportsConfigurationEntities($collection) { + return $collection == StorageInterface::DEFAULT_COLLECTION; + } + + /** + * {@inheritdoc} + */ public function getConfigCollectionInfo() { if (!isset($this->configCollectionInfo)) { $this->configCollectionInfo = new ConfigCollectionInfo(); diff --git a/core/lib/Drupal/Core/Config/ConfigManagerInterface.php b/core/lib/Drupal/Core/Config/ConfigManagerInterface.php index d908e3f..7da86f7 100644 --- a/core/lib/Drupal/Core/Config/ConfigManagerInterface.php +++ b/core/lib/Drupal/Core/Config/ConfigManagerInterface.php @@ -162,6 +162,17 @@ public function findConfigEntityDependentsAsEntities($type, array $names); public function getConfigEntitiesToChangeOnDependencyRemoval($type, array $names, $dry_run = TRUE); /** + * Determines if the provided collection supports configuration entities. + * + * @param string $collection + * The collection to check. + * + * @return bool + * TRUE if the collection support configuration entities, FALSE if not. + */ + public function supportsConfigurationEntities($collection); + + /** * Gets available collection information using the event system. * * @return \Drupal\Core\Config\ConfigCollectionInfo diff --git a/core/lib/Drupal/Core/Config/StorageComparer.php b/core/lib/Drupal/Core/Config/StorageComparer.php index 2e61f96..7b3b3d4 100644 --- a/core/lib/Drupal/Core/Config/StorageComparer.php +++ b/core/lib/Drupal/Core/Config/StorageComparer.php @@ -212,7 +212,7 @@ public function createChangelist() { $this->addChangelistUpdate($collection); $this->addChangelistDelete($collection); // Only collections that support configuration entities can have renames. - if ($collection == StorageInterface::DEFAULT_COLLECTION) { + if ($this->configManager->supportsConfigurationEntities($collection)) { $this->addChangelistRename($collection); } } @@ -415,7 +415,7 @@ protected function getAndSortConfigData($collection) { $source_data = $source_storage->readMultiple($source_names); // If the collection only supports simple configuration do not use // configuration dependencies. - if ($collection == StorageInterface::DEFAULT_COLLECTION) { + if ($this->configManager->supportsConfigurationEntities($collection)) { $dependency_manager = new ConfigDependencyManager(); $this->targetNames[$collection] = $dependency_manager->setData($target_data)->sortAll(); $this->sourceNames[$collection] = $dependency_manager->setData($source_data)->sortAll(); diff --git a/core/lib/Drupal/Core/ContentNegotiation.php b/core/lib/Drupal/Core/ContentNegotiation.php index 1074b81..e45c92d 100644 --- a/core/lib/Drupal/Core/ContentNegotiation.php +++ b/core/lib/Drupal/Core/ContentNegotiation.php @@ -10,7 +10,10 @@ use Symfony\Component\HttpFoundation\Request; /** - * Provides content negotation based upon query parameters. + * This class is a central library for content type negotiation. + * + * @todo Replace this class with a real content negotiation library based on + * mod_negotiation. Development of that is a work in progress. */ class ContentNegotiation { @@ -33,8 +36,21 @@ public function getContentType(Request $request) { return 'iframeupload'; } - if ($request->query->has('_format')) { - return $request->query->get('_format'); + // Check all formats, if priority format is found return it. + $first_found_format = FALSE; + foreach ($request->getAcceptableContentTypes() as $mime_type) { + $format = $request->getFormat($mime_type); + if ($format === 'html') { + return $format; + } + if (!is_null($format) && !$first_found_format) { + $first_found_format = $format; + } + } + + // No HTML found, return first found. + if ($first_found_format) { + return $first_found_format; } if ($request->isXmlHttpRequest()) { diff --git a/core/lib/Drupal/Core/Database/Driver/fake/ConditionResolver.php b/core/lib/Drupal/Core/Database/Driver/fake/ConditionResolver.php new file mode 100644 index 0000000..ea69504 --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/ConditionResolver.php @@ -0,0 +1,94 @@ +conditions(); + $and = $conditions['#conjunction'] == 'AND'; + unset($conditions['#conjunction']); + $match = TRUE; + foreach ($conditions as $condition) { + $match = $condition['field'] instanceof Condition ? static::matchGroup($row, $condition['field']) : static::matchSingle($row, $condition); + // For AND, finish matching on the first fail. For OR, finish on first + // success. + if ($and != $match) { + break; + } + } + return $match; + } + + /** + * Match a single row and its condition. + * + * @param \Drupal\migrate\tests\DatabaseRowInterface $row + * The row to match. + * + * @param array $condition + * An array representing a single condition. + * + * @return bool + * TRUE if the condition matches. + * + * @throws \Exception + */ + protected static function matchSingle(DatabaseRowInterface $row, array $condition) { + $row_value = $row->getValue($condition['field']); + switch ($condition['operator']) { + case '=': + return $row_value == $condition['value']; + + case '<=': + return $row_value <= $condition['value']; + + case '>=': + return $row_value >= $condition['value']; + + case '!=': + return $row_value != $condition['value']; + + case '<>': + return $row_value != $condition['value']; + + case '<': + return $row_value < $condition['value']; + + case '>': + return $row_value > $condition['value']; + + case 'IN': + return in_array($row_value, $condition['value']); + + case 'IS NULL': + return !isset($row_value); + + case 'IS NOT NULL': + return isset($row_value); + + default: + throw new \Exception(sprintf('operator %s is not supported', $condition['operator'])); + } + } + +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRow.php b/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRow.php new file mode 100644 index 0000000..ca98582 --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRow.php @@ -0,0 +1,29 @@ +row = $row; + } + + /** + * {@inheritdoc} + */ + public function getValue($field) { + return $this->row[$field]; + } + +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRowInterface.php b/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRowInterface.php new file mode 100644 index 0000000..9aa3965 --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRowInterface.php @@ -0,0 +1,22 @@ +fieldsWithTable = $fields_with_table; + $this->fields = $fields; + parent::__construct($row); + } + + /** + * {@inheritdoc} + */ + public function getValue($field) { + $field_info = isset($this->fieldsWithTable[$field]) ? $this->fieldsWithTable[$field] : $this->fields[$field]; + if (array_key_exists($field_info['field'], $this->row[$field_info['table']]['result'])) { + $index = 'result'; + } + else { + $index = 'all'; + } + return $this->row[$field_info['table']][$index][$field_info['field']]; + } + +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeConnection.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeConnection.php new file mode 100644 index 0000000..1be5147 --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeConnection.php @@ -0,0 +1,167 @@ +databaseContents = $database_contents; + $this->connectionOptions = $connection_options; + $this->tablePrefix = $prefix; + } + + /** + * {@inheritdoc} + */ + public function getConnectionOptions() { + return $this->connectionOptions; + } + + /** + * {@inheritdoc} + */ + public function tablePrefix($table = 'default') { + return $this->tablePrefix; + } + + /** + * {@inheritdoc} + */ + public function select($table, $alias = NULL, array $options = array()) { + return new FakeSelect($this->databaseContents, $table, $alias); + } + + /** + * {@inheritdoc} + */ + public function insert($table, array $options = array()) { + return new FakeInsert($this->databaseContents, $table); + } + + /** + * {@inheritdoc} + */ + public function merge($table, array $options = array()) { + return new FakeMerge($this->databaseContents, $table); + } + + /** + * {@inheritdoc} + */ + public function update($table, array $options = array()) { + return new FakeUpdate($this->databaseContents, $table); + } + + /** + * {@inheritdoc} + */ + public function delete($table, array $options = array()) { + return new FakeDelete($this->databaseContents, $table); + } + + /** + * {@inheritdoc} + */ + public function truncate($table, array $options = array()) { + return new FakeTruncate($this->databaseContents, $table); + } + + /** + * {@inheritdoc} + */ + public function schema() { + return new FakeDatabaseSchema($this->databaseContents); + } + + /** + * {@inheritdoc} + */ + public function query($query, array $args = array(), $options = array()) { + throw new \Exception('Method not supported'); + } + + /** + * {@inheritdoc} + */ + public function queryRange($query, $from, $count, array $args = array(), array $options = array()) { + throw new \Exception('Method not supported'); + } + + /** + * {@inheritdoc} + */ + public function queryTemporary($query, array $args = array(), array $options = array()) { + throw new \Exception('Method not supported'); + } + + /** + * {@inheritdoc} + */ + public function driver() { + throw new \Exception('Method not supported'); + } + + /** + * {@inheritdoc} + */ + public function databaseType() { + throw new \Exception('Method not supported'); + } + + /** + * {@inheritdoc} + */ + public function createDatabase($database) { + // There is nothing to do. + } + + /** + * {@inheritdoc} + */ + public function mapConditionOperator($operator) { + throw new \Exception('Method not supported'); + } + + /** + * {@inheritdoc} + */ + public function nextId($existing_id = 0) { + throw new \Exception('Method not supported'); + } + +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeDatabaseSchema.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeDatabaseSchema.php new file mode 100644 index 0000000..d3e9161 --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeDatabaseSchema.php @@ -0,0 +1,230 @@ +uniqueIdentifier = uniqid('', TRUE); + + // @todo Maybe we can generate an internal representation. + $this->databaseContents = &$database_contents; + } + + /** + * {@inheritdoc} + */ + public function tableExists($table) { + return in_array($table, array_keys($this->databaseContents)); + } + + /** + * {@inheritdoc} + */ + public function prefixNonTable($table) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + protected function getPrefixInfo($table = 'default', $add_prefix = TRUE) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function addField($table, $field, $spec, $keys_new = array()) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function addIndex($table, $name, $fields) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function addPrimaryKey($table, $fields) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function addUniqueKey($table, $name, $fields) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function changeField($table, $field, $field_new, $spec, $keys_new = array()) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * PHP magic __clone() method. + */ + public function __clone() { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function createTable($name, $table) { + #throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function dropField($table, $field) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function dropIndex($table, $name) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function dropPrimaryKey($table) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function dropTable($table) { + unset($this->databaseContents[$table]); + } + + /** + * {@inheritdoc} + */ + public function dropUniqueKey($table, $name) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function fieldExists($table, $column) { + if (!empty($this->databaseContents[$table])) { + $row = reset($this->databaseContents[$table]); + return isset($row[$column]); + } + else { + throw new \Exception("Can't determine whether field exists with an empty / nonexistent table."); + } + } + + /** + * {@inheritdoc} + */ + public function fieldNames($fields) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function fieldSetDefault($table, $field, $default) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function fieldSetNoDefault($table, $field) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function findTables($table_expression) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function getFieldTypeMap() { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function indexExists($table, $name) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function nextPlaceholder() { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function prepareComment($comment, $length = NULL) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function renameTable($table, $new_name) { + throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function uniqueIdentifier() { + return $this->uniqueIdentifier; + } + +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeDelete.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeDelete.php new file mode 100644 index 0000000..4a75bfb --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeDelete.php @@ -0,0 +1,79 @@ +databaseContents = &$database_contents; + $this->table = $table; + $this->condition = new Condition('AND'); + } + + /** + * {@inheritdoc} + */ + public function execute() { + $affected = 0; + if (isset($this->databaseContents[$this->table])) { + $original_row_count = count($this->databaseContents[$this->table]); + $condition = $this->condition; + $this->databaseContents[$this->table] = array_filter($this->databaseContents[$this->table], function ($row_array) use ($condition) { + $row = new DatabaseRow($row_array); + return !ConditionResolver::matchGroup($row, $condition); + }); + $affected = $original_row_count - count($this->databaseContents[$this->table]); + } + return $affected; + } + + /** + * {@inheritdoc} + */ + public function exists(SelectInterface $select) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function where($snippet, $args = array()) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeInsert.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeInsert.php new file mode 100644 index 0000000..9d7012b --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeInsert.php @@ -0,0 +1,71 @@ +databaseContents = &$database_contents; + $this->table = $table; + } + + /** + * {@inheritdoc} + */ + public function useDefaults(array $fields) { + throw new \Exception('This method is not supported'); + } + + /** + * {@inheritdoc} + */ + public function from(SelectInterface $query) { + throw new \Exception('This method is not supported'); + } + + /** + * {@inheritdoc} + */ + public function execute() { + foreach ($this->insertValues as $values) { + $this->databaseContents[$this->table][] = array_combine($this->insertFields, $values); + } + } + +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeMerge.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeMerge.php new file mode 100644 index 0000000..dd3117e --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeMerge.php @@ -0,0 +1,61 @@ +databaseContents = &$database_contents; + $this->table = $table; + $this->conditionTable = $table; + $this->condition = new Condition('AND'); + } + + /** + * {@inheritdoc} + */ + public function execute() { + if (!count($this->condition)) { + throw new InvalidMergeQueryException(t('Invalid merge query: no conditions')); + } + $select = new FakeSelect($this->databaseContents, $this->conditionTable, 'c'); + $count = $select + ->condition($this->condition) + ->countQuery() + ->execute() + ->fetchField(); + if ($count) { + $update = new FakeUpdate($this->databaseContents, $this->table); + $update + ->fields($this->updateFields) + ->condition($this->condition) + ->execute(); + return self::STATUS_UPDATE; + } + $insert = new FakeInsert($this->databaseContents, $this->table); + $insert->fields($this->insertFields)->execute(); + return self::STATUS_INSERT; + } + +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeSelect.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeSelect.php new file mode 100644 index 0000000..9a95a6e --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeSelect.php @@ -0,0 +1,529 @@ + array( + * array( + * 'uid' => 1, + * 'name' => 'admin', + * ), + * array( + * 'uid' => 2, + * 'name' => 'alice', + * ), + * ), + * 'node' => array( + * array( + * 'nid' => 1, + * ) + * ) + * ) + * @endcode + * + * @var array + */ + protected $databaseContents; + + protected $countQuery = FALSE; + protected $fieldsWithTable = array(); + + /** + * Constructs a new FakeSelect. + * + * @param array $database_contents + * An array of mocked database content. + * @param string $table + * The base table name used within fake select. + * @param string $alias + * The base table alias used within fake select. + * @param string $conjunction + * The operator to use to combine conditions: 'AND' or 'OR'. + */ + public function __construct(array $database_contents, $table, $alias, $conjunction = 'AND') { + $this->databaseContents = $database_contents; + $this->addJoin(NULL, $table, $alias); + $this->where = new Condition($conjunction); + $this->having = new Condition($conjunction); + } + + /** + * {@inheritdoc} + */ + public function leftJoin($table, $alias = NULL, $condition = NULL, $arguments = array()) { + return $this->addJoin('LEFT', $table, $alias, $condition, $arguments); + } + + /** + * {@inheritdoc} + */ + public function addJoin($type, $table, $alias = NULL, $condition = NULL, $arguments = array()) { + if ($table instanceof SelectInterface) { + // @todo implement this. + throw new \Exception('Subqueries are not supported at this moment.'); + } + $alias = parent::addJoin($type, $table, $alias, $condition, $arguments); + if (isset($type)) { + if ($type != 'INNER' && $type != 'LEFT') { + throw new \Exception(sprintf('%s type not supported, only INNER and LEFT.', $type)); + } + if (!preg_match('/^(\w+\.)?(\w+)\s*=\s*(\w+)\.(\w+)$/', $condition, $matches)) { + throw new \Exception('Only x.field1 = y.field2 conditions are supported.' . $condition); + } + if (!$matches[1] && count($this->tables) == 2) { + $aliases = array_keys($this->tables); + $matches[1] = $aliases[0]; + } + else { + $matches[1] = substr($matches[1], 0, -1); + } + if (!$matches[1]) { + throw new \Exception('Only x.field1 = y.field2 conditions are supported.' . $condition); + } + if ($matches[1] == $alias) { + $this->tables[$alias] += array( + 'added_field' => $matches[2], + 'original_table_alias' => $matches[3], + 'original_field' => $matches[4], + ); + } + elseif ($matches[3] == $alias) { + $this->tables[$alias] += array( + 'added_field' => $matches[4], + 'original_table_alias' => $matches[1], + 'original_field' => $matches[2], + ); + } + else { + throw new \Exception('The JOIN condition does not contain the alias of the joined table.'); + } + } + return $alias; + } + + /** + * {@inheritdoc} + */ + public function execute() { + // @todo: Implement distinct() handling. + + // Single table count queries often do not contain fields which this class + // does not support otherwise, so add a shortcut. + if (count($this->tables) == 1 && $this->countQuery) { + $table_info = reset($this->tables); + $where = $this->where; + if (!empty($this->databaseContents[$table_info['table']])) { + $results = array_filter($this->databaseContents[$table_info['table']], function ($row_array) use ($where) { + return ConditionResolver::matchGroup(new DatabaseRow($row_array), $where); + }); + } + else { + $results = array(); + } + } + else { + $all_rows = $this->executeJoins(); + $all_rows = $this->resolveConditions($this->where, $all_rows); + if (!empty($this->order)) { + usort($all_rows, array($this, 'sortCallback')); + } + // Now flatten the rows so that each row becomes a field alias => value + // array. + $results = array(); + foreach ($all_rows as $table_rows) { + $result_row = array(); + foreach ($table_rows as $row) { + $result_row += $row['result']; + } + $results[] = $result_row; + } + } + if (!empty($this->range)) { + $results = array_slice($results, $this->range['start'], $this->range['length']); + } + if ($this->countQuery) { + $results = array(array(count($results))); + } + return new FakeStatement($results); + } + + /** + * Create an initial result set by executing the joins and picking fields. + * + * @return array + * A multidimensional array, the first key are table aliases, the second + * are field aliases, the values are the database contents or NULL in case + * of JOINs. + */ + protected function executeJoins() { + $fields = array(); + foreach ($this->fields as $field_info) { + $this->fieldsWithTable[$field_info['table'] . '.' . $field_info['field']] = $field_info; + $fields[$field_info['table']][$field_info['field']] = $field_info['alias']; + } + foreach ($this->tables as $alias => $table_info) { + if ($table = reset($this->databaseContents[$table_info['table']])) { + foreach (array_keys($table) as $field) { + if (!isset($this->fields[$field])) { + $this->fieldsWithTable[$field] = array( + 'table' => $alias, + 'field' => $field, + ); + $this->fieldsWithTable["$alias.$field"] = array( + 'table' => $alias, + 'field' => $field, + ); + } + } + } + } + // This will contain a multiple dimensional array. The first key will be a + // table alias, the second either result or all, the third will be a field + // alias. all contains every field in the table with the original field + // names while result contains only the fields requested. This allows for + // filtering on fields that were not added via addField(). + $results = array(); + foreach ($this->tables as $table_alias => $table_info) { + // The base table for this query. + if (empty($table_info['join type'])) { + foreach ($this->databaseContents[$table_info['table']] as $candidate_row) { + $results[] = $this->getNewRow($table_alias, $fields, $candidate_row); + } + } + else { + $new_rows = array(); + + // Dynamically build a set of joined rows. Check existing rows and see + // if they can be joined with incoming rows. + foreach ($results as $row) { + $joined = FALSE; + foreach ($this->databaseContents[$table_info['table']] as $candidate_row) { + if ($row[$table_info['original_table_alias']]['result'][$table_info['original_field']] == $candidate_row[$table_info['added_field']]) { + $joined = TRUE; + $new_rows[] = $this->getNewRow($table_alias, $fields, $candidate_row, $row); + } + } + if (!$joined && $table_info['join type'] == 'LEFT') { + // Because PHP doesn't scope their foreach statements, + // $candidate_row may contain the last value assigned to it from the + // previous statement. + // @TODO: empty tables? Those are a problem. + $keys = array_keys($candidate_row); + $values = array_fill(0, count($keys), NULL); + $new_row = array( + 'result' => $fields[$table_alias], + 'all' => array_combine($keys, $values), + ); + $new_rows[] = array($table_alias => $new_row) + $row; + } + } + $results = $new_rows; + } + } + return $results; + } + + /** + * Retrieves a new row. + * + * @param string $table_alias + * @param array $fields + * @param array $candidate_row + * @param array $row + * + * @return array + */ + protected function getNewRow($table_alias, $fields, $candidate_row, $row = array()) { + $new_row[$table_alias]['all'] = $candidate_row; + foreach ($fields[$table_alias] as $field => $alias) { + $new_row[$table_alias]['result'][$alias] = $candidate_row[$field]; + } + return $new_row + $row; + } + + /** + * {@inheritdoc} + */ + public function countQuery() { + $query = clone $this; + return $query->setCountQuery(); + } + + /** + * Set this query to be a count query. + */ + protected function setCountQuery() { + $this->countQuery = TRUE; + return $this; + } + + /** + * usort callback to order the results. + */ + protected function sortCallback($a, $b) { + $a_row = new DatabaseRowSelect($a, $this->fieldsWithTable, $this->fields); + $b_row = new DatabaseRowSelect($b, $this->fieldsWithTable, $this->fields); + foreach ($this->order as $field => $direction) { + $a_value = $a_row->getValue($field); + $b_value = $b_row->getValue($field); + if ($a_value != $b_value) { + return (($a_value < $b_value) == ($direction == 'ASC')) ? -1 : 1; + } + } + return 0; + } + + /** + * Resolves conditions by removing non-matching rows. + * + * @param \Drupal\Core\Database\Query\Condition $condition_group + * The condition group to check. + * @param array $rows + * An array of rows excluding non-matching rows. + * + * @return \Drupal\Core\Database\Driver\fake\ConditionResolver + * The condition resolver object. + */ + protected function resolveConditions(Condition $condition_group, array &$rows) { + $fields_with_table = $this->fieldsWithTable; + $fields = $this->fields; + return array_filter($rows, function ($row_array) use ($condition_group, $fields_with_table, $fields) { + $row = new DatabaseRowSelect($row_array, $fields_with_table, $fields); + return ConditionResolver::matchGroup($row, $condition_group); + }); + } + + /** + * {@inheritdoc} + */ + public function orderBy($field, $direction = 'ASC') { + $this->order[$field] = strtoupper($direction); + return $this; + } + + // ================== we could support these. + /** + * {@inheritdoc} + */ + public function groupBy($field) { + // @todo: Implement groupBy() method. + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function havingCondition($field, $value = NULL, $operator = NULL) { + // @todo: Implement havingCondition() method. + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function uniqueIdentifier() { + // TODO: Implement uniqueIdentifier() method. + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + // ================== the rest won't be supported, ever. + /** + * {@inheritdoc} + */ + public function nextPlaceholder() { + // TODO: Implement nextPlaceholder() method. + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function isPrepared() { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function preExecute(SelectInterface $query = NULL) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function where($snippet, $args = array()) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function extend($extender_name) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function &getExpressions() { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function &getGroupBy() { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function &getUnion() { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function forUpdate($set = TRUE) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function rightJoin($table, $alias = NULL, $condition = NULL, $arguments = array()) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function &conditions() { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function orderRandom() { + // We could implement this but why bother. + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function union(SelectInterface $query, $type = '') { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function addExpression($expression, $alias = NULL, $arguments = array()) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function &getTables() { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function getArguments(PlaceholderInterface $query_place_holder = NULL) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function &getOrderBy() { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function &getFields() { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function exists(SelectInterface $select) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function notExists(SelectInterface $select) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function arguments() { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function compile(Connection $connection, PlaceholderInterface $query_place_holder) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function compiled() { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function fields($table_alias, array $fields = array()) { + if (!$fields) { + $table = $this->tables[$table_alias]['table']; + if (!empty($this->databaseContents[$table])) { + $fields = array_keys(reset($this->databaseContents[$table])); + } + else { + throw new \Exception(SafeMarkup::format('All fields on empty table @table is not supported.', array('@table' => $table))); + } + } + return parent::fields($table_alias, $fields); + } +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeStatement.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeStatement.php new file mode 100644 index 0000000..7aaf574 --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeStatement.php @@ -0,0 +1,104 @@ +current()); + $return = $row[$index]; + $this->next(); + return $return; + } + + /** + * {@inheritdoc} + */ + public function fetchAssoc() { + $return = FALSE; + if ($this->valid()) { + $return = $this->current(); + $this->next(); + } + return $return; + } + + /** + * {@inheritdoc} + */ + public function fetchCol($index = 0) { + $return = array(); + foreach ($this as $row) { + $row = array_values($row); + $return[] = $row[$index]; + } + return $return; + } + + /** + * {@inheritdoc} + */ + public function fetchAllKeyed($key_index = 0, $value_index = 1) { + $return = array(); + foreach ($this as $row) { + $row = array_values($row); + $return[$row[$key_index]] = $row[$value_index]; + } + return $return; + } + + /** + * {@inheritdoc} + */ + public function fetchAllAssoc($key, $fetch = NULL) { + $return = array(); + foreach ($this as $row) { + $return[$row[$key]] = $row; + } + return $return; + } + + /** + * {@inheritdoc} + */ + public function fetchObject() { + $return = $this->fetchAssoc(); + return $return === FALSE ? FALSE : (object) $return; + } + +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeTruncate.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeTruncate.php new file mode 100644 index 0000000..d0be873 --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeTruncate.php @@ -0,0 +1,36 @@ +databaseContents = &$database_contents; + $this->table = $table; + } + + /** + * Executes the TRUNCATE query. + */ + public function execute() { + $this->databaseContents[$this->table] = array(); + } + +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeUpdate.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeUpdate.php new file mode 100644 index 0000000..0505c22 --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeUpdate.php @@ -0,0 +1,88 @@ +databaseContents = &$database_contents; + $this->table = $table; + $this->condition = new Condition('AND'); + } + + /** + * {@inheritdoc} + */ + public function execute() { + $affected = 0; + if (isset($this->databaseContents[$this->table])) { + $fields = $this->fields; + $condition = $this->condition; + array_walk($this->databaseContents[$this->table], function (&$row_array) use ($fields, $condition, &$affected) { + $row = new DatabaseRow($row_array); + if (ConditionResolver::matchGroup($row, $condition)) { + $row_array = $fields + $row_array; + $affected++; + } + }); + } + return $affected; + } + + /** + * {@inheritdoc} + */ + public function exists(SelectInterface $select) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function where($snippet, $args = array()) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function expression($field, $expression, array $arguments = NULL) { + throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__)); + } + +} diff --git a/core/lib/Drupal/Core/Database/Driver/fake/Install/Tasks.php b/core/lib/Drupal/Core/Database/Driver/fake/Install/Tasks.php new file mode 100644 index 0000000..11ed2f3 --- /dev/null +++ b/core/lib/Drupal/Core/Database/Driver/fake/Install/Tasks.php @@ -0,0 +1,35 @@ + drupal_install_profile_distribution_name())); - $default_database = \Drupal::service('site.path') . '/files/.ht.sqlite'; + $default_database = conf_path(FALSE) . '/files/.ht.sqlite'; $form['database']['#default_value'] = empty($database['database']) ? $default_database : $database['database']; return $form; } diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php index 21672fb..154470d 100644 --- a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php @@ -260,7 +260,7 @@ public function renameTable($table, $new_name) { $schema = $this->introspectSchema($table); // SQLite doesn't allow you to rename tables outside of the current - // database. So the syntax '... RENAME TO database.table' would fail. + // database. So the syntax '...RENAME TO database.table' would fail. // So we must determine the full table name here rather than surrounding // the table with curly braces in case the db_prefix contains a reference // to a database outside of our existing database. diff --git a/core/lib/Drupal/Core/Datetime/DateFormatter.php b/core/lib/Drupal/Core/Datetime/DateFormatter.php index 0aad043..82e9969 100644 --- a/core/lib/Drupal/Core/Datetime/DateFormatter.php +++ b/core/lib/Drupal/Core/Datetime/DateFormatter.php @@ -15,7 +15,6 @@ use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; -use Symfony\Component\HttpFoundation\RequestStack; /** * Provides a service to handler various date related functionality. @@ -53,13 +52,6 @@ class DateFormatter { */ protected $configFactory; - /** - * The request stack. - * - * @var \Symfony\Component\HttpFoundation\RequestStack - */ - protected $requestStack; - protected $country = NULL; protected $dateFormats = array(); @@ -93,15 +85,12 @@ class DateFormatter { * The string translation. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The configuration factory. - * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack - * The request stack. */ - public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, TranslationInterface $translation, ConfigFactoryInterface $config_factory, RequestStack $request_stack) { + public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, TranslationInterface $translation, ConfigFactoryInterface $config_factory) { $this->dateFormatStorage = $entity_manager->getStorage('date_format'); $this->languageManager = $language_manager; $this->stringTranslation = $translation; $this->configFactory = $config_factory; - $this->requestStack = $request_stack; } /** @@ -122,13 +111,13 @@ public function __construct(EntityManagerInterface $entity_manager, LanguageMana * (optional) If $type is 'custom', a PHP date format string suitable for * input to date(). Use a backslash to escape ordinary text, so it does not * get interpreted as date format characters. - * @param string|null $timezone + * @param string $timezone * (optional) Time zone identifier, as described at * http://php.net/manual/timezones.php Defaults to the time zone used to * display the page. - * @param string|null $langcode - * (optional) Language code to translate to. NULL (default) means to use - * the user interface language for the page. + * @param string $langcode + * (optional) Language code to translate to. Defaults to the language used to + * display the page. * * @return string * A translated date string in the requested format. @@ -174,26 +163,17 @@ public function format($timestamp, $type = 'medium', $format = '', $timezone = N /** * Formats a time interval with the requested granularity. * - * Note that for intervals over 30 days, the output is approximate: a "month" - * is always exactly 30 days, and a "year" is always 365 days. It is not - * possible to make a more exact representation, given that there is only one - * input in seconds. If you are formatting an interval between two specific - * timestamps, use \Drupal\Core\Datetime\DateFormatter::formatDiff() instead. - * * @param int $interval * The length of the interval in seconds. * @param int $granularity * (optional) How many different units to display in the string (2 by * default). - * @param string|null $langcode - * (optional) langcode: The language code for the language used to format - * the date. Defaults to NULL, which results in the user interface language - * for the page being used. + * @param string $langcode + * (optional) Language code to translate to a language other than what is + * used to display the page. Defaults to NULL. * * @return string * A translated string representation of the interval. - * - * @see \Drupal\Core\Datetime\DateFormatter::formatDiff() */ public function formatInterval($interval, $granularity = 2, $langcode = NULL) { $output = ''; @@ -234,186 +214,12 @@ public function getSampleDateFormats($langcode = NULL, $timestamp = NULL, $timez // All date format characters for the PHP date() function. $date_chars = str_split('dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU'); $date_elements = array_combine($date_chars, $date_chars); - return array_map(function ($character) use ($timestamp, $timezone, $langcode) { + return array_map(function($character) use ($timestamp, $timezone, $langcode) { return $this->format($timestamp, 'custom', $character, $timezone, $langcode); }, $date_elements); } /** - * Formats the time difference from the current request time to a timestamp. - * - * @param $timestamp - * A UNIX timestamp to compare against the current request time. - * @param array $options - * (optional) An associative array with additional options. The following - * keys can be used: - * - granularity: An integer value that signals how many different units to - * display in the string. Defaults to 2. - * - langcode: The language code for the language used to format the date. - * Defaults to NULL, which results in the user interface language for the - * page being used. - * - strict: A Boolean value indicating whether or not the timestamp can be - * before the current request time. If TRUE (default) and $timestamp is - * before the current request time, the result string will be "0 seconds". - * If FALSE and $timestamp is before the current request time, the result - * string will be the formatted time difference. - * - * @return string - * A translated string representation of the difference between the given - * timestamp and the current request time. This interval is always positive. - * - * @see \Drupal\Core\Datetime\DateFormatter::formatDiff() - * @see \Drupal\Core\Datetime\DateFormatter::formatTimeDiffSince() - */ - public function formatTimeDiffUntil($timestamp, $options = array()) { - $request_time = $this->requestStack->getCurrentRequest()->server->get('REQUEST_TIME'); - return $this->formatDiff($request_time, $timestamp, $options); - } - - /** - * Formats the time difference from a timestamp to the current request time. - * - * @param $timestamp - * A UNIX timestamp to compare against the current request time. - * @param array $options - * (optional) An associative array with additional options. The following - * keys can be used: - * - granularity: An integer value that signals how many different units to - * display in the string. Defaults to 2. - * - langcode: The language code for the language used to format the date. - * Defaults to NULL, which results in the user interface language for the - * page being used. - * - strict: A Boolean value indicating whether or not the timestamp can be - * after the current request time. If TRUE (default) and $timestamp is - * after the current request time, the result string will be "0 seconds". - * If FALSE and $timestamp is after the current request time, the result - * string will be the formatted time difference. - * - * @return string - * A translated string representation of the difference between the given - * timestamp and the current request time. This interval is always positive. - * - * @see \Drupal\Core\Datetime\DateFormatter::formatDiff() - * @see \Drupal\Core\Datetime\DateFormatter::formatTimeDiffUntil() - */ - public function formatTimeDiffSince($timestamp, $options = array()) { - $request_time = $this->requestStack->getCurrentRequest()->server->get('REQUEST_TIME'); - return $this->formatDiff($timestamp, $request_time, $options); - } - - /** - * Formats a time interval between two timestamps. - * - * @param int $from - * A UNIX timestamp, defining the from date and time. - * @param int $to - * A UNIX timestamp, defining the to date and time. - * @param array $options - * (optional) An associative array with additional options. The following - * keys can be used: - * - granularity: An integer value that signals how many different units to - * display in the string. Defaults to 2. - * - langcode: The language code for the language used to format the date. - * Defaults to NULL, which results in the user interface language for the - * page being used. - * - strict: A Boolean value indicating whether or not the $from timestamp - * can be after the $to timestamp. If TRUE (default) and $from is after - * $to, the result string will be "0 seconds". If FALSE and $from is - * after $to, the result string will be the formatted time difference. - * - * @return string - * A translated string representation of the interval. This interval is - * always positive. - * - * @see \Drupal\Core\Datetime\DateFormatter::formatInterval() - * @see \Drupal\Core\Datetime\DateFormatter::formatTimeDiffSince() - * @see \Drupal\Core\Datetime\DateFormatter::formatTimeDiffUntil() - */ - public function formatDiff($from, $to, $options = array()) { - - $options += array( - 'granularity' => 2, - 'langcode' => NULL, - 'strict' => TRUE, - ); - - if ($options['strict'] && $from > $to) { - return $this->t('0 seconds'); - } - - $date_time_from = new \DateTime(); - $date_time_from->setTimestamp($from); - - $date_time_to = new \DateTime(); - $date_time_to->setTimestamp($to); - - $interval = $date_time_to->diff($date_time_from); - - $granularity = $options['granularity']; - $output = ''; - - // We loop over the keys provided by \DateInterval explicitly. Since we - // don't take the "invert" property into account, the resulting output value - // will always be positive. - foreach (array('y', 'm', 'd', 'h', 'i', 's') as $value) { - if ($interval->$value > 0) { - // Switch over the keys to call formatPlural() explicitly with literal - // strings for all different possibilities. - switch ($value) { - case 'y': - $interval_output = $this->formatPlural($interval->y, '1 year', '@count years', array(), array('langcode' => $options['langcode'])); - break; - - case 'm': - $interval_output = $this->formatPlural($interval->m, '1 month', '@count months', array(), array('langcode' => $options['langcode'])); - break; - - case 'd': - // \DateInterval doesn't support weeks, so we need to calculate them - // ourselves. - $interval_output = ''; - $days = $interval->d; - if ($days >= 7) { - $weeks = floor($days / 7); - $interval_output .= $this->formatPlural($weeks, '1 week', '@count weeks', array(), array('langcode' => $options['langcode'])); - $days -= $weeks * 7; - $granularity--; - } - if ($granularity > 0 && $days > 0) { - $interval_output .= ($interval_output ? ' ' : '') . $this->formatPlural($days, '1 day', '@count days', array(), array('langcode' => $options['langcode'])); - } - break; - - case 'h': - $interval_output = $this->formatPlural($interval->h, '1 hour', '@count hours', array(), array('langcode' => $options['langcode'])); - break; - - case 'i': - $interval_output = $this->formatPlural($interval->i, '1 minute', '@count minutes', array(), array('langcode' => $options['langcode'])); - break; - - case 's': - $interval_output = $this->formatPlural($interval->s, '1 second', '@count seconds', array(), array('langcode' => $options['langcode'])); - break; - - } - $output .= ($output ? ' ' : '') . $interval_output; - $granularity--; - } - - if ($granularity == 0) { - break; - } - } - - if (empty($output)) { - $output = $this->t('0 seconds'); - } - - return $output; - } - - /** * Loads the given format pattern for the given langcode. * * @param string $format diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index b8eeb4f..d21a8fa 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -311,7 +311,7 @@ public static function findSitePath(Request $request, $require_settings = TRUE) if (!$script_name) { $script_name = $request->server->get('SCRIPT_FILENAME'); } - $http_host = $request->getHttpHost(); + $http_host = $request->getHost(); $sites = array(); include DRUPAL_ROOT . '/sites/sites.php'; diff --git a/core/lib/Drupal/Core/Entity/ContentUninstallValidator.php b/core/lib/Drupal/Core/Entity/ContentUninstallValidator.php index e791d8a..cc139e0 100644 --- a/core/lib/Drupal/Core/Entity/ContentUninstallValidator.php +++ b/core/lib/Drupal/Core/Entity/ContentUninstallValidator.php @@ -18,13 +18,6 @@ class ContentUninstallValidator implements ModuleUninstallValidatorInterface { use StringTranslationTrait; /** - * The entity manager. - * - * @var \Drupal\Core\Entity\EntityManagerInterface - */ - protected $entityManager; - - /** * Constructs a new ContentUninstallValidator. * * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager diff --git a/core/lib/Drupal/Core/Entity/Display/EntityFormDisplayInterface.php b/core/lib/Drupal/Core/Entity/Display/EntityFormDisplayInterface.php index 068c41f..b71b0ec 100644 --- a/core/lib/Drupal/Core/Entity/Display/EntityFormDisplayInterface.php +++ b/core/lib/Drupal/Core/Entity/Display/EntityFormDisplayInterface.php @@ -41,7 +41,7 @@ * // widget is 'single-value' (provides the input for one field value, * // most common case), and will therefore be repeated as many times as * // needed, or 'multiple-values' (one single widget allows the input of - * // several values; e.g., checkboxes, select box, etc.). + * // several values, e.g checkboxes, select box...). * 'field_foo' => array( * '#access' => TRUE if the current user has 'edit' grants for the field, * FALSE if not. diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index 89a8e9f..4861138 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -972,22 +972,20 @@ public function getTranslationFromContext(EntityInterface $entity, $langcode = N } // Retrieve language fallback candidates to perform the entity language - // negotiation, unless the current translation is already the desired one. - if ($entity->language()->getId() != $langcode) { - $context['data'] = $entity; - $context += array('operation' => 'entity_view', 'langcode' => $langcode); - $candidates = $this->languageManager->getFallbackCandidates($context); + // negotiation. + $context['data'] = $entity; + $context += array('operation' => 'entity_view', 'langcode' => $langcode); + $candidates = $this->languageManager->getFallbackCandidates($context); - // Ensure the default language has the proper language code. - $default_language = $entity->getUntranslated()->language(); - $candidates[$default_language->getId()] = LanguageInterface::LANGCODE_DEFAULT; + // Ensure the default language has the proper language code. + $default_language = $entity->getUntranslated()->language(); + $candidates[$default_language->getId()] = LanguageInterface::LANGCODE_DEFAULT; - // Return the most fitting entity translation. - foreach ($candidates as $candidate) { - if ($entity->hasTranslation($candidate)) { - $translation = $entity->getTranslation($candidate); - break; - } + // Return the most fitting entity translation. + foreach ($candidates as $candidate) { + if ($entity->hasTranslation($candidate)) { + $translation = $entity->getTranslation($candidate); + break; } } } diff --git a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionSubscriber.php index 46d6c46..883927c 100644 --- a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionSubscriber.php @@ -198,7 +198,13 @@ public function onException(GetResponseForExceptionEvent $event) { * The format as which to treat the exception. */ protected function getFormat(Request $request) { - $format = $request->query->get(MainContentViewSubscriber::WRAPPER_FORMAT, $request->getRequestFormat()); + // @todo We are trying to switch to a more robust content negotiation + // library in https://www.drupal.org/node/1505080 that will make + // $request->getRequestFormat() reliable as a better alternative + // to this code. We therefore use this style for now on the expectation + // that it will get replaced with better code later. This approach makes + // that change easier when we get to it. + $format = \Drupal::service('http_negotiation.format_negotiator')->getContentType($request); // These are all JSON errors for our purposes. Any special handling for // them can/should happen in earlier listeners if desired. diff --git a/core/lib/Drupal/Core/EventSubscriber/HttpExceptionSubscriberBase.php b/core/lib/Drupal/Core/EventSubscriber/HttpExceptionSubscriberBase.php index 6fcacc9..a14d327 100644 --- a/core/lib/Drupal/Core/EventSubscriber/HttpExceptionSubscriberBase.php +++ b/core/lib/Drupal/Core/EventSubscriber/HttpExceptionSubscriberBase.php @@ -86,12 +86,11 @@ public function onException(GetResponseForExceptionEvent $event) { $exception = $event->getException(); // Make the exception available for example when rendering a block. - $request = $event->getRequest(); - $request->attributes->set('exception', $exception); + $event->getRequest()->attributes->set('exception', $exception); $handled_formats = $this->getHandledFormats(); - $format = $request->query->get(MainContentViewSubscriber::WRAPPER_FORMAT, $request->getRequestFormat()); + $format = $event->getRequest()->getRequestFormat(); if ($exception instanceof HttpExceptionInterface && (empty($handled_formats) || in_array($format, $handled_formats))) { $method = 'on' . $exception->getStatusCode(); diff --git a/core/lib/Drupal/Core/Executable/ExecutablePluginBase.php b/core/lib/Drupal/Core/Executable/ExecutablePluginBase.php index c438e1d..38767e1 100644 --- a/core/lib/Drupal/Core/Executable/ExecutablePluginBase.php +++ b/core/lib/Drupal/Core/Executable/ExecutablePluginBase.php @@ -17,6 +17,21 @@ abstract class ExecutablePluginBase extends ContextAwarePluginBase implements ExecutableInterface { /** + * The condition manager to proxy execute calls through. + * + * @var \Drupal\Component\Plugin\PluginManagerInterface + */ + protected $executableManager; + + /** + * {@inheritdoc} + */ + public function setExecutableManager(ExecutableManagerInterface $executableManager) { + $this->executableManager = $executableManager; + return $this; + } + + /** * Gets an array of definitions of available configuration options. * * @todo: This needs to go into an interface. diff --git a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php index 3238ce6..508e1b3 100644 --- a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php +++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php @@ -8,10 +8,8 @@ namespace Drupal\Core\Extension; use Drupal\Component\FileCache\FileCacheFactory; -use Drupal\Core\DrupalKernel; use Drupal\Core\Extension\Discovery\RecursiveExtensionFilterIterator; use Drupal\Core\Site\Settings; -use Symfony\Component\HttpFoundation\Request; /** * Discovers available extensions in the filesystem. @@ -164,16 +162,8 @@ public function scan($type, $include_tests = NULL) { $searchdirs[static::ORIGIN_PARENT_SITE] = $parent_site; } - // Find the site-specific directory to search. Since we are using this - // method to discover extensions including profiles, we might be doing this - // at install time. Therefore Kernel service is not always available, but is - // preferred. - if (\Drupal::hasService('kernel')) { - $searchdirs[static::ORIGIN_SITE] = \Drupal::service('site.path'); - } - else { - $searchdirs[static::ORIGIN_SITE] = DrupalKernel::findSitePath(Request::createFromGlobals()); - } + // Search the site-specific directory. + $searchdirs[static::ORIGIN_SITE] = conf_path(); // Unless an explicit value has been passed, manually check whether we are // in a test environment, in which case test extensions must be included. diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php index d99c9dd..9c93000 100644 --- a/core/lib/Drupal/Core/Extension/ModuleInstaller.php +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php @@ -334,7 +334,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) { $reason_message[] = implode(', ', $reason); } throw new ModuleUninstallValidatorException(format_string('The following reasons prevents the modules from being uninstalled: @reasons', array( - '@reasons' => implode('; ', $reason_message), + '@reasons' => implode(', ', $reason_message), ))); } // Set the actual module weights. diff --git a/core/lib/Drupal/Core/Extension/ModuleUninstallValidatorInterface.php b/core/lib/Drupal/Core/Extension/ModuleUninstallValidatorInterface.php index eeabca5..5e62b0e 100644 --- a/core/lib/Drupal/Core/Extension/ModuleUninstallValidatorInterface.php +++ b/core/lib/Drupal/Core/Extension/ModuleUninstallValidatorInterface.php @@ -20,10 +20,6 @@ * * @return string[] * An array of reasons the module can not be uninstalled, empty if it can. - * Each reason should not end with any punctuation since multiple reasons - * can be displayed together. - * - * @see theme_system_modules_uninstall() */ public function validate($module); } diff --git a/core/lib/Drupal/Core/Extension/RequiredModuleUninstallValidator.php b/core/lib/Drupal/Core/Extension/RequiredModuleUninstallValidator.php deleted file mode 100644 index a285e00..0000000 --- a/core/lib/Drupal/Core/Extension/RequiredModuleUninstallValidator.php +++ /dev/null @@ -1,56 +0,0 @@ -stringTranslation = $string_translation; - } - - /** - * {@inheritdoc} - */ - public function validate($module) { - $reasons = []; - $module_info = $this->getModuleInfoByModule($module); - if (!empty($module_info['required'])) { - $reasons[] = $this->t('The @module module is required', ['@module' => $module_info['name']]); - } - return $reasons; - } - - /** - * Returns the module info for a specific module. - * - * @param string $module - * The name of the module. - * - * @return array - * The module info, or NULL if that module does not exist. - */ - protected function getModuleInfoByModule($module) { - $modules = system_rebuild_module_data(); - return isset($modules[$module]->info) ? $modules[$module]->info : []; - } - -} diff --git a/core/lib/Drupal/Core/Field/FieldModuleUninstallValidator.php b/core/lib/Drupal/Core/Field/FieldModuleUninstallValidator.php index b2e474d..b54579c 100644 --- a/core/lib/Drupal/Core/Field/FieldModuleUninstallValidator.php +++ b/core/lib/Drupal/Core/Field/FieldModuleUninstallValidator.php @@ -53,7 +53,7 @@ public function validate($module_name) { if ($storage_definition->getProvider() == $module_name) { $storage = $this->entityManager->getStorage($entity_type_id); if ($storage instanceof FieldableEntityStorageInterface && $storage->countFieldData($storage_definition, TRUE)) { - $reasons[] = $this->t('There is data for the field @field-name on entity type @entity_type', array( + $reasons[] = $this->t('There is data for the field @field-name on entity type @entity_type.', array( '@field-name' => $storage_definition->getName(), '@entity_type' => $entity_type->getLabel(), )); diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php index 30dae80..04f96fa 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php @@ -87,7 +87,7 @@ public function viewElements(FieldItemListInterface $items) { foreach ($items as $delta => $item) { if ($item->value) { - $updated = $this->t('@time ago', array('@time' => $this->dateFormatter->formatTimeDiffSince($item->value))); + $updated = $this->t('@time ago', array('@time' => $this->dateFormatter->formatInterval(REQUEST_TIME - $item->value))); } else { $updated = $this->t('never'); diff --git a/core/lib/Drupal/Core/Field/WidgetInterface.php b/core/lib/Drupal/Core/Field/WidgetInterface.php index 39f7cc4..d110cec 100644 --- a/core/lib/Drupal/Core/Field/WidgetInterface.php +++ b/core/lib/Drupal/Core/Field/WidgetInterface.php @@ -66,18 +66,18 @@ public function settingsSummary(); * hook_field_widget_WIDGET_TYPE_form_alter(). * * The FAPI element callbacks (such as #process, #element_validate, - * #value_callback, etc.) used by the widget do not have access to the - * original $field_definition passed to the widget's constructor. Therefore, - * if any information is needed from that definition by those callbacks, the - * widget implementing this method, or a - * hook_field_widget[_WIDGET_TYPE]_form_alter() implementation, must extract - * the needed properties from the field definition and set them as ad-hoc - * $element['#custom'] properties, for later use by its element callbacks. + * #value_callback...) used by the widget do not have access to the original + * $field_definition passed to the widget's constructor. Therefore, if any + * information is needed from that definition by those callbacks, the widget + * implementing this method, or a hook_field_widget[_WIDGET_TYPE]_form_alter() + * implementation, must extract the needed properties from the field + * definition and set them as ad-hoc $element['#custom'] properties, for later + * use by its element callbacks. * * @param \Drupal\Core\Field\FieldItemListInterface $items * Array of default values for this field. * @param int $delta - * The order of this item in the array of sub-elements (0, 1, 2, etc.). + * The order of this item in the array of sub-elements (0, 1, 2, etc). * @param array $element * A form element array containing basic properties for the widget: * - #field_parents: The 'parents' space for the field in the form. Most diff --git a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php index d17f065..0f2f3a7 100644 --- a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php +++ b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php @@ -21,13 +21,6 @@ class SiteConfigureForm extends ConfigFormBase { /** - * The site path. - * - * @var string - */ - protected $sitePath; - - /** * The user storage. * * @var \Drupal\user\UserStorageInterface @@ -67,8 +60,6 @@ class SiteConfigureForm extends ConfigFormBase { * * @param string $root * The app root. - * @param string $site_path - * The site path. * @param \Drupal\user\UserStorageInterface $user_storage * The user storage. * @param \Drupal\Core\State\StateInterface $state @@ -78,9 +69,8 @@ class SiteConfigureForm extends ConfigFormBase { * @param \Drupal\Core\Locale\CountryManagerInterface $country_manager * The country manager. */ - public function __construct($root, $site_path, UserStorageInterface $user_storage, StateInterface $state, ModuleInstallerInterface $module_installer, CountryManagerInterface $country_manager) { + public function __construct($root, UserStorageInterface $user_storage, StateInterface $state, ModuleInstallerInterface $module_installer, CountryManagerInterface $country_manager) { $this->root = $root; - $this->sitePath = $site_path; $this->userStorage = $user_storage; $this->state = $state; $this->moduleInstaller = $module_installer; @@ -93,7 +83,6 @@ public function __construct($root, $site_path, UserStorageInterface $user_storag public static function create(ContainerInterface $container) { return new static( $container->get('app.root'), - $container->get('site.path'), $container->get('entity.manager')->getStorage('user'), $container->get('state'), $container->get('module_installer'), @@ -126,7 +115,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form['#title'] = $this->t('Configure site'); // Warn about settings.php permissions risk - $settings_dir = $this->sitePath; + $settings_dir = conf_path(); $settings_file = $settings_dir . '/settings.php'; // Check that $_POST is empty so we only show this message when the form is // first displayed, not on the next page after it is submitted. (We do not diff --git a/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php b/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php index 4d0f9fe..8cf65c9 100644 --- a/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php +++ b/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php @@ -11,7 +11,6 @@ use Drupal\Core\Database\Database; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides a form to configure and rewrite settings.php. @@ -19,32 +18,6 @@ class SiteSettingsForm extends FormBase { /** - * The site path. - * - * @var string - */ - protected $sitePath; - - /** - * Constructs a new SiteSettingsForm. - * - * @param string $site_path - * The site path. - */ - public function __construct($site_path) { - $this->sitePath = $site_path; -} - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('site.path') - ); - } - - /** * {@inheritdoc} */ public function getFormId() { @@ -55,7 +28,8 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $settings_file = './' . $this->sitePath . '/settings.php'; + $conf_path = './' . conf_path(FALSE); + $settings_file = $conf_path . '/settings.php'; $form['#title'] = $this->t('Database configuration'); diff --git a/core/lib/Drupal/Core/Menu/LocalTaskManager.php b/core/lib/Drupal/Core/Menu/LocalTaskManager.php index 86136d0..2ef5de1 100644 --- a/core/lib/Drupal/Core/Menu/LocalTaskManager.php +++ b/core/lib/Drupal/Core/Menu/LocalTaskManager.php @@ -11,6 +11,7 @@ use Drupal\Core\Access\AccessManagerInterface; use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Cache\NullBackend; use Drupal\Core\Controller\ControllerResolverInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Language\LanguageManagerInterface; @@ -18,6 +19,7 @@ use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator; use Drupal\Core\Plugin\Discovery\YamlDiscovery; use Drupal\Core\Plugin\Factory\ContainerFactory; +use Drupal\Core\Routing\RouteBuilderInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\Session\AccountInterface; @@ -89,6 +91,13 @@ class LocalTaskManager extends DefaultPluginManager implements LocalTaskManagerI protected $routeProvider; /** + * The route builder. + * + * @var \Drupal\Core\Routing\RouteBuilderInterface + */ + protected $routeBuilder; + + /** * The access manager. * * @var \Drupal\Core\Access\AccessManagerInterface @@ -113,6 +122,8 @@ class LocalTaskManager extends DefaultPluginManager implements LocalTaskManagerI * The current route match. * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider * The route provider to load routes by name. + * @param \Drupal\Core\Routing\RouteBuilderInterface $route_builder + * The route builder. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. * @param \Drupal\Core\Cache\CacheBackendInterface $cache @@ -124,7 +135,7 @@ class LocalTaskManager extends DefaultPluginManager implements LocalTaskManagerI * @param \Drupal\Core\Session\AccountInterface $account * The current user. */ - public function __construct(ControllerResolverInterface $controller_resolver, RequestStack $request_stack, RouteMatchInterface $route_match, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, AccessManagerInterface $access_manager, AccountInterface $account) { + public function __construct(ControllerResolverInterface $controller_resolver, RequestStack $request_stack, RouteMatchInterface $route_match, RouteProviderInterface $route_provider, RouteBuilderInterface $route_builder, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, AccessManagerInterface $access_manager, AccountInterface $account) { $this->discovery = new YamlDiscovery('links.task', $module_handler->getModuleDirectories()); $this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery); $this->factory = new ContainerFactory($this, '\Drupal\Core\Menu\LocalTaskInterface'); @@ -132,6 +143,7 @@ public function __construct(ControllerResolverInterface $controller_resolver, Re $this->requestStack = $request_stack; $this->routeMatch = $route_match; $this->routeProvider = $route_provider; + $this->routeBuilder = $route_builder; $this->accessManager = $access_manager; $this->account = $account; $this->moduleHandler = $module_handler; diff --git a/core/lib/Drupal/Core/Render/Element/Checkbox.php b/core/lib/Drupal/Core/Render/Element/Checkbox.php index 5f39bcc..6574685 100644 --- a/core/lib/Drupal/Core/Render/Element/Checkbox.php +++ b/core/lib/Drupal/Core/Render/Element/Checkbox.php @@ -13,17 +13,6 @@ /** * Provides a form element for a single checkbox. * - * Properties: - * - #return_value: The value to return when the checkbox is checked. - * - * Usage example: - * @code - * $form['copy'] = array( - * '#type' => 'checkbox', - * '#title' => t('Send me a copy'), - * ); - * @endcode - * * @see \Drupal\Core\Render\Element\Checkboxes * * @FormElement("checkbox") diff --git a/core/lib/Drupal/Core/Render/Element/Checkboxes.php b/core/lib/Drupal/Core/Render/Element/Checkboxes.php index d931460..1891ceb 100644 --- a/core/lib/Drupal/Core/Render/Element/Checkboxes.php +++ b/core/lib/Drupal/Core/Render/Element/Checkboxes.php @@ -12,21 +12,9 @@ /** * Provides a form element for a set of checkboxes. * - * Properties: - * - #options: An associative array whose keys are the values returned for each - * checkbox, and whose values are the labels next to each checkbox. The - * #options array cannot have a 0 key, as it would not be possible to discern - * checked and unchecked states. - * - * Usage example: - * @code - * $form['high_school']['tests_taken'] = array( - * '#type' => 'checkboxes', - * '#options' => array('SAT' => t('SAT'), 'ACT' => t('ACT'))), - * '#title' => t('What standardized tests did you take?'), - * ... - * ); - * @endcode + * #options is an associative array, where the key is the #return_value of the + * checkbox and the value is displayed. The #options array cannot have a 0 key, + * as it would not be possible to discern checked and unchecked states. * * @see \Drupal\Core\Render\Element\Radios * @see \Drupal\Core\Render\Element\Checkbox diff --git a/core/lib/Drupal/Core/Render/Element/File.php b/core/lib/Drupal/Core/Render/Element/File.php index c8b3c7f..5f72c8d 100644 --- a/core/lib/Drupal/Core/Render/Element/File.php +++ b/core/lib/Drupal/Core/Render/Element/File.php @@ -65,7 +65,7 @@ public static function processFile(&$element, FormStateInterface $form_state, &$ public static function preRenderFile($element) { $element['#attributes']['type'] = 'file'; Element::setAttributes($element, array('id', 'name', 'size')); - static::setAttributes($element, array('js-form-file', 'form-file')); + static::setAttributes($element, array('form-file')); return $element; } diff --git a/core/lib/Drupal/Core/Render/Element/HtmlTag.php b/core/lib/Drupal/Core/Render/Element/HtmlTag.php index 5dc3afe..9b2ab57 100644 --- a/core/lib/Drupal/Core/Render/Element/HtmlTag.php +++ b/core/lib/Drupal/Core/Render/Element/HtmlTag.php @@ -69,9 +69,6 @@ public function getInfo() { * wrapper prefix. * - #value_suffix: (optional) A string to append to #value, e.g. a CDATA * wrapper suffix. - * - #noscript: (optional) If TRUE, the markup (including any prefix or - * suffix) will be wrapped in a