diff --git a/core/assets/vendor/domready/ready.min.js b/core/assets/vendor/domready/ready.min.js index c4ebe97..0d681c7 100644 --- a/core/assets/vendor/domready/ready.min.js +++ b/core/assets/vendor/domready/ready.min.js @@ -1,4 +1,4 @@ /*! - * domready (c) Dustin Diaz 2014 - License MIT + * domready (c) Dustin Diaz 2012 - License MIT */ -!function(e,t){typeof module!="undefined"?module.exports=t():typeof define=="function"&&typeof define.amd=="object"?define(t):this[e]=t()}("domready",function(){var e=[],t,n=document,r="DOMContentLoaded",i=/^loaded|^i|^c/.test(n.readyState);return i||n.addEventListener(r,t=function(){n.removeEventListener(r,t),i=1;while(t=e.shift())t()}),function(t){i?t():e.push(t)}}) +!function(e,t){typeof module!="undefined"?module.exports=t():typeof define=="function"&&typeof define.amd=="object"?define(t):this[e]=t()}("domready",function(e){function p(e){h=1;while(e=t.shift())e()}var t=[],n,r=!1,i=document,s=i.documentElement,o=s.doScroll,u="DOMContentLoaded",a="addEventListener",f="onreadystatechange",l="readyState",c=o?/^loaded|^c/:/^loaded|c/,h=c.test(i[l]);return i[a]&&i[a](u,n=function(){i.removeEventListener(u,n,r),p()},r),o&&i.attachEvent(f,n=function(){/^c/.test(i[l])&&(i.detachEvent(f,n),p())}),e=o?function(n){self!=top?h?n():t.push(n):function(){try{s.doScroll("left")}catch(t){return setTimeout(function(){e(n)},50)}n()}()}:function(e){h?e():t.push(e)}}) diff --git a/core/core.libraries.yml b/core/core.libraries.yml index e405d95..bc3cb37 100644 --- a/core/core.libraries.yml +++ b/core/core.libraries.yml @@ -25,7 +25,8 @@ ckeditor: domready: remote: https://github.com/ded/domready - version: 1.0.4 + # @todo Stable release required for Drupal 8.0. + version: master js: assets/vendor/domready/ready.min.js: { weight: -21 } diff --git a/core/includes/batch.inc b/core/includes/batch.inc index 0366c10..d78248d 100644 --- a/core/includes/batch.inc +++ b/core/includes/batch.inc @@ -47,38 +47,42 @@ function _batch_page(Request $request) { // Register database update for the end of processing. drupal_register_shutdown_function('_batch_shutdown'); - $build = array(); - // Add batch-specific CSS. + $attached = array('#attached' => array('css' => array())); foreach ($batch['sets'] as $batch_set) { if (isset($batch_set['css'])) { foreach ($batch_set['css'] as $css) { - $build['#attached']['css'][$css] = array(); + $attached['#attached']['css'][$css] = array(); } } } + drupal_render($attached); $op = $request->get('op', ''); + $output = NULL; switch ($op) { case 'start': - case 'do_nojs': // Display the full progress page on startup and on each additional // non-JavaScript iteration. - $current_set = _batch_current_set(); - $build['#title'] = $current_set['title']; - $build['content'] = _batch_progress_page(); + $output = _batch_progress_page(); break; case 'do': // JavaScript-based progress page callback. - return _batch_do(); + $output = _batch_do(); + break; + + case 'do_nojs': + // Non-JavaScript-based progress page. + $output = _batch_progress_page(); + break; case 'finished': - // _batch_finished() returns a RedirectResponse. - return _batch_finished(); + $output = _batch_finished(); + break; } - return $build; + return $output; } /** @@ -103,6 +107,7 @@ function _batch_progress_page() { $batch = &batch_get(); $current_set = _batch_current_set(); + drupal_set_title($current_set['title'], PASS_THROUGH); $new_op = 'do_nojs'; @@ -123,7 +128,6 @@ function _batch_progress_page() { $fallback = $current_set['error_message'] . '
' . $batch['error_message']; $fallback = array( '#theme' => 'maintenance_page', - '#title' => $current_set['title'], '#content' => $fallback, '#show_messages' => FALSE, ); @@ -191,7 +195,7 @@ function _batch_progress_page() { ), ), ); - return $build; + return drupal_render($build); } /** diff --git a/core/includes/common.inc b/core/includes/common.inc index 4cbeb7d..57095f7 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -4571,7 +4571,7 @@ function drupal_render_cache_by_query($query, $function, $expire = Cache::PERMAN * $granularity was passed in, more parts are added. */ function drupal_render_cid_parts($granularity = NULL) { - global $theme, $base_root; + global $theme, $base_root, $user; $cid_parts[] = $theme; @@ -4588,10 +4588,10 @@ function drupal_render_cid_parts($granularity = NULL) { // resource drag for sites with many users, so when a module is being // equivocal, we favor the less expensive 'PER_ROLE' pattern. if ($granularity & DRUPAL_CACHE_PER_ROLE) { - $cid_parts[] = 'r.' . implode(',', \Drupal::currentUser()->getRoles()); + $cid_parts[] = 'r.' . implode(',', $user->getRoles()); } elseif ($granularity & DRUPAL_CACHE_PER_USER) { - $cid_parts[] = 'u.' . \Drupal::currentUser()->id(); + $cid_parts[] = 'u.' . $user->id(); } if ($granularity & DRUPAL_CACHE_PER_PAGE) { diff --git a/core/includes/entity.inc b/core/includes/entity.inc index 51b0f79..fa5f370 100644 --- a/core/includes/entity.inc +++ b/core/includes/entity.inc @@ -241,7 +241,11 @@ function entity_revision_delete($entity_type, $revision_id) { function entity_load_by_uuid($entity_type_id, $uuid, $reset = FALSE) { $entity_type = \Drupal::entityManager()->getDefinition($entity_type_id); - if (!$uuid_key = $entity_type->getKey('uuid')) { + // Configuration entities do not use annotations to set the UUID key. + if ($entity_type->isSubclassOf('Drupal\Core\Config\Entity\ConfigEntityInterface')) { + $uuid_key = 'uuid'; + } + elseif (!$uuid_key = $entity_type->getKey('uuid')) { throw new EntityStorageException("Entity type $entity_type_id does not support UUIDs."); } diff --git a/core/includes/errors.inc b/core/includes/errors.inc index 56c276f..761b7bd 100644 --- a/core/includes/errors.inc +++ b/core/includes/errors.inc @@ -218,22 +218,19 @@ function _drupal_log_error($error, $fatal = FALSE) { } if ($fatal) { + // Should not translate the string to avoid errors producing more errors. + drupal_set_title('Error'); // We fallback to a maintenance page at this point, because the page generation // itself can generate errors. // Should not translate the string to avoid errors producing more errors. $message = 'The website has encountered an error. Please try again later.'; if ($is_installer) { // install_display_output() prints the output and ends script execution. - $output = array( - '#title' => 'Error', - '#markup' => $message, - ); - install_display_output($output, $GLOBALS['install_state']); + install_display_output($message, $GLOBALS['install_state']); } else { $output = array( '#theme' => 'maintenance_page', - '#title' => 'Error', '#content' => $message, ); $output = drupal_render($output); diff --git a/core/includes/form.inc b/core/includes/form.inc index 710b848..20edb53 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -9,7 +9,6 @@ use Drupal\Component\Utility\Number; use Drupal\Component\Utility\String; use Drupal\Component\Utility\UrlHelper; -use Drupal\Component\Utility\Xss; use Drupal\Core\Database\Database; use Drupal\Core\Language\Language; use Drupal\Core\Template\Attribute; @@ -877,9 +876,7 @@ function form_process_select($element) { } /** - * Prepares variables for select element templates. - * - * Default template: select.html.twig. + * Returns HTML for a select form element. * * It is possible to group options together; to do this, change the format of * $options to an associative array in which the keys are group labels, and the @@ -890,14 +887,15 @@ function form_process_select($element) { * - element: An associative array containing the properties of the element. * Properties used: #title, #value, #options, #description, #extra, * #multiple, #required, #name, #attributes, #size. + * + * @ingroup themeable */ -function template_preprocess_select(&$variables) { +function theme_select($variables) { $element = $variables['element']; element_set_attributes($element, array('id', 'name', 'size')); _form_set_attributes($element, array('form-select')); - $variables['attributes'] = $element['#attributes']; - $variables['options'] = form_select_options($element); + return '' . form_select_options($element) . ''; } /** @@ -1002,59 +1000,68 @@ function form_get_options($element, $key) { } /** - * Prepares variables for fieldset element templates. - * - * Default template: fieldset.html.twig. + * Returns HTML for a fieldset form element and its children. * - * @param array $variables + * @param $variables * An associative array containing: * - element: An associative array containing the properties of the element. - * Properties used: #attributes, #children, #description, #id, #title, - * #value. + * Properties used: #attributes, #children, #description, #id, + * #title, #value. + * + * @ingroup themeable */ -function template_preprocess_fieldset(&$variables) { +function theme_fieldset($variables) { $element = $variables['element']; element_set_attributes($element, array('id')); _form_set_attributes($element, array('form-wrapper')); - $variables['attributes'] = $element['#attributes']; - $variables['attributes']['class'][] = 'form-item'; + + $element['#attributes']['class'][] = 'form-item'; + + if (!empty($element['#description'])) { + $description_id = $element['#attributes']['id'] . '--description'; + $element['#attributes']['aria-describedby'] = $description_id; + } // If the element is required, a required marker is appended to the label. - $variables['required'] = ''; + // @see theme_form_element_label() + $required = ''; if (!empty($element['#required'])) { - $variables['required'] = array( + $marker = array( '#theme' => 'form_required_marker', '#element' => $element, ); + $required = drupal_render($marker); } - $variables['prefix'] = isset($element['#field_prefix']) ? $element['#field_prefix'] : NULL; - $variables['suffix'] = isset($element['#field_suffix']) ? $element['#field_suffix'] : NULL; - $variables['children'] = $element['#children']; - - // Build legend properties. - $variables['legend'] = array(); $legend_attributes = array(); if (isset($element['#title_display']) && $element['#title_display'] == 'invisible') { $legend_attributes['class'][] = 'visually-hidden'; } - $variables['legend']['attributes'] = new Attribute($legend_attributes); - $variables['legend']['title'] = (isset($element['#title']) && $element['#title'] !== '') ? Xss::filterAdmin($element['#title']) : ''; - // Build description properties. - $variables['description'] = array(); - if (!empty($element['#description'])) { - $description_id = $element['#attributes']['id'] . '--description'; - $description_attributes = array( - 'class' => 'description', - 'id' => $description_id, - ); - $variables['description']['attributes'] = new Attribute($description_attributes); - $variables['description']['content'] = $element['#description']; + $output = ''; - // Add the description's id to the fieldset aria attributes. - $variables['attributes']['aria-describedby'] = $description_id; + if ((isset($element['#title']) && $element['#title'] !== '') || !empty($element['#required'])) { + // Always wrap fieldset legends in a SPAN for CSS positioning. + $output .= ''; + $output .= t('!title!required', array('!title' => $element['#title'], '!required' => $required)); + $output .= ''; } + $output .= '
'; + + if (isset($element['#field_prefix'])) { + $output .= '' . $element['#field_prefix'] . ' '; + } + $output .= $element['#children']; + if (isset($element['#field_suffix'])) { + $output .= ' ' . $element['#field_suffix'] . ''; + } + if (!empty($element['#description'])) { + $attributes = array('class' => 'description', 'id' => $description_id); + $output .= '' . $element['#description'] . '
'; + } + $output .= ''; + $output .= "\n"; + return $output; } /** @@ -2672,16 +2679,16 @@ function form_pre_render_color($element) { } /** - * Prepares variables for form templates. - * - * Default template: form.html.twig. + * Returns HTML for a form. * * @param $variables * An associative array containing: * - element: An associative array containing the properties of the element. * Properties used: #action, #method, #attributes, #children + * + * @ingroup themeable */ -function template_preprocess_form(&$variables) { +function theme_form($variables) { $element = $variables['element']; if (isset($element['#action'])) { $element['#attributes']['action'] = UrlHelper::stripDangerousProtocols($element['#action']); @@ -2690,8 +2697,8 @@ function template_preprocess_form(&$variables) { if (empty($element['#attributes']['accept-charset'])) { $element['#attributes']['accept-charset'] = "UTF-8"; } - $variables['attributes'] = $element['#attributes']; - $variables['children'] = $element['#children']; + // Anonymous DIV to satisfy XHTML compliance. + return '
' . $element['#children'] . '
'; } /** diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 7f32f71..8d08d94 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -10,9 +10,6 @@ use Drupal\Core\Database\Database; use Drupal\Core\Database\DatabaseExceptionWrapper; use Drupal\Core\Database\Install\TaskException; -use Drupal\Core\Installer\Exception\AlreadyInstalledException; -use Drupal\Core\Installer\Exception\InstallerException; -use Drupal\Core\Installer\Exception\NoProfilesException; use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageManager; use Drupal\Core\StringTranslation\Translator\FileTranslation; @@ -92,24 +89,12 @@ function install_drupal($settings = array()) { $interactive = empty($settings); $install_state = $settings + array('interactive' => $interactive) + install_state_defaults(); - try { - // Begin the page request. This adds information about the current state of - // the Drupal installation to the passed-in array. - install_begin_request($install_state); - // Based on the installation state, run the remaining tasks for this page - // request, and collect any output. - $output = install_run_tasks($install_state); - } - catch (InstallerException $e) { - // In the non-interactive installer, exceptions are always thrown directly. - if (!$install_state['interactive']) { - throw $e; - } - $output = array( - '#title' => $e->getTitle(), - '#markup' => $e->getMessage(), - ); - } + // Begin the page request. This adds information about the current state of + // the Drupal installation to the passed-in array. + install_begin_request($install_state); + // Based on the installation state, run the remaining tasks for this page + // request, and collect any output. + $output = install_run_tasks($install_state); // After execution, all tasks might be complete, in which case // $install_state['installation_finished'] is TRUE. In case the last task @@ -541,7 +526,7 @@ function install_begin_request(&$install_state) { // Do not install over a configured settings.php. if (!empty($GLOBALS['databases'])) { - throw new AlreadyInstalledException($container->get('string_translation')); + throw new Exception(install_already_done_error()); } } @@ -551,7 +536,7 @@ function install_begin_request(&$install_state) { $config = glob(config_get_config_directory(CONFIG_ACTIVE_DIRECTORY) . '/*.' . FileStorage::getFileExtension()); if (!empty($config)) { $task = NULL; - throw new AlreadyInstalledException($container->get('string_translation')); + throw new Exception(install_already_done_error()); } } @@ -642,7 +627,7 @@ function install_run_task($task, &$install_state) { // rendered, which means the task is not complete yet. if (empty($form_state['executed'])) { $install_state['task_not_complete'] = TRUE; - return $form; + return drupal_render($form); } // Otherwise, return nothing so the next task will run in the same // request. @@ -662,7 +647,7 @@ function install_run_task($task, &$install_state) { drupal_form_submit($function, $form_state); $errors = form_get_errors($form_state); if (!empty($errors)) { - throw new InstallerException(implode("\n", $errors)); + throw new Exception(implode("\n", $errors)); } } } @@ -969,7 +954,7 @@ function install_full_redirect_url($install_state) { /** * Displays themed installer output and ends the page request. * - * Installation tasks should use #title to set the desired page + * Installation tasks should use drupal_set_title() to set the desired page * title, but otherwise this function takes care of theming the overall page * output during every step of the installation. * @@ -1015,17 +1000,7 @@ function install_display_output($output, $install_state) { ); drupal_add_region_content('sidebar_first', drupal_render($task_list)); } - $install_page = array( - '#theme' => 'install_page', - // $output has to be rendered here, because the install page template is not - // wrapped into the html template, which means that any #attached libraries - // in $output will not be loaded, because the wrapping HTML has been printed - // already. - '#content' => drupal_render($output), - ); - if (isset($output['#title'])) { - $install_page['#page']['#title'] = $output['#title']; - } + $install_page = array('#theme' => 'install_page', '#content' => $output); print drupal_render($install_page); exit; } @@ -1097,11 +1072,11 @@ function install_verify_completed_task() { } // Do not trigger an error if the database query fails, since the database // might not be set up yet. - catch (\Exception $e) { + catch (Exception $e) { } if (isset($task)) { if ($task == 'done') { - throw new AlreadyInstalledException(\Drupal::service('string_translation')); + throw new Exception(install_already_done_error()); } return $task; } @@ -1139,7 +1114,7 @@ function install_settings_form($form, &$form_state, &$install_state) { $conf_path = './' . conf_path(FALSE); $settings_file = $conf_path . '/settings.php'; - $form['#title'] = t('Database configuration'); + drupal_set_title(t('Database configuration')); $drivers = drupal_get_database_types(); $drivers_keys = array_keys($drivers); @@ -1330,21 +1305,26 @@ function install_settings_form_submit($form, &$form_state) { */ function install_select_profile(&$install_state) { if (empty($install_state['parameters']['profile'])) { - // If there are no profiles at all, installation cannot proceed. - if (empty($install_state['profiles'])) { - throw new NoProfilesException(\Drupal::service('string_translation')); - } - // Try to automatically select a profile. - if ($profile = _install_select_profile($install_state['profiles'])) { - $install_state['parameters']['profile'] = $profile; + // Try to find a profile. + $profile = _install_select_profile($install_state['profiles']); + if (empty($profile)) { + // We still don't have a profile, so display a form for selecting one. + // Only do this in the case of interactive installations, since this is + // not a real form with submit handlers (the database isn't even set up + // yet), rather just a convenience method for setting parameters in the + // URL. + if ($install_state['interactive']) { + include_once __DIR__ . '/form.inc'; + drupal_set_title(t('Select an installation profile')); + $form = drupal_get_form('install_select_profile_form', $install_state); + return drupal_render($form); + } + else { + throw new Exception(install_no_profile_error()); + } } else { - // The non-interactive installer requires a profile parameter. - if (!$install_state['interactive']) { - throw new InstallerException(t('Missing profile parameter.')); - } - // Otherwise, display a form to select a profile. - return drupal_get_form('install_select_profile_form', $install_state); + $install_state['parameters']['profile'] = $profile; } } } @@ -1404,10 +1384,9 @@ function _install_select_profile($profiles) { * @ingroup forms */ function install_select_profile_form($form, &$form_state, $install_state) { - $form['#title'] = t('Select an installation profile'); - $profiles = array(); $names = array(); + foreach ($install_state['profiles'] as $profile) { $details = install_profile_info($profile->name); // Skip this extension if its type is not profile. @@ -1581,7 +1560,10 @@ function install_select_language(&$install_state) { // translation files were found the form shows a select list of the // corresponding languages to choose from. if ($install_state['interactive']) { - return drupal_get_form('install_select_language_form', count($files) > 1 ? $files : array()); + drupal_set_title(t('Choose language')); + include_once __DIR__ . '/form.inc'; + $elements = drupal_get_form('install_select_language_form', count($files) > 1 ? $files : array()); + return drupal_render($elements); } // If we are performing a non-interactive installation. If only one language // (English) is available, assume the user knows what he is doing. Otherwise @@ -1592,7 +1574,7 @@ function install_select_language(&$install_state) { return; } else { - throw new InstallerException(t('Sorry, you must select a language to continue the installation.')); + throw new Exception(t('Sorry, you must select a language to continue the installation.')); } } } @@ -1613,8 +1595,6 @@ function install_select_language_form($form, &$form_state, $files = array()) { $select_options = array(); $browser_options = array(); - $form['#title'] = t('Choose language'); - // Build a select list with language names in native language for the user // to choose from. And build a list of available languages for the browser // to select the language default from. @@ -1893,6 +1873,24 @@ function _install_get_version_info($version) { } /** + * Indicates that there are no profiles available. + */ +function install_no_profile_error() { + drupal_set_title(t('No profiles available')); + return t('We were unable to find any installation profiles. Installation profiles tell us what modules to enable and what schema to install in the database. A profile is necessary to continue with the installation process.'); +} + +/** + * Indicates that Drupal has already been installed. + */ +function install_already_done_error() { + global $base_url; + + drupal_set_title(t('Drupal already installed')); + return t('
  • To start over, you must empty your existing database, delete your active configuration, and copy default.settings.php over settings.php.
  • To install to a different database, edit the appropriate settings.php file in the sites folder.
  • To locate your active configuration, view the appropriate settings.php file in the sites folder.
  • To upgrade an existing installation, proceed to the update script.
  • View your existing site.
', array('@base-url' => $base_url)); +} + +/** * Loads information about the chosen profile during installation. * * @param $install_state @@ -1908,7 +1906,7 @@ function install_load_profile(&$install_state) { $install_state['profile_info'] = install_profile_info($install_state['parameters']['profile'], $install_state['parameters']['langcode']); } else { - throw new InstallerException(t('Sorry, the profile you have chosen cannot be loaded.')); + throw new Exception(t('Sorry, the profile you have chosen cannot be loaded.')); } } @@ -2074,7 +2072,7 @@ function _install_prepare_import($langcode) { * @ingroup forms */ function install_configure_form($form, &$form_state, &$install_state) { - $form['#title'] = t('Configure site'); + drupal_set_title(t('Configure site')); // Warn about settings.php permissions risk $settings_dir = conf_path(); @@ -2176,6 +2174,8 @@ function install_finished(&$install_state) { // registered by the installation profile are registered correctly. drupal_flush_all_caches(); + drupal_set_title(t('@drupal installation complete', array('@drupal' => drupal_install_profile_distribution_name())), PASS_THROUGH); + $messages = drupal_set_message(); $output = '

' . t('Congratulations, you installed @drupal!', array('@drupal' => drupal_install_profile_distribution_name())) . '

