Quantcast
Channel: Issues for Drupal core
Viewing all 295177 articles
Browse latest View live

After enabling Require Summary on a field can't save the field

$
0
0

Problem/Motivation

After enabling Require summary on a Text (formatted, long, with summary) field, when editing the field can't save without giving a default Summary.

Also I can check Require summary without summary input being checked.

Steps to reproduce

  • Navigate to /admin/structure/block/block-content/manage/basic/fields/block_content.basic.body
  • Enable Require summary (but not Summary input)
  • Save (Message: Saved Body configuration)
  • Navigate to /admin/structure/block/block-content
  • Add custom block
  • Note: only Block description and Body field are visible, no summary
  • Add description
  • Add body
  • Error: Summary field is required.. Note: This behavior is different in Drupal 9.5. There is no longer an error on save. See comment #59.
  • Back to /admin/structure/block/block-content/manage/basic/fields/block_content.basic.body
  • Note: summary is not visible
  • Disable Require summary
  • Error: Summary field is required.. Note: This behavior is different in Drupal 9.5. There is no longer an error on save. See comment #59.

Screenshots

Before:

before1

before2

After:

after1

after2

Proposed resolution

Update the form validation to require that Summary input must be enabled before Require summary can be enabled.

Also even when Require Summary is checked, builders can still save the field UI without putting a default summary in.

Remaining tasks

  1. Create patch
  2. Review patch
  3. Answer outstanding questions
  4. Test patch- Use test-only feature
  5. Commit

Outstanding questions

