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

Only reload updated part of Layout Builder element

$
0
0

Problem/Motivation

Currently, when an action occurs in layout builder, such as saving a block, the entire layout builder object is rebuilt and reloaded into the page. For a larger page with more blocks, this can result in a noticeable lag time until interactivity is returned to the user.

Proposed resolution

Return appropriate HTML fragments and only reload the affected part of the layout builder element instead of the whole thing.

Remaining tasks

Identify actions where this can happen.
Refactor the code.
Write new tests, if necessary.

User interface changes

TBD.

API changes

TBD.

Data model changes

TBD.

Release notes snippet

TBD.


Set MenuLinkContent getEntity to public visibility

$
0
0

Problem/Motivation

When dealing with Menu Link plugins programmatically, a developer might need to retrieve the content entity to access their fields or translations, at the moment the current best way to do this, seems to load the the entity using the uuid.

Steps to reproduce

N/A

Proposed resolution

Make the getEntity method public so it can be used from the \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent plugin.

Remaining tasks

- Approve the change
- Find a suitable test.
- Create a Change Record.

User interface changes

N/A

API changes

Visibility of MenuLinkContent::getEntity changed to public.

Data model changes

N/A

Release notes snippet

Before the change (extracted from) https://drupal.stackexchange.com/questions/235754/get-menu-link-item-fro...

if ($link instanceof \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent) {
  $uuid = $link->getDerivativeId();
  $entity = \Drupal::service('entity.repository')
    ->loadEntityByUuid('menu_link_content', $uuid);
  $field_value = $entity->field_example->value;
}

After:

if ($link instanceof \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent) {
  $entity = $link->getEntity();
  $field_value = $entity->field_example->value;
}

Original report by Grimreaper

Hello,

When manipulating menu, it would be convenient to be able to access the menu link content entity easily.

Setting the visibility of the getEntity method would help.

I will upload a patch.

Add a `langcode` data type to config schema

$
0
0

Problem/Motivation

As part of #2164373: [META] Untie config validation from form validation — enables validatable Recipes, decoupled admin UIs …, we are going to want to validate language codes as language codes, with their own constraints, rather than as plain strings.

Steps to reproduce

N/A

Proposed resolution

Add a new langcode data type to config schema, which implements certain validation constraints that are specific to language codes.

Remaining tasks

Figure out how to implement the feature and add robust test coverage.

User interface changes

None.

API changes

TBD, but there will probably be at least one new config data type (langcode) and possibly a new validation constraint or two.

Release notes snippet

TBD

Drupal 10.1 + Rejecting paths not conforming to standard URL's set by Drupal

Difficulties upgrading to 9.5.9 due to the laminas-diactoros change

$
0
0

Upgrade to 9.5.9 via composer throws this error and gives a black screen unaccessible site A rollback is necessary

It appears laminas is to blame in some way

[root@main public_html]# drush cache:rebuild
PHP Warning: require(/var/www/public_html/vendor/composer/../laminas/laminas-diactoros/src/functions/create_uploaded_file.php): Failed to open stream: No such file or directory in /var/www/public_html/vendor/composer/autoload_real.php on line 45
PHP Fatal error: Uncaught Error: Failed opening required '/var/www/public_html/vendor/composer/../laminas/laminas-diactoros/src/functions/create_uploaded_file.php' (include_path='/var/www/public_html/vendor/pear/archive_tar:/var/www/public_html/vendor/pear/console_getopt:/var/www/public_html/vendor/pear/pear-core-minimal/src:/var/www/public_html/vendor/pear/pear_exception:.:/usr/share/pear:/usr/share/php:/usr/share/pear:/usr/share/php') in /var/www/public_html/vendor/composer/autoload_real.php:45
Stack trace:
#0 /var/www/public_html/vendor/composer/autoload_real.php(49): {closure}('07d7f1a47144818...', '/var/www/bigbay...')
#1 /var/www/public_html/vendor/autoload.php(25): ComposerAutoloaderInitf197092365111500249304d9be7b237b::getLoader()
#2 /var/www/public_html/vendor/drush/drush/drush.php(56): include_once('/var/www/...')
#3 /var/www/public_html/vendor/drush/drush/includes/preflight.inc(18): require('/var/www/...')
#4 phar:///usr/bin/drush/bin/drush.php(143): drush_main()
#5 /usr/bin/drush(14): require('phar:///usr/bin...')
#6 {main}
thrown in /var/www/public_html/vendor/composer/autoload_real.php on line 45
[root@main public_html]#

