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

Template file_link is difficult to alter

$
0
0

Problem/Motivation

In order to add target="_blank" to a file link, I had to replicate most of template_preprocess_file_link. The documentation for $variables['attributes'] ("An associative array of attributes to be placed in the a tag") is wrong after #2236855: Use CSS for file icons in file fields

Proposed resolution

Add a link_attributes variable to the template?

Add URL options variable to the template which includes attributes. See #29

This may be deprecated eventually: #2615660: Allow Link and LinkGenerator::generate() to provide attributes.

Remaining tasks

Review the patch and change record.

User interface changes

API changes

Data model changes


Images appear as circle icons in teaser view regardless of image style settings

$
0
0

Problem/Motivation

In the olivero theme, teaser images show up as circle icons regardless of image style settings.

Steps to reproduce

Proposed resolution

Any way to override this default?

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Menu link plugins should provide a way for the link to be conditionally hidden

$
0
0

AFAICT, there's no way for a menu link plugin to cause the menu link not to appear.

There is MenuLinkInterface::isEnabled(), but returning FALSE from that causes the menu link itself to become disabled.

I've also tried returning either '' or NULL from getRouteName(), but that causes a routing crash. There's route '<none>' but that creates a link to the current page.

At this point the only thing I can see to do is to create a custom route which always denies access, and return that route name.

Use case is that I am writing a custom menu link plugin to show a user's group. If the user has no group memberships, then the link should not show.

Allow to use placeholders in derivative entity actions

$
0
0

Problem/Motivation

Derivative entity actions label is created by appending the singular label of the entity to the action label.
It would be nice to be able to use a "special" placeholder for improving their UX.

E.g. Creating my action "Upload to Lingotek" I get a label "Upload to Lingotek content item". It would be much nicer if it would be "Upload content item to Lingotek".

Proposed resolution

Add a "magic" @entity_type_label. Then in your action you can do:

/**
 * @Action(
 *   id = "entity:lingotek_upload_action",
 *   action_label = @Translation("Upload @entity_type_label to Lingotek"),
 *   deriver = "Drupal\lingotek\Plugin\Action\Derivative\ContentEntityLingotekActionDeriver",
 * )
 **/

Remaining tasks

Agree on this solution and implement.

User interface changes

None out of the box.

API changes

None.

Data model changes

None

Nitpick follow-up to update_fix_compatibility() fix

File delete form throws UndefinedLinkTemplateException without destination parameter

$
0
0

Problem/Motivation

Since 10.1.0 it is possible to delete files. The feature works using the delete button on the Files view, however when visiting the file delete form directly on /file/{file}/delete, without a destination parameter in the URL, this happens:

Drupal\Core\Entity\Exception\UndefinedLinkTemplateException: No link template 'canonical' found for the 'file' entity type in Drupal\Core\Entity\EntityBase->toUrl() (line 196 of core/lib/Drupal/Core/Entity/EntityBase.php).

Drupal\Core\Entity\ContentEntityDeleteForm->traitGetCancelUrl() (Line: 87)
Drupal\Core\Entity\ContentEntityDeleteForm->getCancelUrl() (Line: 42)
Drupal\Core\Form\ConfirmFormHelper::buildCancelLink(Object, Object) (Line: 88)
...

The cause of the issue is that ConfirmFormHelper::buildCancelLink() checks for a route-based cancel link if there's no destination, calling ContentEntityDeleteForm->getCancelUrl() .

Steps to reproduce

On a newly installed Drupal 10.1.7 site, where Image module is enabled, create a content type with an image field.
Make sure your account has permission to 'delete own files'.
Add a node and upload an image to the field.
Visit /file/1/delete

Proposed resolution

Possibly, adding a canonical link template to file entity. This was proposed previously, but at the time the decision was not to add it.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Clean up Claro's tables/tablesort/tableselect CSS

$
0
0

Problem/Motivation

Follow-up from #3432244: Split tablesort.module.css out to its own library and attach it via tablesort.

Claro has several different files for table styling, but there is no clear separation between the files as to what's targeting what kind of table.

There are broadly three kinds of tables that get rendered by Drupal:

1. HTML table
2. HTML table with tablesort
3. HTML table with tableselect

These are styled by the following files:

css/components/tables.css
css/components/tableselect.css
css/classy/components/tablesort.css
css/components/tablesort-indicator.css

tables.css defines all of these styles, which afaict should be in tablesort.css:

