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

Add DanielVeza as a co-maintainer of Layout Builder

$
0
0

Problem/Motivation

@DanielVeza has been extremely active and productive in the Layout Builder issue queue:
#3423920: Custom Blocks with Layout Builder Enabled No Longer Use Front End Theme
#3398196: Field block for empty image field with no default image rendering empty div in Layout Builder
#3158916: Enable Layout Builder via code in tests when that UI is not being tested
#3033153: Contextual links can be used to drag and drop Layout Blocks.
#2985362: Create an interface to share the definition of the overridable methods on DefaultsSectionStorageInterface and LayoutEntityDisplayInterface
#2941189: Confirmation form for disabling per-entity layout overrides shows a success message and should not
He's shown a great depth of understanding of the code and a great degree of care for the users.

We've discussed maintainership and he is interested.
I also discussed with my fellow co-maintainers and they are supportive.

Proposed resolution

  1. @DanielVeza to confirm publicly and confirm that:
  2. patch/MR to maintainers.txt
  3. review
  4. rtbc
  5. commit
  6. update maintainers on node/3060

Remaining tasks

As above

User interface changes

API changes

Data model changes

Release notes snippet


Try to optimize test ordering when run-tests.sh is used with a mixture of test types

$
0
0

Problem/Motivation

Core gitlab runs use run-tests for concurrency, on only one test suite at a time (unit, kernel, functional, functional js).

In contrib gitlab runs, concurrent test runs run all groups at once, and this appears to go in the unit, kernel, functional, functional js order.

See the order of initial output on:
https://git.drupalcode.org/project/paragraphs/-/jobs/629259

i.e. If we run functional javascript -> functional -> kernel -> unit instead, we should be able to get overall faster test runs.

This is because functional and functional js tests take dozens or hundreds of times as long to run as unit tests, so if concurrency is maxed out, several unit tests can be finished in the space of one functional test. If a functional test is already running and there are spare threads for unit tests, this time is 'free', but if the unit tests all run first, then you end up with long running tests occupying just a single thread at the end of the job, with other CPUs idle.

Steps to reproduce

Proposed resolution

When multiple tests are run by run-tests.sh, reverse the order of the test groups so that slowest tests run first.

We will need to decide whether @group #slow should be used to determine the order only within a test group, or the order of tests within the whole run - it might make sense for it to be within the whole run?
If we only change the default order of test discovery, @group #slow will continue to work to modify the order of tests regardless of type, which seems fine and makes this a very small change.

Remaining tasks

This will have no effect on core test runs, so ideally we'd see how much difference it makes with a contrib module that has a decent test suite like paragraphs.

User interface changes

API changes

Data model changes

Release notes snippet

\Drupal\Core\Template\Attribute should implement Countable interface

$
0
0

Problem/Motivation

There are already different open issues to refactor the Attribute class. This issue is not intended to take a different direction, but I think is neither in conflict with those open issues:
- #2444003: Optimize Drupal\Core\Template\Attribute
- #2972143: Create \Drupal\Component\Utility\ArrayObject
- #2575867: MarkupInterface should implement \Countable

While the issues linked above have a more ambitious target, and they don't seem to be merged soon, I'm opening this one with the single purpose of making Attribute objects countable. I'm facing this issue while working with the ui_patterns module, trying to initialize a field as an Attribute object. That scenario is causing an error because of the following code:
https://git.drupalcode.org/project/ui_patterns/-/blob/8.x-1.x/src/Elemen...

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Deprecate file_managed_file_save_upload(), file_save_upload() and _file_save_upload_from_form() and replace with a service

$
0
0

Problem/Motivation

Part of #3221796: [META] Modernise file upload logic. Replace file_managed_file_save_upload(), file_save_upload() and _file_save_upload_from_form with new services to separate the Form API and user-facing messages from API-level services.

Steps to reproduce

Current sequence:

Current sequence diagram

Proposed resolution

BeforeAfterNotes
file_managed_file_save_upload() and _file_save_upload_from_form()\Drupal\file\Upload\FileElementHelper::saveFileUploads()Provides a callback for \Drupal\file\Element\ManagedFile::valueCallback()
Handles setting form errors, including combining error messages, and user-facing messages
file_save_upload()\Drupal\file\Upload\FormFileUploadHandler::saveFileUploads()Loops through multiple uploads for the existing \Drupal\file\Upload\FileUploadHandler::handleFileUpload()
By default adds error messages using Messenger::addError() but can be suppressed for cases where FileElementHelper wants to add them as form errors.