Fix awkward details in hook system

$
0
0

Problem/Motivation

The hook system has some awkward details that make refactoring and improving it harder.
Especially, these force some complex tricks in #3366083: [META] Hooks via attributes on service methods (hux style)#3368812: Hux-style hooks, proof of concept
Some of this can be cleaned up without major BC breaks.

Single module ModuleHandler->invoke()

One should think that this is equivalent to just calling the one implementations from ->invokeAll(), that matches the given module.
With the huxified system, it would mean _any_ implementation that is associated with that module.

However, this is not fully the case:
If the function $module . '_' . $hook exists at the time when ModuleHandler->invoke() is called, then that function is always called, even if it is not part of the (cached) list for ->invokeAll(). The latter can be the case if:

  • The implementation was removed through hook_module_implements_alter(), OR
  • The file that contains the function (e.g. *.install) was not included at the time of discovery, OR
  • The module that owns this implementation is not currently enabled - this is the case for hook_requirements().

The hook_module_implements_alter() has limited effects on single ->invoke():

  • Reordering of implementations has no effect, because there is only one function.
  • Removal of implementations has no effect, because the function is still called.
  • Anything that causes a file with the $module . '_' . $hook function to be included, if it would otherwise not be, does have an effect. This generally means that hook_module_implements_alter() has to add a module with include group, e.g. $implementations['mymodule'] = 'mygroup'. This could even be another module that implements the hook on behalf of the module being called.

In fact, most of the hooks that are called with ->invoke() are never called with ->invokeAll().
This means we could consider to handle them completely separately.

Removal of missing functions from the cached list

If a list of implementations is loaded from cache, a function_exists() check is performed on every cached implementation.
If the function does not exist, it is removed from the list, and the updated list is later written to the cache.

The only use case I can think of is during development, if the developer temporarily checks out another git branch, or temporarily removes a function.

The practice of writing the updated list to the cache is questionable.
If you switch back to the main git branch, the function that was accidentally added is now gone from the cache.

Removing this mechanism would make things much easier in #3366083: [META] Hooks via attributes on service methods (hux style).

Removal or adding of modules

Currently it is possible to add or remove modules with ModuleHandler->addModule(), ->addProfile() and ->setModuleList().
This is a bit problematic with #3366083: [META] Hooks via attributes on service methods (hux style), because the services in the container where the ModuleHandler instance comes from is still based on the old module list. So we can add hook implementations for the newly added module, but the respective services won't be available at that time.

Note that this problem is only about adding ore removing modules.
Reordering modules via module_set_weight() is actually fine, because the order of hook implementations _can_ be dynamically changed.

Proposed resolution

Consider to simplify or remove some of these fragile mechanical details.

Possible changes:

  • For ->invoke(), we could completely disregard hook_module_implements_alter().
  • No longer remove missing functions from the cached list, unless a cache rebuild was explicitly requested.
    Instead, remove these functions in every request/process when the list is verified. This is not any better or worse for behavior, but it is easier to refactor.
  • Don't allow removing or adding modules in ModuleHandler. Allow reordering for module_set_weight(), but otherwise, used the fixed list from the container parameter.
    This sounds like a BC break, although I don't know of any known contrib modules that need this outside of tests.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Revert and Delete actions should not be available for the current revision

$
0
0

Problem/Motivation

Created as a follow-up to #2350939: Implement a generic revision UI.