.sortable-heading > a {
  display: block;
  padding-block: var(--space-xs);
  padding-inline: 0 1.5rem;
  -webkit-text-decoration: none;
  text-decoration: none;
  color: inherit;
}

.sortable-heading > a:focus,
.sortable-heading > a:hover {
  -webkit-text-decoration: none;
  text-decoration: none;
}

.sortable-heading > a:focus::before,
.sortable-heading > a:hover::before {
  border-color: inherit;
}

.sortable-heading > a:focus::after,
.sortable-heading > a:hover::after {
  opacity: 1;
}

.sortable-heading > a::before {
  position: absolute;
  z-index: 0;
  inset-block-start: 0;
  inset-inline-end: 1rem;
  inset-block-end: 0;
  inset-inline-start: 1rem;
  display: block;
  content: "";
  border-bottom: 0.125rem solid transparent;

.sortable-heading > a::after {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: 1rem;
  width: 0.875rem;
  height: 1rem;
  margin-block-start: -0.5rem;
  content: "";
  opacity: 0.5;
  background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='8'%3e%3cpath d='M1.75.25v1.5h10.5V.25zm0 3v1.5h7.5v-1.5zm0 3v1.5h4.5v-1.5z'    fill='%23000f33'/%3e%3c/svg%3e") no-repeat 50% 50%;
  background-size: contain;
}

[dir="rtl"] :is(.sortable-heading > a::after) {
  /* Horizontally flip the element. */
  transform: scaleX(-1);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='8'%3e%3cpath d='M1.75.25v1.5h10.5V.25zm0 3v1.5h7.5v-1.5zm0 3v1.5h4.5v-1. 5z' fill='%23000f33'/%3e%3c/svg%3e");
}

@media (forced-colors: active) {
  [dir="rtl"] :is(.sortable-heading > a::after) {
    mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='8'%3e%3cpath d='M1.75.25v1.5h10.5V.25zm0 3v1.5h7.5v-1.5zm0 3v1.5h4.5v-1.5z'        fill='%23000f33'/%3e%3c/svg%3e") no-repeat 50% 50%;
  }
}

@media (forced-colors: active) {
  .sortable-heading > a::after {
    opacity: 1;
    background: linktext;
    mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='8'%3e%3cpath d='M1.75.25v1.5h10.5V.25zm0 3v1.5h7.5v-1.5zm0 3v1.5h4.5v-1.5z'        fill='%23000f33'/%3e%3c/svg%3e") no-repeat 50% 50%;
  }
}

.sortable-heading.is-active > a {
  color: var(--color-absolutezero);
}

.sortable-heading.is-active > a::before {
  border-bottom: 0.1875rem solid var(--color-absolutezero);
}

.sortable-heading.is-active > a::after {
  content: none;
}

td.is-active {
  background: none;
}

Steps to reproduce

Proposed resolution

Move the tablesort-specific CSS to tablesort.css, manually test for regressions.

Additionally, we could audit for duplicated selectors and remove any rules that will never be used.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Views exposed form action incorrect for embedded views' displays with other displays with paths

$
0
0

Problem/Motivation

When an embedded view display (such as a block) has exposed filters, if the view also contains a display with a path (page, export, etc) then the exposed form action will be set to the other display's path. This results in Reset buttons redirecting to other displays for example.

Proposed resolution

This is a tricky one, this could be as involved as rewriting the Drupal\views\Plugin\views\display\DisplayPluginBase::getLinkDisplay logic.

Remaining tasks

Write a failing test
Find a solution

Original report

When a view is setup to use the "Embed" display in a view, using AJAX in the form in any way will cause the action attribute of the HTML form object to be rewritten to submit to '/views/ajax' instead of the current page. This issue is harmless unless the filter in your embedded view uses the Reset button to clear the form and reload the page. When the Reset button is pressed, it'll direct you to /views/ajax instead of your current page.

A variation of this bug is if you have both a Page display setup and an Embed display setup in the view. If both of these displays exist in the same view, then the form's action attribute for the filter in the Embed display will be rewritten to submit to whatever path you setup for the Page display. I'll use this more elaborate scenario in my steps below.

To reproduce this bug:

  1. Create a new view named "Ajax Test"
  2. Change the format to Table. In the settings make the title field sortable
  3. Edit the Title field to give it a label of "Title"
  4. Add the Title field to the Filter Criteria with the filter configured to use the Contains operator. Check the "Expose this filter to visitors" box.
  5. Under Advanced Options, enable AJAX for this view
  6. In the Exposed Form options, make sure Basic is chosen as the type and in the settings check off the box that inserts a Reset button.
  7. Add a "Page" display to this view. Keep all the same settings. Only edit the path for the Page display. Use "/wrong-endpoint" as the path
  8. Save the view

Now we need to embed this view into a page. I'm going to use the Page Example module from the Drupal Examples for Developers set of modules for the dummy page needed to create an embedded view display, but it can be embedded in other ways and would still work the same.

  1. Install and enable the Page Example module to create a sample page we can embed into.
  2. Open 'Drupal\page_example\Controller\PageExampleController'
  3. Edit the description method and append the following before the "return $build" line:

    $build['test'] = views_embed_view('ajax_test', 'embed_1');

Go to the example page at '/examples/page-example'. Your embedded view should be there with the exposed filter. Inspect the HTML form object. The action attribute at this time should be '/examples/page-example'.

Now use the exposed filter to filter the table results. The results will narrow to match your search terms and the "Reset" button will appear. Inspect the form object again. The form will now submit to '/wrong-endpont'. The AJAX parts of the view will continue to work. You can use the table header sort. You can use new search terms and your results will filter as expected, but if you press the Reset button, you'll be redirected to the '/wrong-endpoint' page that was created as a Page type of display for this view.

If you skipped that step of creating the Page type display, and your AJAX Test view only has an Embed display, you will instead get redirected to /views/ajax. Fixed by #2820347: Exposed filter reset redirects user to 404 page on AJAX view when placed as a block so it goes to the current page instead.

This issue does not occur if the view in question is not an embedded view. If you try to repeat this behavior on the Views Page that we created at /wrong-endpoint, you will get the correct behavior. The form's action attribute will not get changed to direct to the wrong page when AJAX rebuilds the form.


ChainedFastBackend should not invalidate the whole fastBackend when doing a Set()

$
0
0

Problem/Motivation

The current implementation of ChainedFastBackend and DatabaseCacheTagsChecksum are not efficient when dealing with changes - writes to the cache backends.

- DatabaseCacheTagsChecksum heavily relies on the database to do validate cache item checksum so ChainedFastBackend is completely avoiding the use of tags on the fastBackend.

- ChainedFastBackend is invalidating the complete fastBackend on every cache write - both for the current head and other heads.

This implementation behaviour is penalizing applications where data changes a lot. ChainedFastBackend even had to be disabled during the install process where cache writes happen all the time. We don't won't a Drupal that will only work for read-only applications.

Proposed resolution

- Create a new Cache API (CacheRawBackend) that is simpler, faster and lighter than the current one. This new API saves data as-is in the storage backend so that it can leverage native funcionalities such as counter() (apc_inc for example) and touch(). This new Cache API is not tag aware.

- Create a new ChainedFastBackend (ChainedRawFastBackend) on top of the new Cache API. The old implementation of ChainedFastBackend cannot be used on the new Cache API because this new API is not able to store cache metadata such as the created timestamp, so it needs a new invalidation strategy. As the new Cache API, the new ChainedRawFastBackend is not tag aware.

- Implement an alternative to DatabaseCacheTagsChecksum that is built on top of the new ChainedRawFastBackend.

- Improve the current ChainedFastBackend to not invalidate the fastBackend for it's own webhead. It should only invalidate the fastBackend for other heads/processes.

- Bring back the usage of tags for the fastCache backend in ChainedFastBackend. This is needed to prevent the complete invalidation of the fastBackend when something changes. It should not be a problem now that cache tags are backed by a fast in-memory storage backend.

- Bring back ChainedFastBackend during the install process. It should actually be faster than not using ChainedFastBackend at all.

Remaining tasks

Profile before doing any further work and decide if it is worth the effort
Review all the code. I've already spoted some bugs in it
Write test coverage - lots of them

User interface changes

None

API changes

No API changes, only new APIs and changes in implementation details.

Data model changes

None.

Random failure: "Drupal.contextual.ContextualModelView is not a constructor".

$
0
0

Problem/Motivation

I've been seeing this random failure in Drupal CMS's end-to-end tests, which are run with Cypress. It's unclear why this should be happening, since that most definitely is a class with a constructor.

The tests themselves don't interact with contextual links in any way, they simply visit pages that have contextual links available (for example, pages where you are an authenticated user with permission to do certain contextual operations).

Proposed resolution

TBD

Remaining tasks

TBD

ModuleHandler::resetImplementations should reset all properties with hook implementations

$
0
0

Problem/Motivation

When working on https://git.drupalcode.org/project/drupal/-/merge_requests/855 I couldn't get NodeAccessGrantsCacheContextTest::testCacheContext to pass.

The reason is, we call $this->moduleHandler()->hasImplementations('node_grants')

hasImplementations calls getHookListeners which reads from the invokeMap cache if it's set. However, there's no way to force reset this cache in a kernel test. When debugging the above test, I noticed node_access_test was still in the invokeMap for node_grants even after it was uninstalled.

Steps to reproduce

See above test

Proposed resolution

$this->invokeMap = []; in resetImplementations

Remaining tasks

Agree
Review
Commit

User interface changes

None

Introduced terminology

None

API changes

None

Data model changes

None

Release notes snippet

N/A

[policy, no patch] Defer disruptive 11.3 deprecations for removal until 13.0

$
0
0

Problem/Motivation

Decide when to defer deprecations in this cycle.

During the Drupal 9.5.x cycle, we tried to defer as many issues with deprecations as possible to 10.1, this meant quite a lot of issues were delayed from landing.

During the 10.x cycle, we deferred deprecations as of 10.3. But that was only 9 months before the release of 11.0.0.

Steps to reproduce

Proposed resolution

If a deprecation is for @internal code like constructors or plugins, continue to deprecate for removal in 12.x

If a deprecation is for base classes, interfaces, or otherwise likely to affect a lot of modules, deprecate for removal in 13.x

Module/Theme deprecations are allowed - it's actually easier to do these at the end of a major release cycle than earlier on, and while they're slightly disruptive for sites when they update, they're generally not disruptive for contrib or custom modules since the API of the deprecated module stays the same.

There will be lots of edge cases, we can link examples from this issue.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Allow admin users to be reminded when forms in /admin are likely to alter configuration

$
0
0

Problem/Motivation

For some time, actually since at least Dev Days in Milan, I’ve struggled with how difficult it is for an administrator to be aware if a change on a production site might actually be changing the running configuration and, therefore, be liable for overwriting in a future code/config deployment.

I propose that, rather than a wholesale change of the /admin menu at this time, we optionally add an alert box to forms using a process inspired by the Configuration Override Warn module, using reflection to look for the method “getEditableConfigNames” and know it is editing config. Inspiration for this comes from the Configuration Override Warn module, though I expect we have it a little easier doing this from core.

An admin user looking at a typical config form would see:

screenshot of a CAPTCHA module form showing the warning message

And there would be a toggle to enable the behaviour in /admin/. It would be nice to allow a custom message to be added to the warning, such as “Alteration of this form should normally be carried out by the dev team."

Steps to reproduce

n/a

Proposed resolution

new feature in core

Remaining tasks

Create proof of concept
Agree wording and placement of message and config option to enable

User interface changes

Added warning to all forms that alter configuration

Introduced terminology

API changes

Data model changes

Release notes snippet

PlainTextOutput::renderFromHtml may render potentially dangerous output

$
0
0

Despite its name and description PlainTextOutput::renderFromHtml() does not guarantee the output to be plain text.

\Drupal\Component\Render\PlainTextOutput::renderFromHtml('&lt;script&gt;alert("XSS")&lt;/script&gt;');
The above code returns <script>alert(XSS)</script>.

We may need rename the class or at least warn users about possible security implications of it.

Modernize file.module forms

$
0
0

Problem/Motivation

This issue is created as part of Part of meta issue #2072251: [meta] Modernize forms to use FormBase
Above issue was part of refactoring forms to use the FormBase class.

Now that #2059245: Add a FormBase class containing useful methods is also in in, we should look at old forms that have empty validateForm() methods, or still use Drupal::service() or t().
Fix any discrepancies if there are any.

The title looks good as it is similar to all the other issues created in meta issue #2072251: [meta] Modernize forms to use FormBase

Proposed resolution

Convert existing FormInterface forms to extend FormBase
Remove un-necessary validate functions.
Fix phpstan issues if any.

Quick search yields only a few test classes.

Remaining tasks

Needs review

User interface changes

N/A

API changes

N/A


Olivero table.css should be in its own library and #attached to tables

$
0
0

Problem/Motivation

Olivero adds table.css to its base library, but the vast majority of pages don't include tables.

I think Olivero could define a table library, move the CSS there, then attach this to all table render elements / #theme table.

This would remove 2.2k of unused CSS on pages that don't have tables.

Steps to reproduce

Proposed resolution

Add a new library, like olivero.table and move table.css there.

Attach the library to tables, probably could be done in olivero_preprocess_table() which already exists.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Navigation module's help text should not link to the contrib module

$
0
0

Problem/Motivation

If you visit the help page for the Navigation module there is text that says:

For more information, see the online documentation for the Navigation module.

The online documentation doesn't really exist, it just links to the contrib module page which doesn't have any additional documentation.

Steps to reproduce

Visit /admin/help/navigation

After

Proposed resolution

Remove the sentence.

Remaining tasks

Fixing it.

Remove lazy declaration and proxy class for cron and use service closure instead

$
0
0

Problem/Motivation

As discussed in #3228623: DX: Creating lazy services is too difficult/obscure/bespoke/brittle the DX for our current lazy service proxies is poor. We tried using symfony lazy services in #3396928: Deprecate Drupal ProxyBuilder in favor of Symfony lazy services however that was not possible due to:

Sadly SF uses eval for the proxy classes which at least I can't see working with our serialized container solution

However we can now use service closures to lazy-load services which are supported by our serialized container.

This is the issue to do this for the cron service.

Steps to reproduce

Proposed resolution

Replacy services tagged 'lazy' with service closures.

Prefer using autowiring and the #[AutowireServiceClosure] attribute over the !service_closure yaml command where possible.

https://symfony.com/doc/current/service_container/autowiring.html#genera...

This requires changing the constructor signature and adding a new method to invoke the closure like so:

Before:

public function __construct(
  protected CronInterface $cron,
) {}

Service definition:

services:
  my_service:
    class: Foo\Bar
    arguments: ['@cron']

After:

public function __construct(
  protected \Closure $cronClosure,
) {}


protected function getCron(): CronInterface {
  return ($this->cronClosure)();
}

Service definition:

services:
  my_service:
    class: Foo\Bar
    arguments: [!service_closure '@cron']

Autowiring approach

Before:

public function __construct(
  protected CronInterface $cron,
) {}

Service definition:

services:
  my_service:
    class: Foo\Bar
    autowire: true

After:

public function __construct(
#[AutowireServiceClosure('cron')]
  protected \Closure $cronClosure,
) {}


protected function getCron(): CronInterface {
  return ($this->cronClosure)();
}

Service definition:

services:
  my_service:
    class: Foo\Bar
    autowire: true

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Invalid service alias for backend_overridable services in some cases when default_backend is set

$
0
0

Problem/Motivation

Discussing with ghost of drupal past (he prefers not being credited) about backend_overrides(https://www.drupal.org/node/2306083) he found an edge case where an invalid service alias would be created.

He wrote the fix, I wrote the test.

Steps to reproduce

Set 'default_backend' container parameter to 'whatever' while having a "my-service" tagged as backend_overridable.
If you have a service named ".my-service", an alias from 'my-service' to '.my-service' would be created, instead of creating an alias to 'whatever.my-service'.

Technically nothing stops us to create a service which id starts with a dot, so this might have any kind of consequences, possibly a WSOD.

Proposed resolution

Check $driver_backend and/or $default_backend before setting the alias.

Remaining tasks

Review.

User interface changes

None.

Introduced terminology

None.

API changes

None.

Data model changes

None.

Release notes snippet

None.

Make doctrine/lexer:^3.0 compatible with \Drupal\Component\Annotation\Doctrine.

$
0
0

Problem/Motivation

In #3429602: Annotation component has an undeclared dependency on doctrine/lexer 2 we're adding a dependency on doctrine/lexer:^2.0 to both the Annotation component and core itself.

doctrine/lexer:^3.0 currently throws a fatal error:

Steps to reproduce

$ composer update doctrine/lexer
$ drush cr
PHP Fatal error:  Uncaught Error: Cannot use object of type Doctrine\Common\Lexer\Token as array in drupal/core/lib/Drupal/Component/Annotation/Doctrine/DocParser.php:619

Proposed resolution

Make doctrine/lexer:^3.0 compatible with \Drupal\Component\Annotation\Doctrine.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Viewing all 294899 articles
Browse latest View live


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