Outstanding questions (see comments in #38, #53, and #59 for reference).
When editing the text field on an entity:

  1. When the Summary input is enabled/checked, should the Summary field under Default value automatically display? Or should it only display after the field has been saved? How is this handled in other places? - not sure but also seems like a follow up as this is about fixing a bug (least how I understand it) - Opened #3394040: When the Summary input is enabled/checked, should the Summary field under Default value automatically display
  2. When the Summary input is disabled/unchecked, what should happen to any existing values in the Summary field? - Seems like a follow up but this issue shouldn't tough that. - Opened #3394041: When the Summary input is disabled/unchecked, what should happen to any existing values in the Summary field?
  3. When Summary input is disabled/unchecked should Require summary be automatically unchecked? - Yes updating fix

User interface changes

See screenshots

API changes

NA

Data model changes

NA

Release notes snippet

NA


It should not be possible to install Drupal database into a site where it is already installed when pending translation imports exists

$
0
0

Problem/Motivation

In some scenarios it is possible to access the /core/install.php even when a site is already installed. This can lead to regenerating the admin user. Original raised with the security team but advised its fine to publicly post.

This is possible because this code here in core/includes/install.core.inc

  if ($install_state['config_verified'] && empty($task)) {
    if (count($kernel->getConfigStorage()->listAll())) {
      $task = NULL;
      throw new AlreadyInstalledException($container->get('string_translation'));
    }
  }

Checks that $task is empty, and if not it assumes its in the new installation process and let's the install continue without throwing the AlreadyInstalledException.
When translations are pending import, the task is set as `install_import_translations` because this code will result in TRUE:

$needs_translations = $locale_module_installed && ((count($install_state['translations']) > 1 && !empty($install_state['parameters']['langcode']) && $install_state['parameters']['langcode'] != 'en') || \Drupal::languageManager()->isMultilingual());

Steps to reproduce

You can see this issue by:

  1. Create a drupal site
  2. Install the site and enable translations
  3. Deploy with any importing translation failure
  4. Go to /core/install.php and reinstall Drupal, setting the admin user and password to whatever you want
  5. Go to the site on completion and login as your new admin user. The existing database is not wiped, but the admin user is overridden

Note that the Contact module must also be enabled on the site otherwise the install process triggers a fatal error stopping the above from happening. So probably many sites don't have this potential issue as a result.

Proposed resolution

Double-check that Drupal is not yet installed.

Remaining tasks

Provide an additional check

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

Prevent re-installation of Drupal

Support NULL services

$
0
0

Problem/Motivation

If a service is NULL you get an error: ReverseContainer::generateServiceIdHash(): Argument #1 ($object) must be of type object, null givenSymfony supports optional dependencies so we should too.

Steps to reproduce

  1. Make a service that uses a factory.
  2. Have the factory return NULL for the service.
  3. Clear caches or install a module or do something to rebuild the container.

Proposed resolution

Remove NULL services before recording the container.

Don't hide permissions local tasks on bundles when no permissions are defined

$
0
0

Problem/Motivation

Follow-up from #3344789: Return early in EntityPermissionsForm::access if the user does not have "administer permissions".

We could drop the check for whether there are permissions or not entirely from the access check, and just show a short message on the page when no permissions for a bundle are defined.

The UX regression of showing a somewhat useless tab, is better than the regression of multi-second page loads with admin_toolbar module and etc.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

_node_mass_update_batch_process fails during user cancel when revision is deleted

$
0
0

Problem/Motivation

In _node_mass_update_batch_process() we call _node_mass_update_helper() with the loaded node object or revision. If the node or revision is somehow deleted during the cancel process, the batch process fails with the error:
_node_mass_update_helper(): Argument #1 ($node) must be of type Drupal\node\NodeInterface, null given

Steps to reproduce

  1. Create a bunch of nodes for a user
  2. Cancel the user using user_cancel_reassign
  3. Delete one of the nodes of the user while the cancel process is running
  4. An error should be shown: _node_mass_update_helper(): Argument #1 ($node) must be of type Drupal\node\NodeInterface, null given

Proposed resolution

Check if the node or revision still exists before calling _node_mass_update_helper()

Remaining tasks

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

Single Directory Components templates are not auto reloaded after change

$
0
0

Problem/Motivation

When twig.config:auto_reload is true, the component's templates are not refreshed, they only refreshed after the change to the YML file.
This is also weird because the parsed YML file is cached separately anyway.

This issue lies in \Drupal\Core\Template\Loader\ComponentLoader::isFresh. It is checking the YML file, and if YML is not updated, it will never check the template itself.

Steps to reproduce

Set twig.config:auto_reload to true
Create component
Render component
Change the component's template
The component still renders the old contents while the usual templates are refreshed.

Proposed resolution

Always check if the template file is fresh. Not sure the YML file needs to be checked at all since its contents will be cached anyway.

Remaining tasks

-

User interface changes

-

API changes

-

Data model changes

-

Release notes snippet

-

Remove ThemeInitialization::resolveStyleSheetPlaceholders

$
0
0

Problem/Motivation

The docblock for \Drupal\Core\Theme\ThemeInitialization::resolveStyleSheetPlaceholders has a todo comment:

@todo Remove in Drupal 9.0.x.

I couldn't find any references to this method in core, nor in contrib.

Steps to reproduce

Proposed resolution

Remove the function.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Varnish issue with dynamic page cache module

$
0
0

Updated content not reflecting on front end for anonymous user if page have "X-drupal-dynamic-cache" header is set as "UNCACHEABLE"

1. Install dynamic page cache.
2. Set up varnish.
3. Pass "User" cache context to that page through custom code.
4. Now you will see "X-drupal-dynamic-cache" header as "UNCACHEABLE"
5. However, this page will be cached to varnish
6. Now try to update the content then cache for that page does not purge from varnish. So updated content will not reflect on frontend for anonymous until we clear the varnish cache directly from varnish.

If we have user or session cache context on a page then dynamic page cache module set "X-drupal-dynamic-cache" header as "UNCACHEABLE" due to which purge module does not able to set "X-Acquia-Site" header for that page.

If page does not have "X-Acquia-Site" header set then Varnish is not able to purge cache for that page on tag invalidation.

So can we create a patch for Dynamic Cache Module so that it will never set "X-drupal-dynamic-cache" header as "UNCACHEABLE" for anonymous user?

diff --git a/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php b/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php
index 22b51b9e..4e961b44 100644
--- a/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php
+++ b/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php
@@ -165,7 +165,8 @@ class DynamicPageCacheSubscriber implements EventSubscriberInterface {
     }
 
     // There's no work left to be done if this is an uncacheable response.
-    if (!$this->shouldCacheResponse($response)) {
+    // Do not set uncacheable for anonymous user.
+    if (!\Drupal::currentUser()->isAnonymous() && !$this->shouldCacheResponse($response)) {
       // The response is uncacheable, mark it as such.
       $response->headers->set(self::HEADER, 'UNCACHEABLE');
       return;

Simple decimals fail to pass validation

$
0
0

Problem/Motivation

- Create decimal field, set precision to 10 (minimum in the UI and scale to 4
- Saving new node with value 19999.0000 succeeds (precision is 5+4 = 9).
- Saving new node with value 99999.0000 fails (same precision as above).

or

- Create decimal field, set scale to anything over 6 (need 8 to store bitcoin values for example). I used 16 as precission.
- Saving new node with value 20.12345678 fails validation while 0.1234567 succeeds.

This is because Drupal\Component\Utility\Number::validStep() returns false. Detailed investigation on this function (which is only used once in Drupal), reveals that the first argument ($value) is received as a string, but $step and $offset are floats. PHP seems to slightly mangle the $step value on the first case above from 0.0001 to 0.00010000000000000001438. Passing the step parameter as a string in the case of decimal numbers maintains the correct precision, and allows a correct approximation calculation.

Proposed resolution

Bypass weak PHP floating-point handling by passing the step as a string.

Remaining tasks

Merge. Commit. Decimals FTW!

User interface changes

None.

API changes

None.

Data model changes

None.

Possible workaround if you need big decimals

Disable this validation by setting the render element #step to 'any'

i.e.

$element['#step'] = 'any';

In the case of fields, you can do

function MYMODULE_form_FORM_WITH_BIG_DECIMAL_FIELD_alter (array &$form, FormStateInterface $form_state) {
  $form['field_some']['widget'][0]['value']['#step']='any';
}

And if you want to target all decimal fields:

/**
 * Prevents validation of decimal numbers
 * @see https://www.drupal.org/node/2230909
 */
function MYMODULE_field_widget_form_alter(&$element, \Drupal\Core\Form\FormStateInterface $form_state, $context) {
  $field_definition = $context['items']->getFieldDefinition();
  if ($field_definition->getType() == 'decimal') {
    $element['value']['#step'] = 'any';
  }
}

Improve date format in status report EOL message

$
0
0

Problem/Motivation

The date format could be more readable:

Covered until 2023-Nov.

Suggested change:

Covered until November 2023.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

When using drupalGet(), provide an associative array for $headers

$
0
0

Problem/Motivation

I noticed this while working on https://www.drupal.org/project/admin_toolbar/issues/3407845, where a test in the newly set-up CI fails. This is because the test just extends ToolbarAdminMenuTest, where drupalGet is called thusly:

$this->drupalGet('toolbar/subtrees/' . $subtrees_hash, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']], ['X-Requested-With: XMLHttpRequest']);

Resulting in this pipeline-error:

TypeError: Behat\Mink\Session::setRequestHeader(): Argument #1 ($name) must be of type string, int given, called in /builds/issue/admin_toolbar-3407845/web/core/tests/Drupal/Tests/UiHelperTrait.php on line 235

As the documentation for drupalGet() states:

An array containing additional HTTP request headers, the array keys are the header names and the array values the header values.

So in the above case it would be

$this->drupalGet('toolbar/subtrees/' . $subtrees_hash, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']], ['X-Requested-With' => 'XMLHttpRequest']);

Proposed resolution

Try and find all spots in the code where drupalGet() is called with headers where only one string per header instead of a key-value pair is used, and split them up.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Expose triggering update of media metadata + thumbnail to end users

$
0
0

Problem/Motivation

It's currently impossible for end-users to manually pull metadata associated with media assets from the source into the Drupal media entity, after the entity is created. Similarly, the Thumbnail (which is not a metadata per se) is treated the same way, it is currently only retrieved from the source when the entity is first created.

Several scenarios have shown this is a big limitation, being a prominent example the situation when the source providing the thumbnail is remote (like an YouTube video), and the thumbnail is changed on the remote source after the entity has been created in Drupal. Currently there is no mechanism for users to update the Thumbnail in this scenario. The same is valid for all other metadata attributes that source plugins could define (name, filesize, filemime, width, height, etc).

This issue was spun-off from #2878119: Whether queued or not, update the media thumbnail and metadata before beginning the entity save database transaction.

Proposed resolution

Expose to the UI the possibility of end users with correct permissions to trigger an immediate update of the asset's metadata + thumbnail

Remaining tasks

  • Usability re-review

User interface changes

- New contextual link "Update metadata" is available in the front-end

contextual link

- New operation dropbutton "Update metadata" is available in the back-end

dropbutton

- New "Update metadata" action is available in media administrative views, as a bulk operation.

bulk action

API changes

A new public method \Drupal\media\MediaInterface::updateMetadata() is added to the Media interface.

Data model changes

None

Release notes snippet

Adds the ability for users to manually trigger updating metadata on media entities (e.g. updating a more recent YouTube thumbnail).

Ajax views leave obsolete Drupal.Ajax instances

$
0
0

When browsing an Ajax view, many Drupal.Ajax are created for the refresh feature. Those objects are not cleaned up.

Need to either add some code to clean them up or prevent several objects from being created.

File migration slows down and eats more and more memory, eventually stops

$
0
0

Problem/Motivation

I am attempting to migrate around ~300,000 files from Drupal 7. As I do the migration import, I hit this:

Memory usage is 435.23 MB (85% of limit 512 MB), reclaiming memory.                                                                                                                                        [warning]
Memory usage is now 439.99 MB (86% of limit 512 MB), not enough reclaimed, starting new batch                                                                                                              [warning]

What's interesting, is that on the first run, I got about 70,000 files in one go before hitting the wall, then it halfed, then it halfed again, and now I'm to less than 1,000 per run before hitting the memory limit.

Proposed resolution

Figure out what's causing the memory usage to be so high.

Remaining tasks

  1. Figure out what the problem is
  2. Write Patch

User interface changes

N/A

API changes

N/A

Data model changes

N/A

convert ProviderRepositoryTest to a kernel test

$
0
0

Problem/Motivation

ProviderRepositoryTest can be converted to a kernel test, as it makes no HTTP requests.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet


View with Contextual Filter & Relationship displays WSD in 10.3.0

$
0
0

Problem/Motivation

I have a content type of Room that has an entity reference field to another content type, Organisation. I have a view that lists rooms, using the entity reference field as a relationship to display fields from the related Organisation nodes. I have a view with two displays, the first one lists all the rooms in a table, grouped by the Organisation title (this works fine) and the second uses a contextual filter on the Organisation to show the Rooms for the organisation (filtered by the node ID from the URL). When I view an organisation and it's rooms on the second view, I get a white screen of death since upgrading to Drupal 10.3.0

Steps to reproduce

Upgrade to to Drupal 10.3.0
View the complete list of Rooms by Organisation
Click on the link to one of the Organisations to display the those rooms filtered by that organisation
WSD

Proposed resolution

I can list Organisations by the Content page and edit them. This seems to be an issue with Views that use contextual filters and relationships. The config export is below and I've confirmed the config for the view does not change when I upgrade drupal core. The issue is with block_1

For now I will need to revert to 10.2.7

uuid: 0daff11f-5427-4fcf-bc52-cc8da491b65a
langcode: en
status: true
dependencies:
  config:
    - core.entity_view_mode.node.teaser
    - field.storage.node.body
    - field.storage.node.field_type
    - node.type.room
    - user.role.authenticated
  module:
    - node
    - options
    - text
    - user
_core:
  default_config_hash: wCGRBQ2612zX9UGIoUV0_LfKS2TJ9NbtHDarusKBX20
id: cil_meet
label: 'CIL Meet'
module: views
description: ''
tag: ''
base_table: node_field_data
base_field: nid
display:
  default:
    id: default
    display_title: Master
    display_plugin: default
    position: 0
    display_options:
      title: 'CIL Meet'
      fields:
        body:
          id: body
          table: node__body
          field: body
          relationship: field_organisation
          group_type: group
          admin_label: ''
          plugin_id: field
          label: ''
          exclude: true
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: false
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: text_summary_or_trimmed
          settings:
            trim_length: 600
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
        title_1:
          id: title_1
          table: node_field_data
          field: title
          relationship: field_organisation
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: title
          plugin_id: field
          label: ''
          exclude: true
          alter:
            alter_text: true
            text: "<h2>{{ title_1 }}</h2>\r\n{{ body }}"
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: false
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: false
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: string
          settings:
            link_to_entity: true
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
        title:
          id: title
          table: node_field_data
          field: title
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: title
          plugin_id: field
          label: 'Room (click/tap to join)'
          exclude: false
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: false
            ellipsis: false
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: true
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: string
          settings:
            link_to_entity: true
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
        body_1:
          id: body_1
          table: node__body
          field: body
          relationship: none
          group_type: group
          admin_label: ''
          plugin_id: field
          label: Description
          exclude: false
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: true
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: text_default
          settings: {  }
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
        field_type:
          id: field_type
          table: node__field_type
          field: field_type
          relationship: none
          group_type: group
          admin_label: ''
          plugin_id: field
          label: Type
          exclude: false
          alter:
            alter_text: true
            text: "{% if field_type[:7] == 'Classic' %}\r\n\r\n{% else %}\r\n{{ field_type }}\r\n{% endif %}"
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: true
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: list_default
          settings: {  }
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
      pager:
        type: none
        options:
          offset: 0
      exposed_form:
        type: basic
        options:
          submit_button: Apply
          reset_button: false
          reset_button_label: Reset
          exposed_sorts_label: 'Sort by'
          expose_sort_order: true
          sort_asc_label: Asc
          sort_desc_label: Desc
      access:
        type: role
        options:
          role:
            authenticated: authenticated
      cache:
        type: tag
        options: {  }
      empty:
        area_text_custom:
          id: area_text_custom
          table: views
          field: area_text_custom
          relationship: none
          group_type: group
          admin_label: ''
          plugin_id: text_custom
          empty: true
          content: 'No results'
          tokenize: false
      sorts:
        title:
          id: title
          table: node_field_data
          field: title
          relationship: field_organisation
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: title
          plugin_id: standard
          order: ASC
          expose:
            label: ''
            field_identifier: title
          exposed: false
        title_1:
          id: title_1
          table: node_field_data
          field: title
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: title
          plugin_id: standard
          order: ASC
          expose:
            label: ''
            field_identifier: title_1
          exposed: false
      arguments: {  }
      filters:
        status:
          id: status
          table: node_field_data
          field: status
          entity_type: node
          entity_field: status
          plugin_id: boolean
          value: '1'
          group: 1
          expose:
            operator: ''
            operator_limit_selection: false
            operator_list: {  }
        type:
          id: type
          table: node_field_data
          field: type
          entity_type: node
          entity_field: type
          plugin_id: bundle
          value:
            room: room
          expose:
            operator_limit_selection: false
            operator_list: {  }
        sticky:
          id: sticky
          table: node_field_data
          field: sticky
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: sticky
          plugin_id: boolean
          operator: '='
          value: '1'
          group: 1
          exposed: false
          expose:
            operator_id: ''
            label: ''
            description: ''
            use_operator: false
            operator: ''
            operator_limit_selection: false
            operator_list: {  }
            identifier: ''
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
          is_grouped: false
          group_info:
            label: ''
            description: ''
            identifier: ''
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
        langcode:
          id: langcode
          table: node_field_data
          field: langcode
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: langcode
          plugin_id: language
          operator: in
          value:
            '***LANGUAGE_language_interface***': '***LANGUAGE_language_interface***'
          group: 1
          exposed: false
          expose:
            operator_id: ''
            label: ''
            description: ''
            use_operator: false
            operator: ''
            operator_limit_selection: false
            operator_list: {  }
            identifier: ''
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
            reduce: false
          is_grouped: false
          group_info:
            label: ''
            description: ''
            identifier: ''
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
        langcode_1:
          id: langcode_1
          table: node_field_data
          field: langcode
          relationship: field_organisation
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: langcode
          plugin_id: language
          operator: in
          value:
            '***LANGUAGE_language_interface***': '***LANGUAGE_language_interface***'
          group: 1
          exposed: false
          expose:
            operator_id: ''
            label: ''
            description: ''
            use_operator: false
            operator: ''
            operator_limit_selection: false
            operator_list: {  }
            identifier: ''
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
            reduce: false
          is_grouped: false
          group_info:
            label: ''
            description: ''
            identifier: ''
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
      style:
        type: table
        options:
          grouping:
            -
              field: title_1
              rendered: true
              rendered_strip: false
          row_class: ''
          default_row_class: true
          columns:
            body: body
            title_1: title_1
            title: title
            body_1: body_1
          default: '-1'
          info:
            body:
              sortable: false
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
            title_1:
              sortable: false
              default_sort_order: asc
              align: views-align-left
              separator: ''
              empty_column: true
              responsive: ''
            title:
              sortable: false
              default_sort_order: asc
              align: views-align-left
              separator: ''
              empty_column: false
              responsive: ''
            body_1:
              sortable: false
              default_sort_order: asc
              align: views-align-left
              separator: ''
              empty_column: false
              responsive: ''
          override: true
          sticky: false
          summary: ''
          empty_table: false
          caption: ''
          description: ''
      row:
        type: 'entity:node'
        options:
          view_mode: teaser
      query:
        type: views_query
        options:
          query_comment: ''
          disable_sql_rewrite: false
          distinct: false
          replica: false
          query_tags: {  }
      relationships:
        field_organisation:
          id: field_organisation
          table: node__field_organisation
          field: field_organisation
          relationship: none
          group_type: group
          admin_label: 'field_organisation: Content'
          plugin_id: standard
          required: true
      header: {  }
      footer: {  }
      display_extenders: {  }
    cache_metadata:
      max-age: -1
      contexts:
        - 'languages:language_content'
        - 'languages:language_interface'
        - 'user.node_grants:view'
        - user.roles
      tags:
        - 'config:field.storage.node.body'
        - 'config:field.storage.node.field_type'
  block_1:
    id: block_1
    display_title: 'Organisation Index Block'
    display_plugin: block
    position: 2
    display_options:
      arguments:
        nid:
          id: nid
          table: tracker_node
          field: nid
          relationship: field_organisation
          group_type: group
          admin_label: ''
          plugin_id: node_nid
          default_action: default
          exception:
            value: all
            title_enable: false
            title: All
          title_enable: false
          title: ''
          default_argument_type: node
          default_argument_options: {  }
          summary_options:
            base_path: ''
            count: true
            override: false
            items_per_page: 25
          summary:
            sort_order: asc
            number_of_records: 0
            format: default_summary
          specify_validation: false
          validate:
            type: none
            fail: 'not found'
          validate_options: {  }
          break_phrase: false
          not: false
      defaults:
        fields: true
        arguments: false
      display_description: ''
      display_extenders: {  }
      block_description: 'CIL Meet Rooms for an Organisation'
    cache_metadata:
      max-age: -1
      contexts:
        - 'languages:language_content'
        - 'languages:language_interface'
        - url
        - 'user.node_grants:view'
        - user.roles
      tags:
        - 'config:field.storage.node.body'
        - 'config:field.storage.node.field_type'
  block_2:
    id: block_2
    display_title: 'Main Page Block'
    display_plugin: block
    position: 1
    display_options:
      display_description: ''
      display_extenders: {  }
      block_description: 'CIL Meet Rooms by Organisation'
    cache_metadata:
      max-age: -1
      contexts:
        - 'languages:language_content'
        - 'languages:language_interface'
        - 'user.node_grants:view'
        - user.roles
      tags:
        - 'config:field.storage.node.body'
        - 'config:field.storage.node.field_type'

[regression] Drupal.editors.ckeditor5.onChange event doesn't fire after final input if user types too fast.

$
0
0

Problem/Motivation

The release of Drupal 10.2.5 has introduced a regression in (but not limited to) Site Studio's implementation of CKEditor 5 that results in user input being lost if they type too fast.

  1. A user types into Standard install profile's "Article" node type's "body" field
  2. Uses the Drupal.editors.ckeditor5.onChange event to pull the value of the editor using ckInstance.getData() and store that in a JSON blob.
  3. Since this change https://git.drupalcode.org/project/drupal/-/commit/5540b5f84a6ae7899df01... if a user types multiple characters in quick succession, only the first character they type is registered in the on change event and all subsequent inputs are lost.
  4. I think the issue is due to the use of the immediate variable on the debounce call.

Steps to reproduce

If you paste this snippet into the JS console on a node page with a CKEditor instance and then type into the editor quickly vs slowly, you can see the issue. When typing quickly the onChange event is fired after the first user input but not fired again after the user types their last input.

Drupal.editors.ckeditor5.onChange(document.getElementById('edit-body-0-value'), () => {
 const ckInstance = Drupal.CKEditor5Instances.values().next().value;
  console.log(ckInstance.getData())
});

I've attached a video showing the above steps to test demonstrating the issue.

ContentEntityStorageBase::loadRevision() should use the static and the persistent entity cache like ContentEntityStorageBase::load()

$
0
0

Problem/Motivation

#597236: Add entity caching to core added the entity cache to core, but unfortunately it did not consider enabling it when loading an entity by revision ID.
There are contrib modules such as Entity Reference Revisions, Paragraphs and core modules such as Content Moderation, which rely heavily on loading entity revisions.

A developer might build a system where she is using ContentEntityStorageBase::loadRevision() to load a default entity revision and by doing so one will currently not profit from the entity cache.

ContentEntityStorageBase::loadRevision() is neither using the static entity cache nor the persistent entity cache, which has as a consequence that the function is inconsistent with ContentEntityStorageBase::load(), as if you retrieve an entity multiple times in a single request with the latter one it will always return a reference to the same entity object, but if you retrieve it multiple times with the former one you will always get a new entity object and thus a completely different object reference.

The attached test demonstrates all the problems.

Proposed resolution

  1. Enable static entity caching for ContentEntityStorageBase::loadRevision() for all revisions.
  2. Enable persistent entity caching for ContentEntityStorageBase::loadRevision() for all revisions.
  3. Ensure that ContentEntityStorageBase::load() and ContentEntityStorageBase::loadRevision() return a reference to the same entity object, if loading the default entity revision.
  4. To ensure backwards compatibility $storage::resetCache() will be invalidating all cached revisions. Include an optimization to invalidate only the default revision when the entity has only revisionable fields.

Remaining tasks

Review.

User interface changes

none

API changes

  1. \Drupal\Core\Entity\RevisionableStorageInterface::loadRevisionUnchanged() to load an entity revision bypassing the static cache.
  2. \Drupal\Core\Entity\RevisionableStorageInterface::resetRevisionCache($revision_id) for reseting the static and persistent cache for specific revision IDs
  3. $storage->loadRevision($revision_id) === $storage->loadRevision($revision_id)now evaluates to TRUE
  4. $storage->load($id) === $storage->loadRevision($revision_id)now evaluates to TRUE if $revision_id references the current default revision

Data model changes

none

Add Tugboat configuration to core

$
0
0

Problem/Motivation

Based on this comment by @drumm at #3200622-3: Have Drupal core Tugboat previews default to using Umami profile (instead of standard), we can add a .tugboat/config.yml file to Drupal core in order to manage Tugboat configuration more effectively.

At the moment Tugboat configurations are hosted at https://github.com/TugboatQA/drupalorg/tree/master/drupal. The way this works, it should pick up the configuration file right away if it exists. Details at https://git.drupalcode.org/project/drupalorg/-/blob/7.x-3.x/drupalorg/in....

Drupal core's current Tugboat QA integration requires a bit of custom code both in Drupal.org Customizations and with a separate repository hosted on GitHub that contains the configuration for Drupal core versions, as necessary. When a new core development branch is created, the Tugboat QA support team often needs to create a new branch here before Tugboat previews will build correctly for the new branch. For the most part, these separate configs are identical, with PHP versions being the primary difference.

It would be ideal for these Tugboat config files to live inside of the Drupal core repository itself. The benefits of this are:

  1. Each branch can maintain their desired PHP compatibility without impacting other Tugboat builds
  2. New branches will automatically inherit the working Tugboat config from the previous branch
  3. The Drupal.org Customizations module will be able to remove custom code that is used to pull the Drupal core config from the separate GitHub repository.
  4. On a related note, currently if a Tugboat Base Preview needs to be created, it requires the execution of a custom drush command in d.o prod, which means that someone on the Drupal Association Engineering team needs to execute this. If the config lived in the repository, the Tugboat QA support team could perform these operations without needing to inconvenience the DA team.
  5. If PHP compatibility is being worked on in an MR, that branch can modify the config.yml to change to the newer PHP version. This would allow for manual QA of the new PHP version in Tugboat previews prior to the merge occurring.

, so that each branch can customize as necessary, and so that additional logic isn't needed inside of the drupalorg module to create

Proposed resolution

Add this config.yml file to the 11.x branch, and then backport to other active branches from there.

Some discussion around this change can be found in Drupal slack.

[drupalImage] Optionally apply image style to images uploaded in CKEditor 5

$
0
0

Updated: Comment #212

Problem/Motivation

Inserting an image in the text editor dialog today allows the user to fiddle with image dimensions. It doesn't even have aspect ratio locking.

It's not great for the authoring experience nor for structured content reasons that users are defining the specific dimensions of every single image they insert. It'd be much better to allow them to choose from image styles — just like we do for image fields.

Proposed resolution

Allow an image style to be selected in the image dialog, which gets stored in a data-image-style attribute, and is handled by a yet-to-be-added imagestyle filter.

Remaining tasks

  1. Initial patch: select image style in dialog, inserting that sets a data- attribute, and a filter transforms the end result.
  2. Get #1589176-4: Follow-up: Use data-* to store #states api informations— a blocker to this patch — committed.

User interface changes

  • The new ability to select an image style.
  • A new filter.

API changes

None.

Viewing all 295177 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>