There are several problems that result from the Revert and Delete actions being available for the current revision.

  1. The user interface break slightly, with the Revert/Delete split/drop button being directly to the right of the "Current revision" text, all under the single "Operations" column.
  2. Following through the Revert action technically works, in that a new "revert" revision is created, practically nothing has changed because the "current revision" is the current state of the content. In other words, reverting the current revision is illogical because there is nothing to revert to.
  3. Following through the Delete action results in an error and White Screen of Death, which leaves the entity in a broken and unrecoverable state.

Screenshot of the revision list showing the current revision.

The current solution to this is that every entity implementing the Generic Revision UI must include logic in its own access checker to ensure that the Revert and Delete actions cannot be accessed. Example from #1984588: Add Block Content revision UI:

'revert' => AccessResult::allowedIfHasPermissions($account, [
  'administer blocks',
  'revert any ' . $bundle . ' block content revisions',
], 'OR')->orIf(AccessResult::forbiddenIf($entity->isDefaultRevision() && $entity->isLatestRevision())),
'delete revision' => AccessResult::allowedIfHasPermissions($account, [
  'administer blocks',
  'delete any ' . $bundle . ' block content revisions',
], 'OR')->orIf(AccessResult::forbiddenIf($entity->isDefaultRevision() && $entity->isLatestRevision())),