Notes on error handling

In order to decouple adding Messenger error messages in low-level file upload logic, we introduce an error handler that comes in two flavours:

  1. One that simply collects error messages for later retrieval
  2. On that just adds error messages to the Messenger service

In order to display info messages when a file is renamed, we introduced an event handler that handles FileUploadedEvents.

Reasoning:

Currently file_managed_file_save_upload() and _file_save_upload_from_form() have behaviour to combine upload errors and display them in a list, only if there is more than one. It does this by manipulating error messages (removing them, storing them, then re-adding them).

Default behaviour of file_save_upload() is just to add Messenger error messages.

Proposed sequence:

Proposed sequence diagram

Remaining tasks

  • Add tests for new services
  • Add legacy tests for deprecated functions
  • Update mermain diagrams with current architecture
  • Update issue summary

User interface changes

API changes

  • file_managed_file_save_upload(), _file_save_upload_from_form and file_save_upload()are deprecated
  • New \Drupal\file\Upload\FileElementHelperand \Drupal\file\Upload\FormFileUploadHandler services are added
  • A new FileUploaded event is dispatched on success of individual file uploads

Data model changes

Release notes snippet

Provide BC for ImageStyleDownloadController

$
0
0

Problem/Motivation

Multiple contrib modules are broken since ImageStyleDownloadController::deliver() now takes a string of the expected scheme for derivatives as a required parameter

Steps to reproduce

AVIF: #3450240: Drupal 10.3 compatibility
Stage File Proxy: #3450243: Drupal 10.3 compatibility
WebP: Probably also broken

Proposed resolution

Provide default value and throw a deprecation error.

public function deliver(Request $request, $scheme, ImageStyleInterface $image_style, ?string $required_derivative_scheme = null) {
  if ($required_derivative_scheme === NULL) {
    // @todo throw a deprecation.
    $required_derivative_scheme = $scheme;
  }
  // ...
}

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Let GDToolkit support AVIF image format

$
0
0

Problem/Motivation

AVIF image file format is getting traction in browsers' support.

Write up with examples https://jakearchibald.com/2020/avif-has-landed/

This issue is proposing to implement support to this image format in Drupal core's GD Toolkit.

Done:

Proposed resolution

Extend the GD toolkit to support AVIF too.

Remaining tasks

Figure out what to do about the fact that AVIF has to be compiled into PHP and that automatic detection is hard.

https://github.com/libgd/libgd/issues/782

https://github.com/php/php-src/pull/7526

User interface changes

new conversion format available for image effect "convert"

API changes

no

Data model changes

no

Release notes snippet

GDToolkit now supports the AVIF image format.

Determine which core config entity methods should be config actions

$
0
0

Problem/Motivation

