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

CKEditor 5 text selected in a rich text field (wysiwyg) has invisible background when used inside a modal dialog

$
0
0

Problem/Motivation

When selecting a portion of text in a WYSIWYG field using CKEditor 5 inside a modal dialog, the selected text does not have the usual background color, causing confusion for editors who think nothing has been selected.

ckeditor5 text selection modal issue

Steps to reproduce

This is my current setup:

  • Drupal Core 10.2.6
  • Layout Builder module is enabled
  • Custom subtheme of bootstrap_barrio active
  • "Gin" as the active Administration theme

The problem occurs only when using CKEditor in Layout Builder through a modal dialog. In other scenarios, like a regular WYSIWYG field on a node form, it works correctly.

It is unclear if a combination of enabled modules, themes, or specific configurations could be causing the problem.
The issue began after updating Drupal Core from 9 to 10.
The problem persists across different themes.

Proposed resolution

Similar to other problems documented for CKEditor when used inside a modal dialog (e.g., https://www.drupal.org/project/drupal/issues/3328425), I propose adding the following CSS to the CKEditor's editor.css stylesheet. This will force the browser to show the expected background color on selected text:

.ui-dialog p::selection {
  color: var(--font-color);
  background: var(--ck-color-link-fake-selection);
}

As mentioned above, the issue persists across different themes, which indicates it is not theme-specific, that's why I'm proposing applying the workaround directly to the CKEditor CSS file.

Remaining tasks

  • Test
  • Get maintainer approval

Adjust custom navigation logo dimensions on upload

$
0
0

Problem/Motivation

Navigation allows to upload a custom logo to be included at the top of the bar.
Nowadays, the only restriction applied is related to image weight, but not for dimensions. That means that image bigger thatn te expected placement are being adjusted via CSS.

For a better resource management, would be great to adjust the custom logo dimensions to the logo placeholder to avoid loading unnecessarily big images.

Proposed resolution

The proposal here is to use a similar approach as we already have when uploading a picture to an image field that exceeds the maximum allowed size for the field.

When image is bigger than 40x40px, it would be automatically scaled during upload and a message like this would be shown to the end user:
The image was resized to fit within the navigation logo expected dimensions of 40x40 pixels. The new dimensions of the resized image are 40x40 pixels.

Following this path, code would be much simpler, reducing the number of possible points of failure and we would be safer assuming that original image can be used directly as navigation logo.

To give more flexibility, the icon size could be set as properties in the navigation.settings config entity, but not shown. So contrib modules or advanced site administrators could modify them.

Remaining tasks

#3444391: Center small navigation logo on collapsed state is in progress.

User interface changes

Adds message during file upload to notify user the image will be automatically resized if above expected size.

API changes

Adds image width/height as Configuration (no UI additions for these). For flexibility around image sizes changes tied to config rather than code, same as current file-size restriction already.

Data model changes

Uses Configuration to establish expected size of navigation logo.

Add symfony/polyfill-php84 and make use of new array functions

$
0
0

Problem/Motivation

PHP 8.4 will be released after Drupal 11, meaning we won't be able to use new features until we drop support for PHP 8.3. Fortunately symfony provides polyfills for many of these functions.

Steps to reproduce

Proposed resolution

Add symfony/polyfill-php84. Modernize some areas of core to use array_find, array_all, array_any and other related functions. \Drupal\Component\Assertion\Inspector is a good place to start because it has many related functions and has good unit test coverage

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Provide a NavigationLinkBlock Plugin and use Help as an usage example

$
0
0

Problem/Motivation

Providing a Single Link Navigation Block type could be useful for situations where a single item needs to be added to navigation and creating a new menu just for this purpose would be overkill and complex for editors.

A good example of this is the Help link in the current navigation. This is a single link and it was hardcoded in the NavigationUserBlock to avoid creating an extra menu.

If we add this new item, we could migrate Help link to be an usage of this block type and significantly simplify logic in NavigationUserBlock.

Related issues where complexity could be reduced:

#3441576: Investigate using the core "User account menu" in favor of custom Navigation Block for same
#3441118: [PP1] Add the user image to the user menu when available

Steps to reproduce

Current process to add a single link to page Foo in navigation:

  1. Go to Add Menu Page and create and arbitrary menu called Bar
  2. Edit the Bar menu and add menu item to Foo and its title
  3. Go to Navigation Layout page and add a new Bar Menu block
  4. Configure the Bar Menu Block to use 1st level and depth of 1
  5. Link to Foo is added to Navigation

Proposed resolution

Proposed flow to create a single link to Foo page to Navigation:

  1. Go to Navigation Layout page and add a new Link block
  2. Configure the Link block entering Foo route and title (Icon to be discussed)
  3. Link to Foo is added to Navigation

For now, this new block type will not be available to be added via UI. But created to make the work on the related issues smoother.

Remaining tasks

Update proposed resolution
Update change record

User interface changes

None. While we added a new Link block here, it is presently hidden from the general Block layout page as well as the Navigation layout page.

API changes

A new block with machine name navigation_link was added.

Data model changes

None.

exception message thrown in createConnectionOptionsFromUrl() is unclear

$
0
0

Problem/Motivation

> throw new \InvalidArgumentException('Minimum requirement: driver://host/database');

This is unclear.

Would be better as something like:

> throw new \InvalidArgumentException("The given database connection URL '$url' is badly formed. The minimum requirement is 'driver://host/database'.");

Steps to reproduce

Proposed resolution

Change the message to "The given database connection URL '$url' is invalid. The minimum requirement is: 'driver://host/database'"

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Add example and sections to Block API documentation

$
0
0

Problem/Motivation

Unlike many other pages of core documentation, the Block API documentation doesn't contain a worked example.

Compare:

* https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Menu%21me...
* https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Routing%2...
* https://api.drupal.org/api/drupal/core%21core.api.php/group/form_api/8.2.x
* https://api.drupal.org/api/drupal/core%21modules%21block%21block.api.php...

While the Block API documentation links off to examples elsewhere in a contrib module, this is probably not great practice (and definitely not consistent with the other API docs.)

Proposed resolution

Add an example to block.api.php
Add sections.
Do not remove references to \Drupal\Core\Block\Annotation\Block. let's do that in a separate issue

Remaining tasks

Review
Commit

User interface changes

None.

API changes

None.

Data model changes

None.

Use a readonly class for Pager value object

$
0
0

Problem/Motivation

In PHP 8.1 and above we can use read only properties. The primary benefit of this is to reduce side effects from values changing after they are initialized, but it also allows us to reduce boilerplate, as we can safely make these properties public and remove the need for a getter method.

In PHP 8.2 and above we can mark a whole class as read only, ensuring that all properties on the class are read only.

Value objects are great candidates for readonly classes. The \Drupal\Core\Pager\Pager class is a prime example of one that can be converted.

Steps to reproduce

Proposed resolution

  • Mark \Drupal\Core\Pager\Pager as readonly
  • Declare $totalPages, $currentPage, $totalItems and $limit as public
  • Deprecate getters
  • Update template_preprocess_pager to access public properties directly

Remaining tasks

How do we provide backwards compatibility for a class becoming readonly? Probably need a whole new class and deprecate the old class.

User interface changes

API changes

Data model changes

Release notes snippet

Remove unused variables in catch statements

$
0
0

Problem/Motivation

Since PHP 8.0 we can omit the exception variable in catch blocks if the variable is unused.

Steps to reproduce

Proposed resolution

Add SlevomatCodingStandard.Exceptions.RequireNonCapturingCatch to phpcs.xml.dist and run composer phpcbf.

Remaining tasks

Discuss coding standards

User interface changes

API changes

Data model changes

Release notes snippet


Protect against empty revision timestamps in VersionHistoryController::getRevisionDescription

$
0
0

Problem/Motivation

People are seeing errors on Taxonomy revision pages when upgrading from 10.2 to 10.3, see #2936995: Add taxonomy term revision UI

This is also being reported in #3317361: New revision fields don't have a default value after making an entity revisionable but that issue seems more general.

IMO we could be more defensive and check for NULL values before calling format() because as we know, Drupal is prone to field values not being there.

Steps to reproduce

From what I've read:

Start on 10.2
Create some terms
Upgrade to 10.3
Visit a term revisions page.

Proposed resolution

Add NULL checks in VersionHistoryController::getRevisionDescription for the revision creation time
Test coverage

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

New revision fields don't have a default value after making an entity revisionable

$
0
0

Problem/Motivation

After making an entity type revisionable and visiting the revision overview of that entity, the page crashes with the following error: 'The timestamp must be numeric'. This issue was first reported by @joachim in #2350939-82: Implement a generic revision UI and I just encountered the same issue when working on #2880154: Convert comments to be revisionable.

I can't seem to find code that set an initial value for this field (and the revision_user field for that matter) on any entity types that were already converted to be revisionable (eg. block content, terms, menu links), so I'm assuming there's existing content in the wild with NULL values for those columns.

Steps to reproduce

  1. Make an entity type revisionable
  2. Include the changes of #2350939: Implement a generic revision UI in your project
  3. Visit the revision overview of a pre-existing entity

Proposed resolution

Either we should set an initial value for revision_created during the upgrade (taken from the created column), or we should handle the field being empty throughout the UI.

In #2880154: Convert comments to be revisionable I created a post update hook to set the default values, but another way to do it would be to use Drupal\Core\FieldBaseFieldDefinition::setInitialValueFromField. That doesn't currently work though, but it used to before. Since the removal of SqlContentEntityStorageSchemaConverter we have to use updateFieldableEntityType when making an entity type revisionable. The installation of the revision fields happens in that method. However, setInitialValueFromField doesn't seem to work when installing fields using updateFieldableEntityType. I tried it and the revision_created and revision_log_message columns of existing comments are still NULL after the upgrade.

SQLContentEntityStorage::saveToDedicatedTables() doesn't correctly use storage configuration

$
0
0

Problem/Motivation

During an upgrade from 8.6.16 to 8.7.3, I ran into an issue with taxonomy_post_update_make_taxonomy_term_revisionable() .

The following error is thrown during processing of the update.

Base table or view not found: 1146 Table 'drupal.tmp_ed8154taxonomy_term_r__ff793441e7' doesn't exist: ...

.

Through some debugging, I determined that the temporary table, tmp_ed8154taxonomy_term_r__ff793441e7 was related to a custom field, field_default_access, an entity reference field on my Vocabulary. The default tempary table name, tmp__taxonomy_term_revision__field_default_access, turns out to be 49 characters, and is replaced with the hash format tmp table name, see DefaultTableMapping::generateFieldTableName() . While tracing the code for the EntityDefinitionUpdateManager::updateFieldableEntityType() , I discovered that this table was actually being created, but with a different sha255 has, resulting in the table name tmp_ed8154taxonomy_term_r__d348111e42.

Further discovery determined that SQLContentEntityStorage::saveToDedicatedTables() doesn't use the "$field_storage_definitions" used through out the update code, but calls $field_definition->getFieldStorageDefinition(); , which results in a different instance of the storage definition, with a different ( getUniqueStorageIdentifier() ), and as a result the table name isn't mapped correctly.

The issue here may be related to #3056539: Updating an entity type from non-revisionable to revisionable fails if it has non-revisionable fields stored in dedicated tables, however it doesn't appear the missing table in that issue is the result of the incorrect hashed table id, but it may be the result of not using the current table mapping correctly.

Proposed resolution

Changes the entity storage to use its internal definitions instead of the ones provided by the entity field manager.

Remaining tasks

#26.2
Review
Commit

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

Fix instances of ints passed to functions expecting strings

$
0
0

Problem/Motivation

This is a child issue of #3404246: Fix strict type errors detected by phpstan in order to reduce the scope.

The scope includes any issues detected by FunctionCallParametersCheck where the function is expecting a string but receiving an int.

Steps to reproduce

See the parent issue.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Some dialogs are difficult to scroll with keyboard

$
0
0

Problem/Motivation

If you have a long list of fields to scroll through and you don't want to filter them (maybe you don't remember the name) you can't use the keyboard (up/down/page up/page down) to scroll, unless you set focus to one of the Re-use buttons first.