'; // Ensure the URL that is generated for the home page does not have 'install.php' @@ -2197,11 +2197,7 @@ function install_finished(&$install_state) { $snapshot = \Drupal::service('config.storage.snapshot'); \Drupal::service('config.manager')->createSnapshot($active, $snapshot); - $build = array( - '#title' => t('@drupal installation complete', array('@drupal' => drupal_install_profile_distribution_name())), - '#markup' => $output, - ); - return $build; + return $output; } /** @@ -2529,7 +2525,7 @@ function install_check_requirements($install_state) { * in the URL. Otherwise, no output is returned, so that the next task can be * run in the same page request. * - * @throws \Drupal\Core\Installer\Exception\InstallerException + * @thows \Exception */ function install_display_requirements($install_state, $requirements) { // Check the severity of the requirements reported. @@ -2540,13 +2536,14 @@ function install_display_requirements($install_state, $requirements) { // and indicating a desire to continue anyway. See drupal_requirements_url(). if ($severity == REQUIREMENT_ERROR || ($severity == REQUIREMENT_WARNING && empty($install_state['parameters']['continue']))) { if ($install_state['interactive']) { - $build['#title'] = t('Requirements problem'); - $build['report'] = array( + drupal_set_title(t('Requirements problem')); + $status_report = array( '#theme' => 'status_report', '#requirements' => $requirements, - '#suffix' => t('Check the messages and try again.', array('!url' => check_url(drupal_requirements_url($severity)))), ); - return $build; + $status_report = drupal_render($status_report); + $status_report .= t('Check the messages and try again.', array('!url' => check_url(drupal_requirements_url($severity)))); + return $status_report; } else { // Throw an exception showing any unmet requirements. @@ -2560,7 +2557,7 @@ function install_display_requirements($install_state, $requirements) { } } if (!empty($failures)) { - throw new InstallerException(implode("\n\n", $failures)); + throw new \Exception(implode("\n\n", $failures)); } } } @@ -2728,7 +2725,7 @@ function install_configure_form_submit($form, &$form_state) { $account->pass = $form_state['values']['account']['pass']; $account->name = $form_state['values']['account']['name']; $account->save(); - // Load current user and perform final login tasks. + // Load global $user and perform final login tasks. $account = user_load(1); user_login_finalize($account); diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 3a8ce65..1526113 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -88,7 +88,7 @@ function drupal_theme_access($theme) { * Initializes the theme system by loading the theme. */ function drupal_theme_initialize() { - global $theme, $theme_key; + global $theme, $user, $theme_key; // If $theme is already set, assume the others are set, too, and do nothing if (isset($theme)) { @@ -1693,7 +1693,8 @@ function theme_table($variables) { */ function theme_mark($variables) { $type = $variables['status']; - if (\Drupal::currentUser()->isAuthenticated()) { + global $user; + if ($user->isAuthenticated()) { if ($type == MARK_NEW) { return ' ' . t('new') . ''; } @@ -1823,16 +1824,20 @@ function theme_indentation($variables) { } /** - * Prepares variables for container templates. + * Returns HTML to wrap child elements in a container. * - * Default template: container.html.twig. + * Used for grouped form items. Can also be used as a #theme_wrapper for any + * renderable element, to surround it with a
and add attributes such as + * classes or an HTML id. * - * @param array $variables + * @param $variables * An associative array containing: * - element: An associative array containing the properties of the element. * Properties used: #id, #attributes, #children. + * + * @ingroup themeable */ -function template_preprocess_container(&$variables) { +function theme_container($variables) { $element = $variables['element']; // Ensure #attributes is set. $element += array('#attributes' => array()); @@ -1847,8 +1852,7 @@ function template_preprocess_container(&$variables) { $element['#attributes']['class'][] = 'form-wrapper'; } - $variables['children'] = $element['#children']; - $variables['attributes'] = $element['#attributes']; + return '' . $element['#children'] . '
'; } /** @@ -2116,6 +2120,9 @@ function template_preprocess_html(&$variables) { * Uses the arg() function to generate a series of page template suggestions * based on the current path. * + * Any changes to variables in this preprocessor should also be changed inside + * template_preprocess_maintenance_page() to keep all of them consistent. + * * @see drupal_render_page() */ function template_preprocess_page(&$variables) { @@ -2370,12 +2377,19 @@ function template_preprocess_maintenance_page(&$variables) { $variables['head_title_array'] = $head_title; $variables['head_title'] = implode(' | ', $head_title); + $variables['base_path'] = base_path(); $variables['front_page'] = url(); + $variables['breadcrumb'] = ''; + $variables['feed_icons'] = ''; $variables['help'] = ''; $variables['language'] = $language_interface; + $variables['language']->dir = $language_interface->direction ? 'rtl' : 'ltr'; $variables['logo'] = theme_get_setting('logo.url'); + $variables['main_menu'] = array(); + $variables['secondary_menu'] = array(); $variables['site_name'] = (theme_get_setting('features.name') ? String::checkPlain($site_name) : ''); $variables['site_slogan'] = (theme_get_setting('features.slogan') ? filter_xss_admin($site_slogan) : ''); + $variables['tabs'] = ''; // Compile a list of classes that are going to be applied to the body element. $variables['attributes']['class'][] = 'maintenance-page'; @@ -2433,7 +2447,6 @@ function template_preprocess_maintenance_page(&$variables) { */ function template_preprocess_install_page(&$variables) { template_preprocess_maintenance_page($variables); - $variables['attributes']['class'][] = 'install-page'; // Override the site name that is displayed on the page, since Drupal is // still in the process of being installed. $variables['site_name'] = drupal_install_profile_distribution_name(); @@ -2548,7 +2561,7 @@ function drupal_common_theme() { 'template' => 'maintenance-page', ), 'install_page' => array( - 'variables' => array('content' => NULL, 'show_messages' => TRUE, 'page' => array()), + 'variables' => array('content' => NULL, 'show_messages' => TRUE), 'template' => 'install-page', ), 'task_list' => array( @@ -2587,11 +2600,9 @@ function drupal_common_theme() { ), 'select' => array( 'render element' => 'element', - 'template' => 'select', ), 'fieldset' => array( 'render element' => 'element', - 'template' => 'fieldset', ), 'details' => array( 'render element' => 'element', @@ -2608,7 +2619,6 @@ function drupal_common_theme() { ), 'form' => array( 'render element' => 'element', - 'template' => 'form', ), 'textarea' => array( 'render element' => 'element', @@ -2633,7 +2643,6 @@ function drupal_common_theme() { ), 'container' => array( 'render element' => 'element', - 'template' => 'container', ), ); } diff --git a/core/includes/update.inc b/core/includes/update.inc index 0bca244..fc1e0af 100644 --- a/core/includes/update.inc +++ b/core/includes/update.inc @@ -147,6 +147,7 @@ function update_check_requirements($skip_warnings = FALSE) { // them if the caller has indicated they should be skipped. if ($severity == REQUIREMENT_ERROR || ($severity == REQUIREMENT_WARNING && !$skip_warnings)) { update_task_list('requirements'); + drupal_set_title('Requirements problem'); $status = array( '#theme' => 'status_report', '#requirements' => $requirements, @@ -156,7 +157,6 @@ function update_check_requirements($skip_warnings = FALSE) { drupal_add_http_header('Content-Type', 'text/html; charset=utf-8'); $maintenance_page = array( '#theme' => 'maintenance_page', - '#title' => 'Requirements problem', '#content' => $status_report, ); print drupal_render($maintenance_page); diff --git a/core/lib/Drupal/Component/Utility/Xss.php b/core/lib/Drupal/Component/Utility/Xss.php index df96015..2797d31 100644 --- a/core/lib/Drupal/Component/Utility/Xss.php +++ b/core/lib/Drupal/Component/Utility/Xss.php @@ -70,6 +70,8 @@ public static function filter($string, $html_tags = array('a', 'em', 'strong', ' if (!Unicode::validateUtf8($string)) { return ''; } + // Store the text format. + static::split($html_tags, TRUE, $mode); // Remove NULL characters (ignored by some browsers). $string = str_replace(chr(0), '', $string); // Remove Netscape 4 JS entities. @@ -84,10 +86,7 @@ public static function filter($string, $html_tags = array('a', 'em', 'strong', ' $string = preg_replace('/&#[Xx]0*((?:[0-9A-Fa-f]{2})+;)/', '&#x\1', $string); // Named entities. $string = preg_replace('/&([A-Za-z][A-Za-z0-9]*;)/', '&\1', $string); - $html_tags = array_flip($html_tags); - $splitter = function ($matches) use ($html_tags, $mode) { - return static::split($matches[1], $html_tags, $mode); - }; + return preg_replace_callback('% ( <(?=[^a-zA-Z!/]) # a lone < @@ -97,7 +96,7 @@ public static function filter($string, $html_tags = array('a', 'em', 'strong', ' <[^>]*(>|$) # a string that starts with a <, up until the > or the end of the string | # or > # just a > - )%x', $splitter, $string); + )%x', 'static::split', $string); } /** @@ -124,20 +123,32 @@ public static function filterAdmin($string) { /** * Processes an HTML tag. * - * @param string $string - * The HTML tag to process. - * @param array $html_tags - * An array where the keys are the allowed tags and the values are not - * used. - * @param bool $split_mode - * Whether $html_tags is a list of allowed (if FILTER_MODE_WHITELIST) or + * @param array $matches + * An array with various meaning depending on the value of $store. + * If $store is TRUE then the array contains the allowed tags. + * If $store is FALSE then the array has one element, the HTML tag to process. + * @param bool $store + * Whether to store $matches. + * @param bool $mode + * (optional) Ignored when $store is FALSE, otherwise used to determine + * whether $matches is a list of allowed (if FILTER_MODE_WHITELIST) or * disallowed (if FILTER_MODE_BLACKLIST) HTML tags. * * @return string * If the element isn't allowed, an empty string. Otherwise, the cleaned up * version of the HTML element. */ - protected static function split($string, $html_tags, $split_mode) { + protected static function split($matches, $store = FALSE, $mode = Xss::FILTER_MODE_WHITELIST) { + static $html_tags, $split_mode; + + if ($store) { + $html_tags = array_flip($matches); + $split_mode = $mode; + return; + } + + $string = $matches[1]; + if (substr($string, 0, 1) != '<') { // We matched a lone ">" character. return '>'; diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php index 18e0260..87b43f7 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php @@ -174,7 +174,11 @@ public function isSyncing() { * {@inheritdoc} */ public function createDuplicate() { - $duplicate = parent::createDuplicate(); + $duplicate = clone $this; + $duplicate->set($this->getEntityType()->getKey('id'), NULL); + + // @todo Inject the UUID service into the Entity class once possible. + $duplicate->set('uuid', \Drupal::service('uuid')->generate()); // Prevent the new duplicate from being misinterpreted as a rename. $duplicate->setOriginalId(NULL); diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php index 9a61693..e8f8088 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php @@ -51,15 +51,6 @@ public function getConfigPrefix() { /** * {@inheritdoc} */ - public function getKeys() { - // Always add a default 'uuid' key. - return array('uuid' => 'uuid') + parent::getKeys(); - } - - - /** - * {@inheritdoc} - */ public function getBaseTable() { return FALSE; } diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php index ec27d7e..8f4f66c 100644 --- a/core/lib/Drupal/Core/CoreServiceProvider.php +++ b/core/lib/Drupal/Core/CoreServiceProvider.php @@ -125,6 +125,7 @@ public static function registerTwig(ContainerBuilder $container) { // When in the installer, twig_cache must be FALSE until we know the // files folder is writable. 'cache' => drupal_installation_attempted() ? FALSE : settings()->get('twig_cache', TRUE), + 'base_template_class' => 'Drupal\Core\Template\TwigTemplate', // @todo Remove in followup issue // @see http://drupal.org/node/1712444. 'autoescape' => FALSE, diff --git a/core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php index a2aa7d8..5bdf61c 100644 --- a/core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php @@ -78,13 +78,13 @@ public function onException(GetResponseForExceptionEvent $event) { * {@inheritdoc} * * The priority for request must be higher than the highest event subscriber - * accessing the current user. + * accessing the global $user. * The priority for the response must be as low as possible allowing e.g the * Cookie provider to send all relevant session data to the user. */ public static function getSubscribedEvents() { // Priority must be higher than LanguageRequestSubscriber as LanguageManager - // access current user in case language module enabled. + // access global $user in case language module enabled. $events[KernelEvents::REQUEST][] = array('onKernelRequestAuthenticate', 300); $events[KernelEvents::RESPONSE][] = array('onRespond', 0); $events[KernelEvents::EXCEPTION][] = array('onException', 0); diff --git a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php index 93bfb42..39aad11 100644 --- a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php @@ -44,9 +44,9 @@ public function onKernelRequestMaintenance(GetResponseEvent $event) { if ($request->attributes->get('_maintenance') != MENU_SITE_ONLINE && !($response instanceof RedirectResponse)) { // Deliver the 503 page. drupal_maintenance_theme(); + drupal_set_title(t('Site under maintenance')); $maintenance_page = array( '#theme' => 'maintenance_page', - '#title' => t('Site under maintenance'), '#content' => filter_xss_admin( t(\Drupal::config('system.maintenance')->get('message'), array('@site' => \Drupal::config('system.site')->get('name'))) ), diff --git a/core/lib/Drupal/Core/Field/Annotation/FieldFormatter.php b/core/lib/Drupal/Core/Field/Annotation/FieldFormatter.php index fc4a4c4..11f2246 100644 --- a/core/lib/Drupal/Core/Field/Annotation/FieldFormatter.php +++ b/core/lib/Drupal/Core/Field/Annotation/FieldFormatter.php @@ -74,13 +74,4 @@ class FieldFormatter extends Plugin { */ public $settings = array(); - /** - * An integer to determine the weight of this formatter relative to other - * formatter in the Field UI when selecting a formatter for a given field - * instance. - * - * @var int optional - */ - public $weight = NULL; - } diff --git a/core/lib/Drupal/Core/Field/FormatterBase.php b/core/lib/Drupal/Core/Field/FormatterBase.php index 1b4287f..35bbf33 100644 --- a/core/lib/Drupal/Core/Field/FormatterBase.php +++ b/core/lib/Drupal/Core/Field/FormatterBase.php @@ -106,7 +106,7 @@ public function view(FieldItemListInterface $items) { } } - $addition = array_merge($info, $elements); + $addition[$field_name] = array_merge($info, $elements); } return $addition; diff --git a/core/lib/Drupal/Core/Field/FormatterPluginManager.php b/core/lib/Drupal/Core/Field/FormatterPluginManager.php index d81ff57..b825272 100644 --- a/core/lib/Drupal/Core/Field/FormatterPluginManager.php +++ b/core/lib/Drupal/Core/Field/FormatterPluginManager.php @@ -167,15 +167,13 @@ public function prepareConfiguration($field_type, array $configuration) { */ public function getOptions($field_type = NULL) { if (!isset($this->formatterOptions)) { - $options = array(); $field_types = $this->fieldTypeManager->getDefinitions(); - $formatter_types = $this->getDefinitions(); - uasort($formatter_types, array('Drupal\Component\Utility\SortArray', 'sortByWeightElement')); - foreach ($formatter_types as $name => $formatter_type) { - foreach ($formatter_type['field_types'] as $formatter_field_type) { + $options = array(); + foreach ($this->getDefinitions() as $name => $formatter) { + foreach ($formatter['field_types'] as $formatter_field_type) { // Check that the field type exists. if (isset($field_types[$formatter_field_type])) { - $options[$formatter_field_type][$name] = $formatter_type['label']; + $options[$formatter_field_type][$name] = $formatter['label']; } } } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php deleted file mode 100644 index d5e0c17..0000000 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php +++ /dev/null @@ -1,46 +0,0 @@ - $item) { - // The text value has no text format assigned to it, so the user input - // should equal the output, including newlines. - $elements[$delta] = array('#markup' => nl2br(String::checkPlain($item->value))); - } - - return $elements; - } - -} diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php index 7c27fff..93fc622 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/EmailItem.php @@ -18,9 +18,7 @@ * id = "email", * label = @Translation("E-mail"), * description = @Translation("An entity field containing an e-mail value."), - * configurable = FALSE, - * default_widget = "string", - * default_formatter = "string" + * configurable = FALSE * ) */ class EmailItem extends FieldItemBase { diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php index 2ef9971..5d09d90 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/StringItem.php @@ -21,9 +21,7 @@ * settings = { * "max_length" = "255" * }, - * configurable = FALSE, - * default_widget = "string", - * default_formatter = "string" + * configurable = FALSE * ) */ class StringItem extends FieldItemBase { @@ -62,12 +60,7 @@ public function getConstraints() { if ($max_length = $this->getSetting('max_length')) { $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager(); $constraints[] = $constraint_manager->create('ComplexData', array( - 'value' => array( - 'Length' => array( - 'max' => $max_length, - 'maxMessage' => t('%name: may not be longer than @max characters.', array('%name' => $this->getFieldDefinition()->getLabel(), '@max' => $max_length)), - ), - ), + 'value' => array('Length' => array('max' => $max_length)) )); } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/StringWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/StringWidget.php deleted file mode 100644 index 8d13286..0000000 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/StringWidget.php +++ /dev/null @@ -1,82 +0,0 @@ - 'number', - '#title' => t('Size of textfield'), - '#default_value' => $this->getSetting('size'), - '#required' => TRUE, - '#min' => 1, - ); - $element['placeholder'] = array( - '#type' => 'textfield', - '#title' => t('Placeholder'), - '#default_value' => $this->getSetting('placeholder'), - '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'), - ); - return $element; - } - - /** - * {@inheritdoc} - */ - public function settingsSummary() { - $summary = array(); - - $summary[] = t('Textfield size: !size', array('!size' => $this->getSetting('size'))); - $placeholder = $this->getSetting('placeholder'); - if (!empty($placeholder)) { - $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder)); - } - - return $summary; - } - - /** - * {@inheritdoc} - */ - public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) { - $element['value'] = $element + array( - '#type' => 'textfield', - '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL, - '#size' => $this->getSetting('size'), - '#placeholder' => $this->getSetting('placeholder'), - '#maxlength' => $this->getFieldSetting('max_length'), - '#attributes' => array('class' => array('text-full')), - ); - - return $element; - } - -} diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php index 6432fb1..d770871 100644 --- a/core/lib/Drupal/Core/Field/WidgetBase.php +++ b/core/lib/Drupal/Core/Field/WidgetBase.php @@ -111,21 +111,25 @@ public function form(FieldItemListInterface $items, array &$form, array &$form_s // Most widgets need their internal structure preserved in submitted values. $elements += array('#tree' => TRUE); - return array( - // Aid in theming of widgets by rendering a classified container. - '#type' => 'container', - // Assign a different parent, to keep the main id for the widget itself. - '#parents' => array_merge($parents, array($field_name . '_wrapper')), - '#attributes' => array( - 'class' => array( - 'field-type-' . drupal_html_class($this->fieldDefinition->getType()), - 'field-name-' . drupal_html_class($field_name), - 'field-widget-' . drupal_html_class($this->getPluginId()), + $return = array( + $field_name => array( + // Aid in theming of widgets by rendering a classified container. + '#type' => 'container', + // Assign a different parent, to keep the main id for the widget itself. + '#parents' => array_merge($parents, array($field_name . '_wrapper')), + '#attributes' => array( + 'class' => array( + 'field-type-' . drupal_html_class($this->fieldDefinition->getType()), + 'field-name-' . drupal_html_class($field_name), + 'field-widget-' . drupal_html_class($this->getPluginId()), + ), ), + '#access' => $items->access('edit'), + 'widget' => $elements, ), - '#access' => $items->access('edit'), - 'widget' => $elements, ); + + return $return; } /** diff --git a/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php b/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php deleted file mode 100644 index 3f16728..0000000 --- a/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php +++ /dev/null @@ -1,39 +0,0 @@ -stringTranslation = $string_translation; - - $title = $this->t('Drupal already installed'); - $message = $this->t('
    -
  • To start over, you must empty your existing database, delete your active configuration, and copy default.settings.php over settings.php.
  • -
  • To install to a different database, edit the appropriate settings.php file in the sites folder.
  • -
  • To locate your active configuration, view the appropriate settings.php file in the sites folder.
  • -
  • To upgrade an existing installation, proceed to the update script.
  • -
  • View your existing site.
  • -
