Commit 88be740c authored by Crell's avatar Crell

Merge remote-tracking branch 'upstream/8.x' into kernel

Conflicts:
	core/modules/node/node.module
	core/modules/overlay/overlay.module
parents d4517669 9b88eeac
......@@ -74,32 +74,32 @@
const WATCHDOG_ALERT = 1;
/**
* Log message severity -- Critical: critical conditions.
* Log message severity -- Critical conditions.
*/
const WATCHDOG_CRITICAL = 2;
/**
* Log message severity -- Error: error conditions.
* Log message severity -- Error conditions.
*/
const WATCHDOG_ERROR = 3;
/**
* Log message severity -- Warning: warning conditions.
* Log message severity -- Warning conditions.
*/
const WATCHDOG_WARNING = 4;
/**
* Log message severity -- Notice: normal but significant condition.
* Log message severity -- Normal but significant conditions.
*/
const WATCHDOG_NOTICE = 5;
/**
* Log message severity -- Informational: informational messages.
* Log message severity -- Informational messages.
*/
const WATCHDOG_INFO = 6;
/**
* Log message severity -- Debug: debug-level messages.
* Log message severity -- Debug-level messages.
*/
const WATCHDOG_DEBUG = 7;
......@@ -843,7 +843,7 @@ function variable_initialize($conf = array()) {
* The default value to use if this variable has never been set.
*
* @return
* The value of the variable.
* The value of the variable. Unserialization is taken care of as necessary.
*
* @see variable_del()
* @see variable_set()
......@@ -1590,8 +1590,16 @@ function watchdog_exception($type, Exception $exception, $message = NULL, $varia
* NULL if message is already translated or not possible to
* translate.
* @param $severity
* The severity of the message, as per RFC 3164. Possible values are
* WATCHDOG_ERROR, WATCHDOG_WARNING, etc.
* The severity of the message; one of the following values as defined in
* @link http://www.faqs.org/rfcs/rfc3164.html RFC 3164: @endlink
* - WATCHDOG_EMERGENCY: Emergency, system is unusable.
* - WATCHDOG_ALERT: Alert, action must be taken immediately.
* - WATCHDOG_CRITICAL: Critical conditions.
* - WATCHDOG_ERROR: Error conditions.
* - WATCHDOG_WARNING: Warning conditions.
* - WATCHDOG_NOTICE: (default) Normal but significant conditions.
* - WATCHDOG_INFO: Informational messages.
* - WATCHDOG_DEBUG: Debug-level messages.
* @param $link
* A link to associate with the message.
*
......@@ -1782,7 +1790,7 @@ function drupal_is_denied($ip) {
// won't be denied. However the user asked explicitly not to use the
// database and also in this case it's quite likely that the user relies
// on higher performance solutions like a firewall.
elseif (class_exists('Database', FALSE)) {
elseif (class_exists('Drupal\Core\Database\Database', FALSE)) {
$denied = (bool)db_query("SELECT 1 FROM {blocked_ips} WHERE ip = :ip", array(':ip' => $ip))->fetchField();
}
return $denied;
......@@ -2157,24 +2165,8 @@ function _drupal_bootstrap_configuration() {
// Initialize the configuration, including variables from settings.php.
drupal_settings_initialize();
// Include and activate the class loader.
$loader = drupal_classloader();
// Register explicit vendor namespaces.
$loader->registerNamespaces(array(
// All Symfony-borrowed code lives in /core/vendor/Symfony.
'Symfony' => DRUPAL_ROOT . '/core/vendor',
));
// Register the Drupal namespace for classes in core as a fallback.
// This allows to register additional namespaces within the Drupal namespace
// (e.g., for modules) and avoids an additional file_exists() on the Drupal
// core namespace, since the class loader can already determine the best
// namespace match based on a string comparison. It further allows modules to
// register/overload namespaces in Drupal core.
$loader->registerNamespaceFallbacks(array(
// All Drupal-namespaced code in core lives in /core/lib/Drupal.
'Drupal' => DRUPAL_ROOT . '/core/lib',
));
// Activate the class loader.
drupal_classloader();
}
/**
......@@ -2355,6 +2347,10 @@ function drupal_container($reset = FALSE) {
static $container = NULL;
if ($reset || !isset($container)) {
$container = new ContainerBuilder();
// An interface language always needs to be available for t() and other
// functions. This default is overridden by drupal_language_initialize()
// during language negotiation.
$container->register(LANGUAGE_TYPE_INTERFACE, 'Drupal\\Core\\Language\\Language');
}
return $container;
}
......@@ -2575,43 +2571,32 @@ function language_multilingual() {
/**
* Returns a list of configured languages.
*
* @param $only_enabled
* (optional) Whether to return only enabled languages.
*
* @return
* An associative array of languages, keyed by the language code, ordered by
* weight ascending and name ascending.
*/
function language_list($only_enabled = FALSE) {
function language_list() {
$languages = &drupal_static(__FUNCTION__);
// Initialize master language list.
if (!isset($languages)) {
// Initialize local language list caches.
$languages = array('all' => array(), 'enabled' => array());
// Fill in master language list based on current configuration.
$default = language_default();
if (language_multilingual() || module_exists('language')) {
// Use language module configuration if available.
$languages['all'] = db_query('SELECT * FROM {language} ORDER BY weight ASC, name ASC')->fetchAllAssoc('langcode');
$languages = db_query('SELECT * FROM {language} ORDER BY weight ASC, name ASC')->fetchAllAssoc('langcode');
}
else {
// No language module, so use the default language only.
$languages['all'][$default->langcode] = $default;
$languages = array($default->langcode => $default);
}
// Initialize default property so callers have an easy reference and can
// save the same object without data loss. Also fill in the filtered list
// of enabled languages only.
foreach ($languages['all'] as $langcode => $language) {
$languages['all'][$langcode]->default = ($langcode == $default->langcode);
if ($language->enabled) {
$languages['enabled'][$langcode] = $languages['all'][$langcode];
}
// save the same object without data loss.
foreach ($languages as $langcode => $language) {
$languages[$langcode]->default = ($langcode == $default->langcode);
}
}
return $only_enabled ? $languages['enabled'] : $languages['all'];
return $languages;
}
/**
......@@ -2662,7 +2647,6 @@ function language_default() {
'langcode' => 'en',
'name' => 'English',
'direction' => 0,
'enabled' => 1,
'weight' => 0,
));
$default->default = TRUE;
......@@ -2865,6 +2849,24 @@ function drupal_classloader() {
$loader = new UniversalClassLoader();
break;
}
// Register explicit vendor namespaces.
$loader->registerNamespaces(array(
// All Symfony-borrowed code lives in /core/vendor/Symfony.
'Symfony' => DRUPAL_ROOT . '/core/vendor',
));
// Register the Drupal namespace for classes in core as a fallback.
// This allows to register additional namespaces within the Drupal namespace
// (e.g., for modules) and avoids an additional file_exists() on the Drupal
// core namespace, since the class loader can already determine the best
// namespace match based on a string comparison. It further allows modules
// to register/overload namespaces in Drupal core.
$loader->registerNamespaceFallbacks(array(
// All Drupal-namespaced code in core lives in /core/lib/Drupal.
'Drupal' => DRUPAL_ROOT . '/core/lib',
));
// Register the loader with PHP.
$loader->register();
}
return $loader;
......
......@@ -3517,7 +3517,13 @@ function drupal_build_css_cache($css) {
$data = '';
$uri = '';
$map = variable_get('drupal_css_cache_files', array());
$key = hash('sha256', serialize($css));
// Create a new array so that only the file names are used to create the hash.
// This prevents new aggregates from being created unnecessarily.
$css_data = array();
foreach ($css as $css_file) {
$css_data[] = $css_file['data'];
}
$key = hash('sha256', serialize($css_data));
if (isset($map[$key])) {
$uri = $map[$key];
}
......@@ -5019,7 +5025,13 @@ function drupal_build_js_cache($files) {
$contents = '';
$uri = '';
$map = variable_get('drupal_js_cache_files', array());
$key = hash('sha256', serialize($files));
// Create a new array so that only the file names are used to create the hash.
// This prevents new aggregates from being created unnecessarily.
$js_data = array();
foreach ($files as $file) {
$js_data[] = $file['data'];
}
$key = hash('sha256', serialize($js_data));
if (isset($map[$key])) {
$uri = $map[$key];
}
......
......@@ -579,16 +579,16 @@ function file_save_htaccess($directory, $private = TRUE) {
/**
* Loads file objects from the database.
*
* @param $fids
* An array of file IDs.
* @param $conditions
* @param array|bool $fids
* An array of file IDs, or FALSE to load all files.
* @param array $conditions
* (deprecated) An associative array of conditions on the {file_managed}
* table, where the keys are the database fields and the values are the
* values those fields must have. Instead, it is preferable to use
* EntityFieldQuery to retrieve a list of entity IDs loadable by
* this function.
*
* @return
* @return array
* An array of file objects, indexed by fid.
*
* @todo Remove $conditions in Drupal 8.
......@@ -598,8 +598,8 @@ function file_save_htaccess($directory, $private = TRUE) {
* @see entity_load()
* @see EntityFieldQuery
*/
function file_load_multiple($fids = array(), $conditions = array()) {
return entity_load('file', $fids, $conditions);
function file_load_multiple($fids = array(), array $conditions = array()) {
return entity_load_multiple('file', $fids, $conditions);
}
/**
......
......@@ -3597,6 +3597,20 @@ function form_process_fieldset(&$element, &$form_state) {
// Contains form element summary functionalities.
$element['#attached']['library'][] = array('system', 'drupal.form');
return $element;
}
/**
* Adds members of this group as actual elements for rendering.
*
* @param $element
* An associative array containing the properties and children of the
* fieldset.
*
* @return
* The modified element with all group members.
*/
function form_pre_render_fieldset($element) {
// The .form-wrapper class is required for #states to treat fieldsets like
// containers.
if (!isset($element['#attributes']['class'])) {
......@@ -3612,20 +3626,6 @@ function form_process_fieldset(&$element, &$form_state) {
}
}
return $element;
}
/**
* Adds members of this group as actual elements for rendering.
*
* @param $element
* An associative array containing the properties and children of the
* fieldset.
*
* @return
* The modified element with all group members.
*/
function form_pre_render_fieldset($element) {
// Fieldsets may be rendered outside of a Form API context.
if (!isset($element['#parents']) || !isset($element['#groups'])) {
return $element;
......
......@@ -230,26 +230,6 @@ function install_begin_request(&$install_state) {
// Allow command line scripts to override server variables used by Drupal.
require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';
// Ensure that the class loader is available so that we can leverage classes
// as part of the install routine.
$loader = drupal_classloader();
// Register explicit vendor namespaces.
$loader->registerNamespaces(array(
// All Symfony-borrowed code lives in /core/includes/Symfony.
'Symfony' => DRUPAL_ROOT . '/core/vendor',
));
// Register the Drupal namespace for classes in core as a fallback.
// This allows to register additional namespaces within the Drupal namespace
// (e.g., for modules) and avoids an additional file_exists() on the Drupal
// core namespace, since the class loader can already determine the best
// namespace match based on a string comparison. It further allows modules to
// register/overload namespaces in Drupal core.
$loader->registerNamespaceFallbacks(array(
// All Drupal-namespaced code in core lives in /core/includes/Drupal.
'Drupal' => DRUPAL_ROOT . '/core/lib',
));
if (!$install_state['interactive']) {
drupal_override_server_variables($install_state['server']);
}
......@@ -1932,8 +1912,13 @@ function install_configure_form_submit($form, &$form_state) {
// We precreated user 1 with placeholder values. Let's save the real values.
$account = user_load(1);
$merge_data = array('init' => $form_state['values']['account']['mail'], 'roles' => !empty($account->roles) ? $account->roles : array(), 'status' => 1, 'timezone' => $form_state['values']['date_default_timezone']);
user_save($account, array_merge($form_state['values']['account'], $merge_data));
$account->init = $account->mail = $form_state['values']['account']['mail'];
$account->roles = !empty($account->roles) ? $account->roles : array();
$account->status = 1;
$account->timezone = $form_state['values']['date_default_timezone'];
$account->pass = $form_state['values']['account']['pass'];
$account->name = $form_state['values']['account']['name'];
$account->save();
// Load global $user and perform final login tasks.
$user = user_load(1);
user_login_finalize();
......
......@@ -342,8 +342,7 @@ function language_negotiation_method_invoke($method_id, $method = NULL) {
if (!isset($results[$method_id])) {
global $user;
// Get the enabled languages only.
$languages = language_list(TRUE);
$languages = language_list();
if (!isset($method)) {
$negotiation_info = language_negotiation_info();
......
......@@ -452,6 +452,8 @@ function module_enable($module_list, $enable_dependencies = TRUE) {
registry_update();
// Refresh the schema to include it.
drupal_get_schema(NULL, TRUE);
// Update the theme registry to include it.
drupal_theme_rebuild();
// Allow modules to react prior to the installation of a module.
module_invoke_all('modules_preinstall', array($module));
......@@ -574,6 +576,8 @@ function module_disable($module_list, $disable_dependents = TRUE) {
// Update the registry to remove the newly-disabled module.
registry_update();
_system_update_bootstrap_status();
// Update the theme registry to remove the newly-disabled module.
drupal_theme_rebuild();
}
}
......
......@@ -237,7 +237,7 @@ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callb
/**
* Get the theme registry.
*
* @param $complete
* @param bool $complete
* Optional boolean to indicate whether to return the complete theme registry
* array or an instance of the ThemeRegistry class. If TRUE, the complete
* theme registry array will be returned. This is useful if you want to
......@@ -252,7 +252,20 @@ function _drupal_theme_initialize($theme, $base_theme = array(), $registry_callb
* class.
*/
function theme_get_registry($complete = TRUE) {
static $theme_registry = array();
// Use the advanced drupal_static() pattern, since this is called very often.
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['registry'] = &drupal_static('theme_get_registry');
}
$theme_registry = &$drupal_static_fast['registry'];
// Initialize the theme, if this is called early in the bootstrap, or after
// static variables have been reset.
if (!is_array($theme_registry)) {
drupal_theme_initialize();
$theme_registry = array();
}
$key = (int) $complete;
if (!isset($theme_registry[$key])) {
......@@ -335,6 +348,7 @@ function _theme_save_registry($theme, $registry) {
* to add more theme hooks.
*/
function drupal_theme_rebuild() {
drupal_static_reset('theme_get_registry');
cache()->deletePrefix('theme_registry');
}
......@@ -943,8 +957,6 @@ function drupal_find_base_themes($themes, $key, $used_keys = array()) {
* @see themeable
*/
function theme($hook, $variables = array()) {
static $hooks = NULL;
// If called before all modules are loaded, we do not necessarily have a full
// theme registry to work with, and therefore cannot process the theme
// request properly. See also _theme_load_registry().
......@@ -952,10 +964,7 @@ function theme($hook, $variables = array()) {
throw new Exception(t('theme() may not be called until all modules are loaded.'));
}
if (!isset($hooks)) {
drupal_theme_initialize();
$hooks = theme_get_registry(FALSE);
}
$hooks = theme_get_registry(FALSE);
// If an array of hook candidates were passed, use the first one that has an
// implementation.
......@@ -2537,6 +2546,9 @@ function template_preprocess_html(&$variables) {
$variables['head_title_array'] = $head_title;
$variables['head_title'] = implode(' | ', $head_title);
// Display the html.tpl.php’s default mobile metatags for responsive design.
$variables['default_mobile_metatags'] = TRUE;
// Populate the page template suggestions.
if ($suggestions = theme_get_suggestions(arg(), 'html')) {
$variables['theme_hook_suggestions'] = $suggestions;
......
......@@ -38,7 +38,7 @@ function _drupal_maintenance_theme() {
// The bootstrap was not complete. So we are operating in a crippled
// environment, we need to bootstrap just enough to allow hook invocations
// to work. See _drupal_log_error().
if (!class_exists('Database', FALSE)) {
if (!class_exists('Drupal\Core\Database\Database', FALSE)) {
require_once DRUPAL_ROOT . '/core/includes/database.inc';
}
......
......@@ -184,20 +184,42 @@ function update_prepare_d8_language() {
db_drop_field('languages', 'prefix');
db_drop_field('languages', 'domain');
db_drop_field('languages', 'native');
db_drop_field('languages', 'enabled');
// Update language count.
variable_set('language_count', db_query('SELECT COUNT(language) FROM {languages}')->fetchField());
// Rename the languages table to language.
db_rename_table('languages', 'language');
// Finally install/enable the language module. We need to use the update
// specific version of this function to ensure schema conflicts don't happen
// due to our updated data.
// Install/enable the language module. We need to use the update specific
// version of this function to ensure schema conflicts don't happen due to
// our updated data.
$modules = array('language');
update_module_add_to_system($modules);
update_module_enable($modules);
// Rename 'language' column to 'langcode'.
require_once DRUPAL_ROOT . '/core/modules/language/language.install';
language_update_8000();
db_drop_primary_key('language');
$langcode_spec = array(
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
'default' => '',
'description' => "Language code, e.g. 'de' or 'en-US'.",
);
db_change_field('language', 'language', 'langcode', $langcode_spec, array('primary key' => array('langcode')));
// Update the 'language_default' system variable with the langcode change.
$language_default = variable_get('language_default');
if (!empty($language_default)) {
if (isset($language_default->language)) {
$language_default->langcode = $language_default->language;
unset($language_default->language);
}
unset($language_default->enabled);
variable_set('language_default', $language_default);
}
}
}
......
......@@ -46,7 +46,7 @@ function drupal_var_export($var, $prefix = '') {
$output = "'" . $var . "'";
}
}
else if (is_object($var) && get_class($var) === 'stdClass') {
elseif (is_object($var) && get_class($var) === 'stdClass') {
// var_export() will export stdClass objects using an undefined
// magic method __set_state() leaving the export broken. This
// workaround avoids this by casting the object as an array for
......
......@@ -57,7 +57,7 @@ function set($cid, $data, $expire = CACHE_PERMANENT, array $tags = array()) {}
*/
function delete($cid) {
try {
if (class_exists('Database')) {
if (class_exists('Drupal\Core\Database\Database')) {
parent::delete($cid);
}
}
......@@ -69,7 +69,7 @@ function delete($cid) {
*/
function deleteMultiple(array $cids) {
try {
if (class_exists('Database')) {
if (class_exists('Drupal\Core\Database\Database')) {
parent::deleteMultiple($cids);
}
}
......@@ -81,7 +81,7 @@ function deleteMultiple(array $cids) {
*/
function deletePrefix($prefix) {
try {
if (class_exists('Database')) {
if (class_exists('Drupal\Core\Database\Database')) {
parent::deletePrefix($prefix);
}
}
......@@ -90,7 +90,7 @@ function deletePrefix($prefix) {
function invalidateTags(array $tags) {
try {
if (class_exists('Database')) {
if (class_exists('Drupal\Core\Database\Database')) {
parent::invalidateTags($tags);
}
}
......@@ -102,7 +102,7 @@ function invalidateTags(array $tags) {
*/
function flush() {
try {
if (class_exists('Database')) {
if (class_exists('Drupal\Core\Database\Database')) {
parent::flush();
}
}
......
......@@ -38,9 +38,8 @@
* otherwise, will fail silently. So $var = &$object['foo'] will not throw an
* error, and $var will be populated with the contents of $object['foo'], but
* that data will be passed by value, not reference. For more information on
* the PHP limitation, see the note in the official PHP documentation atá
* http://php.net/manual/arrayaccess.offsetget.php on
* ArrayAccess::offsetGet().
* the PHP limitation, see the note in the official PHP documentation at
* http://php.net/manual/arrayaccess.offsetget.php on ArrayAccess::offsetGet().
*
* By default, the class accounts for caches where calling functions might
* request keys in the array that won't exist even after a cache rebuild. This
......
......@@ -131,24 +131,8 @@ Drupal.behaviors.blockDrag = {
var select = $(this);
tableDrag.rowObject = new tableDrag.row(row);
// Find the correct region and insert the row as the first in the region.
table.find('tr.region-message').each(function () {
if ($(this).is('.region-' + select[0].value + '-message')) {
// Add the new row and remove the old one.
$(this).after(row);
// Manually update weights and restripe.
tableDrag.updateFields(row.get(0));
tableDrag.rowObject.changed = true;
if (tableDrag.oldRowElement) {
$(tableDrag.oldRowElement).removeClass('drag-previous');
}
tableDrag.oldRowElement = row.get(0);
tableDrag.restripeTable();
tableDrag.rowObject.markChanged();
tableDrag.oldRowElement = row;
row.addClass('drag-previous');
}
});
// Find the correct region and insert the row as the last in the region.
table.find('.region-' + select[0].value + '-message').nextUntil('.region-message').last().before(row);
// Modify empty regions with added or removed fields.
checkEmptyRegions(table, row);
......
......@@ -468,10 +468,10 @@ function _block_rehash($theme = NULL) {
if (!isset($block['weight'])) {
$block['weight'] = 0;
}
if (!empty($block['region']) && $block['region'] != BLOCK_REGION_NONE && !isset($regions[$block['region']])) {
if (!empty($block['region']) && $block['region'] != BLOCK_REGION_NONE && !isset($regions[$block['region']]) && $block['status'] == 1) {
drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => $block['info'], '%region' => $block['region'])), 'warning');
// Disabled modules are moved into the BLOCK_REGION_NONE later so no
// need to move the bock to another region.
// need to move the block to another region.
$block['status'] = 0;
}
// Set region to none if not enabled and make sure status is set.
......@@ -628,9 +628,9 @@ function block_form_user_profile_form_alter(&$form, &$form_state) {
/**
* Implements hook_user_presave().
*/
function block_user_presave(&$edit, $account) {
if (isset($edit['block'])) {
$edit['data']['block'] = $edit['block'];
function block_user_presave($account) {
if (isset($account->block)) {
$account->data['block'] = $account->block;
}
}
......
......@@ -542,8 +542,8 @@ class BlockCacheTestCase extends DrupalWebTestCase {
$this->normal_user_alt = $this->drupalCreateUser();
// Sync the roles, since drupalCreateUser() creates separate roles for
// the same permission sets.
user_save($this->normal_user_alt, array('roles' => $this->normal_user->roles));
$this->normal_user_alt->roles = $this->normal_user->roles;
$this->normal_user_alt->save();
// Enable our test block.
$edit['blocks[block_test_test_cache][region]'] = 'sidebar_first';
......@@ -844,3 +844,255 @@ class BlockHiddenRegionTestCase extends DrupalWebTestCase {
$this->assertText('Search', t('Block was displayed on the front page.'));
}
}
/**
* Functional tests for the language list configuration forms.
*/
class BlockLanguageTestCase extends DrupalWebTestCase {