Steps to reproduce

  • Open your browser at 1920x1080 or smaller
  • Install Drupal with demo_umami profile
  • Navigate to /admin/structure/types/manage/page/fields
  • Press "Re-use an existing field"
  • Click outside the "Filter by field or field type" textbox
  • Press the down arrow or page down key on your keyboard
  • Nothing happens

Proposed resolution

Maybe I need to adjust my habits. It's possible to scroll after pressing Shift+Tab from the first focused field. This sets focus to the .ui-dialog-content element instead of the .ui-dialog element. But this feels different to other forms, such as /node/add/article, where I can click outside a form element and then scroll the page. Attaching a video to demonstrate.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Improve X-Drupal-Cache and X-Drupal-Dynamic-Cache headers, even for responses that are not cacheable

$
0
0

Problem/Motivation

Currently if a response is not cacheable Drupal sets X-Drupal-Dynamic-Cache = UNCACHEABLE, but in some cases it does not. See DynamicPageCacheSubscriber::onResponse for details.

Steps to reproduce

NA

Proposed resolution

Always set X-Drupal-Dynamic-Cache header.

  1. This changes the existing X-Drupal-Dynamic-Cache: UNCACHEABLE to X-Drupal-Dynamic-Cache: UNCACHEABLE (poor cacheability).
  2. This adds X-Drupal-Dynamic-Cache: UNCACHEABLE (no cacheability) (for responses which aren't instances of CacheableResponseInterface).
  3. This adds X-Drupal-Dynamic-Cache: UNCACHEABLE (policy) (when the Dynamic Page Cache request/response policy tagged services deny caching).

This makes it much easier for developers to understand what the Dynamic Page Cache module is doing, and why.

Remaining tasks

Review

User interface changes

NA

API changes

NA

Data model changes

Don't think so

Release notes snippet

Page Cache & Dynamic Page Cache response headers improved to include more detail about the cacheability. See change record.

Wrong DRUPAL_ROOT with non-standard code structure

$
0
0

Problem/Motivation

When Drupal in installed in a non-standard installation structure, DRUPAL_ROOT is defined incorrectly and various parts of Drupal don't work.

This is important because the standard way of developing a Composer package, by defining a path repository in a project to symlink a git clone of the package, isn't currently possible with Drupal core.

Definitions

- project root: the folder where the root composer.json is
- app root (also drupal root): The folder where Drupal's entry-point index.php is. This is where the HTTP request to Drupal is made. Typically PROJECT_ROOT/web.
- scaffolding: The process which copies files into the app root when Drupal is installed with Composer. This is done by a Composer plugin within Drupal.
- Composer symlinking: The technique of using a 'path' repository for a package which points to a local git clone of the package. This causes Composer to symlink the package from the git clone into its location in the project. This is a method used to develop a package which needs to be used in the context of a Composer project -- such as Drupal core.

There are various kinds of installation structures for Drupal, depending on where and how Drupal core is installed:

- drupal/recommended-project: drupal scaffolded into the web/ folder.
- plain git clone of Drupal core, with `composer install` run at its root.
- drupal/legacy-project: drupal scaffolded into the project root.
- drupal core symlinked in by Composer, such as with the joachim-n/drupal-core-development-project Composer template. (This is the best way to develop a Composer package within a project -- see https://medium.com/pvtl/local-composer-package-development-47ac5c0e5bb4.)
- drupal installed in vendor/ - this is not possible because of other issues, and will not be fixed here, but this issue should aim to make DRUPAL_ROOT correct for this structure.

What causes the problem

We use Composer to install Drupal into the app root rather than /vendor, and Drupal
expects to find files like settings.php and extensions in the app root. Because of this, code in a Drupal project falls into several 'zones':

- Composer autoloader
- Composer vendor code
- Drupal core
- Drupal scaffolded files such as index.php and update.php
- Drupal settings, files, and extensions

These different zones don't all know how to get hold of code in the other zones:

- The autoloader always knows how to load Composer vendor code, and Drupal core code, because Composer installed it.
- Composer vendor code, e.g. Drush, knows the location of the Composer autoloader relative to itself, because it knows it's in vendor/foo/bar. But it has to make assumptions for the location of Drupal core or scaffolded files.
- Drupal core doesn't know the location of anything, because where it was installed is defined in composer.json. It has to make assumptions about how to get to the autoloader. It does that with a special autoload.php file at the root of the Drupal repository. (For the drupal/recommended-project template, an autoload.php is scaffolded into web/ so that it can go one level up and find the vendor folder. In drupal/legacy-project Drupal's include() loads the repository's autoload.php, and in drupal/recommended-project the same include() loads the scaffolded autoload.php.)
- Drupal core has to make assumptions about how to find its settings.
- Composer vendor code has to make assumptions about how to find Drupal settings. This affects things like Drush and Drupal Console.
- Drupal's scaffolded files can know about all code locations, since they are written by the scaffold plugin during Composer installation. During this process we can get the location of anything from Composer, and write it into the scaffolded files.
- Drupal settings.php file: knows the location of scaffolded index.php, as that is fixed relative to itself.

These assumptions all break in non-standard installation structures. In particular, the use of __DIR__ in these assumptions breaks when Drupal is symlinked into a project.

Fixing this is difficult because Drupal has MANY different entry points:

- HTTP request to the index.php file which is scaffolded into the app root
- HTTP request to scaffolded install.php
- HTTP request to scaffolded update.php
- HTTP request to core/rebuild.php, which is not scaffolded.
- tests run with phpunit
- tests run with run-tests.sh (this case doesn't really count, as run-tests.sh is only meant for Drupal CI, whose installation structure is a known quantity: see #3228531: document run-tests.sh as not intended for public consumption)
- code in a Composer package (e.g. Drush or Console) bookstraps Drupal
- scripts in core/scripts

Proposed resolution

Various approaches have been tried (see old branches in the issue fork). But ultimately, there's only one thing we can rely on: Composer knows the location of everything, because it installs everything.

Asking Composer runtime API every page load is potentially a performance hit, but it's simple to have Composer write a file containing the data we need during Composer installation.

So the plan is as follows:

1. For Composer vendor code which needs to find Drupal, have core's drupal/core-composer-scaffold Composer plugin write the locations class file into the plugin's own folder.

The file is written as a class, so that it can always be loaded by Composer. (Making it a plain file registered as a Composer autoload 'file' item causes problems with package dependency hierarchy.) This class currently only defines one constant, but #3208975: split the concept of DRUPAL_ROOT/app root into app root and Drupal web root could expand on that.

For cases where drupal/core-composer-scaffold is not installed, fall back on the existing behaviour for guessing the location of Drupal core.

Deprecate the $app_root parameter to DrupalKernel, since DrupalKernel uses the plugin.

2. For code in Drupal core which needs to get to the autoloader, replace all uses of __DIR__ with code which uses the actual path of the executed file. This is to prevent PHP from resolving symlinks.

Remaining tasks

See comment in the MR

API changes

- new functionality for drupal/core-composer-scaffold
- new DrupalLocations class, which 3rd party code can use to find Drupal's location
- DrupalKernel's $app_root parameter in various methods is deprecated
- DrupalKernel::guessApplicationRoot is deprecated and renamed. This is protected but Drush uses it, for instance.

Original summary

I usually link drupal inside my www directory like seen in the following ls output.
I think symlinking like that is not unusual, as it helps with version controlling of own projects.

core -> ../drupalcheckout/core
.htaccess
../drupalcheckout/index.php
../drupalcheckout/modules
profiles
robots.txt -> ../drupalcheckout/robots.txt
sites
themes -> ../drupalcheckout/themes

i've attached a script which will setup such an environment in the current directory.

With this setup BASE_ROOT in install.php will be set to the drupalcheckout directory.
Install then tries to find a settings.php in ../drupalcheckout/sites/default and not ./sites/default.

same Problem and fix should be considered for update.php and authorize.php

related discussions:
#1055856: Optimize settings.php discovery
#484554: Stop relying on Apache for determining the current path


"core/scripts/drupal install" should provide a --no-progress option

$
0
0

Problem/Motivation

For automated installations via CI or similar the progress output of core/scripts/drupal install is unnecessary and looks a bit strange, for example:

 0/17 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░]
Installing Drupal
 6/17 [▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░]
Set up database
 7/17 [▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░]
Set up database
 9/17 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░]
Install site
11/17 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░]
Configure site
12/17 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░]
Configure site
13/17 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░]
Congratulations, you installed Drupal!
17/17 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓]
Congratulations, you installed Drupal!