', array( - '@base-url' => $GLOBALS['base_url'], - )); - parent::__construct($message, $title); - } - -} diff --git a/core/lib/Drupal/Core/Installer/Exception/InstallerException.php b/core/lib/Drupal/Core/Installer/Exception/InstallerException.php deleted file mode 100644 index e8c1ec3..0000000 --- a/core/lib/Drupal/Core/Installer/Exception/InstallerException.php +++ /dev/null @@ -1,64 +0,0 @@ -title = $title; - } - - /** - * Returns the exception page title. - * - * @return string - */ - public function getTitle() { - return $this->title; - } - - /** - * Translates a string using StringTranslation. - * - * @see \Drupal\Core\StringTranslation\TranslationInterface::translate() - */ - protected function t($string, array $args = array(), array $options = array()) { - return $this->stringTranslation->translate($string, $args, $options); - } - -} diff --git a/core/lib/Drupal/Core/Installer/Exception/NoProfilesException.php b/core/lib/Drupal/Core/Installer/Exception/NoProfilesException.php deleted file mode 100644 index cc8d596..0000000 --- a/core/lib/Drupal/Core/Installer/Exception/NoProfilesException.php +++ /dev/null @@ -1,31 +0,0 @@ -stringTranslation = $string_translation; - - $title = $this->t('No profiles available'); - $message = $this->t('We were unable to find any installation profiles. Installation profiles tell us what modules to enable and what schema to install in the database. A profile is necessary to continue with the installation process.'); - parent::__construct($message, $title); - } - -} diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php index 7efae71..9cd17b0 100644 --- a/core/lib/Drupal/Core/Template/TwigExtension.php +++ b/core/lib/Drupal/Core/Template/TwigExtension.php @@ -21,24 +21,25 @@ public function getFunctions() { // @todo re-add unset => twig_unset if this is really needed return array( // @todo Remove URL function once http://drupal.org/node/1778610 is resolved. - new \Twig_SimpleFunction('url', 'url'), - // This function will receive a renderable array, if an array is detected. - new \Twig_SimpleFunction('render_var', 'twig_render_var'), + 'url' => new \Twig_Function_Function('url'), + // These functions will receive a TwigReference object, if a render array is detected + 'hide' => new TwigReferenceFunction('twig_hide'), + 'render_var' => new TwigReferenceFunction('twig_render_var'), + 'show' => new TwigReferenceFunction('twig_show'), ); } public function getFilters() { return array( - new \Twig_SimpleFilter('t', 't'), - new \Twig_SimpleFilter('trans', 't'), + 't' => new \Twig_Filter_Function('t'), + 'trans' => new \Twig_Filter_Function('t'), // The "raw" filter is not detectable when parsing "trans" tags. To detect // which prefix must be used for translation (@, !, %), we must clone the // "raw" filter and give it identifiable names. These filters should only // be used in "trans" tags. // @see TwigNodeTrans::compileString() - new \Twig_SimpleFilter('passthrough', 'twig_raw_filter'), - new \Twig_SimpleFilter('placeholder', 'twig_raw_filter'), - new \Twig_SimpleFilter('without', 'twig_without'), + 'passthrough' => new \Twig_Filter_Function('twig_raw_filter'), + 'placeholder' => new \Twig_Filter_Function('twig_raw_filter'), ); } @@ -52,6 +53,8 @@ public function getNodeVisitors() { public function getTokenParsers() { return array( + new TwigFunctionTokenParser('hide'), + new TwigFunctionTokenParser('show'), new TwigTransTokenParser(), ); } diff --git a/core/lib/Drupal/Core/Template/TwigNodeExpressionNameReference.php b/core/lib/Drupal/Core/Template/TwigNodeExpressionNameReference.php new file mode 100644 index 0000000..c66d73f --- /dev/null +++ b/core/lib/Drupal/Core/Template/TwigNodeExpressionNameReference.php @@ -0,0 +1,29 @@ +getAttribute('name'); + $compiler + ->raw('$this->getContextReference($context, ') + ->string($name) + ->raw(')'); + } + +} diff --git a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php index 64315fb..710faa0 100644 --- a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php +++ b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php @@ -19,9 +19,36 @@ class TwigNodeVisitor implements \Twig_NodeVisitorInterface { /** - * {@inheritdoc} + * TRUE when this node is a function getting arguments by reference. + * + * For example: 'hide' or 'render' are such functions. + * + * @var bool + */ + protected $isReference = FALSE; + + /** + * Implements Twig_NodeVisitorInterface::enterNode(). */ function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) { + if ($node instanceof \Twig_Node_Expression_Function) { + $name = $node->getAttribute('name'); + $func = $env->getFunction($name); + + // Optimization: Do not support nested functions. + if ($this->isReference && $func instanceof \Twig_Function_Function) { + $this->isReference = FALSE; + } + if ($func instanceof TwigReferenceFunction) { + // We need to create a TwigReference + $this->isReference = TRUE; + } + } + if ($node instanceof \Twig_Node_Print) { + // Our injected render_var needs arguments passed by reference -- in case of render array + $this->isReference = TRUE; + } + return $node; } @@ -35,14 +62,26 @@ function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) { */ function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) { if ($node instanceof \Twig_Node_Print) { + $this->isReference = FALSE; + $class = get_class($node); - $line = $node->getLine(); return new $class( - new \Twig_Node_Expression_Function('render_var', new \Twig_Node(array($node->getNode('expr'))), $line), - $line + new \Twig_Node_Expression_Function('render_var', new \Twig_Node(array($node->getNode('expr'))), $node->getLine()), + $node->getLine() ); } + if ($this->isReference) { + if ($node instanceof \Twig_Node_Expression_Name) { + $name = $node->getAttribute('name'); + return new TwigNodeExpressionNameReference($name, $node->getLine()); + } + elseif ($node instanceof \Twig_Function_Function) { + // Do something! + $this->isReference = FALSE; + } + } + return $node; } diff --git a/core/lib/Drupal/Core/Template/TwigReference.php b/core/lib/Drupal/Core/Template/TwigReference.php new file mode 100644 index 0000000..0b8b506 --- /dev/null +++ b/core/lib/Drupal/Core/Template/TwigReference.php @@ -0,0 +1,131 @@ +setReference($variable); + * @endcode + * + * When a TwigReference is accessed via the offsetGet method the resulting + * reference is again wrapped within a TwigReference. Therefore references to + * render arrays within render arrays are also retained. + * + * To unwrap TwigReference objects the reference can be retrieved out of the + * object by calling the getReference() method like this: + * @code + * $variable = &$obj->getReference(); + * @endcode + * This allows render(), hide() and show() to access the original variable and + * change it. The process of unwrapping and passing by reference to this + * functions is done transparently by the TwigReferenceFunctions helper class. + * + * @see TwigReferenceFunction + * @see TwigReferenceFunctions + */ +class TwigReference extends \ArrayObject { + + /** + * Holds an internal reference to the original array. + * + * @var array + */ + protected $writableRef = array(); + + /** + * Constructs a \Drupal\Core\Template\TwigReference object. + * + * The argument to the constructor is ignored as it is not safe that this will + * always be a reference. + * + * To set a reference use: + * @code + * $obj = new TwigReference(); + * $obj->setReference($variable); + * @endcode + * + * @param $array + * The array parameter is ignored and not passed to the parent + */ + public function __construct($array = NULL) { + parent::__construct(); + } + + /** + * Sets a reference in the internal storage. + * + * @param $array + * The array to set as internal reference. + */ + public function setReference(&$array) { + $this->exchangeArray($array); + $this->writableRef = &$array; + } + + /** + * Gets a reference to the internal storage. + * + * Should be called like: + * @code + * $reference = &$obj->getReference(); + * @endcode + * + * @return + * Returns the stored internal reference. + */ + public function &getReference() { + return $this->writableRef; + } + + /** + * Sets offset in internal reference and internal storage to value. + * + * This is just for completeness, but should never be used, because + * twig cannot set properties and should not. + * + * @link http://php.net/manual/en/arrayaccess.offsetset.php + * @param mixed $offset + * The offset to assign the value to. + * @param mixed $value + * The value to set. + */ + public function offsetSet($offset, $value) { + $this->writableRef[$offset] = $value; + parent::offsetSet($offset, $value); + } + + /** + * Retrieves offset from internal reference. + * + * In case of a render array, it is wrapped again within a TwigReference + * object. + * + * @param mixed $offset + * The offset to retrieve. + * + * @return mixed + * Returns a TwigReference object wrapping the array if the retrieved offset + * is a complex array (i.e. not an attribute). Else it returns the retrived + * offset directly. + */ + public function offsetGet($offset) { + if (!is_array($this->writableRef[$offset]) || $offset[0] == '#') { + return $this->writableRef[$offset]; + } + + // Wrap the returned array in a new TwigReference. + $x = clone $this; // clone is faster than new + $x->setReference($this->writableRef[$offset]); + return $x; + } +} diff --git a/core/lib/Drupal/Core/Template/TwigReferenceFunction.php b/core/lib/Drupal/Core/Template/TwigReferenceFunction.php new file mode 100644 index 0000000..6ca4cbd --- /dev/null +++ b/core/lib/Drupal/Core/Template/TwigReferenceFunction.php @@ -0,0 +1,14 @@ +setReference($content); + * return $obj; + * } + * + * // [...] + * // Simplified, generated twig code + * $_content_ = getContextReference($content); + * + * Drupal\Core\Template\TwigReferenceFunctions::hide( + * getAttribute($_content_, 'links') + * ); + * @endcode + * A TwigReference object is passed to the __callStatic function of + * TwigReferenceFunctions. The method unwraps the TwigReference and calls the + * hide() method essentially with a reference to $content['links']. + * + * Therefore the hidden property is correctly set and a successive call to + * render() will not render the content twice. + * + * @see TwigReference + * @see TwigReferenceFunction + * @see TwigFactory + * + */ +class TwigReferenceFunctions { + + /** + * Magic function to call functions called from twig templates with a + * reference to the original variable. + * + * This checks if the array provided by value is containing a reference to + * the original version. If yes it replaces the argument with its reference. + * + * @param $name + * The name of the function to call. + * @param $arguments + * The arguments to process and pass to the called function. + * + * @return mixed + * Returns the output of the called function. + * + * @see TwigReference + */ + public static function __callStatic($name, $arguments) { + foreach ($arguments as $key => $val) { + if (is_object($val) && $val instanceof TwigReference) { + $arguments[$key] = &$val->getReference(); + } + } + + // Needed to pass by reference -- could also restrict to maximum one + // argument instead + $args = array(); + foreach ($arguments as $key => &$arg) { + $args[$key] = &$arg; + } + + return call_user_func_array($name, $args); + } +} diff --git a/core/lib/Drupal/Core/Template/TwigTemplate.php b/core/lib/Drupal/Core/Template/TwigTemplate.php new file mode 100644 index 0000000..cfa0e15 --- /dev/null +++ b/core/lib/Drupal/Core/Template/TwigTemplate.php @@ -0,0 +1,89 @@ + $item))); + trigger_error($msg->getMessage(), E_USER_WARNING); + return NULL; + } + + // Return item instead of its reference inside a loop. + // @todo 'hide' and 'show' are not supported inside a loop for now. + // This should be a non-issue as soon as this lands: + // @see http://drupal.org/node/1922304 + if (isset($context['_seq'])) { + return $context[$item]; + } + + // The first test also finds empty / null render arrays + if (!$context[$item] || isset($this->is_no_reference[$item])) { + return $context[$item]; + } + + if (isset($context['_references'][$item])) { + return $context['_references'][$item]; + } + + // @todo Check if this is a render array (existence of #theme?) + if ((!isset($this->is_reference[$item])) && ($context[$item] instanceof \TwigMarkup || !is_array($context[$item]))) { + $this->is_no_reference[$item] = TRUE; + return $context[$item]; + } + + if ($this->twig_reference == NULL) { + $this->twig_reference = new TwigReference(); + } + $ref = clone $this->twig_reference; // clone is _much_ faster than new + $ref->setReference($context[$item]); + + // Save that this is a reference + $context['_references'][$item] = $ref; + $this->is_reference[$item] = TRUE; + + return $ref; + } +} diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php index 59a4735..48bef95 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php @@ -49,6 +49,13 @@ class CustomBlockType extends ConfigEntityBase implements CustomBlockTypeInterfa public $id; /** + * The custom block type UUID. + * + * @var string + */ + public $uuid; + + /** * The custom block type label. * * @var string diff --git a/core/modules/block/lib/Drupal/block/Entity/Block.php b/core/modules/block/lib/Drupal/block/Entity/Block.php index cb49cac..c0d4de9 100644 --- a/core/modules/block/lib/Drupal/block/Entity/Block.php +++ b/core/modules/block/lib/Drupal/block/Entity/Block.php @@ -49,6 +49,13 @@ class Block extends ConfigEntityBase implements BlockInterface, EntityWithPlugin public $id; /** + * The block UUID. + * + * @var string + */ + public $uuid; + + /** * The plugin instance settings. * * @var array diff --git a/core/modules/block/templates/block-list.html.twig b/core/modules/block/templates/block-list.html.twig index 474c654..873d192 100644 --- a/core/modules/block/templates/block-list.html.twig +++ b/core/modules/block/templates/block-list.html.twig @@ -13,9 +13,10 @@ * @ingroup themeable */ #} +{% hide(form.place_blocks) %}
- {{ form|without('place_blocks') }} + {{ form }}
{{ form.place_blocks }} diff --git a/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/Breakpoint.php b/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/Breakpoint.php index 02c1945..08ae4b6 100644 --- a/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/Breakpoint.php +++ b/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/Breakpoint.php @@ -52,6 +52,13 @@ class Breakpoint extends ConfigEntityBase implements BreakpointInterface { public $id; /** + * The breakpoint UUID. + * + * @var string + */ + public $uuid; + + /** * The breakpoint name (machine name) as specified by theme or module. * * @var string diff --git a/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/BreakpointGroup.php b/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/BreakpointGroup.php index 80f10e0..f3807af 100644 --- a/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/BreakpointGroup.php +++ b/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/BreakpointGroup.php @@ -34,6 +34,13 @@ class BreakpointGroup extends ConfigEntityBase implements BreakpointGroupInterfa public $id; /** + * The breakpoint group UUID. + * + * @var string + */ + public $uuid; + + /** * The breakpoint group machine name. * * @var string diff --git a/core/modules/ckeditor/ckeditor.module b/core/modules/ckeditor/ckeditor.module index 7000dbf..bf1a8ec 100644 --- a/core/modules/ckeditor/ckeditor.module +++ b/core/modules/ckeditor/ckeditor.module @@ -48,10 +48,17 @@ function ckeditor_theme() { * Implements hook_ckeditor_css_alter(). */ function ckeditor_ckeditor_css_alter(array &$css, Editor $editor) { + $filters = array(); + if (!empty($editor->format)) { + $filters = entity_load('filter_format', $editor->format) + ->filters() + ->getAll(); + } + // Add the filter caption CSS if the text format associated with this text // editor uses the filter_caption filter. This is used by the included // CKEditor DrupalImageCaption plugin. - if ($editor->getFilterFormat()->filters('filter_caption')->status) { + if (isset($filters['filter_caption']) && $filters['filter_caption']->status) { $css[] = drupal_get_path('module', 'filter') . '/css/filter.caption.css'; } } diff --git a/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/DrupalImageCaption.php b/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/DrupalImageCaption.php index 6c01e8e..bdbb7bb 100644 --- a/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/DrupalImageCaption.php +++ b/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/DrupalImageCaption.php @@ -64,10 +64,17 @@ public function getConfig(Editor $editor) { * {@inheritdoc} */ function isEnabled(Editor $editor) { + $filters = array(); + if (!empty($editor->format)) { + $filters = entity_load('filter_format', $editor->format) + ->filters() + ->getAll(); + } + // Automatically enable this plugin if the text format associated with this // text editor uses the filter_caption filter and the DrupalImage button is // enabled. - if ($editor->getFilterFormat()->filters('filter_caption')->status) { + if (isset($filters['filter_caption']) && $filters['filter_caption']->status) { $enabled = FALSE; foreach ($editor->settings['toolbar']['rows'] as $row) { foreach ($row as $group) { diff --git a/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/Internal.php b/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/Internal.php index 1e6eb5f..c683e3e 100644 --- a/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/Internal.php +++ b/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/CKEditorPlugin/Internal.php @@ -286,7 +286,7 @@ protected function generateFormatTagsSetting(Editor $editor) { */ protected function generateAllowedContentSetting(Editor $editor) { // When nothing is disallowed, set allowedContent to true. - $format = $editor->getFilterFormat(); + $format = entity_load('filter_format', $editor->format); $filter_types = $format->getFilterTypes(); if (!in_array(FilterInterface::TYPE_HTML_RESTRICTOR, $filter_types)) { return TRUE; diff --git a/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php b/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php index 7a6f3cc..4f59069 100644 --- a/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php +++ b/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php @@ -127,9 +127,6 @@ function testGetJSSettings() { $format = entity_load('filter_format', 'filtered_html'); $format->filters('filter_html')->settings['allowed_html'] .= '
 

'; $format->save(); - // $editor is a Text Editor object that has a statically cached FilterFormat - // which is now outdated. Therefore, reload it. - $editor = entity_load('editor', $editor->id()); $expected_config['allowedContent']['pre'] = array('attributes' => TRUE, 'styles' => FALSE, 'classes' => TRUE); $expected_config['allowedContent']['h3'] = array('attributes' => TRUE, 'styles' => FALSE, 'classes' => TRUE); $expected_config['format_tags'] = 'p;h3;h4;h5;h6;pre'; @@ -138,9 +135,6 @@ function testGetJSSettings() { // Disable the filter_html filter: allow *all *tags. $format->setFilterConfig('filter_html', array('status' => 0)); $format->save(); - // $editor is a Text Editor object that has a statically cached FilterFormat - // which is now outdated. Therefore, reload it. - $editor = entity_load('editor', $editor->id()); $expected_config['allowedContent'] = TRUE; $expected_config['format_tags'] = 'p;h1;h2;h3;h4;h5;h6;pre'; $this->assertIdentical($expected_config, $this->ckeditor->getJSSettings($editor), 'Generated JS settings are correct for customized configuration.'); @@ -174,9 +168,6 @@ function testGetJSSettings() { ), )); $format->save(); - // $editor is a Text Editor object that has a statically cached FilterFormat - // which is now outdated. Therefore, reload it. - $editor = entity_load('editor', $editor->id()); $expected_config['allowedContent'] = array( 'p' => array( 'attributes' => TRUE, diff --git a/core/modules/comment/comment.tokens.inc b/core/modules/comment/comment.tokens.inc index b58230a..a4c9af1 100644 --- a/core/modules/comment/comment.tokens.inc +++ b/core/modules/comment/comment.tokens.inc @@ -142,6 +142,11 @@ function comment_tokens($type, $tokens, array $data = array(), array $options = $replacements[$original] = $sanitize ? check_plain($comment->getHostname()) : $comment->getHostname(); break; + case 'name': + $name = ($comment->getOwnerId() == 0) ? \Drupal::config('user.settings')->get('anonymous') : $comment->getAuthorName(); + $replacements[$original] = $sanitize ? filter_xss($name) : $name; + break; + case 'mail': $mail = $comment->getAuthorEmail(); $replacements[$original] = $sanitize ? check_plain($mail) : $mail; diff --git a/core/modules/comment/lib/Drupal/comment/CommentManager.php b/core/modules/comment/lib/Drupal/comment/CommentManager.php index 126d6b4..2102abe 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentManager.php +++ b/core/modules/comment/lib/Drupal/comment/CommentManager.php @@ -147,9 +147,6 @@ public function addDefaultField($entity_type, $bundle, $field_name = 'comment', 'name' => $field_name, 'type' => 'comment', 'translatable' => '0', - 'settings' => array( - 'description' => 'Default comment field', - ), )); // Create the field. $field->save(); diff --git a/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php b/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php index f46a606..fc04bd8 100644 --- a/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php +++ b/core/modules/comment/lib/Drupal/comment/Controller/AdminController.php @@ -80,10 +80,6 @@ public function __construct(FieldInfo $field_info, CommentManagerInterface $comm public function overviewBundles() { $header = array( 'field_name' => $this->t('Field name'), - 'description' => array( - 'data' => $this->t('Description'), - 'class' => array(RESPONSIVE_PRIORITY_MEDIUM), - ), 'usage' => array( 'data' => $this->t('Used in'), 'class' => array(RESPONSIVE_PRIORITY_MEDIUM), @@ -122,7 +118,6 @@ public function overviewBundles() { ); $row['data']['field_name']['data'] = $field_info->get('locked') ? $this->t('@label (@field_name) (Locked)', $tokens) : $this->t('@label (@field_name)', $tokens); - $row['data']['description']['data'] = $field_info->getSetting('description'); $row['data']['usage']['data'] = array( '#theme' => 'item_list', '#items' => array(), diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php index be4f79f..b50bafc 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/Field/FieldType/CommentItem.php @@ -18,9 +18,6 @@ * id = "comment", * label = @Translation("Comments"), * description = @Translation("This field manages configuration and presentation of comments on an entity."), - * settings = { - * "description" = "", - * }, * instance_settings = { * "default_mode" = COMMENT_MODE_THREADED, * "per_page" = 50, @@ -198,19 +195,4 @@ public static function processSettingsElement($element) { return $element; } - /** - * {@inheritdoc} - */ - public function settingsForm(array $form, array &$form_state, $has_data) { - $element = array(); - - $element['description'] = array( - '#type' => 'textarea', - '#title' => t('Field description'), - '#description' => t('Describe this comment field. The text will be displayed on the Comments Forms page.'), - '#default_value' => $this->getSetting('description'), - ); - return $element; - } - } diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentAdminTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentAdminTest.php index 4f2f211..e631da2 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentAdminTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentAdminTest.php @@ -162,9 +162,6 @@ public function testCommentAdmin() { // Make sure titles visible. $this->assertText('Field name'); $this->assertText('Used in'); - $this->assertText('Description'); - // Make sure the description is present. - $this->assertText('Default comment field'); // Manage fields. $this->clickLink('Manage fields'); $this->assertResponse(200); diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentValidationTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentValidationTest.php index 56f8a54..020e1ab 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentValidationTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentValidationTest.php @@ -136,8 +136,7 @@ protected function assertLengthViolation(CommentInterface $comment, $field_name, $violations = $comment->validate(); $this->assertEqual(count($violations), 1, "Violation found when $field_name is too long."); $this->assertEqual($violations[0]->getPropertyPath(), "$field_name.0.value"); - $field_label = $comment->get($field_name)->getFieldDefinition()->getLabel(); - $this->assertEqual($violations[0]->getMessage(), t('%name: may not be longer than @max characters.', array('%name' => $field_label, '@max' => $length))); + $this->assertEqual($violations[0]->getMessage(), t('This value is too long. It should have %limit characters or less.', array('%limit' => $length))); } } diff --git a/core/modules/comment/templates/comment.html.twig b/core/modules/comment/templates/comment.html.twig index 5fca73b..570448f 100644 --- a/core/modules/comment/templates/comment.html.twig +++ b/core/modules/comment/templates/comment.html.twig @@ -7,11 +7,8 @@ * - author: Comment author. Can be a link or plain text. * - content: The content-related items for the comment display. Use * {{ content }} to print them all, or print a subset such as - * {{ content.field_example }}. Use the following code to temporarily suppress - * the printing of a given child element: - * @code - * {{ content|without('field_example') }} - * @endcode + * {{ content.field_example }}. Use hide(content.field_example) to temporarily + * suppress the printing of a given element. * - created: Formatted date and time for when the comment was created. * Preprocess functions can reformat it by calling format_date() with the * desired parameters on the 'comment.created' variable. @@ -95,7 +92,9 @@ - {{ content|without('links') }} + {# We hide the links now so that we can render them later. #} + {% hide(content.links) %} + {{ content }} {% if signature %}
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php index 89413d2..24be35e 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImportUITest.php @@ -52,11 +52,11 @@ function testImport() { // Create new config entity. $original_dynamic_data = array( 'id' => 'new', + 'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651', 'label' => 'New', 'weight' => 0, 'style' => '', 'status' => TRUE, - 'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651', 'langcode' => language_default()->id, 'protected_property' => '', ); diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php index b597aa7..f23cdcb 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php @@ -163,11 +163,11 @@ function testNew() { // Create new config entity. $original_dynamic_data = array( 'id' => 'new', + 'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651', 'label' => 'New', 'weight' => 0, 'style' => '', 'status' => TRUE, - 'uuid' => '30df59bd-7b03-4cf7-bb35-d42fc49f0651', 'langcode' => language_default()->id, 'protected_property' => '', ); diff --git a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php index 029a7ac..1bb4deb 100644 --- a/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php +++ b/core/modules/config/tests/config_test/lib/Drupal/config_test/Entity/ConfigTest.php @@ -49,6 +49,13 @@ class ConfigTest extends ConfigEntityBase implements ConfigTestInterface { public $id; /** + * The UUID for the configuration entity. + * + * @var string + */ + public $uuid; + + /** * The human-readable name of the configuration entity. * * @var string diff --git a/core/modules/contact/lib/Drupal/contact/Entity/Category.php b/core/modules/contact/lib/Drupal/contact/Entity/Category.php index a2fe218..b2f2460 100644 --- a/core/modules/contact/lib/Drupal/contact/Entity/Category.php +++ b/core/modules/contact/lib/Drupal/contact/Entity/Category.php @@ -49,6 +49,13 @@ class Category extends ConfigEntityBase implements CategoryInterface { public $id; /** + * The category UUID. + * + * @var string + */ + public $uuid; + + /** * The category label. * * @var string diff --git a/core/modules/contact/lib/Drupal/contact/MessageFormController.php b/core/modules/contact/lib/Drupal/contact/MessageFormController.php index 885a87b..0678654 100644 --- a/core/modules/contact/lib/Drupal/contact/MessageFormController.php +++ b/core/modules/contact/lib/Drupal/contact/MessageFormController.php @@ -28,7 +28,7 @@ class MessageFormController extends ContentEntityFormController { * Overrides Drupal\Core\Entity\EntityFormController::form(). */ public function form(array $form, array &$form_state) { - $user = \Drupal::currentUser(); + global $user; $message = $this->entity; $form = parent::form($form, $form_state, $message); $form['#attributes']['class'][] = 'contact-form'; @@ -139,7 +139,7 @@ public function preview(array $form, array &$form_state) { * Overrides Drupal\Core\Entity\EntityFormController::save(). */ public function save(array $form, array &$form_state) { - $user = \Drupal::currentUser(); + global $user; $language_interface = \Drupal::languageManager()->getCurrentLanguage(); $message = $this->entity; diff --git a/core/modules/contextual/js/contextual.js b/core/modules/contextual/js/contextual.js index b01b07f..a843a9a 100644 --- a/core/modules/contextual/js/contextual.js +++ b/core/modules/contextual/js/contextual.js @@ -41,7 +41,7 @@ * @param string html * The server-side rendered HTML for this contextual link. */ - function initContextual ($contextual, html) { + function initContextual($contextual, html) { var $region = $contextual.closest('.contextual-region'); var contextual = Drupal.contextual; @@ -101,7 +101,7 @@ * A contextual links placeholder DOM element, containing the actual * contextual links as rendered by the server. */ - function adjustIfNestedAndOverlapping ($contextual) { + function adjustIfNestedAndOverlapping($contextual) { var $contextuals = $contextual // @todo confirm that .closest() is not sufficient .parents('.contextual-region').eq(-1) @@ -156,17 +156,10 @@ }); // Update all contextual links placeholders whose HTML is cached. - var uncachedIDs = _.filter(ids, function initIfCached (contextualID) { + var uncachedIDs = _.filter(ids, function initIfCached(contextualID) { var html = storage.getItem('Drupal.contextual.' + contextualID); if (html !== null) { - // Initialize after the current executation cycle, to make the AJAX - // request for retrieving the uncached contextual links as soon as - // possible, but also to ensure that other Drupal behaviors have had the - // chance to set up an event listener on the Backbone collection - // Drupal.contextual.collection. - window.setTimeout(function () { - initContextual($context.find('[data-contextual-id="' + contextualID + '"]'), html); - }); + initContextual($context.find('[data-contextual-id="' + contextualID + '"]'), html); return false; } return true; diff --git a/core/modules/editor/lib/Drupal/editor/EditorInterface.php b/core/modules/editor/lib/Drupal/editor/EditorInterface.php index 2fab152..71897f9 100644 --- a/core/modules/editor/lib/Drupal/editor/EditorInterface.php +++ b/core/modules/editor/lib/Drupal/editor/EditorInterface.php @@ -10,15 +10,8 @@ use Drupal\Core\Config\Entity\ConfigEntityInterface; /** - * Provides an interface defining a text editor entity. + * Provides an interface defining a editor entity. */ interface EditorInterface extends ConfigEntityInterface { - /** - * Returns the filter format this text editor is associated with. - * - * @return \Drupal\filter\FilterFormatInterface - */ - public function getFilterFormat(); - } diff --git a/core/modules/editor/lib/Drupal/editor/Entity/Editor.php b/core/modules/editor/lib/Drupal/editor/Entity/Editor.php index c58d2fa..0053de4 100644 --- a/core/modules/editor/lib/Drupal/editor/Entity/Editor.php +++ b/core/modules/editor/lib/Drupal/editor/Entity/Editor.php @@ -15,7 +15,7 @@ * * @ConfigEntityType( * id = "editor", - * label = @Translation("Text Editor"), + * label = @Translation("Editor"), * entity_keys = { * "id" = "format" * } @@ -53,21 +53,14 @@ class Editor extends ConfigEntityBase implements EditorInterface { public $image_upload = array(); /** - * The filter format this text editor is associated with. - * - * @var \Drupal\filter\FilterFormatInterface - */ - protected $filterFormat; - - /** - * {@inheritdoc} + * Overrides Drupal\Core\Entity\Entity::id(). */ public function id() { return $this->format; } /** - * {@inheritdoc} + * Overrides Drupal\Core\Entity\Entity::__construct() */ public function __construct(array $values, $entity_type) { parent::__construct($values, $entity_type); @@ -82,14 +75,4 @@ public function __construct(array $values, $entity_type) { $this->settings += $default_settings; } - /** - * {@inheritdoc} - */ - public function getFilterFormat() { - if (!$this->filterFormat) { - $this->filterFormat = \Drupal::entityManager()->getStorageController('filter_format')->load($this->format); - } - return $this->filterFormat; - } - } diff --git a/core/modules/email/email.module b/core/modules/email/email.module index 54d426a..f74da6f 100644 --- a/core/modules/email/email.module +++ b/core/modules/email/email.module @@ -35,5 +35,20 @@ function email_field_info_alter(&$info) { $info['email']['class'] = '\Drupal\email\ConfigurableEmailItem'; $info['email']['list_class'] = '\Drupal\Core\Field\ConfigFieldItemList'; $info['email']['default_widget'] = 'email_default'; + if (\Drupal::moduleHandler()->moduleExists('text')) { + $info['email']['default_formatter'] = 'text_plain'; + } + else { + $info['email']['default_formatter'] = 'email_mailto'; + } $info['email']['provider'] = 'email'; } + +/** + * Implements hook_field_formatter_info_alter(). + */ +function email_field_formatter_info_alter(&$info) { + if (isset($info['text_plain'])) { + $info['text_plain']['field_types'][] = 'email'; + } +} diff --git a/core/modules/entity/config/schema/entity.schema.yml b/core/modules/entity/config/schema/entity.schema.yml index 6334cb4..a2d0b43 100644 --- a/core/modules/entity/config/schema/entity.schema.yml +++ b/core/modules/entity/config/schema/entity.schema.yml @@ -139,13 +139,3 @@ entity_form_display.field.*: weight: type: integer label: 'Weight' - -entity_view_display.field.string: - type: entity_field_view_display_base - label: 'Plain text display format settings' - mapping: - settings: - type: sequence - label: 'Settings' - sequence: - - type: string diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityViewDisplay.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityViewDisplay.php index e4d3880..a35c4ac 100644 --- a/core/modules/entity/lib/Drupal/entity/Entity/EntityViewDisplay.php +++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityViewDisplay.php @@ -230,7 +230,7 @@ public function buildMultiple(array $entities) { // Then let the formatter build the output for each entity. foreach ($entities as $key => $entity) { $items = $entity->get($field_name); - $build[$key][$field_name] = $formatter->view($items); + $build[$key] += $formatter->view($items); } } } diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php index 150b73b..93d132d 100644 --- a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php +++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php @@ -25,6 +25,13 @@ public $id; /** + * Unique UUID for the config entity. + * + * @var string + */ + public $uuid; + + /** * Entity type to be displayed. * * @var string diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayModeBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayModeBase.php index 6705f03..1541143 100644 --- a/core/modules/entity/lib/Drupal/entity/EntityDisplayModeBase.php +++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayModeBase.php @@ -22,6 +22,13 @@ public $id; /** + * The UUID of the form or view mode. + * + * @var string + */ + public $uuid; + + /** * The human-readable name of the form or view mode. * * @var string diff --git a/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeAddForm.php b/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeAddForm.php index 49be44f..b1aa3af 100644 --- a/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeAddForm.php +++ b/core/modules/entity/lib/Drupal/entity/Form/EntityDisplayModeAddForm.php @@ -27,8 +27,6 @@ class EntityDisplayModeAddForm extends EntityDisplayModeFormBase { public function buildForm(array $form, array &$form_state, $entity_type_id = NULL) { $this->targetEntityTypeId = $entity_type_id; $form = parent::buildForm($form, $form_state); - // Change replace_pattern to avoid undesired dots. - $form['id']['#machine_name']['replace_pattern'] = '[^a-z0-9_]+'; $definition = $this->entityManager->getDefinition($this->targetEntityTypeId); $form['#title'] = $this->t('Add new %label @entity-type', array('%label' => $definition->getLabel(), '@entity-type' => $this->entityType->getLowercaseLabel())); return $form; diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayModeTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayModeTest.php index 133b8c3..d8bae0a 100644 --- a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayModeTest.php +++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayModeTest.php @@ -48,16 +48,8 @@ public function testEntityViewModeUI() { $this->drupalGet('admin/structure/display-modes/view/add'); $this->assertNoLink(t('Test entity - revisions and data table'), 'An entity type with no view builder cannot have view modes.'); - // Test adding a view mode including dots in machine_name. - $this->clickLink(t('Test entity')); - $edit = array( - 'id' => strtolower($this->randomName()) . '.' . strtolower($this->randomName()), - 'label' => $this->randomString(), - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertRaw('The machine-readable name must contain only lowercase letters, numbers, and underscores.'); - // Test adding a view mode. + $this->clickLink(t('Test entity')); $edit = array( 'id' => strtolower($this->randomName()), 'label' => $this->randomString(), @@ -94,16 +86,8 @@ public function testEntityFormModeUI() { $this->drupalGet('admin/structure/display-modes/form/add'); $this->assertNoLink(t('Entity Test without label'), 'An entity type with no form controller cannot have form modes.'); - // Test adding a view mode including dots in machine_name. - $this->clickLink(t('Test entity')); - $edit = array( - 'id' => strtolower($this->randomName()) . '.' . strtolower($this->randomName()), - 'label' => $this->randomString(), - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertRaw('The machine-readable name must contain only lowercase letters, numbers, and underscores.'); - // Test adding a form mode. + $this->clickLink(t('Test entity')); $edit = array( 'id' => strtolower($this->randomName()), 'label' => $this->randomString(), diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidgetBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidgetBase.php index 66849a7..3e045d5 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidgetBase.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Field/FieldWidget/AutocompleteWidgetBase.php @@ -71,6 +71,8 @@ public function settingsSummary() { * {@inheritdoc} */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) { + global $user; + $entity = $items->getEntity(); // Prepare the autocomplete route parameters. @@ -94,7 +96,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#size' => $this->getSetting('size'), '#placeholder' => $this->getSetting('placeholder'), '#element_validate' => array(array($this, 'elementValidate')), - '#autocreate_uid' => ($entity instanceof EntityOwnerInterface) ? $entity->getOwnerId() : \Drupal::currentUser()->id(), + '#autocreate_uid' => ($entity instanceof EntityOwnerInterface) ? $entity->getOwnerId() : $user->id(), ); return array('target_id' => $element); diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php index fbd4461..43fd7ee 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php @@ -120,7 +120,7 @@ public function testSort() { // Test as a non-admin. $normal_user = $this->drupalCreateUser(array('access content')); - $this->container->set('current_user', $normal_user); + $GLOBALS['user'] = $normal_user; $handler = $this->container->get('plugin.manager.entity_reference.selection')->getSelectionHandler($instance); diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc index a2f6c7c..3898037 100644 --- a/core/modules/field/field.attach.inc +++ b/core/modules/field/field.attach.inc @@ -91,13 +91,20 @@ function field_invoke_method($method, $target_function, EntityInterface $entity, $target = call_user_func($target_function, $field_definition); if (method_exists($target, $method)) { - $field_name = $field_definition->getName(); - $items = $entity->get($field_name); + $items = $entity->get($field_definition->getName()); $items->filterEmptyItems(); $result = $target->$method($items, $a, $b); + if (isset($result)) { - $return[$field_name] = $result; + // For methods with array results, we merge results together. + // For methods with scalar results, we collect results in an array. + if (is_array($result)) { + $return = array_merge($return, $result); + } + else { + $return[] = $result; + } } } } diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php index 9e8adee..3388c95 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php @@ -66,6 +66,15 @@ class FieldConfig extends ConfigEntityBase implements FieldConfigInterface { public $name; /** + * The field UUID. + * + * This is assigned automatically when the field is created. + * + * @var string + */ + public $uuid; + + /** * The name of the entity type the field can be attached to. * * @var string diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php index cd78415..e61896a 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php @@ -45,6 +45,15 @@ class FieldInstanceConfig extends ConfigEntityBase implements FieldInstanceConfi public $id; /** + * The instance UUID. + * + * This is assigned automatically when the instance is created. + * + * @var string + */ + public $uuid; + + /** * The name of the field attached to the bundle by this instance. * * @var string diff --git a/core/modules/field/lib/Drupal/field/Tests/Views/FieldUITest.php b/core/modules/field/lib/Drupal/field/Tests/Views/FieldUITest.php index 3f01234..07507fe 100644 --- a/core/modules/field/lib/Drupal/field/Tests/Views/FieldUITest.php +++ b/core/modules/field/lib/Drupal/field/Tests/Views/FieldUITest.php @@ -73,7 +73,7 @@ public function testHandlerUI() { }, $result); // @todo Replace this sort by assertArray once it's in. sort($options, SORT_STRING); - $this->assertEqual($options, array('string', 'text_default', 'text_trimmed'), 'The text formatters for a simple text field appear as expected.'); + $this->assertEqual($options, array('text_default', 'text_plain', 'text_trimmed'), 'The text formatters for a simple text field appear as expected.'); $this->drupalPostForm(NULL, array('options[type]' => 'text_trimmed'), t('Apply')); diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldDefaultFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldDefaultFormatter.php index 97beb5c..457c76f 100644 --- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldDefaultFormatter.php +++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldDefaultFormatter.php @@ -22,8 +22,7 @@ * }, * settings = { * "test_formatter_setting" = "dummy test string" - * }, - * weight = 1 + * } * ) */ class TestFieldDefaultFormatter extends FormatterBase { diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptyFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptyFormatter.php index e624bf9..592a958 100644 --- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptyFormatter.php +++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptyFormatter.php @@ -21,8 +21,7 @@ * }, * settings = { * "test_empty_string" = "**EMPTY FIELD**" - * }, - * weight = -5 + * } * ) */ class TestFieldEmptyFormatter extends FormatterBase { diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptySettingFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptySettingFormatter.php index fa4d9a9..e825aa8 100644 --- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptySettingFormatter.php +++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldEmptySettingFormatter.php @@ -21,8 +21,7 @@ * }, * settings = { * "field_empty_setting" = "" - * }, - * weight = -1 + * } * ) */ class TestFieldEmptySettingFormatter extends FormatterBase { diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldMultipleFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldMultipleFormatter.php index 87d9553..588ad66 100644 --- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldMultipleFormatter.php +++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldMultipleFormatter.php @@ -22,8 +22,7 @@ * }, * settings = { * "test_formatter_setting_multiple" = "dummy test string" - * }, - * weight = 5 + * } * ) */ class TestFieldMultipleFormatter extends FormatterBase { diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldNoSettingsFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldNoSettingsFormatter.php index 4ab58f1..1d3d150 100644 --- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldNoSettingsFormatter.php +++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldNoSettingsFormatter.php @@ -19,7 +19,6 @@ * field_types = { * "test_field", * }, - * weight = -10 * ) */ class TestFieldNoSettingsFormatter extends FormatterBase { diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldPrepareViewFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldPrepareViewFormatter.php index 85b97f1..a8ff2a9 100644 --- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldPrepareViewFormatter.php +++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldPrepareViewFormatter.php @@ -22,8 +22,7 @@ * }, * settings = { * "test_formatter_setting_additional" = "dummy test string" - * }, - * weight = 10 + * } * ) */ class TestFieldPrepareViewFormatter extends FormatterBase { diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidget.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidget.php index ae80042..bf6e093 100644 --- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidget.php +++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidget.php @@ -23,8 +23,7 @@ * }, * settings = { * "test_widget_setting" = "dummy test string" - * }, - * weight = -10 + * } * ) */ class TestFieldWidget extends WidgetBase { diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidgetMultiple.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidgetMultiple.php index a16eb3f..be8fed9 100644 --- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidgetMultiple.php +++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldWidget/TestFieldWidgetMultiple.php @@ -25,8 +25,7 @@ * settings = { * "test_widget_setting_multiple" = "dummy test string" * }, - * multiple_values = TRUE, - * weight = 10 + * multiple_values = TRUE * ) */ class TestFieldWidgetMultiple extends WidgetBase { diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php index c9ce1be..ecd41fd 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php @@ -63,7 +63,7 @@ public function __construct(EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, PluginManagerBase $plugin_manager, ConfigFactoryInterface $config_factory) { parent::__construct($entity_manager); - $this->fieldTypes = $field_type_manager->getDefinitions(); + $this->fieldTypes = $field_type_manager->getConfigurableDefinitions(); $this->pluginManager = $plugin_manager; $this->configFactory = $config_factory; } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Plugin/Derivative/FieldUiLocalTask.php b/core/modules/field_ui/lib/Drupal/field_ui/Plugin/Derivative/FieldUiLocalTask.php index 4d43cc1..e80bd9d 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Plugin/Derivative/FieldUiLocalTask.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Plugin/Derivative/FieldUiLocalTask.php @@ -123,13 +123,11 @@ public function getDerivativeDefinitions(array $base_plugin_definition) { 'title' => 'Default', 'route_name' => "field_ui.form_display_overview_$entity_type_id", 'parent_id' => "field_ui.fields:form_display_overview_$entity_type_id", - 'weight' => -1, ); $this->derivatives['field_display_default_' . $entity_type_id] = array( 'title' => 'Default', 'route_name' => "field_ui.display_overview_$entity_type_id", 'parent_id' => "field_ui.fields:display_overview_$entity_type_id", - 'weight' => -1, ); // One local task for each form mode. diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUIRouteTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUIRouteTest.php index ef7bbfa..b01112d 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUIRouteTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUIRouteTest.php @@ -79,7 +79,6 @@ public function testFieldUIRoutes() { $this->drupalGet('admin/config/people/accounts/form-display/register'); $this->assertTitle('Manage form display | Drupal'); $this->assertLocalTasks(); - $this->assert(count($this->xpath('//ul/li[1]/a[contains(text(), :text)]', array(':text' => 'Default'))) == 1, 'Default secondary tab is in first position.'); } /** diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php index 133b578..4a25ca6 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php @@ -51,28 +51,12 @@ function testFormatterUI() { $setting_name = key($default_settings); $setting_value = $display_options['settings'][$setting_name]; - // Display the "Manage display" screen and check that the expected formatter - // is selected. + // Display the "Manage display" screen and check that the expected formatter is + // selected. $this->drupalGet($manage_display); $this->assertFieldByName('fields[field_test][type]', $format, 'The expected formatter is selected.'); $this->assertText("$setting_name: $setting_value", 'The expected summary is displayed.'); - // Check whether formatter weights are respected. - $result = $this->xpath('//select[@id=:id]/option', array(':id' => 'edit-fields-field-test-type')); - $options = array_map(function($item) { - return (string) $item->attributes()->value[0]; - }, $result); - $expected_options = array ( - 'field_no_settings', - 'field_empty_test', - 'field_empty_setting', - 'field_test_default', - 'field_test_multiple', - 'field_test_with_prepare_view', - 'hidden', - ); - $this->assertEqual($options, $expected_options, 'The expected formatter ordering is respected.'); - // Change the formatter and check that the summary is updated. $edit = array('fields[field_test][type]' => 'field_test_multiple', 'refresh_rows' => 'field_test'); $this->drupalPostAjaxForm(NULL, $edit, array('op' => t('Refresh'))); @@ -155,18 +139,6 @@ public function testWidgetUI() { $this->assertFieldByName('fields[field_test][type]', $widget_type, 'The expected widget is selected.'); $this->assertText("$setting_name: $setting_value", 'The expected summary is displayed.'); - // Check whether widget weights are respected. - $result = $this->xpath('//select[@id=:id]/option', array(':id' => 'edit-fields-field-test-type')); - $options = array_map(function($item) { - return (string) $item->attributes()->value[0]; - }, $result); - $expected_options = array ( - 'test_field_widget', - 'test_field_widget_multiple', - 'hidden', - ); - $this->assertEqual($options, $expected_options, 'The expected widget ordering is respected.'); - // Change the widget and check that the summary is updated. $edit = array('fields[field_test][type]' => 'test_field_widget_multiple', 'refresh_rows' => 'field_test'); $this->drupalPostAjaxForm(NULL, $edit, array('op' => t('Refresh'))); diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module index a97435a..2b09ea7 100644 --- a/core/modules/filter/filter.module +++ b/core/modules/filter/filter.module @@ -466,7 +466,7 @@ function check_markup($text, $format_id = NULL, $langcode = '', $cache = FALSE, * The expanded element. */ function filter_process_format($element) { - $user = \Drupal::currentUser(); + global $user; // Ensure that children appear as subkeys of this element. $element['#tree'] = TRUE; @@ -639,7 +639,9 @@ function filter_form_access_denied($element) { * - id: Filter ID. */ function _filter_tips($format_id, $long = FALSE) { - $formats = filter_formats(\Drupal::currentUser()); + global $user; + + $formats = filter_formats($user); $tips = array(); diff --git a/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php b/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php index 4e6febf..09e098f 100644 --- a/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php +++ b/core/modules/filter/lib/Drupal/filter/Entity/FilterFormat.php @@ -69,6 +69,13 @@ class FilterFormat extends ConfigEntityBase implements FilterFormatInterface, En public $name; /** + * The UUID for this entity. + * + * @var string + */ + public $uuid; + + /** * Weight of this format in the text format selector. * * The first/lowest text format that is accessible for a user is used as diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index c44cffe..1a55bfe 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -74,7 +74,7 @@ function forum_theme() { return array( 'forums' => array( 'template' => 'forums', - 'variables' => array('forums' => array(), 'topics' => array(), 'topics_pager' => array(), 'parents' => NULL, 'term' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL, 'header' => array()), + 'variables' => array('forums' => array(), 'topics' => array(), 'topics_pager' => array(), 'parents' => NULL, 'term' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL), ), 'forum_list' => array( 'template' => 'forum-list', @@ -623,7 +623,7 @@ function template_preprocess_forums(&$variables) { } if ($variables['term'] && empty($variables['term']->forum_container->value) && !empty($variables['topics'])) { - $forum_topic_list_header = $variables['header']; + global $forum_topic_list_header; $table = array( '#theme' => 'table__forum_topic_list', diff --git a/core/modules/forum/lib/Drupal/forum/Controller/ForumController.php b/core/modules/forum/lib/Drupal/forum/Controller/ForumController.php index d503cdb..e982429 100644 --- a/core/modules/forum/lib/Drupal/forum/Controller/ForumController.php +++ b/core/modules/forum/lib/Drupal/forum/Controller/ForumController.php @@ -82,15 +82,12 @@ public function forumPage(TermInterface $taxonomy_term) { $taxonomy_term->parents = $this->forumManager->getParents($taxonomy_term->id()); if (empty($taxonomy_term->forum_container->value)) { - $build = $this->forumManager->getTopics($taxonomy_term->id()); - $topics = $build['topics']; - $header = $build['header']; + $topics = $this->forumManager->getTopics($taxonomy_term->id()); } else { $topics = ''; - $header = array(); } - return $this->build($taxonomy_term->forums, $taxonomy_term, $topics, $taxonomy_term->parents, $header); + return $this->build($taxonomy_term->forums, $taxonomy_term, $topics, $taxonomy_term->parents); } /** @@ -125,20 +122,17 @@ public function forumIndex() { * The topics of this forum. * @param array $parents * The parent forums in relation this forum. - * @param array $header - * Array of header cells. * * @return array * A render array. */ - protected function build($forums, TermInterface $term, $topics = array(), $parents = array(), $header = array()) { + protected function build($forums, TermInterface $term, $topics = array(), $parents = array()) { $config = $this->config('forum.settings'); $build = array( '#theme' => 'forums', '#forums' => $forums, '#topics' => $topics, '#parents' => $parents, - '#header' => $header, '#term' => $term, '#sortby' => $config->get('topics.order'), '#forums_per_page' => $config->get('topics.page_limit'), diff --git a/core/modules/forum/lib/Drupal/forum/ForumManager.php b/core/modules/forum/lib/Drupal/forum/ForumManager.php index a5ba96b..bcc7372 100644 --- a/core/modules/forum/lib/Drupal/forum/ForumManager.php +++ b/core/modules/forum/lib/Drupal/forum/ForumManager.php @@ -140,18 +140,19 @@ public function getTopics($tid) { $forum_per_page = $config->get('topics.page_limit'); $sortby = $config->get('topics.order'); + global $forum_topic_list_header; $user = \Drupal::currentUser(); - $header = array( + $forum_topic_list_header = array( array('data' => $this->t('Topic'), 'field' => 'f.title'), array('data' => $this->t('Replies'), 'field' => 'f.comment_count'), array('data' => $this->t('Last reply'), 'field' => 'f.last_comment_timestamp'), ); $order = $this->getTopicOrder($sortby); - for ($i = 0; $i < count($header); $i++) { - if ($header[$i]['field'] == $order['field']) { - $header[$i]['sort'] = $order['sort']; + for ($i = 0; $i < count($forum_topic_list_header); $i++) { + if ($forum_topic_list_header[$i]['field'] == $order['field']) { + $forum_topic_list_header[$i]['sort'] = $order['sort']; } } @@ -164,7 +165,7 @@ public function getTopics($tid) { ->addTag('node_access') ->addMetaData('base_table', 'forum_index') ->orderBy('f.sticky', 'DESC') - ->orderByHeader($header) + ->orderByHeader($forum_topic_list_header) ->limit($forum_per_page); $count_query = $this->connection->select('forum_index', 'f'); @@ -206,7 +207,7 @@ public function getTopics($tid) { $query ->orderBy('f.sticky', 'DESC') - ->orderByHeader($header) + ->orderByHeader($forum_topic_list_header) ->condition('n.nid', $nids) // @todo This should be actually filtering on the desired node language // and just fall back to the default language. @@ -265,7 +266,7 @@ public function getTopics($tid) { $topics[$topic->id()] = $topic; } - return array('topics' => $topics, 'header' => $header); + return $topics; } diff --git a/core/modules/forum/lib/Drupal/forum/ForumManagerInterface.php b/core/modules/forum/lib/Drupal/forum/ForumManagerInterface.php index cdcfb38..b8896ce 100644 --- a/core/modules/forum/lib/Drupal/forum/ForumManagerInterface.php +++ b/core/modules/forum/lib/Drupal/forum/ForumManagerInterface.php @@ -21,7 +21,7 @@ * Term ID. * * @return array - * Array with keys 'topics' and 'header'. + * Array of topics. */ public function getTopics($tid); diff --git a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php index 0251354..ab7480b 100644 --- a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php +++ b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php @@ -69,6 +69,13 @@ class ImageStyle extends ConfigEntityBase implements ImageStyleInterface, Entity public $label; /** + * The UUID for this entity. + * + * @var string + */ + public $uuid; + + /** * The array of image effects for this image style. * * @var array diff --git a/core/modules/language/lib/Drupal/language/Entity/Language.php b/core/modules/language/lib/Drupal/language/Entity/Language.php index c7ad236..7c92351 100644 --- a/core/modules/language/lib/Drupal/language/Entity/Language.php +++ b/core/modules/language/lib/Drupal/language/Entity/Language.php @@ -50,6 +50,15 @@ class Language extends ConfigEntityBase implements LanguageInterface { public $id; /** + * The language UUID. + * + * This is assigned automatically when the language is created. + * + * @var string + */ + public $uuid; + + /** * The human-readable label for the language. * * @var string diff --git a/core/modules/migrate/lib/Drupal/migrate/Entity/Migration.php b/core/modules/migrate/lib/Drupal/migrate/Entity/Migration.php index 587c888..3967aec 100644 --- a/core/modules/migrate/lib/Drupal/migrate/Entity/Migration.php +++ b/core/modules/migrate/lib/Drupal/migrate/Entity/Migration.php @@ -46,6 +46,15 @@ class Migration extends ConfigEntityBase implements MigrationInterface { public $id; /** + * The migration UUID. + * + * This is assigned automatically when the migration is created. + * + * @var string + */ + public $uuid; + + /** * The human-readable label for the migration. * * @var string diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php index 1774c75..62f697f 100644 --- a/core/modules/node/lib/Drupal/node/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Entity/Node.php @@ -378,7 +378,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setLabel(t('Language code')) ->setDescription(t('The node language code.')); - $fields['title'] = FieldDefinition::create('string') + $fields['title'] = FieldDefinition::create('text') ->setLabel(t('Title')) ->setDescription(t('The title of this node, always treated as non-markup plain text.')) ->setRequired(TRUE) @@ -386,14 +386,15 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setSettings(array( 'default_value' => '', 'max_length' => 255, + 'text_processing' => 0, )) ->setDisplayOptions('view', array( 'label' => 'hidden', - 'type' => 'string', + 'type' => 'text_default', 'weight' => -5, )) ->setDisplayOptions('form', array( - 'type' => 'string', + 'type' => 'text_textfield', 'weight' => -5, )) ->setDisplayConfigurable('form', TRUE); diff --git a/core/modules/node/lib/Drupal/node/Entity/NodeType.php b/core/modules/node/lib/Drupal/node/Entity/NodeType.php index d7fd3b0..d8e413b 100644 --- a/core/modules/node/lib/Drupal/node/Entity/NodeType.php +++ b/core/modules/node/lib/Drupal/node/Entity/NodeType.php @@ -54,6 +54,13 @@ class NodeType extends ConfigEntityBase implements NodeTypeInterface { public $type; /** + * The UUID of the node type. + * + * @var string + */ + public $uuid; + + /** * The human-readable name of the node type. * * @var string diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php index e71d75b..7b0a0a0 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeValidationTest.php @@ -54,7 +54,7 @@ public function testValidation() { $violations = $node->validate(); $this->assertEqual(count($violations), 1, 'Violation found when title is too long.'); $this->assertEqual($violations[0]->getPropertyPath(), 'title.0.value'); - $this->assertEqual($violations[0]->getMessage(), 'Title: may not be longer than 255 characters.'); + $this->assertEqual($violations[0]->getMessage(), 'Title: the text may not be longer than 255 characters.'); $node->set('title', NULL); $violations = $node->validate(); diff --git a/core/modules/node/templates/node-edit-form.html.twig b/core/modules/node/templates/node-edit-form.html.twig index c208cf5..eee9ecc 100644 --- a/core/modules/node/templates/node-edit-form.html.twig +++ b/core/modules/node/templates/node-edit-form.html.twig @@ -15,9 +15,11 @@ * @ingroup themeable */ #} +{% hide(form.advanced) %} +{% hide(form.actions) %}
- {{ form|without('advanced', 'actions') }} + {{ form }}
{{ form.advanced }} diff --git a/core/modules/node/templates/node.html.twig b/core/modules/node/templates/node.html.twig index 5bf5ad9..1f8c823 100644 --- a/core/modules/node/templates/node.html.twig +++ b/core/modules/node/templates/node.html.twig @@ -18,8 +18,8 @@ * - label: The title of the node. * - content: All node items. Use {{ content }} to print them all, * or print a subset such as {{ content.field_example }}. Use - * {{ content|without('field_example') %} to temporarily suppress the printing - * of a given child element. + * {% hide(content.field_example) %} to temporarily suppress the printing + * of a given element. * - user_picture: The node author's picture from user-picture.html.twig. * - date: Formatted creation date. Preprocess functions can reformat it by * calling format_date() with the desired parameters on @@ -93,7 +93,9 @@ {% endif %} - {{ content|without('links') }} + {# We hide links now so that we can render them later. #} + {% hide(content.links) %} + {{ content }}
{{ content.links }} diff --git a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php index 2f5552b..a0f0a0e 100644 --- a/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php +++ b/core/modules/number/lib/Drupal/number/Tests/NumberFieldTest.php @@ -150,195 +150,45 @@ function testNumberDecimalField() { * Test number_integer field. */ function testNumberIntegerField() { - $minimum = rand(-4000, -2000); - $maximum = rand(2000, 4000); - - // Create a field with settings to validate. - $field_name = drupal_strtolower($this->randomName()); - entity_create('field_config', array( - 'name' => $field_name, - 'entity_type' => 'entity_test', - 'type' => 'number_integer', - ))->save(); - - entity_create('field_instance_config', array( - 'field_name' => $field_name, - 'entity_type' => 'entity_test', - 'bundle' => 'entity_test', - 'settings' => array( - 'min' => $minimum, 'max' => $maximum, - ) - ))->save(); - - entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($field_name, array( - 'type' => 'number', - 'settings' => array( - 'placeholder' => '4' - ), - )) - ->save(); - entity_get_display('entity_test', 'entity_test', 'default') - ->setComponent($field_name, array( - 'type' => 'number_integer', - )) - ->save(); - - // Display creation form. - $this->drupalGet('entity_test/add'); - $this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed'); - $this->assertRaw('placeholder="4"'); - - // Submit a valid integer - $value = rand($minimum, $maximum); + // Display the "Add content type" form. + $this->drupalGet('admin/structure/types/add'); + + // Add a content type. + $name = $this->randomName(); + $type = drupal_strtolower($name); + $edit = array('name' => $name, 'type' => $type); + $this->drupalPostForm(NULL, $edit, t('Save and manage fields')); + + // Add an integer field to the newly-created type. + $label = $this->randomName(); + $field_name = drupal_strtolower($label); $edit = array( - 'user_id' => 1, - 'name' => $this->randomName(), - "{$field_name}[0][value]" => $value, + 'fields[_add_new_field][label]'=> $label, + 'fields[_add_new_field][field_name]' => $field_name, + 'fields[_add_new_field][type]' => 'number_integer', ); $this->drupalPostForm(NULL, $edit, t('Save')); - preg_match('|entity_test/manage/(\d+)|', $this->url, $match); - $id = $match[1]; - $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created'); - // Try to set a value below the minimum value - $this->drupalGet('entity_test/add'); + // Add prefix and suffix for the newly-created field. + $prefix = $this->randomName(); + $suffix = $this->randomName(); $edit = array( - 'user_id' => 1, - 'name' => $this->randomName(), - "{$field_name}[0][value]" => $minimum - 1, + 'instance[settings][prefix]' => $prefix, + 'instance[settings][suffix]' => $suffix, ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertRaw(t('%name must be higher than or equal to %minimum.', array('%name' => $field_name, '%minimum' => $minimum)), 'Correctly failed to save integer value less than minimum allowed value.'); + $this->drupalPostForm("admin/structure/types/manage/$type/fields/node.$type.field_$field_name", $edit, t('Save settings')); - // Try to set a decimal value - $this->drupalGet('entity_test/add'); + // Set the formatter to "unformatted" and to "number_integer", and just + // check that the settings summary does not generate warnings. + $this->drupalGet("admin/structure/types/manage/$type/display"); $edit = array( - 'user_id' => 1, - 'name' => $this->randomName(), - "{$field_name}[0][value]" => 1.5, + "fields[field_$field_name][type]" => 'number_unformatted', ); $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertRaw(t('%name is not a valid number.', array('%name' => $field_name)), 'Correctly failed to save decimal value to integer field.'); - - // Try to set a value above the maximum value - $this->drupalGet('entity_test/add'); $edit = array( - 'user_id' => 1, - 'name' => $this->randomName(), - "{$field_name}[0][value]" => $maximum + 1, + "fields[field_$field_name][type]" => 'number_integer', ); $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertRaw(t('%name must be lower than or equal to %maximum.', array('%name' => $field_name, '%maximum' => $maximum)), 'Correctly failed to save integer value greater than maximum allowed value.'); - - // Test with valid entries. - $valid_entries = array( - '-1234', - '0', - '1234', - ); - - foreach ($valid_entries as $valid_entry) { - $this->drupalGet('entity_test/add'); - $edit = array( - 'user_id' => 1, - 'name' => $this->randomName(), - "{$field_name}[0][value]" => $valid_entry, - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - preg_match('|entity_test/manage/(\d+)|', $this->url, $match); - $id = $match[1]; - $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created'); - $this->assertRaw($valid_entry, 'Value is displayed.'); - } - } - - /** - * Test number_float field. - */ - function testNumberFloatField() { - // Create a field with settings to validate. - $field_name = drupal_strtolower($this->randomName()); - entity_create('field_config', array( - 'name' => $field_name, - 'entity_type' => 'entity_test', - 'type' => 'number_float', - ))->save(); - - entity_create('field_instance_config', array( - 'field_name' => $field_name, - 'entity_type' => 'entity_test', - 'bundle' => 'entity_test', - ))->save(); - - entity_get_form_display('entity_test', 'entity_test', 'default') - ->setComponent($field_name, array( - 'type' => 'number', - 'settings' => array( - 'placeholder' => '0.00' - ), - )) - ->save(); - - entity_get_display('entity_test', 'entity_test', 'default') - ->setComponent($field_name, array( - 'type' => 'number_decimal', - )) - ->save(); - - // Display creation form. - $this->drupalGet('entity_test/add'); - $this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed'); - $this->assertRaw('placeholder="0.00"'); - - // Submit a signed decimal value within the allowed precision and scale. - $value = '-1234.5678'; - $edit = array( - 'user_id' => 1, - 'name' => $this->randomName(), - "{$field_name}[0][value]" => $value, - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - preg_match('|entity_test/manage/(\d+)|', $this->url, $match); - $id = $match[1]; - $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created'); - $this->assertRaw(round($value, 2), 'Value is displayed.'); - - // Try to create entries with more than one decimal separator; assert fail. - $wrong_entries = array( - '3.14.159', - '0..45469', - '..4589', - '6.459.52', - '6.3..25', - ); - - foreach ($wrong_entries as $wrong_entry) { - $this->drupalGet('entity_test/add'); - $edit = array( - "{$field_name}[0][value]" => $wrong_entry, - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertRaw(t('%name must be a number.', array('%name' => $field_name)), 'Correctly failed to save float value with more than one decimal point.'); - } - - // Try to create entries with minus sign not in the first position. - $wrong_entries = array( - '3-3', - '4-', - '1.3-', - '1.2-4', - '-10-10', - ); - - foreach ($wrong_entries as $wrong_entry) { - $this->drupalGet('entity_test/add'); - $edit = array( - "{$field_name}[0][value]" => $wrong_entry, - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertRaw(t('%name must be a number.', array('%name' => $field_name)), 'Correctly failed to save float value with minus sign in the wrong position.'); - } } /** diff --git a/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php b/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php index aa8b332..ba1351d 100644 --- a/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php +++ b/core/modules/picture/lib/Drupal/picture/Entity/PictureMapping.php @@ -48,6 +48,13 @@ class PictureMapping extends ConfigEntityBase implements PictureMappingInterface public $id; /** + * The picture UUID. + * + * @var string + */ + public $uuid; + + /** * The picture label. * * @var string diff --git a/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php b/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php index 2256dd4..1916320 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php +++ b/core/modules/rdf/lib/Drupal/rdf/Entity/RdfMapping.php @@ -33,6 +33,13 @@ class RdfMapping extends ConfigEntityBase implements RdfMappingInterface { public $id; /** + * UUID for the config entity. + * + * @var string + */ + public $uuid; + + /** * Entity type to be mapped. * * @var string diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/Field/TextFieldRdfaTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/TextFieldRdfaTest.php index d10318c..b350b95 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/Field/TextFieldRdfaTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/Field/TextFieldRdfaTest.php @@ -73,7 +73,7 @@ public function testDefaultFormatter() { * Tests the plain formatter. */ public function testPlainFormatter() { - $this->assertFormatterRdfa('string', 'http://schema.org/text', $this->testValue); + $this->assertFormatterRdfa('text_plain', 'http://schema.org/text', $this->testValue); } /** diff --git a/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php b/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php index 4c4f6bc..749337c 100644 --- a/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php +++ b/core/modules/rest/lib/Drupal/rest/Tests/CreateTest.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\rest\test\CreateTest. + * Definition of Drupal\rest\test\CreateTest. */ namespace Drupal\rest\Tests; @@ -106,7 +106,7 @@ public function testCreate() { $response = $this->httpRequest('entity/' . $entity_type, 'POST', $invalid_serialized, $this->defaultMimeType); $this->assertResponse(422); $error = drupal_json_decode($response); - $this->assertEqual($error['error'], "Unprocessable Entity: validation failed.\nuuid.0.value: UUID: may not be longer than 128 characters.\n"); + $this->assertEqual($error['error'], "Unprocessable Entity: validation failed.\nuuid.0.value: This value is too long. It should have 128 characters or less.\n"); // Try to create an entity without proper permissions. $this->drupalLogout(); @@ -125,5 +125,4 @@ public function testCreate() { // @todo Add a security test. It should not be possible for example to // create a test entity on a node resource route. } - } diff --git a/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php b/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php index 598401b..9f8d413 100644 --- a/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php +++ b/core/modules/rest/lib/Drupal/rest/Tests/UpdateTest.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\rest\test\UpdateTest. + * Contains Drupal\rest\test\UpdateTest. */ namespace Drupal\rest\Tests; @@ -149,7 +149,7 @@ public function testPatchUpdate() { $response = $this->httpRequest('entity/' . $entity_type . '/' . $entity->id(), 'PATCH', $invalid_serialized, $this->defaultMimeType); $this->assertResponse(422); $error = drupal_json_decode($response); - $this->assertEqual($error['error'], "Unprocessable Entity: validation failed.\nuuid.0.value: UUID: may not be longer than 128 characters.\n"); + $this->assertEqual($error['error'], "Unprocessable Entity: validation failed.\nuuid.0.value: This value is too long. It should have 128 characters or less.\n"); // Try to update an entity without proper permissions. $this->drupalLogout(); @@ -162,5 +162,4 @@ public function testPatchUpdate() { $this->httpRequest('entity/' . $entity_type . '/' . $entity->id(), 'PATCH', $serialized, $this->defaultMimeType); $this->assertResponse(404); } - } diff --git a/core/modules/search/lib/Drupal/search/Entity/SearchPage.php b/core/modules/search/lib/Drupal/search/Entity/SearchPage.php index 36444e0..b992a76 100644 --- a/core/modules/search/lib/Drupal/search/Entity/SearchPage.php +++ b/core/modules/search/lib/Drupal/search/Entity/SearchPage.php @@ -66,6 +66,13 @@ class SearchPage extends ConfigEntityBase implements SearchPageInterface, Entity public $label; /** + * The UUID of the search page entity. + * + * @var string + */ + public $uuid; + + /** * The configuration of the search page entity. * * @var array diff --git a/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php b/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php index 865704d..c6c7636 100644 --- a/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php +++ b/core/modules/serialization/lib/Drupal/serialization/Tests/EntitySerializationTest.php @@ -58,7 +58,7 @@ protected function setUp() { // Create a test entity to serialize. $this->values = array( 'name' => $this->randomName(), - 'user_id' => \Drupal::currentUser()->id(), + 'user_id' => $GLOBALS['user']->id(), 'field_test_text' => array( 'value' => $this->randomName(), 'format' => 'full_html', diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php b/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php index 8e4381a..ce52aca 100644 --- a/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php +++ b/core/modules/shortcut/lib/Drupal/shortcut/Entity/ShortcutSet.php @@ -52,6 +52,13 @@ class ShortcutSet extends ConfigEntityBase implements ShortcutSetInterface { public $id; /** + * The UUID for the configuration entity. + * + * @var string + */ + public $uuid; + + /** * The human-readable name of the configuration entity. * * @var string diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php index 8e452d5..067030b 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php @@ -806,11 +806,6 @@ public function run(array $methods = array()) { $test_methods = array_filter(get_class_methods($class), function ($method) { return strpos($method, 'test') === 0; }); - if (empty($test_methods)) { - // Call $this->assert() here because we need to pass along custom caller - // information, lest the wrong originating code file/line be identified. - $this->assert(FALSE, 'No test methods found.', 'Requirements', array('function' => __METHOD__ . '()', 'file' => __FILE__, 'line' => __LINE__)); - } if ($methods) { $test_methods = array_intersect($test_methods, $methods); } @@ -973,7 +968,8 @@ protected function beforePrepareEnvironment() { * @see TestBase::beforePrepareEnvironment() */ private function prepareEnvironment() { - $user = \Drupal::currentUser(); + global $user; + // Allow (base) test classes to backup global state information. $this->beforePrepareEnvironment(); @@ -1012,6 +1008,9 @@ private function prepareEnvironment() { // Ensure that the current session is not changed by the new environment. require_once DRUPAL_ROOT . '/' . settings()->get('session_inc', 'core/includes/session.inc'); drupal_save_session(FALSE); + // Run all tests as a anonymous user by default, web tests will replace that + // during the test set up. + $user = drupal_anonymous_user(); // Save and clean the shutdown callbacks array because it is static cached // and will be changed by the test run. Otherwise it will contain callbacks @@ -1066,10 +1065,7 @@ private function prepareEnvironment() { $request = Request::create('/'); $this->container->set('request', $request); - - // Run all tests as a anonymous user by default, web tests will replace that - // during the test set up. - $this->container->set('current_user', drupal_anonymous_user()); + $this->container->set('current_user', $GLOBALS['user']); \Drupal::setContainer($this->container); @@ -1121,9 +1117,9 @@ protected function rebuildContainer($environment = 'testing') { // DrupalKernel replaces the container in \Drupal::getContainer() with a // different object, so we need to replace the instance on this test class. $this->container = \Drupal::getContainer(); - // The current user is set in TestBase::prepareEnvironment(). + // The global $user is set in TestBase::prepareEnvironment(). $this->container->set('request', $request); - $this->container->set('current_user', \Drupal::currentUser()); + $this->container->set('current_user', $GLOBALS['user']); } /** @@ -1144,6 +1140,8 @@ protected function tearDown() { * @see TestBase::prepareEnvironment() */ private function restoreEnvironment() { + global $user; + // Reset all static variables. // Unsetting static variables will potentially invoke destruct methods, // which might call into functions that prime statics and caches again. @@ -1227,7 +1225,7 @@ private function restoreEnvironment() { $callbacks = $this->originalShutdownCallbacks; // Restore original user session. - $this->container->set('current_user', $this->originalUser); + $user = $this->originalUser; drupal_save_session(TRUE); } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 2bd20a2..942ebab 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -278,7 +278,7 @@ protected function drupalCreateNode(array $settings = array()) { $settings['uid'] = $this->loggedInUser->id(); } else { - $user = \Drupal::currentUser() ?: drupal_anonymous_user(); + $user = \Drupal::currentUser() ?: $GLOBALS['user']; $settings['uid'] = $user->id(); } } @@ -638,7 +638,7 @@ protected function checkPermissions(array $permissions, $reset = FALSE) { * If a user is already logged in, then the current user is logged out before * logging in the specified user. * - * Please note that neither the current user nor the passed-in user object is + * Please note that neither the global $user nor the passed-in user object is * populated with data of the logged in user. If you need full access to the * user object after logging in, it must be updated manually. If you also need * access to the plain-text password of the user (set by drupalCreateUser()), diff --git a/core/modules/system/lib/Drupal/system/Controller/SystemController.php b/core/modules/system/lib/Drupal/system/Controller/SystemController.php index 28861ad..5f55d6e 100644 --- a/core/modules/system/lib/Drupal/system/Controller/SystemController.php +++ b/core/modules/system/lib/Drupal/system/Controller/SystemController.php @@ -259,7 +259,7 @@ public function themesPage() { ); } $theme->operations[] = array( - 'title' => $this->t('Set as default'), + 'title' => $this->t('Set default'), 'route_name' => 'system.theme_set_default', 'query' => $query, 'attributes' => array('title' => $this->t('Set !theme as default theme', array('!theme' => $theme->info['name']))), @@ -275,7 +275,7 @@ public function themesPage() { 'attributes' => array('title' => $this->t('Enable !theme theme', array('!theme' => $theme->info['name']))), ); $theme->operations[] = array( - 'title' => $this->t('Enable and set as default'), + 'title' => $this->t('Enable and set default'), 'route_name' => 'system.theme_set_default', 'query' => $query, 'attributes' => array('title' => $this->t('Enable !theme as default theme', array('!theme' => $theme->info['name']))), diff --git a/core/modules/system/lib/Drupal/system/Entity/Action.php b/core/modules/system/lib/Drupal/system/Entity/Action.php index 93b38f1..972b4a3 100644 --- a/core/modules/system/lib/Drupal/system/Entity/Action.php +++ b/core/modules/system/lib/Drupal/system/Entity/Action.php @@ -43,6 +43,13 @@ class Action extends ConfigEntityBase implements ActionConfigEntityInterface, En public $label; /** + * The UUID of the action. + * + * @var string + */ + public $uuid; + + /** * The action type. * * @var string diff --git a/core/modules/system/lib/Drupal/system/Entity/DateFormat.php b/core/modules/system/lib/Drupal/system/Entity/DateFormat.php index ce169b9..71c2451 100644 --- a/core/modules/system/lib/Drupal/system/Entity/DateFormat.php +++ b/core/modules/system/lib/Drupal/system/Entity/DateFormat.php @@ -48,6 +48,13 @@ class DateFormat extends ConfigEntityBase implements DateFormatInterface { public $id; /** + * The date format UUID. + * + * @var string + */ + public $uuid; + + /** * The human-readable name of the date format entity. * * @var string diff --git a/core/modules/system/lib/Drupal/system/Entity/Menu.php b/core/modules/system/lib/Drupal/system/Entity/Menu.php index b4abf10..e8aecff 100644 --- a/core/modules/system/lib/Drupal/system/Entity/Menu.php +++ b/core/modules/system/lib/Drupal/system/Entity/Menu.php @@ -38,6 +38,13 @@ class Menu extends ConfigEntityBase implements MenuInterface { public $id; /** + * The menu UUID. + * + * @var string + */ + public $uuid; + + /** * The human-readable name of the menu entity. * * @var string diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php index 1d8db90..d380a51 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php @@ -84,7 +84,7 @@ function testContainer() { '#type' => 'container', '#markup' => 'foo', ), - 'expected' => '
foo
' . "\n", + 'expected' => '
foo
', ), // Container with a class. array( @@ -96,7 +96,7 @@ function testContainer() { 'class' => 'bar', ), ), - 'expected' => '
foo
' . "\n", + 'expected' => '
foo
', ), // Container with children. array( @@ -107,7 +107,7 @@ function testContainer() { '#markup' => 'foo', ), ), - 'expected' => '
foo
' . "\n", + 'expected' => '
foo
', ), ); diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php index 6cfcb68..ba30b48 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php @@ -91,7 +91,7 @@ function testDrupalRenderBasics() { '#theme_wrappers' => array('container'), '#attributes' => array('class' => 'baz'), ), - 'expected' => '
foobar
' . "\n", + 'expected' => '
foobar
', ), // Test that #theme_wrappers can disambiguate element attributes shared // with rendering methods that build #children by using the alternate @@ -109,7 +109,7 @@ function testDrupalRenderBasics() { '#href' => 'http://drupal.org', '#title' => 'bar', ), - 'expected' => '' . "\n", + 'expected' => '', ), // Test that #theme_wrappers can disambiguate element attributes when the // "base" attribute is not set for #theme. @@ -125,7 +125,7 @@ function testDrupalRenderBasics() { ), ), ), - 'expected' => '' . "\n", + 'expected' => '', ), // Two 'container' #theme_wrappers, one using the "base" attributes and // one using an override. @@ -140,7 +140,7 @@ function testDrupalRenderBasics() { 'container', ), ), - 'expected' => '
' . "\n" . '
' . "\n", + 'expected' => '
', ), // Array syntax theme hook suggestion in #theme_wrappers. array( @@ -149,7 +149,7 @@ function testDrupalRenderBasics() { '#theme_wrappers' => array(array('container')), '#attributes' => array('class' => 'foo'), ), - 'expected' => '
' . "\n", + 'expected' => '
', ), // Test handling of #markup as a fallback for #theme hooks. @@ -865,7 +865,7 @@ function testDrupalRenderChildElementRenderCachePlaceholder() { '#suffix' => '' ); $container['test_element'] = $test_element; - $expected_output = '
' . $context['bar'] . '
' . "\n"; + $expected_output = '
' . $context['bar'] . '
'; // #cache disabled. drupal_static_reset('_drupal_add_js'); @@ -938,7 +938,7 @@ function testDrupalRenderChildElementRenderCachePlaceholder() { $this->assertIdentical($token, $expected_token, 'The tokens are identical for the parent element'); // Verify the token is in the cached element. $expected_element = array( - '#markup' => '
' . "\n", + '#markup' => '
', '#post_render_cache' => array( 'common_test_post_render_cache_placeholder' => array( $expected_token => $context, diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTypeConstraintValidatorTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTypeConstraintValidatorTest.php deleted file mode 100644 index 6428ef0..0000000 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTypeConstraintValidatorTest.php +++ /dev/null @@ -1,73 +0,0 @@ - 'Entity type constraint', - 'description' => 'Tests validation constraints for EntityTypeConstraintValidator.', - 'group' => 'Validation', - ); - } - - public function setUp() { - parent::setUp(); - $this->typedData = $this->container->get('typed_data_manager'); - } - - /** - * Tests the EntityTypeConstraintValidator. - */ - public function testValidation() { - // Create a typed data definition with an EntityType constraint. - $entity_type = 'node'; - $definition = DataDefinition::create('entity_reference') - ->setConstraints(array( - 'EntityType' => $entity_type, - ) - ); - - // Test the validation. - $node = $this->container->get('entity.manager')->getStorageController('node')->create(array('type' => 'page')); - $typed_data = $this->typedData->create($definition, $node); - $violations = $typed_data->validate(); - $this->assertEqual($violations->count(), 0, 'Validation passed for correct value.'); - - // Test the validation when an invalid value (in this case a user entity) - // is passed. - $account = $this->createUser(); - - $typed_data = $this->typedData->create($definition, $account); - $violations = $typed_data->validate(); - $this->assertEqual($violations->count(), 1, 'Validation failed for incorrect value.'); - - // Make sure the information provided by a violation is correct. - $violation = $violations[0]; - $this->assertEqual($violation->getMessage(), t('The entity must be of type %type.', array('%type' => $entity_type)), 'The message for invalid value is correct.'); - $this->assertEqual($violation->getRoot(), $typed_data, 'Violation root is correct.'); - $this->assertEqual($violation->getInvalidValue(), $account, 'The invalid value is set correctly in the violation.'); - } -} diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTypedDataDefinitionTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTypedDataDefinitionTest.php index 3704dd9..e2669d5 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTypedDataDefinitionTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTypedDataDefinitionTest.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\system\Tests\Entity\EntityTypedDataDefinitionTest. + * Definition of Drupal\system\Tests\TypedData\EntityTypedDataDefinitionTest. */ namespace Drupal\system\Tests\Entity; @@ -101,7 +101,7 @@ public function testEntities() { // Comparison should ignore the internal static cache, so compare the // serialized objects instead. $this->assertEqual(serialize($field_definitions), serialize(\Drupal::entityManager()->getBaseFieldDefinitions('node'))); - $this->assertEqual($entity_definition->getPropertyDefinition('title')->getItemDefinition()->getDataType(), 'field_item:string'); + $this->assertEqual($entity_definition->getPropertyDefinition('title')->getItemDefinition()->getDataType(), 'field_item:text'); $this->assertNull($entity_definition->getMainPropertyName()); $this->assertNull($entity_definition->getPropertyDefinition('invalid')); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php index 118abe9..f88f281 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php @@ -108,7 +108,7 @@ protected function checkValidation($entity_type) { $test_entity->uuid->value = $this->randomString(129); $violations = $test_entity->validate(); $this->assertEqual($violations->count(), 1, 'Validation failed.'); - $this->assertEqual($violations[0]->getMessage(), t('%name: may not be longer than @max characters.', array('%name' => 'UUID', '@max' => 128))); + $this->assertEqual($violations[0]->getMessage(), t('This value is too long. It should have %limit characters or less.', array('%limit' => '128'))); $test_entity = clone $entity; $test_entity->langcode->value = $this->randomString(13); @@ -126,7 +126,7 @@ protected function checkValidation($entity_type) { $test_entity->name->value = $this->randomString(33); $violations = $test_entity->validate(); $this->assertEqual($violations->count(), 1, 'Validation failed.'); - $this->assertEqual($violations[0]->getMessage(), t('%name: may not be longer than @max characters.', array('%name' => 'Name', '@max' => 32))); + $this->assertEqual($violations[0]->getMessage(), t('This value is too long. It should have %limit characters or less.', array('%limit' => '32'))); // Make sure the information provided by a violation is correct. $violation = $violations[0]; diff --git a/core/modules/system/lib/Drupal/system/Tests/Installer/InstallerTranslationTest.php b/core/modules/system/lib/Drupal/system/Tests/Installer/InstallerTranslationTest.php index 269a846..691d293 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Installer/InstallerTranslationTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Installer/InstallerTranslationTest.php @@ -59,12 +59,4 @@ protected function setUpConfirm() { parent::setUpConfirm(); } - /** - * Verifies that installation succeeded. - */ - public function testInstaller() { - $this->assertUrl('user/1'); - $this->assertResponse(200); - } - } diff --git a/core/modules/system/lib/Drupal/system/Tests/System/ThemeTest.php b/core/modules/system/lib/Drupal/system/Tests/System/ThemeTest.php index 520cb11..cfd79af 100644 --- a/core/modules/system/lib/Drupal/system/Tests/System/ThemeTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/System/ThemeTest.php @@ -235,7 +235,7 @@ function testSwitchDefaultTheme() { // Enable Bartik and set it as the default theme. theme_enable(array('bartik')); $this->drupalGet('admin/appearance'); - $this->clickLink(t('Set as default')); + $this->clickLink(t('Set default')); $this->assertEqual(\Drupal::config('system.theme')->get('default'), 'bartik'); drupal_flush_all_caches(); @@ -245,7 +245,7 @@ function testSwitchDefaultTheme() { $this->assertText('Bartik(' . t('active tab') . ')', 'Default local task on blocks admin page is the default theme.'); // Switch back to Stark and test again to test that the menu cache is cleared. $this->drupalGet('admin/appearance'); - $this->clickLink(t('Set as default'), 0); + $this->clickLink(t('Set default'), 0); $this->drupalGet('admin/structure/block'); $this->assertText('Stark(' . t('active tab') . ')', 'Default local task on blocks admin page has changed.'); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/TwigFilterTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigFilterTest.php deleted file mode 100644 index a80598c..0000000 --- a/core/modules/system/lib/Drupal/system/Tests/Theme/TwigFilterTest.php +++ /dev/null @@ -1,85 +0,0 @@ - 'Twig Filters', - 'description' => 'Test Drupal\'s Twig filters.', - 'group' => 'Theme', - ); - } - - /** - * Test Twig "without" filter. - */ - public function testTwigWithoutFilter() { - $this->drupalGet('/twig-theme-test/filter'); - - $elements = array( - array( - 'expected' => '
No author: You can only find truth with logic if you have already found truth without it.1874-1936.
', - 'message' => '"No author" was successfully rendered.', - ), - array( - 'expected' => '
Complete quote after without: You can only find truth with logic if you have already found truth without it.Gilbert Keith Chesterton1874-1936.
', - 'message' => '"Complete quote after without" was successfully rendered.', - ), - array( - 'expected' => '
Only author: Gilbert Keith Chesterton.
', - 'message' => '"Only author:" was successfully rendered.', - ), - array( - 'expected' => '
No author or date: You can only find truth with logic if you have already found truth without it..
', - 'message' => '"No author or date" was successfully rendered.', - ), - array( - 'expected' => '
Only date: 1874-1936.
', - 'message' => '"Only date" was successfully rendered.', - ), - array( - 'expected' => '
Complete quote again for good measure: You can only find truth with logic if you have already found truth without it.Gilbert Keith Chesterton1874-1936.
', - 'message' => '"Complete quote again for good measure" was successfully rendered.', - ), - array( - 'expected' => '
Marked-up: -
-

You can only find truth with logic if you have already found truth without it.

- -
', - 'message' => '"Marked-up quote" was successfully rendered.', - ), - ); - - foreach ($elements as $element) { - $this->assertRaw($element['expected'], $element['message']); - } - } - -} diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/TwigReferenceObjectTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigReferenceObjectTest.php new file mode 100644 index 0000000..88a4d22 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigReferenceObjectTest.php @@ -0,0 +1,18 @@ +nid = $nid; + $this->title = $title; + } +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/TwigReferenceUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigReferenceUnitTest.php new file mode 100644 index 0000000..0f9534e --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigReferenceUnitTest.php @@ -0,0 +1,147 @@ + 'Theme Twig References', + 'description' => 'Tests TwigReference functions', + 'group' => 'Theme', + ); + } + + function setUp() { + parent::setUp(); + $this->variables = array( + 'foo' => 'bar', + 'baz' => array( + 'foo' => '42', + 'bar' => '23', + ), + 'node' => new TwigReferenceObjectTest( + 42, + 'test node' + ) + ); + } + + /** + * Test function for TwigReference class + */ + function testTwigReference() { + // Create a new TwigReference wrapper + $wrapper = new TwigReference(); + $wrapper->setReference($this->variables); + + // Check that strings are returned as strings + $foo = $wrapper['foo']; + $this->assertEqual($foo, $this->variables['foo'], 'String returned from TwigReference is the same'); + $this->assertTrue(is_string($foo), 'String returned from TwigReference is of type string'); + + // Check that arrays are wrapped again as TwigReference objects + $baz = $wrapper['baz']; + $this->assertTrue(is_object($baz), 'Array returned from TwigReference is of type object'); + $this->assertTrue($baz instanceof TwigReference, 'Array returned from TwigReference is instance of TwigReference'); + + // Check that getReference is giving back a reference to the original array + + $ref = &$baz->getReference(); + $this->assertTrue(is_array($ref), 'getReference returns an array'); + + // Now modify $ref + $ref['#hidden'] = TRUE; + $this->assertEqual($ref['#hidden'], $this->variables['baz']['#hidden'], 'Property set on reference is passed to original array.'); + $this->assertEqual($ref['#hidden'], $baz['#hidden'], 'Property set on reference is passed to wrapper.'); + + // Now modify $baz + $baz['hi'] = 'hello'; + + $this->assertEqual($baz['hi'], $this->variables['baz']['hi'], 'Property set on TwigReference object is passed to original array.'); + $this->assertEqual($baz['hi'], $ref['hi'], 'Property set on TwigReference object is passed to reference.'); + + // Check that an object is passed through directly + $node = $wrapper['node']; + $this->assertTrue(is_object($node), 'Object returned from TwigReference is of type object'); + $this->assertTrue($node instanceof TwigReferenceObjectTest, 'Object returned from TwigReference is instance of TwigReferenceObjectTest'); + } + + /** + * Test function for TwigReferenceFunctions class + */ + function testTwigReferenceFunctions() { + + // Create wrapper + $content = &$this->variables; + + // Use twig nomenclature + $context['content'] = $content; + + // Twig converts {{ hide(content.baz) }} to the following code + + // This will have failed, because getAttribute returns a value and not a reference + + try { + if (isset($context["content"])) { + $_content_ = $context["content"]; + } + else { + $_content_ = NULL; + } + TwigReferenceFunctions::hide($this->getAttribute($_content_, "baz")); + } + catch (Exception $e) { + // Catch the critical warning that a value was passed by reference + } + $this->assertFalse(isset($content['baz']['#printed']), 'baz is not hidden in content after hide() via value'); + + // Now lets do the same with some TwigReference magic! + + $content_wrapper = new TwigReference(); + $content_wrapper->setReference($content); + $context['content'] = $content_wrapper; + + // Twig converts {{ hide(content.baz) }} to the following code + + // This will succeed, because getAttribute returns a value, but it is an object + + if (isset($context["content"])) { + $_content_ = $context["content"]; + } + else { + $_content_ = NULL; + } + TwigReferenceFunctions::hide($this->getAttribute($_content_, "baz")); + + $this->assertTrue(isset($content['baz']['#printed']), 'baz is hidden in content after hide() via TwigReference object'); + + $type = TwigReferenceFunctions::gettype($this->getAttribute($_content_, "baz")); + $this->assertEqual($type, 'array', 'Type returned via TwigReferenceFunctions:: is an array.'); + + $type = gettype($this->getAttribute($_content_, "baz")); + $this->assertEqual($type, 'object', 'Type returned without TwigReferenceFunctions:: is an object.'); + } + + /** + * Helper function to somehow simulate Twigs getAttribute function + */ + public function getAttribute($array, $offset) { + if (isset($array[$offset])) { + return $array[$offset]; + } + + return NULL; + } +} diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc index 9e693fe..37a30e4 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -6,7 +6,6 @@ */ use Drupal\Core\Cache\Cache; -use Drupal\Core\Template\Attribute; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; @@ -470,9 +469,7 @@ function theme_system_modules_uninstall($variables) { } /** - * Prepares variables for appearance page templates. - * - * Default template: system-themes-page.html.twig. + * Returns HTML for the Appearance page. * * @param $variables * An associative array containing: @@ -481,10 +478,10 @@ function theme_system_modules_uninstall($variables) { * * @ingroup themeable */ -function template_preprocess_system_themes_page(&$variables) { - $groups = array(); +function theme_system_themes_page($variables) { $theme_groups = $variables['theme_groups']; - $variables['attributes']['id'] = 'system-themes-page'; + + $output = '
'; foreach ($variables['theme_group_titles'] as $state => $title) { if (!count($theme_groups[$state])) { @@ -492,70 +489,66 @@ function template_preprocess_system_themes_page(&$variables) { continue; } // Start new theme group. - $theme_group = array(); - $theme_group['state'] = $state; - $theme_group['title'] = $title; - $theme_group['themes'] = array(); - $theme_group['attributes'] = new Attribute(array('class' => array('system-themes-list', 'system-themes-list-' . $state, 'clearfix'))); + $output .= '

'. $title .'

'; foreach ($theme_groups[$state] as $theme) { - $current_theme = array(); - // Screenshot depicting the theme. + // Theme the screenshot. if ($theme->screenshot) { - $current_theme['screenshot'] = array( + $image = array( '#theme' => 'image', '#uri' => $theme->screenshot['uri'], '#alt' => $theme->screenshot['alt'], '#title' => $theme->screenshot['title'], '#attributes' => $theme->screenshot['attributes'], ); + $screenshot = drupal_render($image); } else { - $current_theme['screenshot'] = array(); + $screenshot = '
' . t('no screenshot') . '
'; } // Localize the theme description. - $current_theme['description'] = t($theme->info['description']); + $description = t($theme->info['description']); - // Style theme info. + // Style theme info + $notes = count($theme->notes) ? ' (' . join(', ', $theme->notes) . ')' : ''; $theme->classes[] = 'theme-selector'; $theme->classes[] = 'clearfix'; - $current_theme['attributes'] = new Attribute(array('class' => $theme->classes)); - $current_theme['name'] = $theme->info['name']; - $current_theme['version'] = isset($theme->info['version']) ? $theme->info['version'] : ''; - $current_theme['notes'] = $theme->notes; + $output .= '
' . $screenshot . '

' . $theme->info['name'] . ' ' . (isset($theme->info['version']) ? $theme->info['version'] : '') . $notes . '

' . $description . '
'; // Make sure to provide feedback on compatibility. - $current_theme['incompatible'] = ''; if (!empty($theme->incompatible_core)) { - $current_theme['incompatible'] = t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => \Drupal::CORE_COMPATIBILITY)); + $output .= '
' . t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => \Drupal::CORE_COMPATIBILITY)) . '
'; } elseif (!empty($theme->incompatible_php)) { if (substr_count($theme->info['php'], '.') < 2) { $theme->info['php'] .= '.*'; } - $current_theme['incompatible'] = t('This theme requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $theme->info['php'], '!php_version' => phpversion())); + $output .= '
' . t('This theme requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $theme->info['php'], '!php_version' => phpversion())) . '
'; } elseif (!empty($theme->incompatible_base)) { - $current_theme['incompatible'] = t('This theme requires the base theme @base_theme to operate correctly.', array('@base_theme' => $theme->info['base theme'])); + $output .= '
' . t('This theme requires the base theme @base_theme to operate correctly.', array('@base_theme' => $theme->info['base theme'])) . '
'; } elseif (!empty($theme->incompatible_engine)) { - $current_theme['incompatible'] = t('This theme requires the theme engine @theme_engine to operate correctly.', array('@theme_engine' => $theme->info['engine'])); + $output .= '
' . t('This theme requires the theme engine @theme_engine to operate correctly.', array('@theme_engine' => $theme->info['engine'])) . '
'; } - - // Build operation links. - $current_theme['operations'] = array( - '#theme' => 'links', - '#links' => $theme->operations, - '#attributes' => array( - 'class' => array('operations', 'clearfix'), - ), - ); - $theme_group['themes'][] = $current_theme; + else { + $links = array( + '#theme' => 'links', + '#links' => $theme->operations, + '#attributes' => array( + 'class' => array('operations', 'clearfix'), + ), + ); + $output .= drupal_render($links); + } + $output .= '
'; } - $groups[] = $theme_group; + $output .= '
'; } - $variables['theme_groups'] = $groups; + $output .= '
'; + + return $output; } diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php index 5442b26..3ded508 100644 --- a/core/modules/system/system.api.php +++ b/core/modules/system/system.api.php @@ -2250,7 +2250,7 @@ function hook_uninstall() { * installer to pause and display a page to the user by returning any themed * output that should be displayed on that page (but see below for tasks that * use the form API or batch API; the return values of these task functions are - * handled differently). You should also use #title within the task + * handled differently). You should also use drupal_set_title() within the task * callback function to set a custom page title. For some tasks, however, you * may want to simply do some processing and pass control to the next task * without ending the page request; to indicate this, simply do not send back diff --git a/core/modules/system/system.module b/core/modules/system/system.module index edc8532..3deaed8 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -163,11 +163,10 @@ function system_theme() { ), 'system_themes_page' => array( 'variables' => array( - 'theme_groups' => array(), - 'theme_group_titles' => array(), + 'theme_groups' => NULL, + 'theme_group_titles' => NULL, ), 'file' => 'system.admin.inc', - 'template' => 'system-themes-page', ), 'system_config_form' => array( 'render element' => 'form', @@ -1492,6 +1491,116 @@ function system_rebuild_module_data() { */ function _system_rebuild_theme_data() { return \Drupal::service('theme_handler')->rebuildThemeData(); + // Find themes + $themes = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes'); + // Allow modules to add further themes. + if ($module_themes = Drupal::moduleHandler()->invokeAll('system_theme_info')) { + foreach ($module_themes as $name => $uri) { + // @see file_scan_directory() + $themes[$name] = (object) array( + 'uri' => $uri, + 'filename' => pathinfo($uri, PATHINFO_FILENAME), + 'name' => $name, + ); + } + } + + // Find theme engines + $engines = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.engine$/', 'themes/engines'); + + // Set defaults for theme info. + $defaults = array( + 'engine' => 'twig', + 'name' => 'MISSING THEME NAME', + 'regions' => array( + 'sidebar_first' => 'Left sidebar', + 'sidebar_second' => 'Right sidebar', + 'content' => 'Content', + 'header' => 'Header', + 'footer' => 'Footer', + 'highlighted' => 'Highlighted', + 'help' => 'Help', + 'page_top' => 'Page top', + 'page_bottom' => 'Page bottom', + ), + 'description' => '', + 'features' => _system_default_theme_features(), + 'screenshot' => 'screenshot.png', + 'php' => DRUPAL_MINIMUM_PHP, + 'stylesheets' => array(), + 'scripts' => array(), + ); + + $sub_themes = array(); + // Read info files for each theme + foreach ($themes as $key => $theme) { + $themes[$key]->filename = $theme->uri; + $themes[$key]->info = drupal_parse_info_file($theme->uri) + $defaults; + + // Skip this extension if its type is not theme. + if (!isset($themes[$key]->info['type']) || $themes[$key]->info['type'] != 'theme') { + unset($themes[$key]); + continue; + } + + // Add the info file modification time, so it becomes available for + // contributed modules to use for ordering theme lists. + $themes[$key]->info['mtime'] = filemtime($theme->uri); + + // Invoke hook_system_info_alter() to give installed modules a chance to + // modify the data in the .info.yml files if necessary. + $type = 'theme'; + drupal_alter('system_info', $themes[$key]->info, $themes[$key], $type); + + if (!empty($themes[$key]->info['base theme'])) { + $sub_themes[] = $key; + } + + $engine = $themes[$key]->info['engine']; + if (isset($engines[$engine])) { + $themes[$key]->owner = $engines[$engine]->uri; + $themes[$key]->prefix = $engines[$engine]->name; + $themes[$key]->template = TRUE; + } + + // Prefix stylesheets and scripts with module path. + $path = dirname($theme->uri); + $theme->info['stylesheets'] = _system_info_add_path($theme->info['stylesheets'], $path); + $theme->info['scripts'] = _system_info_add_path($theme->info['scripts'], $path); + + // Give the screenshot proper path information. + if (!empty($themes[$key]->info['screenshot'])) { + $themes[$key]->info['screenshot'] = $path . '/' . $themes[$key]->info['screenshot']; + } + } + + // Now that we've established all our master themes, go back and fill in data + // for subthemes. + foreach ($sub_themes as $key) { + $themes[$key]->base_themes = drupal_find_base_themes($themes, $key); + // Don't proceed if there was a problem with the root base theme. + if (!current($themes[$key]->base_themes)) { + continue; + } + $base_key = key($themes[$key]->base_themes); + foreach (array_keys($themes[$key]->base_themes) as $base_theme) { + $themes[$base_theme]->sub_themes[$key] = $themes[$key]->info['name']; + } + // Copy the 'owner' and 'engine' over if the top level theme uses a theme + // engine. + if (isset($themes[$base_key]->owner)) { + if (isset($themes[$base_key]->info['engine'])) { + $themes[$key]->info['engine'] = $themes[$base_key]->info['engine']; + $themes[$key]->owner = $themes[$base_key]->owner; + $themes[$key]->prefix = $themes[$base_key]->prefix; + } + else { + $themes[$key]->prefix = $key; + } + } + } + + return $themes; } /** diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml index 599f9c1..b7fa3cc 100644 --- a/core/modules/system/system.routing.yml +++ b/core/modules/system/system.routing.yml @@ -319,7 +319,7 @@ system.themes_page: system.theme_set_default: path: '/admin/appearance/default' defaults: - _title: 'Set as default theme' + _title: 'Set default theme' _content: '\Drupal\system\Controller\SystemController::themeSetDefault' requirements: _permission: 'administer themes' diff --git a/core/modules/system/templates/container.html.twig b/core/modules/system/templates/container.html.twig deleted file mode 100644 index a643e19..0000000 --- a/core/modules/system/templates/container.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -{# -/** - * @file - * Default theme implementation of a container used to wrap child elements. - * - * Used for grouped form items. Can also be used as a #theme_wrapper for any - * renderable element, to surround it with a
and HTML attributes. - * - * Available variables: - * - attributes: HTML attributes for the containing element. - * - children: The rendered child elements of the container. - * - * @see template_preprocess_container() - * - * @ingroup themeable - */ -#} -{{ children }}
diff --git a/core/modules/system/templates/fieldset.html.twig b/core/modules/system/templates/fieldset.html.twig deleted file mode 100644 index 9e4fe68..0000000 --- a/core/modules/system/templates/fieldset.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{# -/** - * @file - * Default theme implementation for a fieldset element and its children. - * - * Available variables: - * - attributes: HTML attributes for the fieldset element. - * - required: The required marker or empty if the associated fieldset is - * not required. - * - legend: The legend element containing the following properties: - * - title: Title of the fieldset, intended for use as the text of the legend. - * - attributes: HTML attributes to apply to the legend. - * - description: The description element containing the following properties: - * - content: The description content of the fieldset. - * - attributes: HTML attributes to apply to the description container. - * - children: The rendered child elements of the fieldset. - * - prefix: The content to add before the fieldset children. - * - suffix: The content to add after the fieldset children. - * - * @see template_preprocess_fieldset() - * - * @ingroup themeable - */ -#} - - {% if legend.title is not empty or required -%} - {# Always wrap fieldset legends in a SPAN for CSS positioning. #} - {{ legend.title }}{{ required }} - {%- endif %} -
- {% if prefix %} - {{ prefix }} - {% endif %} - {{ children }} - {% if suffix %} - {{ suffix }} - {% endif %} - {% if description.content %} - {{ description.content }}
- {% endif %} -
- diff --git a/core/modules/system/templates/form.html.twig b/core/modules/system/templates/form.html.twig deleted file mode 100644 index b95fe71..0000000 --- a/core/modules/system/templates/form.html.twig +++ /dev/null @@ -1,15 +0,0 @@ -{# -/** - * @file - * Default theme implementation for a 'form' element. - * - * Available variables - * - attributes: A list of HTML attributes for the wrapper element. - * - children: The child elements of the form. - * - * @see template_preprocess_form() - * - * @ingroup themeable - */ -#} -
{{ children }}
diff --git a/core/modules/system/templates/install-page.html.twig b/core/modules/system/templates/install-page.html.twig index 031013e..a462a5a 100644 --- a/core/modules/system/templates/install-page.html.twig +++ b/core/modules/system/templates/install-page.html.twig @@ -12,14 +12,14 @@ */ #} - + {{ head }} {{ head_title }} {{ styles }} {{ scripts }} - +
diff --git a/core/modules/system/templates/maintenance-page.html.twig b/core/modules/system/templates/maintenance-page.html.twig index b5275c7..b71fa24 100644 --- a/core/modules/system/templates/maintenance-page.html.twig +++ b/core/modules/system/templates/maintenance-page.html.twig @@ -3,7 +3,8 @@ * @file * Default theme implementation to display a single Drupal page while offline. * - * All of the available variables are mirrored in html.html.twig. + * All the available variables are mirrored in html.html.twig and + * page.html.twig. * Some may be blank but they are provided for consistency. * * @see template_preprocess_maintenance_page() diff --git a/core/modules/system/templates/select.html.twig b/core/modules/system/templates/select.html.twig deleted file mode 100644 index 21f32ac..0000000 --- a/core/modules/system/templates/select.html.twig +++ /dev/null @@ -1,15 +0,0 @@ -{# -/** - * @file - * Default theme implementation for a select element. - * - * Available variables: - * - attributes: HTML attributes for the select tag. - * - options: The option element children. - * - * @see template_preprocess_select() - * - * @ingroup themeable - */ -#} -{{ options }} diff --git a/core/modules/system/templates/system-themes-page.html.twig b/core/modules/system/templates/system-themes-page.html.twig deleted file mode 100644 index 80089fd..0000000 --- a/core/modules/system/templates/system-themes-page.html.twig +++ /dev/null @@ -1,61 +0,0 @@ -{# -/** - * @file - * Default theme implementation for the Appearance page. - * - * Available variables: - * - attributes: HTML attributes for the main container. - * - theme_groups: A list of theme groups. Each theme group contains: - * - attributes: HTML attributes specific to this theme group. - * - title: Title for the theme group. - * - state: State of the theme group, e.g. enabled or disabled. - * - themes: A list of themes within the theme group. Each theme contains: - * - attributes: HTML attributes specific to this theme. - * - screenshot: A screenshot representing the theme. - * - description: Description of the theme. - * - name: Theme name. - * - version: The theme's version number. - * - notes: Identifies what context this theme is being used in, e.g., - * default theme, admin theme. - * - incompatible: Text describing any compatibility issues. - * - operations: A list of operation links, e.g., Settings, Enable, Disable, - * etc. these links should only be displayed if the theme is compatible. - * - * @see template_preprocess_system_themes_page() - * - * @ingroup themeable - */ -#} - - {% for theme_group in theme_groups %} - -

{{ theme_group.title }}

- {% for theme in theme_group.themes %} - - {% if theme.screenshot %} - {{ theme.screenshot }} - {% else %} -
-
{{ "no screenshot"|t }}
-
- {% endif %} -
-

- {{- theme.name }} {{ theme.version -}} - {% if theme.notes %} - ({{ theme.notes|join(', ') }}) - {%- endif -%} -

-
{{ theme.description }}
- {# Display operation links if the theme is compatible. #} - {% if theme.incompatible %} -
{{ theme.incompatible }}
- {% else %} - {{ theme.operations }} - {% endif %} -
-
- {% endfor %} -
- {% endfor %} -
diff --git a/core/modules/system/tests/modules/twig_extension_test/lib/Drupal/twig_extension_test/TwigExtension/TestExtension.php b/core/modules/system/tests/modules/twig_extension_test/lib/Drupal/twig_extension_test/TwigExtension/TestExtension.php index 3c2b851..93da633 100644 --- a/core/modules/system/tests/modules/twig_extension_test/lib/Drupal/twig_extension_test/TwigExtension/TestExtension.php +++ b/core/modules/system/tests/modules/twig_extension_test/lib/Drupal/twig_extension_test/TwigExtension/TestExtension.php @@ -8,6 +8,7 @@ namespace Drupal\twig_extension_test\TwigExtension; use Drupal\Core\Template\TwigExtension; +use Drupal\Core\Template\TwigReferenceFunction; /** * A test Twig extension that adds a custom function and a custom filter. diff --git a/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php b/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php index ba2a718..45654ea 100644 --- a/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php +++ b/core/modules/system/tests/modules/twig_theme_test/lib/Drupal/twig_theme_test/TwigThemeTestController.php @@ -28,19 +28,4 @@ public function transBlockRender() { ); } - /** - * Menu callback for filters in a Twig template. - */ - public function testFilterRender() { - return array( - '#theme' => 'twig_theme_test_filter', - '#quote' => array( - 'content' => array('#markup' => 'You can only find truth with logic if you have already found truth without it.'), - 'author' => array('#markup' => 'Gilbert Keith Chesterton'), - 'date' => array('#markup' => '1874-1936'), - ), - ); - } - } - diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.filter.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.filter.html.twig deleted file mode 100644 index ce4c405..0000000 --- a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.filter.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -
No author: {{ quote|without('author') }}.
-
Complete quote after without: {{ quote }}.
-
Only author: {{ quote.author }}.
-
No author or date: {{ quote|without('date', 'author') }}.
-
Only date: {{ quote.date }}.
-
Complete quote again for good measure: {{ quote }}.
-
Marked-up: -
-

{{ quote.content }}

- -
-
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module index e47b30c..6edb6f6 100644 --- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module +++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module @@ -4,10 +4,6 @@ * Implements hook_theme(). */ function twig_theme_test_theme($existing, $type, $theme, $path) { - $items['twig_theme_test_filter'] = array( - 'variables' => array('quote' => array()), - 'template' => 'twig_theme_test.filter', - ); $items['twig_theme_test_php_variables'] = array( 'template' => 'twig_theme_test.php_variables', ); diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml index c187bc2..96befd4 100644 --- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml +++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml @@ -11,10 +11,3 @@ twig_theme_test.trans: _content: '\Drupal\twig_theme_test\TwigThemeTestController::transBlockRender' requirements: _access: 'TRUE' - -twig_theme_test.filter: - path: '/twig-theme-test/filter' - defaults: - _content: '\Drupal\twig_theme_test\TwigThemeTestController::testFilterRender' - requirements: - _access: 'TRUE' diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php index ee3d8f3..c9bf8b6 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Vocabulary.php @@ -54,6 +54,13 @@ class Vocabulary extends ConfigEntityBase implements VocabularyInterface { public $vid; /** + * The vocabulary UUID. + * + * @var string + */ + public $uuid; + + /** * Name of the vocabulary. * * @var string diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermValidationTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermValidationTest.php index 009d871..e36668f 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermValidationTest.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermValidationTest.php @@ -56,8 +56,7 @@ public function testValidation() { $violations = $term->validate(); $this->assertEqual(count($violations), 1, 'Violation found when name is too long.'); $this->assertEqual($violations[0]->getPropertyPath(), 'name.0.value'); - $field_label = $term->get('name')->getFieldDefinition()->getLabel(); - $this->assertEqual($violations[0]->getMessage(), t('%name: may not be longer than @max characters.', array('%name' => $field_label, '@max' => 255))); + $this->assertEqual($violations[0]->getMessage(), t('This value is too long. It should have %limit characters or less.', array('%limit' => 255))); $term->set('name', NULL); $violations = $term->validate(); diff --git a/core/modules/taxonomy/templates/taxonomy-term.html.twig b/core/modules/taxonomy/templates/taxonomy-term.html.twig index 2ecc713..a3986fa 100644 --- a/core/modules/taxonomy/templates/taxonomy-term.html.twig +++ b/core/modules/taxonomy/templates/taxonomy-term.html.twig @@ -8,10 +8,10 @@ * - name: Name of the current term. * - content: Items for the content of the term (fields and description). * Use 'content' to print them all, or print a subset such as - * 'content.description'. Use the following code to exclude the - * printing of a given child element: + * 'content.description'. Use the following code to temporarily suppress the + * printing of a given element: * @code - * {{ content|without('description') }} + * {% hide(content.description) %} * @endcode * - attributes: HTML attributes for the wrapper. The 'class' attribute * contains the following classes by default: diff --git a/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php b/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php index 6a47145..e710ded 100644 --- a/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php +++ b/core/modules/telephone/lib/Drupal/telephone/Plugin/Field/FieldType/TelephoneItem.php @@ -19,7 +19,7 @@ * label = @Translation("Telephone number"), * description = @Translation("This field stores a telephone number in the database."), * default_widget = "telephone_default", - * default_formatter = "string" + * default_formatter = "telephone_link" * ) */ class TelephoneItem extends ConfigFieldItemBase { diff --git a/core/modules/telephone/telephone.module b/core/modules/telephone/telephone.module index eee9213..23099a9 100644 --- a/core/modules/telephone/telephone.module +++ b/core/modules/telephone/telephone.module @@ -26,8 +26,20 @@ function telephone_help($path, $arg) { } /** + * Implements hook_field_info_alter(). + */ +function telephone_field_info_alter(&$info) { + if (\Drupal::moduleHandler()->moduleExists('text')) { + $info['telephone']['default_formatter'] = 'text_plain'; + } +} + + +/** * Implements hook_field_formatter_info_alter(). */ function telephone_field_formatter_info_alter(&$info) { - $info['string']['field_types'][] = 'telephone'; + if (isset($info['text_plain'])) { + $info['text_plain']['field_types'][] = 'telephone'; + } } diff --git a/core/modules/text/config/schema/text.schema.yml b/core/modules/text/config/schema/text.schema.yml index dc54670..d377366 100644 --- a/core/modules/text/config/schema/text.schema.yml +++ b/core/modules/text/config/schema/text.schema.yml @@ -110,6 +110,16 @@ entity_view_display.field.text_default: sequence: - type: string +entity_view_display.field.text_plain: + type: entity_field_view_display_base + label: 'Plain text display format settings' + mapping: + settings: + type: sequence + label: 'Settings' + sequence: + - type: string + entity_view_display.field.text_summary_or_trimmed: type: entity_field_view_display_base label: 'Summary or trimmed text display format settings' diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextPlainFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextPlainFormatter.php new file mode 100644 index 0000000..6c15bf5 --- /dev/null +++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldFormatter/TextPlainFormatter.php @@ -0,0 +1,46 @@ + $item) { + // The text value has no text format assigned to it, so the user input + // should equal the output, including newlines. + $elements[$delta] = array('#markup' => nl2br(check_plain($item->value))); + } + + return $elements; + } + +} diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextfieldWidget.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextfieldWidget.php index 35f6957..b35e633 100644 --- a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextfieldWidget.php +++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextfieldWidget.php @@ -8,7 +8,7 @@ namespace Drupal\text\Plugin\Field\FieldWidget; use Drupal\Core\Field\FieldItemListInterface; -use Drupal\Core\Field\Plugin\Field\FieldWidget\StringWidget; +use Drupal\Core\Field\WidgetBase; use Symfony\Component\Validator\ConstraintViolationInterface; /** @@ -18,8 +18,7 @@ * id = "text_textfield", * label = @Translation("Text field"), * field_types = { - * "text", - * "string" + * "text" * }, * settings = { * "size" = "60", @@ -27,22 +26,67 @@ * } * ) */ -class TextfieldWidget extends StringWidget { +class TextfieldWidget extends WidgetBase { + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, array &$form_state) { + $element['size'] = array( + '#type' => 'number', + '#title' => t('Size of textfield'), + '#default_value' => $this->getSetting('size'), + '#required' => TRUE, + '#min' => 1, + ); + $element['placeholder'] = array( + '#type' => 'textfield', + '#title' => t('Placeholder'), + '#default_value' => $this->getSetting('placeholder'), + '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'), + ); + return $element; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + $summary = array(); + + $summary[] = t('Textfield size: !size', array('!size' => $this->getSetting('size'))); + $placeholder = $this->getSetting('placeholder'); + if (!empty($placeholder)) { + $summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder)); + } + + return $summary; + } /** * {@inheritdoc} */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) { - $main_widget = parent::formElement($items, $delta, $element, $form, $form_state); + $main_widget = $element + array( + '#type' => 'textfield', + '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL, + '#size' => $this->getSetting('size'), + '#placeholder' => $this->getSetting('placeholder'), + '#maxlength' => $this->getFieldSetting('max_length'), + '#attributes' => array('class' => array('text-full')), + ); if ($this->getFieldSetting('text_processing')) { - $element = $main_widget['value']; + $element = $main_widget; $element['#type'] = 'text_format'; $element['#format'] = isset($items[$delta]->format) ? $items[$delta]->format : NULL; - $element['#base_type'] = $main_widget['value']['#type']; - return $element; + $element['#base_type'] = $main_widget['#type']; + } + else { + $element['value'] = $main_widget; } - return $main_widget; + + return $element; } /** diff --git a/core/modules/text/lib/Drupal/text/TextProcessed.php b/core/modules/text/lib/Drupal/text/TextProcessed.php index 5d99de3..d07a196 100644 --- a/core/modules/text/lib/Drupal/text/TextProcessed.php +++ b/core/modules/text/lib/Drupal/text/TextProcessed.php @@ -2,12 +2,11 @@ /** * @file - * Contains \Drupal\text\TextProcessed. + * Definition of Drupal\text\TextProcessed. */ namespace Drupal\text; -use Drupal\Component\Utility\String; use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedData; @@ -58,8 +57,8 @@ public function getValue($langcode = NULL) { } else { // Escape all HTML and retain newlines. - // @see \Drupal\Core\Field\Plugin\Field\FieldFormatter\StringFormatter - $this->processed = nl2br(String::checkPlain($text)); + // @see \Drupal\text\Plugin\field\formatter\TextPlainFormatter + $this->processed = nl2br(check_plain($text)); } return $this->processed; } diff --git a/core/modules/text/text.module b/core/modules/text/text.module index 339d9da..b1672de 100644 --- a/core/modules/text/text.module +++ b/core/modules/text/text.module @@ -170,12 +170,3 @@ function text_filter_format_update($format) { function text_filter_format_disable($format) { field_cache_clear(); } - -/** - * Implements hook_field_formatter_info_alter(). - */ -function text_field_formatter_info_alter(&$info) { - $info['string']['field_types'][] = 'text'; - $info['string']['field_types'][] = 'text_with_summary'; - $info['string']['field_types'][] = 'text_long'; -} diff --git a/core/modules/user/lib/Drupal/user/AccountFormController.php b/core/modules/user/lib/Drupal/user/AccountFormController.php index ed4cc07..915e71f 100644 --- a/core/modules/user/lib/Drupal/user/AccountFormController.php +++ b/core/modules/user/lib/Drupal/user/AccountFormController.php @@ -349,7 +349,7 @@ public function validate(array $form, array &$form_state) { if ($mail_taken) { // Format error message dependent on whether the user is logged in or not. - if (\Drupal::currentUser()->isAuthenticated()) { + if ($GLOBALS['user']->isAuthenticated()) { $this->setFormError('mail', $form_state, $this->t('The e-mail address %email is already taken.', array('%email' => $mail))); } else { diff --git a/core/modules/user/lib/Drupal/user/Entity/Role.php b/core/modules/user/lib/Drupal/user/Entity/Role.php index 2a025d9..49152e3 100644 --- a/core/modules/user/lib/Drupal/user/Entity/Role.php +++ b/core/modules/user/lib/Drupal/user/Entity/Role.php @@ -51,6 +51,13 @@ class Role extends ConfigEntityBase implements RoleInterface { public $id; /** + * The UUID of this role. + * + * @var string + */ + public $uuid; + + /** * The human-readable label of this role. * * @var string diff --git a/core/modules/user/lib/Drupal/user/Entity/User.php b/core/modules/user/lib/Drupal/user/Entity/User.php index 2ae6676..b38ea07 100644 --- a/core/modules/user/lib/Drupal/user/Entity/User.php +++ b/core/modules/user/lib/Drupal/user/Entity/User.php @@ -122,7 +122,7 @@ public function postSave(EntityStorageControllerInterface $storage_controller, $ // user and recreate the current one. if ($this->pass->value != $this->original->pass->value) { drupal_session_destroy_uid($this->id()); - if ($this->id() == \Drupal::currentUser()->id()) { + if ($this->id() == $GLOBALS['user']->id()) { drupal_session_regenerate(); } } diff --git a/core/modules/user/lib/Drupal/user/Plugin/Action/CancelUser.php b/core/modules/user/lib/Drupal/user/Plugin/Action/CancelUser.php index 75fa5f5..b404ba0 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Action/CancelUser.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Action/CancelUser.php @@ -60,7 +60,7 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public function executeMultiple(array $entities) { - $this->tempStoreFactory->get('user_user_operations_cancel')->set(\Drupal::currentUser()->id(), $entities); + $this->tempStoreFactory->get('user_user_operations_cancel')->set($GLOBALS['user']->id(), $entities); } /** diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/argument_default/CurrentUser.php b/core/modules/user/lib/Drupal/user/Plugin/views/argument_default/CurrentUser.php index f1d987b..e763bae 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/argument_default/CurrentUser.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/argument_default/CurrentUser.php @@ -10,7 +10,7 @@ use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase; /** - * Default argument plugin to extract the current user + * Default argument plugin to extract the global $user * * This plugin actually has no options so it odes not need to do a great deal. * @@ -22,7 +22,8 @@ class CurrentUser extends ArgumentDefaultPluginBase { public function getArgument() { - return \Drupal::currentUser()->id(); + global $user; + return $user->id(); } } diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php b/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php index d7c3701..d385236 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php @@ -109,21 +109,21 @@ public function validateArgument($argument) { // However, is_integer() will always fail, since $argument is a string. if (is_numeric($argument) && $argument == (int)$argument) { if ($type == 'uid' || $type == 'either') { - if ($argument == \Drupal::currentUser()->id()) { + if ($argument == $GLOBALS['user']->id()) { // If you assign an object to a variable in PHP, the variable // automatically acts as a reference, not a copy, so we use // clone to ensure that we don't actually mess with the - // real current user object. - $account = clone \Drupal::currentUser(); + // real global $user object. + $account = clone $GLOBALS['user']; } $condition = 'uid'; } } else { if ($type == 'name' || $type == 'either') { - $name = \Drupal::currentUser()->getUserName() ?: \Drupal::config('user.settings')->get('anonymous'); + $name = $GLOBALS['user']->getUserName() ?: \Drupal::config('user.settings')->get('anonymous'); if ($argument == $name) { - $account = clone \Drupal::currentUser(); + $account = clone $GLOBALS['user']; } $condition = 'name'; } diff --git a/core/modules/user/lib/Drupal/user/RegisterFormController.php b/core/modules/user/lib/Drupal/user/RegisterFormController.php index 32a7922..c9f1f1d 100644 --- a/core/modules/user/lib/Drupal/user/RegisterFormController.php +++ b/core/modules/user/lib/Drupal/user/RegisterFormController.php @@ -41,7 +41,7 @@ public function form(array $form, array &$form_state) { // If we aren't admin but already logged on, go to the user page instead. if (!$admin && $user->isAuthenticated()) { - return new RedirectResponse(url('user/' . \Drupal::currentUser()->id(), array('absolute' => TRUE))); + return new RedirectResponse(url('user/' . $user->id(), array('absolute' => TRUE))); } $form['#attached']['library'][] = array('core', 'jquery.cookie'); diff --git a/core/modules/user/lib/Drupal/user/TempStore.php b/core/modules/user/lib/Drupal/user/TempStore.php index 458bf5c..dd6451c 100644 --- a/core/modules/user/lib/Drupal/user/TempStore.php +++ b/core/modules/user/lib/Drupal/user/TempStore.php @@ -7,7 +7,6 @@ namespace Drupal\user; -use Drupal\Component\Utility\String; use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface; use Drupal\Core\Lock\LockBackendInterface; @@ -35,6 +34,9 @@ * editing certain data, or even to restrict other users from editing it at * the same time. It is the responsibility of the implementation to decide * when and whether one owner can use or update another owner's data. + * + * @todo We could add getIfOwner() or setIfOwner() methods to make this more + * explicit. */ class TempStore { @@ -83,7 +85,7 @@ class TempStore { * @param mixed $owner * The owner key to store along with the data (e.g. a user or session ID). */ - public function __construct(KeyValueStoreExpirableInterface $storage, LockBackendInterface $lockBackend, $owner) { + function __construct(KeyValueStoreExpirableInterface $storage, LockBackendInterface $lockBackend, $owner) { $this->storage = $storage; $this->lockBackend = $lockBackend; $this->owner = $owner; @@ -98,30 +100,13 @@ public function __construct(KeyValueStoreExpirableInterface $storage, LockBacken * @return mixed * The data associated with the key, or NULL if the key does not exist. */ - public function get($key) { + function get($key) { if ($object = $this->storage->get($key)) { return $object->data; } } /** - * Retrieves a value from this TempStore for a given key. - * - * Only returns the value if the value is owned by $this->owner. - * - * @param string $key - * The key of the data to retrieve. - * - * @return mixed - * The data associated with the key, or NULL if the key does not exist. - */ - public function getIfOwner($key) { - if (($object = $this->storage->get($key)) && ($object->owner == $this->owner)) { - return $object->data; - } - } - - /** * Stores a particular key/value pair only if the key doesn't already exist. * * @param string $key @@ -132,7 +117,7 @@ public function getIfOwner($key) { * @return bool * TRUE if the data was set, or FALSE if it already existed. */ - public function setIfNotExists($key, $value) { + function setIfNotExists($key, $value) { $value = (object) array( 'owner' => $this->owner, 'data' => $value, @@ -144,46 +129,18 @@ public function setIfNotExists($key, $value) { /** * Stores a particular key/value pair in this TempStore. * - * Only stores the given key/value pair if it does not exist yet or is owned - * by $this->owner. - * - * @param string $key - * The key of the data to store. - * @param mixed $value - * The data to store. - * - * @return bool - * TRUE if the data was set, or FALSE if it already exists and is not owned - * by $this->user. - */ - public function setIfOwner($key, $value) { - if ($this->setIfNotExists($key, $value)) { - return TRUE; - } - - if (($object = $this->storage->get($key)) && ($object->owner == $this->owner)) { - $this->set($key, $value); - return TRUE; - } - - return FALSE; - } - - /** - * Stores a particular key/value pair in this TempStore. - * * @param string $key * The key of the data to store. * @param mixed $value * The data to store. */ - public function set($key, $value) { + function set($key, $value) { if (!$this->lockBackend->acquire($key)) { $this->lockBackend->wait($key); if (!$this->lockBackend->acquire($key)) { - throw new TempStoreException(String::format("Couldn't acquire lock to update item %key in %collection temporary storage.", array( + throw new TempStoreException(format_string("Couldn't acquire lock to update item %key in %collection temporary storage.", array( '%key' => $key, - '%collection' => $this->storage->getCollectionName(), + '%collection' => $this->storage->collection, ))); } } @@ -207,7 +164,7 @@ public function set($key, $value) { * An object with the owner and updated time if the key has a value, or * NULL otherwise. */ - public function getMetadata($key) { + function getMetadata($key) { // Fetch the key/value pair and its metadata. $object = $this->storage->get($key); if ($object) { @@ -223,13 +180,13 @@ public function getMetadata($key) { * @param string $key * The key of the data to delete. */ - public function delete($key) { + function delete($key) { if (!$this->lockBackend->acquire($key)) { $this->lockBackend->wait($key); if (!$this->lockBackend->acquire($key)) { - throw new TempStoreException(String::format("Couldn't acquire lock to delete item %key from %collection temporary storage.", array( + throw new TempStoreException(format_string("Couldn't acquire lock to delete item %key from %collection temporary storage.", array( '%key' => $key, - '%collection' => $this->storage->getCollectionName(), + '%collection' => $this->storage->collection, ))); } } @@ -237,28 +194,4 @@ public function delete($key) { $this->lockBackend->release($key); } - /** - * Deletes data from the store for a given key and releases the lock on it. - * - * Only delete the given key if it is owned by $this->owner. - * - * @param string $key - * The key of the data to delete. - * - * @return bool - * TRUE if the object was deleted or does not exist, FALSE if it exists but - * is not owned by $this->owner. - */ - public function deleteIfOwner($key) { - if (!$object = $this->storage->get($key)) { - return TRUE; - } - elseif ($object->owner == $this->owner) { - $this->delete($key); - return TRUE; - } - - return FALSE; - } - } diff --git a/core/modules/user/lib/Drupal/user/TempStoreFactory.php b/core/modules/user/lib/Drupal/user/TempStoreFactory.php index 28d4147..45f421e 100644 --- a/core/modules/user/lib/Drupal/user/TempStoreFactory.php +++ b/core/modules/user/lib/Drupal/user/TempStoreFactory.php @@ -61,7 +61,7 @@ function get($collection, $owner = NULL) { // Use the currently authenticated user ID or the active user ID unless // the owner is overridden. if (!isset($owner)) { - $owner = \Drupal::currentUser()->id() ?: session_id(); + $owner = $GLOBALS['user']->id() ?: session_id(); } // Store the data for this collection in the database. diff --git a/core/modules/user/lib/Drupal/user/Tests/TempStoreDatabaseTest.php b/core/modules/user/lib/Drupal/user/Tests/TempStoreDatabaseTest.php index 0437837..28edf55 100644 --- a/core/modules/user/lib/Drupal/user/Tests/TempStoreDatabaseTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/TempStoreDatabaseTest.php @@ -123,12 +123,6 @@ public function testUserTempStore() { $this->assertIdenticalObject($this->objects[2], $stores[0]->get($key)); // The object is the same when another user loads it. $this->assertIdenticalObject($this->objects[2], $stores[1]->get($key)); - - // This user should be allowed to get, update, delete. - $this->assertTrue($stores[0]->getIfOwner($key) instanceof \stdClass); - $this->assertTrue($stores[0]->setIfOwner($key, $this->objects[1])); - $this->assertTrue($stores[0]->deleteIfOwner($key)); - // Another user can update the object and become the owner. $stores[1]->set($key, $this->objects[3]); $this->assertIdenticalObject($this->objects[3], $stores[0]->get($key)); @@ -140,11 +134,6 @@ public function testUserTempStore() { $metadata = $stores[0]->getMetadata($key); $this->assertEqual($users[1], $metadata->owner); - // The first user should no longer be allowed to get, update, delete. - $this->assertNull($stores[0]->getIfOwner($key)); - $this->assertFalse($stores[0]->setIfOwner($key, $this->objects[1])); - $this->assertFalse($stores[0]->deleteIfOwner($key)); - // Now manually expire the item (this is not exposed by the API) and then // assert it is no longer accessible. db_update('key_value_expire') diff --git a/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php b/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php index 991ac35..d16b4e2 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php @@ -57,7 +57,7 @@ function testUserTokenReplacement() { $this->drupalLogin($user2); $account = user_load($user1->id()); - $global_account = user_load(\Drupal::currentUser()->id()); + $global_account = user_load($GLOBALS['user']->id()); // Generate and test sanitized tokens. $tests = array(); diff --git a/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php b/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php index 02c8d4d..754a08f 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserValidationTest.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\user\Tests\UserValidationTest. + * Definition of Drupal\user\Tests\UserValidationTest. */ namespace Drupal\user\Tests; @@ -160,8 +160,6 @@ protected function assertLengthViolation(EntityInterface $entity, $field_name, $ $violations = $entity->validate(); $this->assertEqual(count($violations), 1, "Violation found when $field_name is too long."); $this->assertEqual($violations[0]->getPropertyPath(), "$field_name.0.value"); - $field_label = $entity->get($field_name)->getFieldDefinition()->getLabel(); - $this->assertEqual($violations[0]->getMessage(), t('%name: may not be longer than @max characters.', array('%name' => $field_label, '@max' => $length))); + $this->assertEqual($violations[0]->getMessage(), t('This value is too long. It should have %limit characters or less.', array('%limit' => $length))); } - } diff --git a/core/modules/user/tests/Drupal/user/Tests/TempStoreTest.php b/core/modules/user/tests/Drupal/user/Tests/TempStoreTest.php deleted file mode 100644 index af54c81..0000000 --- a/core/modules/user/tests/Drupal/user/Tests/TempStoreTest.php +++ /dev/null @@ -1,361 +0,0 @@ - 'TempStore', - 'description' => 'Unit tests the Drupal\user\TempStore class.', - 'group' => 'User', - ); - } - - /** - * {@inheritdoc} - */ - protected function setUp() { - parent::setUp(); - - $this->keyValue = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface'); - $this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface'); - - $this->tempStore = new TempStore($this->keyValue, $this->lock, $this->owner); - - $this->ownObject = (object) array( - 'data' => 'test_data', - 'owner' => $this->owner, - 'updated' => REQUEST_TIME, - ); - - // Clone the object but change the owner. - $this->otherObject = clone $this->ownObject; - $this->otherObject->owner = 2; - } - - /** - * @covers ::get() - */ - public function testGet() { - $this->keyValue->expects($this->at(0)) - ->method('get') - ->with('test_2') - ->will($this->returnValue(FALSE)); - $this->keyValue->expects($this->at(1)) - ->method('get') - ->with('test') - ->will($this->returnValue($this->ownObject)); - - $this->assertNull($this->tempStore->get('test_2')); - $this->assertSame($this->ownObject->data, $this->tempStore->get('test')); - } - - /** - * Tests the getIfOwner() method. - * - * @covers ::getIfOwner() - */ - public function testGetIfOwner() { - $this->keyValue->expects($this->at(0)) - ->method('get') - ->with('test_2') - ->will($this->returnValue(FALSE)); - $this->keyValue->expects($this->at(1)) - ->method('get') - ->with('test') - ->will($this->returnValue($this->ownObject)); - $this->keyValue->expects($this->at(2)) - ->method('get') - ->with('test') - ->will($this->returnValue($this->otherObject)); - - $this->assertNull($this->tempStore->getIfOwner('test_2')); - $this->assertSame($this->ownObject->data, $this->tempStore->getIfOwner('test')); - $this->assertNull($this->tempStore->getIfOwner('test')); - } - - /** - * Tests the set() method with no lock available. - * - * @covers ::set() - * @expectedException \Drupal\user\TempStoreException - */ - public function testSetWithNoLockAvailable() { - $this->lock->expects($this->at(0)) - ->method('acquire') - ->with('test') - ->will($this->returnValue(FALSE)); - $this->lock->expects($this->at(1)) - ->method('wait') - ->with('test'); - $this->lock->expects($this->at(2)) - ->method('acquire') - ->with('test') - ->will($this->returnValue(FALSE)); - - $this->keyValue->expects($this->once()) - ->method('getCollectionName'); - - $this->tempStore->set('test', 'value'); - } - - /** - * Tests a successful set() call. - * - * @covers ::set() - */ - public function testSet() { - $this->lock->expects($this->once()) - ->method('acquire') - ->with('test') - ->will($this->returnValue(TRUE)); - $this->lock->expects($this->never()) - ->method('wait'); - $this->lock->expects($this->once()) - ->method('release') - ->with('test'); - - $this->keyValue->expects($this->once()) - ->method('setWithExpire') - ->with('test', $this->ownObject, 604800); - - $this->tempStore->set('test', 'test_data'); - } - - /** - * Tests the setIfNotExists() methods. - * - * @covers ::setIfNotExists() - */ - public function testSetIfNotExists() { - $this->keyValue->expects($this->once()) - ->method('setWithExpireIfNotExists') - ->with('test', $this->ownObject, 604800) - ->will($this->returnValue(TRUE)); - - $this->assertTrue($this->tempStore->setIfNotExists('test', 'test_data')); - } - - /** - * Tests the setIfOwner() method when no key exists. - * - * @covers ::setIfOwner() - */ - public function testSetIfOwnerWhenNotExists() { - $this->keyValue->expects($this->once()) - ->method('setWithExpireIfNotExists') - ->will($this->returnValue(TRUE)); - - $this->assertTrue($this->tempStore->setIfOwner('test', 'test_data')); - } - - /** - * Tests the setIfOwner() method when a key already exists but no object. - * - * @covers ::setIfOwner() - */ - public function testSetIfOwnerNoObject() { - $this->keyValue->expects($this->once()) - ->method('setWithExpireIfNotExists') - ->will($this->returnValue(FALSE)); - - $this->keyValue->expects($this->once()) - ->method('get') - ->with('test') - ->will($this->returnValue(FALSE)); - - $this->assertFalse($this->tempStore->setIfOwner('test', 'test_data')); - } - - /** - * Tests the setIfOwner() method with matching and non matching owners. - * - * @covers ::setIfOwner() - */ - public function testSetIfOwner() { - $this->lock->expects($this->once()) - ->method('acquire') - ->with('test') - ->will($this->returnValue(TRUE)); - - $this->keyValue->expects($this->exactly(2)) - ->method('setWithExpireIfNotExists') - ->will($this->returnValue(FALSE)); - - $this->keyValue->expects($this->exactly(2)) - ->method('get') - ->with('test') - ->will($this->onConsecutiveCalls($this->ownObject, $this->otherObject)); - - $this->assertTrue($this->tempStore->setIfOwner('test', 'test_data')); - $this->assertFalse($this->tempStore->setIfOwner('test', 'test_data')); - } - - /** - * Tests the getMetadata() method. - * - * @covers ::getMetadata() - */ - public function testGetMetadata() { - $this->keyValue->expects($this->at(0)) - ->method('get') - ->with('test') - ->will($this->returnValue($this->ownObject)); - - $this->keyValue->expects($this->at(1)) - ->method('get') - ->with('test') - ->will($this->returnValue(FALSE)); - - $metadata = $this->tempStore->getMetadata('test'); - $this->assertObjectHasAttribute('owner', $metadata); - // Data should get removed. - $this->assertObjectNotHasAttribute('data', $metadata); - - $this->assertNull($this->tempStore->getMetadata('test')); - } - - /** - * Tests the delete() method. - * - * @covers ::delete() - */ - public function testDelete() { - $this->lock->expects($this->once()) - ->method('acquire') - ->with('test') - ->will($this->returnValue(TRUE)); - $this->lock->expects($this->never()) - ->method('wait'); - $this->lock->expects($this->once()) - ->method('release') - ->with('test'); - - $this->keyValue->expects($this->once()) - ->method('delete') - ->with('test'); - - $this->tempStore->delete('test'); - } - - /** - * Tests the delete() method with no lock available. - * - * @covers ::delete() - * @expectedException \Drupal\user\TempStoreException - */ - public function testDeleteWithNoLockAvailable() { - $this->lock->expects($this->at(0)) - ->method('acquire') - ->with('test') - ->will($this->returnValue(FALSE)); - $this->lock->expects($this->at(1)) - ->method('wait') - ->with('test'); - $this->lock->expects($this->at(2)) - ->method('acquire') - ->with('test') - ->will($this->returnValue(FALSE)); - - $this->keyValue->expects($this->once()) - ->method('getCollectionName'); - - $this->tempStore->delete('test'); - } - - /** - * Tests the deleteIfOwner() method. - * - * @covers ::deleteIfOwner() - */ - public function testDeleteIfOwner() { - $this->lock->expects($this->once()) - ->method('acquire') - ->with('test_2') - ->will($this->returnValue(TRUE)); - - $this->keyValue->expects($this->at(0)) - ->method('get') - ->with('test_1') - ->will($this->returnValue(FALSE)); - $this->keyValue->expects($this->at(1)) - ->method('get') - ->with('test_2') - ->will($this->returnValue($this->ownObject)); - $this->keyValue->expects($this->at(2)) - ->method('delete') - ->with('test_2'); - $this->keyValue->expects($this->at(3)) - ->method('get') - ->with('test_3') - ->will($this->returnValue($this->otherObject)); - - $this->assertTrue($this->tempStore->deleteIfOwner('test_1')); - $this->assertTrue($this->tempStore->deleteIfOwner('test_2')); - $this->assertFalse($this->tempStore->deleteIfOwner('test_3')); - } - -} - diff --git a/core/modules/user/user.module b/core/modules/user/user.module index cfdc66c..a944b30 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -963,6 +963,8 @@ function user_pass_rehash($password, $timestamp, $login) { * @see _user_cancel() */ function user_cancel($edit, $uid, $method) { + global $user; + $account = user_load($uid); if (!$account) { @@ -995,7 +997,7 @@ function user_cancel($edit, $uid, $method) { ); // After cancelling account, ensure that user is logged out. - if ($account->id() == \Drupal::currentUser()->id()) { + if ($account->id() == $user->id()) { // Batch API stores data in the session, so use the finished operation to // manipulate the current user's session id. $batch['finished'] = '_user_cancel_session_regenerate'; @@ -1572,6 +1574,8 @@ function user_form_process_password_confirm($element) { ); if (\Drupal::config('user.settings')->get('password_strength')) { + + global $user; $password_settings['showStrengthIndicator'] = TRUE; $password_settings += array( 'strengthTitle' => t('Password strength:'), @@ -1586,7 +1590,7 @@ function user_form_process_password_confirm($element) { 'fair' => t('Fair'), 'good' => t('Good'), 'strong' => t('Strong'), - 'username' => \Drupal::currentUser()->getUsername(), + 'username' => $user->getUsername(), ); } @@ -1672,7 +1676,7 @@ function user_file_download_access($field, EntityInterface $entity, File $file) * Implements hook_toolbar(). */ function user_toolbar() { - $user = \Drupal::currentUser(); + global $user; // Add logout & user account links or login link. if ($user->isAuthenticated()) { @@ -1746,7 +1750,7 @@ function user_toolbar() { * Logs the current user out. */ function user_logout() { - $user = \Drupal::currentUser(); + global $user; watchdog('user', 'Session closed for %name.', array('%name' => $user->getUsername())); diff --git a/core/modules/user/user.tokens.inc b/core/modules/user/user.tokens.inc index e3c22f2..5412a38 100644 --- a/core/modules/user/user.tokens.inc +++ b/core/modules/user/user.tokens.inc @@ -125,7 +125,7 @@ function user_tokens($type, $tokens, array $data = array(), array $options = arr } if ($type == 'current-user') { - $account = user_load(\Drupal::currentUser()->id()); + $account = user_load($GLOBALS['user']->id()); $replacements += $token_service->generate('user', $tokens, array('user' => $account), $options); } diff --git a/core/modules/user/user.views_execution.inc b/core/modules/user/user.views_execution.inc index c9a3f1d..622cdbf 100644 --- a/core/modules/user/user.views_execution.inc +++ b/core/modules/user/user.views_execution.inc @@ -13,5 +13,6 @@ * Allow replacement of current userid so we can cache these queries. */ function user_views_query_substitutions(ViewExecutable $view) { - return array('***CURRENT_USER***' => \Drupal::currentUser()->id()); + global $user; + return array('***CURRENT_USER***' => $user->id()); } diff --git a/core/modules/views/lib/Drupal/views/Entity/View.php b/core/modules/views/lib/Drupal/views/Entity/View.php index 8eea4c1..62e5536 100644 --- a/core/modules/views/lib/Drupal/views/Entity/View.php +++ b/core/modules/views/lib/Drupal/views/Entity/View.php @@ -96,6 +96,13 @@ class View extends ConfigEntityBase implements ViewStorageInterface { protected $base_field = 'nid'; /** + * The UUID for this entity. + * + * @var string + */ + public $uuid = NULL; + + /** * Stores a reference to the executable version of this view. * * @var \Drupal\views\ViewExecutable diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/BrokenHandlerTrait.php b/core/modules/views/lib/Drupal/views/Plugin/views/BrokenHandlerTrait.php deleted file mode 100644 index e1623f7..0000000 --- a/core/modules/views/lib/Drupal/views/Plugin/views/BrokenHandlerTrait.php +++ /dev/null @@ -1,103 +0,0 @@ - $this->definition['original_configuration']['provider'], - ); - return $this->isOptional() ? t('Optional handler is missing (Module: @module) …', $args) : t('Broken/missing handler (Module: @module) …', $args); - } - - /** - * The option definition for this handler. - * - * @see \Drupal\views\Plugin\views\PluginBase::defineOptions(). - */ - public function defineOptions() { - return array(); - } - - /** - * Ensure the main table for this handler is in the query. This is used - * a lot. - * - * @see \Drupal\views\Plugin\views\HandlerBase::ensureMyTable(). - */ - public function ensureMyTable() { - // No table to ensure. - } - - /** - * Modify the views query. - */ - public function query($group_by = FALSE) { - /* No query to run */ - } - - /** - * Provides a form to edit options for this plugin. - * - * @see \Drupal\views\Plugin\views\PluginBase::defineOptions(). - */ - public function buildOptionsForm(&$form, &$form_state) { - if ($this->isOptional()) { - $description_top = t('The handler for this item is optional. The following details are available:'); - } - else { - $description_top = t('The handler for this item is broken or missing. The following details are available:'); - } - - $items = array( - t('Module: @module', array('@module' => $this->definition['original_configuration']['provider'])), - t('Table: @table', array('@table' => $this->definition['original_configuration']['table'])), - t('Field: @field', array('@field' => $this->definition['original_configuration']['field'])), - ); - - $description_bottom = t('Enabling the appropriate module will may solve this issue. Otherwise, check to see if there is a module update available.'); - - $form['description'] = array( - '#type' => 'container', - '#attributes' => array( - 'class' => array('form-item', 'description'), - ), - 'description_top' => array( - '#markup' => '

' . $description_top . '

', - ), - 'detail_list' => array( - '#theme' => 'item_list', - '#items' => $items, - ), - 'description_bottom' => array( - '#markup' => '

' . $description_bottom . '

', - ), - ); - } - - /** - * Determines if the handler is considered 'broken'. - * - * This means it's a placeholder used when a handler can't be found. - * - * @see \Drupal\views\Plugin\views\HandlerBase::broken(). - */ - public function broken() { - return TRUE; - } - -} diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/area/Broken.php b/core/modules/views/lib/Drupal/views/Plugin/views/area/Broken.php index 6a0967c..dff668b 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/area/Broken.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/area/Broken.php @@ -7,8 +7,6 @@ namespace Drupal\views\Plugin\views\area; -use Drupal\views\Plugin\views\BrokenHandlerTrait; - /** * A special handler to take the place of missing or broken handlers. * @@ -17,7 +15,30 @@ * @PluginID("broken") */ class Broken extends AreaPluginBase { - use BrokenHandlerTrait; + + /** + * {@inheritdoc} + */ + public function adminLabel($short = FALSE) { + $args = array( + '@module' => $this->definition['original_configuration']['provider'], + ); + return $this->isOptional() ? t('Optional handler is missing (Module: @module) …', $args) : t('Broken/missing handler (Module: @module) …', $args); + } + + /** + * {@inheritdoc} + */ + public function defineOptions() { + return array(); + } + + /** + * {@inheritdoc} + */ + public function ensureMyTable() { + // No table to ensure. + } /** * {@inheritdoc} @@ -27,4 +48,48 @@ public function render($empty = FALSE) { return array(); } + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, &$form_state) { + if ($this->isOptional()) { + $description_top = t('The handler for this item is optional. The following details are available:'); + } + else { + $description_top = t('The handler for this item is broken or missing. The following details are available:'); + } + + $items = array( + t('Module: @module', array('@module' => $this->definition['original_configuration']['provider'])), + t('Table: @table', array('@table' => $this->definition['original_configuration']['table'])), + t('Field: @field', array('@field' => $this->definition['original_configuration']['field'])), + ); + + $description_bottom = t('Enabling the appropriate module will may solve this issue. Otherwise, check to see if there is a module update available.'); + + $form['description'] = array( + '#type' => 'container', + '#attributes' => array( + 'class' => array('form-item', 'description'), + ), + 'description_top' => array( + '#markup' => '

' . $description_top . '

', + ), + 'detail_list' => array( + '#theme' => 'item_list', + '#items' => $items, + ), + 'description_bottom' => array( + '#markup' => '

' . $description_bottom . '

', + ), + ); + } + + /** + * {@inheritdoc} + */ + public function broken() { + return TRUE; + } + } diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/argument/Broken.php b/core/modules/views/lib/Drupal/views/Plugin/views/argument/Broken.php index f9f90ac..9e82624 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/argument/Broken.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/argument/Broken.php @@ -7,8 +7,6 @@ namespace Drupal\views\Plugin\views\argument; -use Drupal\views\Plugin\views\BrokenHandlerTrait; - /** * A special handler to take the place of missing or broken handlers. * @@ -17,6 +15,58 @@ * @PluginID("broken") */ class Broken extends ArgumentPluginBase { - use BrokenHandlerTrait; + + public function adminLabel($short = FALSE) { + $args = array( + '@module' => $this->definition['original_configuration']['provider'], + ); + return $this->isOptional() ? t('Optional handler is missing (Module: @module) …', $args) : t('Broken/missing handler (Module: @module) …', $args); + } + + public function defineOptions() { return array(); } + public function ensureMyTable() { /* No table to ensure! */ } + public function query($group_by = FALSE) { /* No query to run */ } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, &$form_state) { + if ($this->isOptional()) { + $description_top = t('The handler for this item is optional. The following details are available:'); + } + else { + $description_top = t('The handler for this item is broken or missing. The following details are available:'); + } + + $items = array( + t('Module: @module', array('@module' => $this->definition['original_configuration']['provider'])), + t('Table: @table', array('@table' => $this->definition['original_configuration']['table'])), + t('Field: @field', array('@field' => $this->definition['original_configuration']['field'])), + ); + + $description_bottom = t('Enabling the appropriate module will may solve this issue. Otherwise, check to see if there is a module update available.'); + + $form['description'] = array( + '#type' => 'container', + '#attributes' => array( + 'class' => array('form-item', 'description'), + ), + 'description_top' => array( + '#markup' => '

' . $description_top . '

', + ), + 'detail_list' => array( + '#theme' => 'item_list', + '#items' => $items, + ), + 'description_bottom' => array( + '#markup' => '

' . $description_bottom . '

', + ), + ); + } + + /** + * Determine if the handler is considered 'broken' + */ + public function broken() { return TRUE; } } diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/field/Broken.php b/core/modules/views/lib/Drupal/views/Plugin/views/field/Broken.php index c76431e..062927f 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/field/Broken.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/field/Broken.php @@ -7,8 +7,6 @@ namespace Drupal\views\Plugin\views\field; -use Drupal\views\Plugin\views\BrokenHandlerTrait; - /** * A special handler to take the place of missing or broken handlers. * @@ -17,6 +15,58 @@ * @PluginID("broken") */ class Broken extends FieldPluginBase { - use BrokenHandlerTrait; + + public function adminLabel($short = FALSE) { + $args = array( + '@module' => $this->definition['original_configuration']['provider'], + ); + return $this->isOptional() ? t('Optional handler is missing (Module: @module) …', $args) : t('Broken/missing handler (Module: @module) …', $args); + } + + public function defineOptions() { return array(); } + public function ensureMyTable() { /* No table to ensure! */ } + public function query($group_by = FALSE) { /* No query to run */ } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, &$form_state) { + if ($this->isOptional()) { + $description_top = t('The handler for this item is optional. The following details are available:'); + } + else { + $description_top = t('The handler for this item is broken or missing. The following details are available:'); + } + + $items = array( + t('Module: @module', array('@module' => $this->definition['original_configuration']['provider'])), + t('Table: @table', array('@table' => $this->definition['original_configuration']['table'])), + t('Field: @field', array('@field' => $this->definition['original_configuration']['field'])), + ); + + $description_bottom = t('Enabling the appropriate module will may solve this issue. Otherwise, check to see if there is a module update available.'); + + $form['description'] = array( + '#type' => 'container', + '#attributes' => array( + 'class' => array('form-item', 'description'), + ), + 'description_top' => array( + '#markup' => '

' . $description_top . '

', + ), + 'detail_list' => array( + '#theme' => 'item_list', + '#items' => $items, + ), + 'description_bottom' => array( + '#markup' => '

' . $description_bottom . '

', + ), + ); + } + + /** + * Determine if the handler is considered 'broken' + */ + public function broken() { return TRUE; } } diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/filter/Broken.php b/core/modules/views/lib/Drupal/views/Plugin/views/filter/Broken.php index 2a4abcf..e4b1333 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/filter/Broken.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/filter/Broken.php @@ -7,7 +7,6 @@ namespace Drupal\views\Plugin\views\filter; -use Drupal\views\Plugin\views\BrokenHandlerTrait; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\ViewExecutable; @@ -19,12 +18,64 @@ * @PluginID("broken") */ class Broken extends FilterPluginBase { - use BrokenHandlerTrait; /** - * {@inheritdoc} + * Overrides \Drupal\views\Plugin\views\filter\FilterPluginBase::init(). */ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { } + public function adminLabel($short = FALSE) { + $args = array( + '@module' => $this->definition['original_configuration']['provider'], + ); + return $this->isOptional() ? t('Optional handler is missing (Module: @module) …', $args) : t('Broken/missing handler (Module: @module) …', $args); + } + + public function defineOptions() { return array(); } + public function ensureMyTable() { /* No table to ensure! */ } + public function query($group_by = FALSE) { /* No query to run */ } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, &$form_state) { + if ($this->isOptional()) { + $description_top = t('The handler for this item is optional. The following details are available:'); + } + else { + $description_top = t('The handler for this item is broken or missing. The following details are available:'); + } + + $items = array( + t('Module: @module', array('@module' => $this->definition['original_configuration']['provider'])), + t('Table: @table', array('@table' => $this->definition['original_configuration']['table'])), + t('Field: @field', array('@field' => $this->definition['original_configuration']['field'])), + ); + + $description_bottom = t('Enabling the appropriate module will may solve this issue. Otherwise, check to see if there is a module update available.'); + + $form['description'] = array( + '#type' => 'container', + '#attributes' => array( + 'class' => array('form-item', 'description'), + ), + 'description_top' => array( + '#markup' => '

' . $description_top . '

', + ), + 'detail_list' => array( + '#theme' => 'item_list', + '#items' => $items, + ), + 'description_bottom' => array( + '#markup' => '

' . $description_bottom . '

', + ), + ); + } + + /** + * Determine if the handler is considered 'broken' + */ + public function broken() { return TRUE; } + } diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/relationship/Broken.php b/core/modules/views/lib/Drupal/views/Plugin/views/relationship/Broken.php index 16ee48c..19d49c7 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/relationship/Broken.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/relationship/Broken.php @@ -7,8 +7,6 @@ namespace Drupal\views\Plugin\views\relationship; -use Drupal\views\Plugin\views\BrokenHandlerTrait; - /** * A special handler to take the place of missing or broken handlers. * @@ -17,6 +15,80 @@ * @PluginID("broken") */ class Broken extends RelationshipPluginBase { - use BrokenHandlerTrait; + + /** + * {@inheritdoc} + */ + public function adminLabel($short = FALSE) { + $args = array( + '@module' => $this->definition['original_configuration']['provider'], + ); + return $this->isOptional() ? t('Optional handler is missing (Module: @module) …', $args) : t('Broken/missing handler (Module: @module) …', $args); + } + + /** + * {@inheritdoc} + */ + protected function defineOptions() { + return array(); + } + + /** + * {@inheritdoc} + */ + public function ensureMyTable() { + // No table to ensure. + } + + /** + * {@inheritdoc} + */ + public function query() { + // No query to run. + } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, &$form_state) { + if ($this->isOptional()) { + $description_top = t('The handler for this item is optional. The following details are available:'); + } + else { + $description_top = t('The handler for this item is broken or missing. The following details are available:'); + } + + $items = array( + t('Module: @module', array('@module' => $this->definition['original_configuration']['provider'])), + t('Table: @table', array('@table' => $this->definition['original_configuration']['table'])), + t('Field: @field', array('@field' => $this->definition['original_configuration']['field'])), + ); + + $description_bottom = t('Enabling the appropriate module will may solve this issue. Otherwise, check to see if there is a module update available.'); + + $form['description'] = array( + '#type' => 'container', + '#attributes' => array( + 'class' => array('form-item', 'description'), + ), + 'description_top' => array( + '#markup' => '

' . $description_top . '

', + ), + 'detail_list' => array( + '#theme' => 'item_list', + '#items' => $items, + ), + 'description_bottom' => array( + '#markup' => '

' . $description_bottom . '

', + ), + ); + } + + /** + * {@inheritdoc} + */ + public function broken() { + return TRUE; + } } diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/sort/Broken.php b/core/modules/views/lib/Drupal/views/Plugin/views/sort/Broken.php index a702625..234ee57 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/sort/Broken.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/sort/Broken.php @@ -7,8 +7,6 @@ namespace Drupal\views\Plugin\views\sort; -use Drupal\views\Plugin\views\BrokenHandlerTrait; - /** * A special handler to take the place of missing or broken handlers. * @@ -17,6 +15,58 @@ * @PluginID("broken") */ class Broken extends SortPluginBase { - use BrokenHandlerTrait; + + public function adminLabel($short = FALSE) { + $args = array( + '@module' => $this->definition['original_configuration']['provider'], + ); + return $this->isOptional() ? t('Optional handler is missing (Module: @module) …', $args) : t('Broken/missing handler (Module: @module) …', $args); + } + + public function defineOptions() { return array(); } + public function ensureMyTable() { /* No table to ensure! */ } + public function query($group_by = FALSE) { /* No query to run */ } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, &$form_state) { + if ($this->isOptional()) { + $description_top = t('The handler for this item is optional. The following details are available:'); + } + else { + $description_top = t('The handler for this item is broken or missing. The following details are available:'); + } + + $items = array( + t('Module: @module', array('@module' => $this->definition['original_configuration']['provider'])), + t('Table: @table', array('@table' => $this->definition['original_configuration']['table'])), + t('Field: @field', array('@field' => $this->definition['original_configuration']['field'])), + ); + + $description_bottom = t('Enabling the appropriate module will may solve this issue. Otherwise, check to see if there is a module update available.'); + + $form['description'] = array( + '#type' => 'container', + '#attributes' => array( + 'class' => array('form-item', 'description'), + ), + 'description_top' => array( + '#markup' => '

' . $description_top . '

', + ), + 'detail_list' => array( + '#theme' => 'item_list', + '#items' => $items, + ), + 'description_bottom' => array( + '#markup' => '

' . $description_bottom . '

', + ), + ); + } + + /** + * Determine if the handler is considered 'broken' + */ + public function broken() { return TRUE; } } diff --git a/core/themes/bartik/bartik.theme b/core/themes/bartik/bartik.theme index 2535b24..f90276b 100644 --- a/core/themes/bartik/bartik.theme +++ b/core/themes/bartik/bartik.theme @@ -169,8 +169,8 @@ function bartik_field__taxonomy_term_reference($variables) { } /** - * Helper function for handling the site name and slogan. - */ ++ * Helper function for handling the site name and slogan. ++ */ function _bartik_process_page(&$variables) { $site_config = \Drupal::config('system.site'); // Always print the site name and slogan, but if they are toggled off, we'll diff --git a/core/themes/bartik/templates/comment.html.twig b/core/themes/bartik/templates/comment.html.twig index b6d4bb9..ad03eb6 100644 --- a/core/themes/bartik/templates/comment.html.twig +++ b/core/themes/bartik/templates/comment.html.twig @@ -7,11 +7,8 @@ * - author: Comment author. Can be a link or plain text. * - content: The content-related items for the comment display. Use * {{ content }} to print them all, or print a subset such as - * {{ content.field_example }}. Use the following code to temporarily suppress - * the printing of a given child element: - * @code - * {{ content|without('field_example') }} - * @endcode + * {{ content.field_example }}. Use hide(content.field_example) to temporarily + * suppress the printing of a given element. * - created: Formatted date and time for when the comment was created. * Preprocess functions can reformat it by calling format_date() with the * desired parameters on the 'comment.created' variable. @@ -109,7 +106,9 @@ {{ title_suffix }} - {{ content|without('links') }} + {# We hide the links now so that we can render them later. #} + {% hide(content.links) %} + {{ content }}