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

Improve cache dependencies in ContentTranslationDeleteAccess and implementation of ContentTranslationManager::isPendingRevisionSupportEnabled

$
0
0

Problem/Motivation

It loads all workflow only to add their cache tag, as any workflow might influence the access check.

That is slow (causes an extra config findByPrefix() query) and loads all those config entities, and it's also incorrect, as a new workflow might be added.

Steps to reproduce

Proposed resolution

Replace with a workflow_list cache tag. That said, this alone won't help, since the implementation then again loads all workflow entities.

However, we already have an API for this that doesn't require looping over them:

\Drupal\content_moderation\ModerationInformation::canModerateEntitiesOfEntityType and \Drupal\content_moderation\ModerationInformation::shouldModerateEntitiesOfBundle.

That relies on cached entity type and bundle information.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet


MenuTreeStorage shouldn't invalidate cache tags if the menu didn't change

$
0
0

Problem/Motivation

While debugging an issue with a menu cache tag I noticed that the tags will be invalidated even if the menu didn't change. As menus are usually used on most pages on the site this can result in a large number of invalidations in the CDN for no reason. MenuTreeStorage::doSave already checks to see if the menu item changed, so we can leverage this information to only clear the cache tags if it did.

Steps to reproduce

Set a conditional breakpoint in CacheTagsInvalidator::invalidate for the config:system.menu.main cache tag. Save the menu without changing anything, and the cache tag will be invalidated.

Proposed resolution

Only save if it has changed.

Remaining tasks

User interface changes

N/A

Introduced terminology

N/A

API changes

Changing the return value of MenuTreeStorage::doSave to return a boolean value instead of the menu name in the array. Currently it returns an associative array like main => main. Change to main => TRUE. This is a protected method so should be ok to change as it's internal?

Data model changes

N/A

Release notes snippet

Implement FormAlter attribute

$
0
0

Problem/Motivation

This may be better suited to a larger Hook implementation conversion discussion rather than specifically FormAlters
From an api standpoint:
We need to be able to connect #[FormAlter('some_form')] and #[Hook('form_some_form_alter')] together

There are currently three form alter hooks:
For ease I will abbreviate them
hook_form_alter -> hfa
hook_form_FORM_ID_alter -> hffia
hook_form_BASE_FORM_ID_alter -> hfbfia

We need to consider dev experience for implementing these with the new hook attribute system.
There are a few considerations:
Order of execution (BASE_FORM_ID is before FORM_ID is before form_alter)
Ordering of hooks across extra types


Suggestion 1:

Move all to FormAlter, handle complexity of determining which to implement and how to handle the developer choosing.
#[FormAlter] === hook_form_alter
#[FormAlter('node_delete_confirm')] === hook_FORM_ID_alter

Steps to reproduce

N/A

Proposed resolution

Add PREFIX Constant
Add SUFFIX Constant
Add single FormAlters attribute
Default hook to form_alter
Add optional form_id parameter
Base Form ID will remain as ambiguous as today
Update Hook attribute to take PREFIX and SUFFIX into account

Remaining tasks

Review
Confirm api can pick up these implementations

User interface changes

N/A

Introduced terminology

N/A

API changes

TBD

Data model changes

N/A

Release notes snippet

Process attachments (CSS/JS) for HTMX responses and add drupal asset libraries

$
0
0

Problem/Motivation

HTMX is designed to make a request, select some portion of the response, and incorporate that element or subtree of elements into the current page. If the response includes CSS to style this new markup or JavaScript to for the proper UX, those assets need to also be added to the page.

Steps to reproduce

  1. Make an htmx request for a response that includes a Dropbutton and insert the dropbutton into a page that does not contain a dropbutton. The pre-render callback for this element attaches the core/drupal.dropbutton asset library.
  2. Observe that the dropbutton markup is neither styled nor functional as the assets from the attached library are not present.

Proposed resolution

  1. Add the existing drupalSettings.ajaxPageState.libraries property calculated by core to all HTMX requests using the htmx:configRequest event.
  2. Create a response processor that processes HTMX requests and determines any missing asset libraries
  3. Encode the additional asset markup as JSON and add that data to the response so that HTMX will also insert that data into the receiving page.
  4. React to the insertion using the htmx:oobAfterSwap event and move the assets into place.