Steps to reproduce

Proposed resolution

There should be a --no-progress option, similar to other command-line tools such as Composer, PHPUnit, etc.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Improve developer experience for 10.3.x upgrade by informing where typed config fails

$
0
0

Problem/Motivation

assert($typed_config instanceof Mapping) in system.post_update.php gives a failure, but it is difficult for less experienced developers to know what caused that failure.

The failure is frequently caused by contributed modules and a quick search for 'assert($typed_config instanceof Mapping' in google reveals many modules have had this issue. Letting the developer know what the failure is could make the process much easier for them to find the culprit module.

Steps to reproduce

Attempt to run update database with a contrib module that fails this assertion

Proposed resolution

Add a description to the assertion

Remaining tasks

Review merge request
Backport to 10.3.x

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

None

Undefined array key "type" in Drupal\Core\Theme\ThemeManager->render()

$
0
0

Problem/Motivation

Found two warnings in dblog

Warning: Undefined array key "type" in Drupal\Core\Theme\ThemeManager->render() (Zeile 292 in html/core/lib/Drupal/Core/Theme/ThemeManager.php).:

Warning: Undefined array key "template" in Drupal\Core\Theme\ThemeManager->render() (Zeile 333 in html/core/lib/Drupal/Core/Theme/ThemeManager.php).:

Steps to reproduce

Don't remove from /html/sites/development.services.yml

  twig.config:
    debug: true
    auto_reload: true

part.

Proposed resolution

Use admin/config/development/settings instead

Fix issue with icon sizes

logic exception in Drupal\Core\Config\Schema\Mapp

$
0
0

Problem/Motivation

php      Error      LogicException: The mapping definition at
                                               `ckeditor5.plugin.ckeditor5_list:properties` is invalid: its `label`
                                               key contains a string. It must be an array. in
                                               Drupal\Core\Config\Schema\Mapp

Steps to reproduce

Since 10.3 upgrade

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Viewing all 291863 articles
Browse latest View live


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