In #3284025: Add configuration actions API we added the ability to add an attribute to config entity methods to make them available to the config actions APIs and, thereby, recipes. We added the attribute to \Drupal\user\Entity\Role::grantPermission() like so:

  /**
   * {@inheritdoc}
   */
  #[ActionMethod(adminLabel: new TranslatableMarkup('Add permission to role'))]
  public function grantPermission($permission) {

The question is what other core provided config entity methods should be available to actions?

Proposed resolution

  1. Determine the methods to make into actions
  2. Make it so

Remaining tasks

User interface changes

API changes

Data model changes

MediaLibraryUiBuilder service does not properly allow additional contextual filter arguments

$
0
0

Problem/Motivation

If you attempt to add contextual filters to the core media library, they will correctly be used when the library results are initially loaded, but are not passed to the view itself, so internal display links (the "grid" and "table" buttons) get URLs built that ignore the contextual arguments.

Steps to reproduce

Add a contextual argument to the core media library (widget displays), such as "media: authored by" and select "user ID from logged in user" as the default value.

Open a media library widget. The view that is loaded only shows the media your user has created. This is correct.

Click on one of the display buttons in the header, either grid or table, and the view will refresh to show all media instead of just your own. This is wrong.

Proposed resolution

Replace the current build call in buildMediaLibraryView()

return $view_executable->buildRenderable($display_id, $args, FALSE);

with

return $view_executable->buildRenderable($display_id, [], FALSE);

I did initially try this with $view_executable->args, but that seems to be redundant and passing [] has exactly the same effect. Current behaviour which passes through just the entity type argument ($args) stops any other contextual filters from working securely when the view is rendered. The $view_executable->execute($args) call a few lines earlier already does the full argument calculations for all contextual filters.

Remaining tasks

Add tests

User interface changes

API changes

Data model changes

Release notes snippet


Deprecate and remove the AJAX replace method

$
0
0

Problem/Motivation

core/lib/Drupal/Core/Render/Element/RenderElement.php 

This looks like a Drupal 7 deprecation.

      // @todo Legacy support. Remove in Drupal 8.
      if (isset($settings['method']) && $settings['method'] == 'replace') {
        $settings['method'] = 'replaceWith';
      }

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

JSON and other serialization formats now handle non-4xx exceptions

$
0
0

Problem/Motivation

Despite claims to the contrary in various code snippets in the exception handling system, non-HTML requests to Drupal aren't that rare, anymore. Modules such as JSON-RPC and Simple OAuth work almost entirely over a JSON, for instance, but exceptions thrown while handling their routes many times come back as HTML.

I am working on getting exceptions thrown during Simple OAuth's processing (e.g., with an extension grant type) and even after adding a default _format: 'json' notation in the route's requirements, I still get HTML error pages.

This is because ExceptionJsonSubscriber and Serialization module's DefaultExceptionSubscriber (which overrides the former, if the module is enabled) both only explicitly handle 4xx.

JSON:API has its own DefaultExceptionSubscriber implementation which does also handle 5xx. I propose extracting this logic to the above two other handlers, so we can get mostly automatic exception handling on non-HTML routes.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Navigation LayoutBuilder UI has dead click zone

Navigation: Fix LB placeholder label on navigation block page

$
0
0

Problem/Motivation

The font size of the placeholder label is large and breaks the UI.

Steps to reproduce

1. Go on /admin/config/user-interface/navigation-block page
2. Uncheck the checkbox "Show content preview"
3. See the Layout builder region in the sidebar
4. Font size is breaking the UI.

Proposed resolution

Remaining tasks

User interface changes

Before

API changes

Data model changes

Release notes snippet

Navigation: Tooltip appears when check Show content preview checkbox

$
0
0

Problem/Motivation

Tooltip appears on the Navigation sidebar when we check the Show content preview checkbox.

Steps to reproduce

1. Install navigation module
2. Go on /admin/config/user-interface/navigation-block page
3. Uncheck and check Show content preview checkbox
4. Now you will see a tooltip in the navigation
5. See image for reference

Proposed resolution

Remaining tasks

User interface changes

Before

API changes

Data model changes

Release notes snippet

Layout builder off-canvas positioning problem when resizing browser

$
0
0

Problem/Motivation

When adding/editing a block in layout builder, if you resize the browser then the off-canvas sidebar doesn't re-position itself correctly.

Steps to reproduce

  1. use Drupal 10.0.9, or 9.5.9
  2. enable layout builder and turn it on for a content type
  3. create a page using the layout builder content type
  4. edit the layout for the page
  5. click "Add section"
  6. resize the right side of browser

Expected behaviour

The layout builder sidebar should move with the right side of the browser.

Actual behaviour

Sidebar stays in one place, or jumps around.

screenshot

I think it has something to do with this change: https://git.drupalcode.org/project/drupal/-/commit/e2d11b5fff7ba50dbb18f...

Deprecated function: strnatcasecmp(): Passing null to parameter #1 ($string1) of type string is deprecated in LayoutPluginManager

$
0
0

Problem/Motivation

Deprecated function: strnatcasecmp(): Passing null to parameter #2 ($string2) of type string is deprecated in Drupal\Core\Layout\LayoutPluginManager->Drupal\Core\Layout\{closure}() (line 204 of core/lib/Drupal/Core/Layout/LayoutPluginManager.php).

appears on pages, where layouts are being listed in a select which uses $this->layoutPluginManager->getLayoutOptions() to get its options.

Example:

$form['field_layouts']['field_layout'] = [
      '#type' => 'select',
      '#title' => $this->t('Select a layout'),
      '#options' => $this->layoutPluginManager->getLayoutOptions(),
      '#default_value' => $layout_plugin->getPluginId(),
      '#ajax' => [
        'callback' => '::settingsAjax',
        'wrapper' => 'field-layout-settings-wrapper',
        'trigger_as' => ['name' => 'field_layout_change'],
      ],
    ];

(FieldLayoutEntityDisplayFormTrait.php)

layout_builder's layout_builder_blank aka BlankLayout neither has a label nor a category defined in its annotation:

/**
 * Provides a layout plugin that produces no output.
 *
 * @see \Drupal\layout_builder\Field\LayoutSectionItemList::removeSection()
 * @see \Drupal\layout_builder\SectionListTrait::addBlankSection()
 * @see \Drupal\layout_builder\SectionListTrait::hasBlankSection()
 *
 * @internal
 *   This layout plugin is intended for internal use by Layout Builder only.
 *
 * @Layout(
 *   id = "layout_builder_blank",
 * )
 */
class BlankLayout extends LayoutDefault {

it should be sorted out by

/**
 * Implements hook_plugin_filter_TYPE_alter().
 */
function layout_builder_plugin_filter_layout_alter(array &$definitions, array $extra, $consumer) {
  // Hide the blank layout plugin from listings.
  unset($definitions['layout_builder_blank']);
}

(layout_builder.module)

but that hook never gets called!

So the layout_builder_blank layout is being passed through without label or category, but these methods rely on these values to be present. They are being called indirectly by $this->layoutPluginManager->getLayoutOptions()

  /**
   * {@inheritdoc}
   *
   * @return \Drupal\Core\Layout\LayoutDefinition[]
   */
  public function getSortedDefinitions(array $definitions = NULL, $label_key = 'label') {
    // Sort the plugins first by category, then by label.
    $definitions = $definitions ?? $this->getDefinitions();
    uasort($definitions, function (LayoutDefinition $a, LayoutDefinition $b) {
      if ($a->getCategory() != $b->getCategory()) {
        return strnatcasecmp($a->getCategory(), $b->getCategory());
      }
      return strnatcasecmp($a->getLabel(), $b->getLabel());
    });
    return $definitions;
  }

  /**
   * {@inheritdoc}
   *
   * @return \Drupal\Core\Layout\LayoutDefinition[][]
   */
  public function getGroupedDefinitions(array $definitions = NULL, $label_key = 'label') {
    $definitions = $this->getSortedDefinitions($definitions ?? $this->getDefinitions(), $label_key);
    $grouped_definitions = [];
    foreach ($definitions as $id => $definition) {
      $grouped_definitions[(string) $definition->getCategory()][$id] = $definition;
    }
    return $grouped_definitions;
  }

  /**
   * {@inheritdoc}
   */
  public function getLayoutOptions() {
    $layout_options = [];
    foreach ($this->getGroupedDefinitions() as $category => $layout_definitions) {
      foreach ($layout_definitions as $name => $layout_definition) {
        $layout_options[$category][$name] = $layout_definition->getLabel();
      }
    }
    return $layout_options;
  }

This is why the error appears.

This deprecation warning didn't appear in older versions of PHP, so the bug wasn't visible.

TL;DR:

/**
 * Implements hook_plugin_filter_TYPE_alter().
 */
function layout_builder_plugin_filter_layout_alter(array &$definitions, array $extra, $consumer) {
  // Hide the blank layout plugin from listings.
  unset($definitions['layout_builder_blank']);
}

(layout_builder.module)
is not called, so the layout_builder_blank layout, which neither has a label nor a description is not being sorted out, which leads to this error!

Steps to reproduce

  1. Install Drupal with the Umami demo profile.
  2. Enable the field_layout module.
  3. Log in as an administrator.
  4. Visit /en/admin/structure/types/manage/article/form-display.

Alternatively, install Drupal with the Standard profile, then enable the field_layout and layout_builder modules.

Further analysis

It seems as like the LayoutPluginManager (DI-injected by $container->get('plugin.manager.core.layout'),) is entirely missing FilteredPluginManagerTrait, so that its alterations are never being called:

/**
   * Implements \Drupal\Core\Plugin\FilteredPluginManagerInterface::getFilteredDefinitions().
   */
  public function getFilteredDefinitions($consumer, $contexts = NULL, array $extra = []) {
    if (!is_null($contexts)) {
      $definitions = $this->getDefinitionsForContexts($contexts);
    }
    else {
      $definitions = $this->getDefinitions();
    }

    $type = $this->getType();
    $hooks = [];
    $hooks[] = "plugin_filter_{$type}";
    $hooks[] = "plugin_filter_{$type}__{$consumer}";
    $this->moduleHandler()->alter($hooks, $definitions, $extra, $consumer);
    $this->themeManager()->alter($hooks, $definitions, $extra, $consumer);
    return $definitions;
  }

meanwhile, they are being called in Layout builder (e.g. admin/structure/types/manage/page/display/default/layout) when adding a section.
So maybe layout_builder is doing something different or special?
If layout_builder is not installed, everything is fine!

Proposed resolution

  1. Add missing attributes to Drupal\layout_builder\Plugin\Layout\BlankLayout so that getCategory() and getLabel() return string|\Drupal\Core\StringTranslation\TranslatableMarkup as required, instead of NULL.
  2. Call getFilteredDefinitions() in LayoutPluginManager::getLayoutOptions().
  3. Add test coverage for (2).

Either (1) or (2) by itself is enough to avoid the error. If we implement (1) but not (2), then it leads to a regression: the blank layout is listed, when it currently is not. See Comment #50. If we implement (2) but not (1), then we are hiding the error instead of fixing it.

For (3), mock Drupal::service('theme.manager'), since that is called in FilteredPluginManagerTrait::themeManager(). Then call getLayoutOptions() and confirm that the module and theme alter() methods are called.

Other approaches:

  1. Add an optional parameter to LayoutPluginManager::getLayoutOptions() and pass it to getFilteredDefinitions(), using $this->getType() as a fallback.
  2. Make $consumer optional in getFilteredDefinitions(), and invoke just the first hook if it is not provided.

Remaining tasks

Decide whether to implement one of the other approaches in this issue or in a follow-up.

User interface changes

None, except for not showing the PHP error.

API changes

To be determined.

Data model changes

None

Release notes snippet

N/A


"To log in to this site, your browser must accept cookies from the domain" error message displayed when user goes back and reload the page

$
0
0

Problem/Motivation

The message "To log in to this site, your browser must accept cookies from the domain" is displayed to the user when they use "Back" button and refresh the page.

Steps to reproduce

1. Login with any user
2. Log out
3. Click to go back (Back button of the browser)
4. Reload the page
5. See the message

The message is quite confusing for the user when they perform the steps above as it doesn't make sense.

Is this by design?

GIF showing the steps and error

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'project' cannot be null

$
0
0

In ExceptionHandler.php line 45:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'project' cann
ot be null: INSERT INTO "locale_file" ("project", "langcode", "version", "t
imestamp", "last_checked") VALUES (:db_insert_placeholder_0, :db_insert_pla
ceholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_
placeholder_4); Array
(
[:db_insert_placeholder_0] =>
[:db_insert_placeholder_1] => en
[:db_insert_placeholder_2] =>
[:db_insert_placeholder_3] => 0
[:db_insert_placeholder_4] => 0
)

In StatementWrapperIterator.php line 111:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'project' cann
ot be null

Add support for !service_closure custom tag in YamlFileLoader

The footer shadow disappears when a button is hovered

$
0
0

Problem/Motivation

When the content region of the navigation is bigger than the available space a shadow to the navigation footer is added to help understand the missing items are scrolling below that region and that there is missing content.

But if an item is active or being hovered right under that shadow, the shadow disappears:

The shadow should still be visible when hovering items in the content.

Proposed resolution

Remaining tasks

User interface changes

CKEditor 5 Paste from Word with "Full HTML": image disappeared when reopening Edit tab

$
0
0

Problem/Motivation

I tested pasting from Word with CKEditor 5, and I noticed image disappeared when reopening Edit tab of content.
It seems <img src=file path> is missing when reopening Edit tab.
- When pasting at Edit tab: <img src="/sites/default/files/inline-images/filename"...> exists. (See CKE5_1_EditTab(pasting).png)
- When opening View tab: <img src="/sites/default/files/inline-images/filename"...> exists. (See CKE5_2_ViewTab.png)
- When reopening Edit tab: <img src="data-entity-uuid="> exists, but no file path. (See CKE5_3_EditTab(reopening).png)

Note. Unlike CKEditor 5, CKEditor 4 saves image data as Base64 encoded data when pasting from Word (<img src="data:image/jpeg;base64,xxxx...>), and this symptom is not reproduced.

Drupal: 10.2.3
Client OS: Windows 10 22H2 build 19045.4291
Chrome: 124.0.6367.203
Word: 16.0 (Microsoft Word for Microsoft 365 version 2308 build 16.0.16731.20542)
Word doc: TextAndImgForPasteTest.docx (from https://github.com/ckeditor/ckeditor5/issues/2493#issuecomment-703472432)

Steps to reproduce

1. Open TextAndImgForPasteTest.docx, copy text and image, paste it into CKEditor 5 field of Edit tab, and save the content.
2. Go to View tab, the image is appeared correctly.
3. Go to Edit tab, the image is disappeared.

Viewing all 291324 articles
Browse latest View live


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