Remaining tasks

  1. Adjust the POC code based on more recent development in the HTMX contribution module.
  2. Add tests to verify the behavior

User interface changes

None

Introduced terminology

Out of Band Swaps is an HTMX concept that describes triggering additional content changes to the requesting page using HTMX markup added to the response. It is "out of band" because it is not the markup selected and placed by the attributes on the element that triggered the request.

API changes

Data model changes

None

Release notes snippet

Implement PSR-20 Clock

$
0
0

Problem/Motivation

PSR-20 defines a standard interface for system clocks.

If it implemented PSR-20, the service could be used with other libraries that can use a PSR-20 clock. And so it would encourage service reuse instead of having multiple implementations on the same website.

Dependency Evaluation - psr/clock

Maintainership of the package

Maintained by PHP-FIG. Drupal already uses a number of similar packages, either directly (psr/log) or through other dependencies such as guzzle (psr/http-client) or symfony (psr/container, etc.)

Security policies of the package

Not sure it's relevant since it's only a single interface

Expected release and support cycles

Unlikely to require frequent updates, except for language evolution, e.g. updating syntax or signatures.

Code quality

The interface is too simple for this to be applicable, see https://github.com/php-fig/clock/blob/master/src/ClockInterface.php

Other dependencies it would add, if any (the full tree, not just direct dependencies), and evaluations for those dependencies as well

N/A

Proposed resolution

  • Add a composer dependency on psr/clock
  • Add a new Drupal\Component\Datetime\Clock implementation ofPsr\Clock\ClockInterface
  • Add a new Psr\Clock\ClockInterface service in core.services.yml
  • Change at least one usage of \Drupal\Component\Datetime\TimeInterface::getCurrentTime() to Psr\Clock\ClockInterface::now() as an example

Remaining tasks

Follow up issue #3513861: [PP-1] Deprecate TimeInterface::getCurrentTime() and replace with ClockInterface::now()->getTimestamp()

User interface changes

Introduced terminology

API changes

Drupal\Component\Datetime\Time implements Psr\Clock\ClockInterface

Data model changes

Release notes snippet

[PP-2] Use form element of type date instead textfield when selecting a date in an exposed filter

$
0
0

Problem/Motivation

When adding a datetime exposed filter I cannot simply select a date - I have to manually enter a date which is very bad UX.

Proposed resolution

Use a form element with '#type' => 'datetime' so it's easy for users to select the date.

Change Record

Remaining tasks