In short, each implementation must include something to the effect of AccessResult::forbiddenIf($entity->isDefaultRevision() && $entity->isLatestRevision() in the access checker, once for the revert operation, and a second time for the delete revision operation.

There are two issues here:

  1. It's reasonable to assume that some developers will forget or not realise they need to include this in their access checkers, resulting in some implementation potentially being buggy.
  2. The fact that every implementation needs to include what is in effect the same lines of code suggests that overall developer effort would be reduced by providing this logic in an access checker out of the box, as well as lowering the barrier to entry and reducing the likelihood of bugs in contrib/custom implementations.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Add standard template for block content

$
0
0

Problem/Motivation

https://www.drupal.org/project/block_content_template something like this

Steps to reproduce

NA

Proposed resolution

Add default template

Remaining tasks

Review if it's worth it
Implement
Write test
code review

User interface changes

New tab to "View" block without being placed on a apge

API changes

NA

Data model changes

NA

Release notes snippet

TBD


[Meta, Plan] Pitch-Burgh: Policy based access in core

$
0
0

Problem/Motivation

This is the meta-issue for fulfillment of deliverables for the winning "Pitch-Burgh" proposal shown here. It will be updated as subtasks are identified/completed.

Completed tasks

Remaining tasks

Here it's important to note that the pitch was about getting policy based access into core, but I've been asked to first focus on getting this to work in contrib so that if core maintainers aren't immediately ready to commit my work, we still have something finished in the end. As such, I'd like to explore expanding Flexible Permissions with a new module that adds the system to core from the outside. This may be harder and cost more time, though.

  • Create a new module that depends on Flexible Permissions
  • In said module, swap out the permission checker with one that leverages FP using a new "Drupal" scope
  • Also swap out the user.permissions cache context to integrate the new calculated permissions
  • Write two calculators to replace core's permission layer: UID1 and role-based permissions

If we have time left after this, it would be great if we could also focus on converting FP into core code and copy the code from the new module into core as well. Minus the swapping out services then, of course, as we'd have access to directly replace them.

Allow specifying `meta` data on JSON:API objects

$
0
0

Problem/Motivation

From the JSON:API spec: https://jsonapi.org/format/#document-meta

Where specified, a meta member can be used to include non-standard meta-information. The value of each meta member MUST be an object (a “meta object”).

Any members MAY be specified within meta objects.

Handling of metadata in the JSON:API normalizers already exists.

RelationshipNormalizer

    return CacheableNormalization::aggregate([
      'data' => $this->serializer->normalize($object->getData(), $format, $context),
      'links' => $this->serializer->normalize($object->getLinks(), $format, $context)->omitIfEmpty(),
      'meta' => CacheableNormalization::permanent($object->getMeta())->omitIfEmpty(),
    ]);

ResourceIdentifierNormalizer

    if ($object->getMeta()) {
      $normalization['meta'] = $this->serializer->normalize($object->getMeta(), $format, $context);
    }

The problem is there's no way to add meta information to these objects. See ResourceObjectNormalizer::serializeField

      if ($field instanceof EntityReferenceFieldItemListInterface) {
        // Build the relationship object based on the entity reference and
        // normalize that object instead.
        assert(!empty($context['resource_object']) && $context['resource_object'] instanceof ResourceObject);
        $resource_object = $context['resource_object'];
        $relationship = Relationship::createFromEntityReferenceField($resource_object, $field);
        $normalized_field = $this->serializer->normalize($relationship, $format, $context);
      }

createFromEntityReferenceField takes a meta and links parameter. But there's no way to add information.

This is useful for building a headless application on Drupal to provide context about the information.

Steps to reproduce

Proposed resolution

Dispatch an event to allow modules to add additional meta to the normalized data

Remaining tasks

  • Reviews
  • Profiling per #61
  • Updates to jsonapi.api.php per #61

User interface changes

API changes

Data model changes

Release notes snippet

allow FieldConfigInterface::setDefaultValueCallback() to accept a callback in service notation

$
0
0

FieldConfigInterface::setDefaultValueCallback() accepts a callback for a base of config field's default value, either as a function or method name.

We get this pattern repeated by entity types over and over again for fields where the default value comes from a service, such as the uid and created fields:

Node entity:

    $fields['uid'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Authored by'))
      ->setDescription(t('The username of the content author.'))
      ->setRevisionable(TRUE)
      ->setSetting('target_type', 'user')
      ->setDefaultValueCallback('Drupal\node\Entity\Node::getCurrentUserId')

...

  public static function getCurrentUserId() {
    return [\Drupal::currentUser()->id()];
  }

Media entity:

    $fields['uid'] = BaseFieldDefinition::create('entity_reference')
      ->setLabel(t('Authored by'))
      ->setDescription(t('The user ID of the author.'))
      ->setRevisionable(TRUE)
      ->setDefaultValueCallback(static::class . '::getCurrentUserId')
...

    $fields['created'] = BaseFieldDefinition::create('created')
      ->setLabel(t('Authored on'))
      ->setDescription(t('The time the media item was created.'))
      ->setTranslatable(TRUE)
      ->setRevisionable(TRUE)
      ->setDefaultValueCallback(static::class . '::getRequestTime')

...

  public static function getCurrentUserId() {
    return [\Drupal::currentUser()->id()];
  }

  public static function getRequestTime() {
    return \Drupal::time()->getRequestTime();
  }

We could remove these wrapper method and save on repeated code and improve DX if we allow setDefaultValueCallback() to accept a callback in service notation the same way that route controllers do, that is, 'service_name:method'.

Olivero: Fix breadcrumb Chevron icon

$
0
0

Problem/Motivation

In the Olivero theme, color for the chevron icon is not as per the Figma design for all the screen sizes.
Before the patch
mobile before patch
tablet before patch
desktop before patch
After the patch
mobile after patch
tablet after patch
desktop after patch

Steps to reproduce

Make sure you have selected the Olivero theme and open it using Chrome or a similar browser inspect the chevron icon color and compare it to the Olivero theme Figma design

Proposed resolution

Replace the color with the one that is mentioned in the Figma design.

Remaining tasks

None

User interface changes

Changing the color from var(--color--gray-45) to var(--color--gray-90) as mentioned in the Figma design.

API changes

None

Data model changes

None

Release notes snippet

None

Use media query event listener instead of a listener on the resize event

$
0
0

Problem/Motivation

in nav-tabs.es6.js we have

    $(window)
      .on('resize.tabs', Drupal.debounce(toggleCollapsed, 150))
      .trigger('resize.tabs');

ToggleCollapsed should be an event listener to the media query defined inside.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Avoid warning from imagecreatefrompng when loading png with obscure iCCP profiles

$
0
0

Problem/Motivation

When a PNG (and some other rarely used formats) image contains iCCP chunk with sRGB IEC61966-2.1 color profile, libpng triggers warning:

Warning: imagecreatefrompng(): gd-png: libpng warning: iCCP: known incorrect sRGB profile in Drupal\system\Plugin\ImageToolkit\GDToolkit->load() (line 201 of core/modules/system/src/Plugin/ImageToolkit/GDToolkit.php).

This warning is printed for any such image, but they're still valid and displayed correctly.

Steps to reproduce

You need an image with iCCP chunk in it and sRGB IEC61966-2.1 color profile. You can achieve this in several ways.

You can find this color profile in attachments for that issue — sRGB IEC61966-2.1.zip. Extract it first to get .icc profile.

For examples, I will use core/tests/fixtures/files/image-test.png. It will be called image-test.png in commands below without full path.

ImageMagick CLI (convert)

Assuming that color profile (.icc) and image (image-test.png) in the same folder.

  1. convert image-test.png -profile sRGB\ IEC61966-2.1.icc -strip -profile sRGB\ IEC61966-2.1.icc -define png:include-chunk=zTXt,iCCP image-1-icpp.png
  2. Upload this image into Drupal and try to process it by any image style.

GIMP (OpenSource image editor)

  1. Open image-test.png in GIMP.
  2. Go to Image | Color Management | Assign Color Profile…
  3. In Assign section in select element chose Select color profile from disk…
  4. Select downloaded .icc profile.
  5. Click Assign.
  6. Save the image by File | Save as chose name and path and click Export. In open modal window, make sure you have checked Save color profile, and then again Export.
  7. Upload this image into Drupal and try to process it by any image style.

Proposed resolution

Add @ symbol before calling imagecreatefrompng() to suppress this warning.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Change PathMatcher::matchPath() $patterns param from string to an array of strings

$
0
0

Problem/Motivation

In #2272201: Move drupal_match_path in path.inc to a service we converted the procedural drupal_match_path and kept the implementation exactly the same. However, taking a string of patterns separated by newline isn't the best interface for this as it's tied to how the form values are submitted currently.

Proposed resolution

Convert the $pattern parameter to an array of strings.

Remaining tasks

Wait until #2272201: Move drupal_match_path in path.inc to a service goes in.

User interface changes

API changes

PathMatcher::matchPath() takes an array of strings instead of a string.


The 'entity:user' context is required and not present

$
0
0

Problem/Motivation

Drupal suddenly stopped to work. I was working on a theme when Drupal started to throw a \Drupal\Component\Plugin\Exception\ContextException on every page view.

The error message and a backtrace are attached. Due to recursion in objects the output of debug_print_backtrace() could not be retrieved.

Steps to reproduce

I don't know. The last thing I remember was clearing all caches.

Proposed resolution

The function Drupal\Core\ParamConverter\EntityConverter->convert contains the code

    $context_id = '@user.current_user_context:current_user';
    if (isset($contexts[$context_id])) {
      $account = $contexts[$context_id]->getContextValue();
      unset($account->_skipProtectedUserFieldConstraint);
      unset($contexts[$context_id]);
    }

which fails. Obviously the result is thrown away for some reason. So there is no need to fail at this point.
The following code seems to work for me:

    $context_id = '@user.current_user_context:current_user';
    if (isset($contexts[$context_id])) {
      try {
        $account = $contexts[$context_id]->getContextValue();
        unset($account->_skipProtectedUserFieldConstraint);
      } catch (\Drupal\Component\Plugin\Exception\ContextException $e) {
      }
      unset($contexts[$context_id]);
    }

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Fix deprecated overloaded function usage in PHP 8.3

$
0
0

Problem/Motivation

There's some deprecations in upcoming PHP 8.3

- https://wiki.php.net/rfc/deprecate_functions_with_overloaded_signatures
- https://wiki.php.net/rfc/assert-string-eval-cleanup

Proposed resolution

https://wiki.php.net/rfc/deprecate_functions_with_overloaded_signatures#...
- Replace deprecated get_class() call without argument

$ git grep 'get_class()'
core/lib/Drupal/Component/Plugin/PluginManagerBase.php:128:    throw new \BadMethodCallException(get_class() . '::getFallbackPluginId() not implemented.');

https://wiki.php.net/rfc/deprecate_functions_with_overloaded_signatures#...
- ReflectionMethod::__construct() with 1 argument

core/lib/Drupal/Component/Utility/ArgumentsResolver.php:126:      return new \ReflectionMethod($callable);

https://wiki.php.net/rfc/deprecate_functions_with_overloaded_signatures#...

$ git grep -A 5 ReflectionProperty|grep setValue
core/tests/Drupal/Tests/Component/Utility/HtmlTest.php-31-    $property->setValue(NULL);

Add 'Layout' Operation Link to entities

$
0
0

Problem/Motivation

Layout Builder Operation Link currently handles a very elementary use-case of adding a 'Layout' operation link to entities which can be customized via Layout Builder. Per a Slack thread on Layout Builder UX by @froboy,
, @larowlan suggested creating an issue to bring over Layout Builder Operation Link's functionality into core. So, this is that issue.

Steps to reproduce

tbd

Proposed resolution

Move 'Layout Builder Operations Link' functionality into core.
Create follow-up issue for Layout Builder Operations Link to deprecate functionality.

Remaining tasks

tbd

User interface changes

Adds a 'Layout' option to entities' Operations Links for those which can be customized via Layout Builder.

API changes

Data model changes

Release notes snippet

Default value for link text is not saved

$
0
0

Problem/Motivation

The default value for "link text" is not being saved.

Steps to reproduce

  1. Add a link field to a content type.
  2. The link field is configured with "Allow link text" set to be required.
  3. Under Default Value, enter text for the "link text".
  4. Leave the "default URL" empty.
  5. Save the field configuration.

Edit the link field and see that the default link text has not been saved.

Proposed resolution

The problem here is that LinkItem::isEmpty() returns true if the item does not have an URI, then WidgetBase::extractFormValues() calls filterEmptyItems() and that removes the items that only have a text but not an URI.
This behaviour is wanted when a user is filling the form normally but not when setting the default value.
However, we lack the context in LinkItem::isEmpty() to know if we are in the default value form or not.

The proposed solution involves overriding extractFormValues() in LinkWidget and not to call filterEmptyItems() if we are in the default value form. This allow settings the default value in the config but then this value is still not used in the real form.

Remaining tasks

Update IS for usability review
Usability review

User interface changes

Yes

TBA

API changes

-

Data model changes

-

Consider replacing hook_field_type_category_info with YML based plugin discovery

$
0
0

Problem/Motivation

In the Drupal 8 cycle we removed most info hooks and replaced them with plugins.

In #3356894: Make field selection less overwhelming by introducing groups we added a new one hook_field_type_category_info

That issue represents a huge win for Drupal so we didn't want to slow progress debating whether it should be a hook or plugins.

This issue is to explore that further.

ApproachProsCons
Info hook
  • lower overhead
  • performance?
  • less discoverable
  • less consistent with other APIs / established standards in D9
  • Need a separate alter hook (which is missing atm)
  • Magic keys for definer and consumer
Plugins (yml)
  • established pattern
  • don't need to know PHP to work with
  • alter hook is simple to add
  • YML is backed by a class, so an API for the consumer
  • Needing to define a plugin manager instead of just firing a hook
  • Magic keys for definer

Steps to reproduce

Proposed resolution

See what the code looks like using YML discovery with an alter hook.
Add a default plugin implementation and change some of the logic in FieldStorageAddForm to it (e.g ->getWeight, ->getDescription, ->isDefault)
Consider bundling in #3372092: [PP-1] Allow hook_field_type_category_info entries to define libraries too

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Viewing all 295035 articles
Browse latest View live


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