Blocked on:

  • Investigate why the default value of the exposed filter is not picked up by the form (see #104). see #115
  • Hide time element for date-only type fields
  • Create a follow-up for the possibility for site builder to decide the widget type from the views management UI (see #48)
  • I think the new logic approach in #216 should also be happening in core/modules/datetime/src/Plugin/views/filter/Date.php where we hide the time element for date-only fields. I didn't get that far, and wanted someone else to agree with the new logic approach before I got much further.
  • We clearly could use even more test coverage of all the possible combinations.
  • We should decide if we really want to remove the placeholders and regexp from the existing filter and potentially break existing views that are using them (#215), or just add a whole new filter plugin with a different name. Then a) site builders can decide which interface they prefer and b) we don't have to worry about upgrade paths.

User interface changes

Exposed date filters will have input[type=date], and will leverage HTML5 handling if supported by the browser, or fall back to the polyfill if it doesn't.
For datetime w/ type date-only we should still use the datetime form element, but in date-only mode ($element['#date_time_element'] = 'none'.

API changes

None.

Data model changes

None.

Config overrides are loaded for English even when translate_english is false

$
0
0

Problem/Motivation

When loading the front page of Umami with an empty cache, there are dozens of queries for configuration language overrides, despite the 'translate_english' setting in locale being off by default.

This accounts for something like 60 unnecessary queries, so marking major.

Steps to reproduce

Proposed resolution

We need to get the translate_english setting from locale.settings - however I'm not sure the best way to do that without triggering an infinite loop.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

File formatter render absolute url to file

$
0
0

Problem/Motivation

Currently, file and image field's field formatter doesn't have support to render/display absolute URL.
ImageUrlFormatter and UrlPlainFormatter classes doesn't have flexibility to display absolute url.

Steps to reproduce

Configure the field formatter and check that we don't have flexibility to render absolute url.

Proposed resolution

- Add an option to both the field formatters.
- Validate option value in viewElements() method and display URL accordingly.
- Add test cases to validate newly added options.

Remaining tasks

Contact Usability for wording of new text in the UI.
- Review MR https://git.drupalcode.org/project/drupal/-/merge_requests/5882 which represents further changes since patch #122

User interface changes

- New option is added on both the field formatters.

File field:


Image field

API changes

- N/A

Data model changes

- N/A

Release notes snippet


Translation of config actions

$
0
0

Problem/Motivation

What is the current story with translations around config actions? I know that, given a correct schema, default configuration will be extracted by potx and become translatable. However, the config in config actions won't correspond to the existing config schema definitions so it won't be translatable?

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Make the conditions in joins in dynamic queries use Condition objects

$
0
0

Problem/Motivation

The conditions in joins in dynamic queries can be and are mostly SQL strings. The conditions can also be a Condition object, like they are in Select queries. The problem is that MongoDB does not support SQL strings.

// MongoDB does not support SQL string conditions.
$connection = \Drupal::database();
$query = $connection->select('node', 'n');
$query->join('inner', 'comment', 'c', '[n].[nid] = [c].[nid]');

Proposed resolution

Remove the use of SQL string conditions in joins in dynamic queries. With an exception for the join and relationship plugins of the views module. There is a followup issue for those changes #3420574: [PP-1] Make the conditions in joins in dynamic queries use Condition objects in the Views module.
Create a new method Drupal\Core\Database\Condition::compare() to compare two fields with each other.

// MongoDB supports conditions as Conditions objects
$connection = \Drupal::database();
$query = $connection->select('node', 'n');
$query->join('left', 'comment', 'c', $connection->joinCondition()->compare('n.nid', 'c.nid'));

Remaining tasks

TBD

User interface changes

TBD

API changes

A new method Drupal\Core\Database\Condition::compare() has been added. To compare two fields with each other.

Data model changes

None

Release notes snippet

TBD

Fix Drupal.Commenting.FunctionComment.Missing in module tests

$
0
0

Problem/Motivation

Working to enable the sniff Drupal.Commenting.FunctionComment.Missing.

Steps to reproduce

Proposed resolution

Fix this sniff for module tests

Remaining tasks

Create an MR
Enable the sniff in phpcs.xml.dist to include module tests
Fix reported errors
Review

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Add hook_entity_translation_access()

$
0
0

Problem/Motivation

Currently is not possible to alter translation access
There is a a GetTranslation method that determines whether you are allowed to translate entities. Currently it is not possible to alter this, the only checks that are done are based on existing permissions in core. When using the group module it may be desirable to add permissions regarding translation on group level, but there maybe many other cases where it is important to alter the permissions.

Proposed resolution

To alter the access result, it would be nice to add a hook_entity_translation_access() like hook hook_entity_access() and hook_entity_create_access().

Remaining tasks

User interface changes

API changes

Data model changes

Add aria-label attribute to navigation menu blocks

$
0
0

Problem/Motivation

This is follow up issue from https://www.drupal.org/project/drupal/issues/3393400#comment-15627607

As part of that issue, the aria-labelled-by attributes were removed from the HTML markup. (Commit)

In order to solve the accessibility issues introduced by that change, an alternative has been proposed by the accessibility team:

<nav aria-label="Title for navigation">
  <ul>
    <li><a href="page11.html">Link 1</a></li>
    <li><a href="page12.html">Link 2</a></li>
    .....
  </ul>
</nav>

Necessary changes in menu blocks markup need to be done to adapt them to achieve the requested outcome.

Proposed resolution

  • Introduce a <nav aria-label="Title for navigation"> wrapper for each menu used with Navigation, as noted above.
  • Introducing that will make the existing wrapping <nav id="menu-builder"> and <nav id="menu-footer"> elements redundant. Lets remove those.
  • Finally, while we're reviewing the labels for menus within the Navigation, lets add an aria-label to the Navigation side bar <aside> element, which currently just reads as "complementary". Add label "Administrative side bar". This aligns nicely with "Administrative top bar" label that we already have for the <aside> element that wraps the Top Bar.

Remaining tasks

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

None

Cannot use positional argument after named argument in _batch_process()

$
0
0

I upgrade an existing project from Drupal 9 to Drupal 10.4.3/10.4.6.

Afterwards I get following when executing any batching functionality:

Error: Cannot use positional argument after named argument in _batch_process() (regel 297 van /data/code/project/www/core/includes/batch.inc).
Ernst	Fout
Backtrace	
#0 /data/code/project/www/core/includes/batch.inc(139): _batch_process()
#1 /data/code/project/www/core/includes/batch.inc(95): _batch_do()
#2 /data/code/project/www/core/modules/system/src/Controller/BatchController.php(52): _batch_page(Object(Symfony\Component\HttpFoundation\Request))
#3 [internal function]: Drupal\system\Controller\BatchController->batchPage(Object(Symfony\Component\HttpFoundation\Request))
#4 /data/code/project/www/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#5 /data/code/project/www/core/lib/Drupal/Core/Render/Renderer.php(638): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#6 /data/code/project/www/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(121): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#7 /data/code/project/www/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#8 /data/code/project/vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#9 /data/code/project/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#10 /data/code/project/www/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#11 /data/code/project/www/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#12 /data/code/project/www/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#13 /data/code/project/www/core/modules/page_cache/src/StackMiddleware/PageCache.php(116): Drupal\Core\StackMiddleware\ContentLength->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 /data/code/project/www/core/modules/page_cache/src/StackMiddleware/PageCache.php(90): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#15 /data/code/project/www/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /data/code/project/www/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /data/code/project/www/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /data/code/project/www/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /data/code/project/www/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /data/code/project/www/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#21 {main}

To me it looks like it's a PHP 8.0+ problem.

Add HTMX dependency to core

$
0
0

Problem/Motivation

As part of #3404409: [Plan] Gradually replace Drupal's AJAX system with HTMX and ongoing discussion in Drupal Slack copied below, there is strong support for adding the HTMX library to core as a first step towards building a functionally equivalent system to Drupal's jQuery based Ajax API.

Summary from Slack

[nod_] The scope of the existing issue shouldn't change, we can open a child issue that deals with adding the library...in that issue we'll need to do the dependency evaluation

[catch] Yeah everything @nod_ says is correct

Proposed resolution

  1. Complete the dependency evaluation
  2. Add the HTMX library to core.

Dependency Evalution

Maintainership of the package
HTMX is an open source project with about 100 maintainers. The lead maintainer is Carson Gross who also has created an account here on drupal.org specifically to support this effort.
Security policies of the package
The HTMX project published a security policy to support our use of the library.
Expected release and support cycles
Releases are expected quarterly.
Code quality
The source code is well maintained and includes automated tests.
Other dependencies it would add, if any (the full tree, not just direct dependencies), and evaluations for those dependencies as well
HTMX has no dependencies by design.
License
The license for HTMX is BSD Zero Clause License, which is listed as a GNU compatible license. It is a public domain equivalent license. The license provides all four freedoms without restriction.

Remaining tasks

  1. ✅ MR to add the library and update vendor-update.js script
  2. ✅ Framework manager sign-off
  3. ✅ Release manager sign-off
  4. Update Current JavaScript dependencies page
  5. Write release notes

Release notes snippet


Prefer to replace some of obj && obj.prop in multi-lines with optional chaining if possible

$
0
0

Problem/Motivation

This issue is almost similar to #3492582: Replace some of obj && obj.prop with optional chaining.
In #3492582, some of obj && obj.prop in a single line was replaced with optional chaining but in multi-lines were partially. There is replaceable obj && obj.prop exist.
For example, checks object and its prop existence with below code in the /core/modules/big_pipe/js/big_pipe.js.

node.nodeType === Node.ELEMENT_NODE &&
  node.nodeName === 'SCRIPT'&&
  node.dataset &&
  node.dataset.bigPipeReplacementForPlaceholderWithId &&
  typeof drupalSettings.bigPipePlaceholderIds[
    node.dataset.bigPipeReplacementForPlaceholderWithId
  ] !== 'undefined',

If uses optional chaining expression, this code can makes code more shorter like below.

node.nodeType === Node.ELEMENT_NODE &&
  node.nodeName === 'SCRIPT'&&
  node.dataset?.bigPipeReplacementForPlaceholderWithId &&
  typeof drupalSettings.bigPipePlaceholderIds[
    node.dataset.bigPipeReplacementForPlaceholderWithId
  ] !== 'undefined',

Proposed resolution

Use optional chaining same as #3492582.

Remaining tasks

TBD

User interface changes

API changes

Data model changes

Release notes snippet

[11.1.x] Add BC stubs for Hook ordering.

$
0
0

Problem/Motivation

We need to add stubs for the order parameter and objects for: #3485896: Hook ordering across OOP, procedural and with extra types i.e replace hook_module_implements_alter
Long discussion in slack: https://drupal.slack.com/archives/C079NQPQUEN/p1741870906383859

Basically since the order parameter and associated objects will not exist and will create a fatal error. We can add the order parameter earlier and stubs for the objects. This will prevent fatal errors.

Steps to reproduce

N/A

Proposed resolution

Add new Hook signature
Add Attributes and Order objects
Update docs to mention 11.2 +

Remaining tasks

N/A

User interface changes

N/A

Introduced terminology

N/A

API changes

N/A

Data model changes

N/A

Release notes snippet

N/A

Convert hook_requirements() that do interact with install time that are not system

$
0
0

Problem/Motivation

There is a new api for install time requirements, we should use this.

Steps to reproduce

  • layout_discovery
  • media
  • package_manager
  • pgsql
  • workspaces
  • testing_requirements

Functional updates:

  • Media had an unnecessary !empty($error), that was removed and baseline updated.
  • Package manager install check technically ran in all phases, but only really needs to run for install time.
  • Package manager similarly the FailureMarker check ran during install, but doesn't really make sense there.

I did not convert the following to leave tests for procedural:

  • requirements1_test

Created a follow up for: experimental_module_requirements_test #3513879: Convert experimental_module_requirements_test_requirements to new Class

Proposed resolution

Convert to the new class structure.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Add validation constraints to core.extension

$
0
0

Problem/Motivation

Over at #1170362: Install profile is disabled for lots of different reasons and core doesn't allow for that, the schema for core.extension:profile is being refined.

Once that lands, we'll be able to make it validatable too, and make the entire config object validatable!

Conversation that triggered this issue to be created:

Wim
IMHO this is missing the following validation constraints, because right now **literally any string is allowed**:
```suggestion:-0+0
      label: 'Install profile'
      constraints:
        NotBlank: []
        ExtensionName: []
        ExtensionExists: profile
```

1. `NotBlank: []` because the empty string is never a valid install profile
2. `ExtensionName: []` because that validates the _shape_ of allowed strings
3. `ExtensionExists: profile` because that validates that (the already valid shape) indeed exists

Note that these 3 constraints are _exactly_ what we do for validating installed modules and themes in `config_dependencies_base`.

The only thing that's missing for that to work is a tiny addition to `ExtensionExistsConstraintValidator::validate()` using `\Drupal\Core\Extension\ProfileExtensionList`?

P.S.: _maybe_ `ExtensionExists` is impossible due to a race condition, but the other two validation constraints should be possible.
Alex
I think we should explore this in a follow-up. This is not really in-scope here.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Modules that create config cannot be installed alongside modules that depend on that config

$
0
0

Problem/Motivation

Experience Builder creates config at install time in hook_rebuild(). It also has tests that install submodules that depend on that config. These tests fail in 11.x because the config is not created in time, even if container_rebuild_required: true is set.

Steps to reproduce

Run Drupal\Tests\experience_builder\Functional\TranslationTest against 11.x.

Proposed resolution

We check validity of the entire config set before grouping the modules:

    // Check the validity of the default configuration. This will throw
    // exceptions if the configuration is not valid.
    $config_installer->checkConfigurationToInstall('module', $module_list);

    // Some modules require a container rebuild before and after install.
    // Group modules such that as many are installed together as possible until
    // one needs a container rebuild.
    $module_groups = [];
    $index = 0;
    foreach ($module_list as $module) {
      // Ensure the container is rebuilt both before and after a module that
      // requires a container rebuild is installed.
      $container_rebuild_required = !empty($module_data[$module]->info['container_rebuild_required']);

Check the validity of each group instead of the whole set at once.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Viewing all 295180 articles
Browse latest View live


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