Quantcast
Viewing all 296593 articles
Browse latest View live

claroAutocompleteTest passes, but log shows a 404

Problem/Motivation

core/tests/Drupal/Nightwatch/Tests/claroAutocompleteTest.js passes in our Nightwatch job on GitLab.
Yet, when we look at it's console log in the saved artifact after the test, we see:
"http://localhost/subdirectory/form-test/autocomplete-1?q=123 - Failed to load resource: the server responded with a status of 404 (Not Found)"

The original IS below already found the solution for the 404 problem:

In core/modules/system/tests/modules/form_test/form_test.routing.yml, how is it possible that these invalid route definitions (use of controller: with no underscore instead of _controller:) don't cause test failures when form_test is used in general and when the autocomplete test is performed in particular?

The test itself isn't affected by the 404. Since it's only testing the layout of the "processing" phase of the autocomplete, it doesn't need a response. In fact this situation is beneficial, since the "processing" phase is currently endless, due to the lack of any response that would end it.

Nevertheless, this is not code we want to have as an example in core.
Also, this form might be used elsewhere someday, by somebody expecting it to actually works.

So let's fix it.

Steps to reproduce

Go to the Nightwatch job of a GitLab CI run, browse the Job artifacts and under nightwatch_output/consoleLogs/Tests/claroAutocompleteTest find the JSON file.
It will contain the key message with value "http://localhost/subdirectory/form-test/autocomplete-1?q=123 - Failed to load resource: the server responded with a status of 404 (Not Found)".
I've attached an example JSON from a random run to the issue.

Proposed resolution

- Fix the invalid route definitions
- Test the return of the autocomplete in claroAutocompleteTest
- Add some comments in claroAutocompleteTest to explain what's actually being tested.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet


Field selection breaks conventions and increases cognitive load

Problem/Motivation

New version of field creation adds unnecessary clutter to the form and increases cognitive load for using the form. ThIs version also breaks conventions on basic html elements. With some changes the form's usability can be easily improved.

Cognitive (gestalt) principles involved are similarity, proximity and same container. The principles are known to take precedence by similarity being overridden by proximity and proximity overridden by same container.

Radio buttons

Radio buttons are based on similarity and proximity. When a radio buttons are placed far away from each other and especially if separated into visual containers the brain will not understand them to be related. Thus here they add visual clutter and cognitive strain by not matching familiar patterns.

First step before

Image may be NSFW.
Clik here to view.

Second step before

Image may be NSFW.
Clik here to view.

Overlapping options to be addressed in a follow-up #3410851: "Selection list" should be removed from field types and given as an option for "number" and "plain text"

Field types are not well defined and hiding the options details makes user unable to select the correct type without toggling between types to read the options descriptions. Especially selection list overlaps with plain text and number. For end user "selection list" is a display widget for contend that is either text, number or reference.

Image may be NSFW.
Clik here to view.
Field dialog GUI highlighting overlap of selectable items

Steps to reproduce

Proposed resolution

  1. Radio buttons should never be used unless they are aligned vertically.
    • Just visually hide the radio buttons and use the whole box to highlight the hover or selected item.
    • Instead of using input for field type, consider using HTML summary or html_tag for type and details containing radiobuttons for options. If we must have input value for type, then consider using hidden and set the correct one based on selected option. This should be logically possible because of the hierarchy/cadinality of types vs options.
  2. Increase the attention value of selected type and its option to form a group that is recognized as strongly connected items. This could be achieved by proximity (display options next to the selected type) or strong similarity (shape, color), this is eliminated with the use of the two step form as the second step makes a focused sub option approach.
  3. "Selection list" should be removed from field types and given as an option for "number" and "plain text" (would be addressed later in a follow up #3410851: "Selection list" should be removed from field types and given as an option for "number" and "plain text")

Text content for descriptions should be reviewed in a separate task.

Remaining tasks

  1. Reduce the distance between related options which was partially addressed by #3408326: Make field selection a two-step form , as we moved to a two step form.
  2. Convert the first step into using cards as clickable items to navigate to the sub-options.
  3. Vertically align all the options on the second step so they are easier to understand.
  4. Adjust the tests for the new UI experience.

User interface changes

First step after
Now uses clickable cards which navigate to the sub-options/field storage options.

Image may be NSFW.
Clik here to view.

Second step after
Now Vertically aligned for easier scanning.

Image may be NSFW.
Clik here to view.

API changes

Data model changes

Release notes snippet

Support IteratorArgument in \Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper::dumpValue

Problem/Motivation

Symfony services can have arrays as arguments. They can converted to \Symfony\Component\DependencyInjection\Argument\IteratorArgument by the ContainerBuilder. They are not supported by \Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper::dumpValue().

Proposed resolution

Convert \Symfony\Component\DependencyInjection\Argument\IteratorArgument to an array so we can dump it.

Remaining tasks

User interface changes

None

API changes

No change.

Data model changes

None

Handle redirects in opentelemetry tracing

Problem/Motivation

When a request that's recorded for Open Telemetry causes a redirect, like a form submission, PerformanceTestBase doesn't look for it, so time to first byte etc. looks a bit off. We should be able to check the performance log for a redirect and show that in the grafana UI in a sensible way.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Paragrah Custom Date field is not Sorting Properly in Views

Problem/Motivation

By Creating View for content listing with adding date field sorting, its not sorting properly

Steps to reproduce

Add Field with date field in paragraph add it to content type.
Create a view for content listing for same content type with date field column
Add a content with below dates

  1. 1-Jan-2023
  2. 3-Jan-2023
  3. 11-Jan-2023
  4. 4-Jan-2023

Add sorting in view for the date column.

Ascending sort will be coming below

  1. 1-Jan-2023
  2. 11-Jan-2023
  3. 3-Jan-2023
  4. 4-Jan-2023

Proposed resolution

Should be sort properly

  1. 1-Jan-2023
  2. 3-Jan-2023
  3. 4-Jan-2023
  4. 11-Jan-2023

Replace multiple test methods in InfoParserUnitTest with 1 testInfoException and a dataprovider

Problem/Motivation

In \Drupal\Tests\Core\Extension\InfoParserUnitTest we have at least 8 test methods that do that same thing

  1. Define a broken yml string
  2. Set 2 yml files to use this exact same string
  3. set an expected exception
  4. parse file 1 and make sure the exception is expected
  5. parse file 2 and make sure the exception is expected(only difference is file name)

Really these could all be 1 test method with dataprovider. Not all the current test methods do the double files but they would be better if they did.

Proposed resolution

Make a 1 test method testInfoException that has a dataprovider that covers all the cases by the current 8(or more) test methods.

This will the advantages of

  1. Being easier to add and review new test cases
  2. Make sure when we add test cases we don't forget anything like calling the parser 2x to make sure the static function doesn't affect the result(this happened originally)

Move the test cases used in these methods

  • testInfoParserMissingKeys
  • testMissingCoreVersionRequirement
  • testInfoParserMissingKey

to a new dataprovider providerInfoException used by new test method testInfoException. Then remove those methods.

Remaining tasks

Review, and Commit

User interface changes

API changes

Data model changes

Release notes snippet

Display the page title, even if "0" in olivero

Problem/Motivation

If a node is created with title "0" then it doesn't show up in olivero theme. It was fixed in #578400: Display the page title, even if "0" for Drupal 7.

Steps to reproduce

Use olivero theme and create a new node with title as "0". Title is not displayed.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Add symfony mailer transports to Dependency Injection Container

Problem/Motivation

Part of #1803948: [META] Adopt the symfony mailer component, adds symfony mailer and transports to the DIC. The scope of this issue is as follows:

Put the necessary services in place such that contrib and custom code can start using the mail delivery part of Symfony Mailer safely in test and in production code by simply retrieving / referencing a configured mailer service from / in the container.

  • As a developer I want to retrieve a configured mailer service from the container in order to submit an e-mail message. Whether or not the message is queued or delivered immediately is subject to the site configuration.
  • As a developer I want my service to reference a mailer service in order to submit an e-mail message. Whether or not the message is queued or delivered immediately is subject to the site configuration.
  • As a developer I want my service to reference a configured transport in order to submit an e-mail message which is delivered immediately.
  • As a developer I want that no mail leaves the system while executing functional and end-to-end tests.
  • As a developer I want to add a third-party transport factory with its own DSN (using a module).
  • As a developer I want to share modules providing third-party transports such that they can be used in combination with any Symfony Mailer based mail building contrib/custom module.
  • As a developer I want to start adding message event subscriber for each hook_mail_alter implementation early on so as to be prepared when users start to switch to the new mail system.

The following items are out of scope in this issue:

  • Service definitions for transports other than the ones included in the Transport directory of the Symfony Mailer component. In particular the transport factories provided under the Bridge are expected to be registered by custom or contrib modules and are out of scope.
  • As a site owner I want to send emails via the SMTP protocol without installing contrib modules.
  • As a site owner I want to send emails using the sendmail binary without installing contrib modules.
  • As a site owner I want that mail sent by my site is using appropriate origin headers (otherwise mail will be often marked as spam or fail delivery entirely). Extracted to #3397418: [PP-1] Ensure origin headers of mails sent using the mailer.transport service comply to RFC5322

Steps to reproduce

Proposed resolution

  1. Add mailer, transport and transport factory services in the same way as Symfony Framework Bundle:

    Add abstract an abstract transport factory service and actual transport factories for the four concrete built-in ones (null, native, sendmail, smtp):

      mailer.transport_factory.abstract:
        abstract: true
        class: Symfony\Component\Mailer\Transport\AbstractTransportFactory
        arguments:
          - '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface'
          - '@?Symfony\Contracts\HttpClient\HttpClientInterface'
          - '@logger.channel.mail'
      mailer.transport_factory.native:
        parent: mailer.transport_factory.abstract
        class: Symfony\Component\Mailer\Transport\NativeTransportFactory
        tags:
          - { name: mailer.transport_factory }
    [...]
    
  2. Collect services tagged with mailer.transport_factory and use them to construct the Symfony Transport facade. Register that in mailer.transport_factory (same service id as in Symfony Framework Bundle). Inject that into TransportFactoryAdapter which is used as a factory to construct the TransportInterface. Client code may retrieve / reference the mailer.transport service whenever it needs a configured transport.

    Note: Drupal doesn't store config in container params. Therefore an adapter is necessary which retrieves the system.mailmailer_dsn config before it delegates transport construction to the Symfony Transport facade.

      mailer.transport_factory_collection:
        class: Drupal\Core\Mailer\TransportFactoryCollection
        public: false
        tags:
          - { name: service_collector, tag: mailer.transport_factory, call: addTransportFactory }
      Drupal\Core\Mailer\TransportFactoryCollection: '@mailer.transport_factory_collection'
      mailer.transport_factory:
        class: Symfony\Component\Mailer\Transport
        arguments: ['@Drupal\Core\Mailer\TransportFactoryCollection']
      Symfony\Component\Mailer\Transport: '@mailer.transport_factory'
      mailer.transport_factory_adapter:
        class: Drupal\Core\Mailer\TransportFactoryAdapter
        autowire: true
        public: false
      Drupal\Core\Mailer\Transport\ConfiguredTransportFactoryInterface: '@mailer.transport_factory_adapter'
      mailer.transport:
        class: Symfony\Component\Mailer\Transport\TransportInterface
        factory: ['@Drupal\Core\Mailer\Transport\ConfiguredTransportFactoryInterface', 'createTransport']
      Symfony\Component\Mailer\Transport\TransportInterface: '@mailer.transport'
  3. Add the mailer.mailer service in a way which uses Symfony messenger automatically if available.
      mailer.messenger.message_handler:
        class: Symfony\Component\Mailer\Messenger\MessageHandler
        autowire: true
        public: false
        tags:
          - { name: messenger.message_handler }
      mailer.mailer:
        class: Symfony\Component\Mailer\Mailer
        arguments:
          - '@Symfony\Component\Mailer\Transport\TransportInterface'
          - '@?Symfony\Component\Messenger\MessageBusInterface'
          - '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface'
      Symfony\Component\Mailer\MailerInterface: '@mailer.mailer'

Contrib and custom modules providing third-party transports supply their own service tagged with the mailer.transport_factory tag, deriving from the abstract transport class.

Note: Symfony mailer provides many transports integrating with third-party providers. Products are rebranded, companies merge and split and they do certainly not respect the release cycle of Symfony or Drupal. Also some third-party transports will pull in additional dependencies (e.g. symfony/http-client). Hence, core should avoid exposing those transports directly and instead leave that to contrib or custom code.

Remaining tasks

User interface changes

API changes

API additions:

  • Service: mailer.mailer implementing Symfony\Component\Mailer\MailerInterface:
    Custom and contrib modules may use this service to pass mails to the mail delivery layer. This is the main entry point.
  • Service: mailer.transport implementing Symfony\Component\Mailer\Transport\TransportInterface:
    Custom and contrib modules may use this service to directly inject mails to the configured mail transport for delivery. This will skip Symfony messenger (if configured). This should only be necessary in advanced use cases.
  • Service: mailer.transport_factory_adapter implementing Drupal\Core\Mailer\Transport\ConfiguredTransportFactoryInterface:
    Custom and contrib modules may decorate or replace this service in order to customize construction of mailer.transport. This should only be necessary in advanced use cases. E.g., if certain messages are sent via dedicated transports.
  • Service: mailer.transport_factory, the Symfony\Component\Mailer\Transport facade:
    Custom and contrib modules may use methods such as fromString() or fromDsnObject() to construct custom transports. This is for advanced use cases as well, the regular way of constructing transports is by retrieving mailer.mailer service.
  • Events MessageEvent, SentMessageEvent and FailedMessageEvent:
    Custom and contrib modules may register event subscribers to act on emails before and after they are sent.
  • Abstract service mailer.transport_factory.abstract and service tag mailer.transport_factory:
    Custom and contrib modules may supply third-party or custom transport factories using mailer.transport_factory.abstract as their parent service, tagged with mailer.transport_factory and typically with Symfony\Component\Mailer\Transport\AbstractTransportFactory as their parent class.
  • The mailer_sendmail_commands setting:
    An array of command lines which are allowed as the command option in the sendmail transport.

API examples:

There is a Sandbox with examples demonstrating how custom / contrib is supposed to use this API.

Architectural aspects

Code location (lib/Drupal/Core/Mailer vs modules/mailer)

Various options have been investigated in order to decide where to put production code.

Pro lib:

  • A mailer component will very likely end up in lib. Essential core modules like user and system require a mailer.
  • Moving classes from a mailer module to core once they are ready is cumbersome. Thus, let's put them in lib from the beginning.

Pro module:

  • A mailer module can be marked experimental. That way it is possible to iterate on the code base without having to add BC layers from the very beginning.

Outcome:. A hybrid approach: Place mailer component directly in core and mark them internal. Register the services from within an experimental mailer module. That way the core classes don't need to be relocated. Going stable means just removing the internal flag from core classes and moving tests and service definitions into core.

Transport construction (mailer.transport service vs ad-hoc creation)

Various options have been investigated on how client code is supposed to create some instance of a TransportInterface. All currently existing Symfony Mailer integrations in contrib create an instance of TransportInterface in an ad-hoc manner whenever one is needed. The Symfony Framework Bundle on the other hand registers a mailer.transports service in the container. It uses the ['@mailer.transport_factory', 'fromStrings'] as a factory method, the transport-DSN map is injected from a container parameter.

Pro mailer.transport service

  • Other symfony components depend on a mailer transport being available from the container. E.g., the MessageHandler (used by the Symfony messenger component) passes an email message directly to the transport (from within a message queue).
  • Some advanced transports maintain state (e.g., RoundRobinTransport). If a transport is created ad-hoc for every mail, that state is lost between invocations. If a transport instance is kept in the container, the same instance is used for subsequent mails.

Pro ad-hoc:

  • Easier to implement with less services. (The Symfony mailer Transport facade doesn't work very well with the way Drupal is configured)

Outcome: Current implementation makes a TransportInterface instance available in the container (service id mailer.transport).

Data model changes

Release notes snippet


Adopt PluginExists validator in relevant places

Problem/Motivation

#2920682: Add config validation for plugin IDs added the PluginExists constraint and used it in 2 places.

There are many more places where we need to use this.

StatusManagerSchemaInterface
In patchplugin.manager.actionaction.configuration.\Drupal\Core\Action\ActionInterface
N/Aplugin.manager.archiver
Doneplugin.manager.block
N/Aplugin.manager.ckeditor
In patchplugin.manager.conditioncondition.plugin.\Drupal\Core\Condition\ConditionInterface
N/Aplugin.manager.config_translation.mapper
In patchplugin.manager.core.layoutlayout_plugin.settings.\Drupal\Core\Layout\LayoutInterface
N/Aplugin.manager.display_variant
Doneplugin.manager.editor
N/Aplugin.manager.element_info
In patchplugin.manager.entity_reference_selectionfield.field_settings.entity_reference\Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
In patchplugin.manager.field.field_typefield_config_base., field.storage.*.*.\Drupal\Core\Field\FieldItemInterface
In patchplugin.manager.field.formatterfield_formatter.\Drupal\Core\Field\FormatterInterface
In patchplugin.manager.field.widgetcore.entity_form_display.*.*.*\Drupal\Core\Field\WidgetInterface
In patchplugin.manager.filter
N/Aplugin.manager.help_section
N/Aplugin.manager.help_section_topics
N/Aplugin.manager.help_topic
In patchplugin.manager.image.effectimage.style.effects.\Drupal\image\ImageEffectInterface
N/Aplugin.manager.language_negotiation_method
N/Aplugin.manager.layout_builder.section_storage
N/Aplugin.manager.link_relation_type
In patchplugin.manager.mailsystem.mail.\Drupal\Core\Mail\MailInterface
In patchplugin.manager.media.sourcemedia.type.\Drupal\media\MediaSourceInterface
N/Aplugin.manager.menu.contextual_link
N/Aplugin.manager.menu.link
N/Aplugin.manager.menu.local_action
N/Aplugin.manager.menu.local_task
N/Aplugin.manager.migrate.destination
N/Aplugin.manager.migrate.field
N/Aplugin.manager.migrate.id_map
N/Aplugin.manager.migrate.process
N/Aplugin.manager.migrate.source
N/Aplugin.manager.migration
N/Aplugin.manager.queue_worker
In patchplugin.manager.rest
In patchplugin.manager.searchsearch.page.Drupal\search\Plugin\SearchInterface
In patchplugin.manager.tour.tiptour.tip.\Drupal\tour\TipPluginInterface
In patchplugin.manager.views.accessviews_display.
In patchplugin.manager.views.area
In patchplugin.manager.views.argument
In patchplugin.manager.views.argument_defaultviews_argument.
In patchplugin.manager.views.argument_validatorviews_argument.
In patchplugin.manager.views.cacheviews_display.
In patchplugin.manager.views.displayviews.view.*
plugin.manager.views.display_extender
In patchplugin.manager.views.exposed_formviews.display.
In patchplugin.manager.views.field
In patchplugin.manager.views.filter
N/Aplugin.manager.views.join
In patchplugin.manager.views.pager
In patchplugin.manager.views.queryviews_display.
In patchplugin.manager.views.relationshipviews_relationship.
In patchplugin.manager.views.rowviews_display.
In patchplugin.manager.views.sort
In patchplugin.manager.views.styleviews_display.
N/Aplugin.manager.views.wizard
In patchplugin.manager.workflows.typeworkflows.workflow.*\Drupal\workflows\WorkflowTypeInterface

Steps to reproduce

Proposed resolution

  1. Adopt it in all relevant places.
  2. Write test that verifies that all default config in Drupal core complies with the validation constraints, by adding a new testValidity() method to \Drupal\KernelTests\Core\Config\DefaultConfigTest

Add return types to SessionHandler

Problem/Motivation

Follow up from #3377256-27: Correctly implement SessionHandlerInterface from @catch

I feel like we could probably check if contrib extends this class, and then go ahead and add return types in a minor release, based on the fact that non-base-classes are not considered @api (per https://www.drupal.org/about/core/policies/core-change-policies/bc-polic...).

As per @quietone in #3377256-28: Correctly implement SessionHandlerInterface

A search for SessionHanlder in contrib didn't find any case where it was extended.

Steps to reproduce

Proposed resolution

Remove #[\ReturnTypeWillChange] attribute and add return types to session handler methods.

Remaining tasks

User interface changes

API changes

The SessionHandler class uses the correct PHP \SessionHandlerInterface method signatures for return types.

Note: This will break subclasses of SessionHandler if they do not specify the correct return types. However, since non-base classes are not considered public API, this isn't considered a BC break. Also a code search revealed no subclass of SessionHandler in contrib.

Data model changes

Release notes snippet

Fix taxonomy_settings migration: it's currently generating incomplete config

Problem/Motivation

Quoting #3412084-16: Follow-up for #3364109: opt in already validatable simple config to FullyValidatable:

The taxonomy_settings migration: it was generating incomplete Drupal 8/9/10 config since the day it was introduced (#2154955: Migrate variables to config in 2014), because taxonomy.settings:maintain_index_table has existed since 2009 in Drupal 7 (see #412518: Convert taxonomy_node_* related code to use field API + upgrade path), its configuration schema was introduced in #1919208: Create configuration schemas for taxonomy module in 2013. But … it was not set by default: its absence was treated as taxonomy_maintain_index_table === TRUE.

Steps to reproduce

N/A

Proposed resolution

Fix the taxonomy_settings migration.

Remaining tasks

User interface changes

None.

API changes

None.

Data model changes

None.

Release notes snippet

None.

Allow to select reference method in link field type for internal links

Problem/Motivation

As link widget for internal links allows to have entity reference autocomplete, it would be nice to have opportunity to select the reference method the same way as it is possible for entity reference field. This way it would be possible to easily find content that is needed using, for example, views entity reference handler.

Steps to reproduce

Standard Drupal installation, article content type, add link field allowing both internal and external links or only internal.

Proposed resolution

Add 'handler' and 'handler_settings' field settings to link field type.

Remaining tasks

Patch needs an update
Before after screenshots in the IS or linked
CR update

User interface changes

Field settings for link field type would have "Reference method" setting, the same as entity reference field.

API changes

None

Data model changes

None

Release notes snippet

Views Rendered Entity field adding unneeded entity display cache tags

Problem/Motivation

The Rendered entity field adds cache tags for a all entity display config entities associated with the entity type of the rendered entity. In other words, if the content (node) view is configured to display a Rendered entity field, the cache tags for all configured entity view displays for node types will be added to the view/view display config's cache metadata. On a site with many content types and entity displays/view modes, this will bubble up all those cache tags on pages where the view is rendered. This can lead to errors such as #2844620: FinishResponseSubscriber: Need warning/error when headers exceed 16k.

Since rendering the entity will bubble up cache tags that are invalidated whenever entity view displays are saved, it is not necessary for the Rendered Entity plugin to include cache tags for the entity view displays in getCacheTags() at all.

Steps to reproduce

  1. Create a few different content types
  2. Create a few different view modes for content
  3. Configure custom displays for some view modes across content types
  4. Create and configure a view to display content with a Rendered entity field. Add a filter for a single content type
  5. Create test content that will be displayed in the view
  6. Visit page with the view.
  7. If http.response.debug_cacheability_headers is true, note that there are tags in the HTTP header for all configured node entity displays.
  8. Alternatively check the relevant entry in the cache_page database table and observe the tags there

Proposed resolution

Change getCacheTags() in \Drupal\views\Plugin\views\field\RenderedEntity to return an empty array.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Disabled text formats can't be seen in the GUI

Problem/Motivation

When you disable a text format it is not possible to re-enable it. This seems counter to the behavior in other situations, such as Views, which allows disabling than re-enabling a display. Furthermore, it can lead to major problems on a site if a text format was mistakenly disabled.

Steps to reproduce

Disable a text format and experience the disappointment upon realizing it can't be re-enabled. You'd need to create a new text format (yet can't create one with the same machine name), then change all items previously using the old one to use the new one.

Proposed resolution

Add an "Enable" operation for disabled text formats, which can be used to re-enable the disabled text format.
Image may be NSFW.
Clik here to view.

Remaining tasks

Code review

User interface changes

The "Enable" operation is available to disabled text formats

API changes

Data model changes

Release notes snippet

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue categoryBug because of unexpected behaviour. Upon disabling the text format it disappears from the form which makes it seem deleted, but it isn't actually deleted because you can't add a new text format with the same machine name.
Issue priorityMajor because as cilefen states in #19:

Actually, there is no workaround for GUI users (imagine "I want my text format back!"), so this is major.

Prioritized changesThe main goal of this issue is two-fold, fixing a DrupalWTF bug and improving usability.
DisruptionNon-disruptive because only the filter format admin interface is changed. No API changes

Add a vendor:// stream wrapper

Blocked by: #2873160: Implement core management of 3rd-party FE libraries

Drupal 8 integration with composer has been excellent for managing 3rd party PHP libraries with Drupal, as the libraries can be called using PSR-4 namespaces to load the libraries, regardless of the location of the vendor folder. Being able to call these files regardless of the location of the vendor folder is important, as the vendor library folder location is dynamic. Many installations have the vendor folder installed in the webroot, however it is a best practice to place the vendor folder outside the webroot, a practice followed by the Drupal Composer template,

The problem comes with CSS and JS libraries. These can be included using composer, but when the vendor file is outside the webroot, any CSS and JS are unusable, as they are not web-accessible and therefore cannot be included in *.libraries.yml files.

For contributed module developers, this has led to two separate methods of managing 3rd party libraries with Drupal 8. PHP libraries can and are managed with Composer, and module developers can use composer.json files to manage their dependencies. However, modules that use 3rd party CSS/JS libraries have to either use D7 methods of creating a libraries folder, and have users manage the dependencies on their own to place the library in a web-accessible location, or use Composer to manage the dependency, then have users copy the CSS and JS files to a web accessible location. An example of this is the jQuery Colorpicker module, which as of the time of writing of this post requires users to manage the library on their own, downloading it to a /libraries folder, linking to the CSS and JS files using:

library:
  version: 1.0.1
  css:
    theme:
      /libraries/jquery_colorpicker/css/colorpicker.css: {}
  js:
    /libraries/jquery_colorpicker/js/colorpicker.js: {}
  dependencies:
    - core/jquery

As you can see, the CSS and JS files are linked to from the /libraries folder. In order to ensure system integrity, hook_requirements() has been implemented, informing users of the requirement of downloading the library and providing instructions on how to do so. This is not ideal. The ideal would be to Include a dependency on the library through Composer, managing the 3rd party library in the same manner as PHP libraries are managed.

The solution to the issue of managing 3rd party CSS and JS libraries with Composer is to use the Vendor Stream Wrapper module. This module is essentially a clone of the private stream wrapper functionality of core, but working with the vendor directory rather than the private files directory. It sets up a vendor:// stream wrapper, and adds parsing to *.libraries.yml files, so that the above jquery_colorpicker.libraries.yml file could be converted to this:

library:
  version: 1.0.1
  css:
    theme:
      vendor://jaypan/jquery_colorpicker/css/colorpicker.css: {}
  js:
    vendor://jaypan/jquery_colorpicker/js/colorpicker.js: {}
  dependencies:
    - core/jquery

The module looks for the vendor folder first in the webroot, then one folder above the webroot. If the vendor folder is in any other location, the location can be set in settings.php.

I think this module should be included into core, to allow for Drupal modules to manage CSS and JS libraries using Composer, unifying 3rd party library management into a single API, rather than having to use D8 methodology for PHP libraries, and D7 methodology for managing CSS and JS libraries. Currently it is a bug that CSS and JS files in a vendor folder that exists outside the webroot are unable to be linked to, and it becomes a security risk if one of the files that is part of the 3rd party library is found to have a security vulnerability. This security vulnerability would not exist for users who have placed their library in a vendor folder that is outside the webroot.


[Meta] Tasks to deprecate Tour module

Problem/Motivation

Track the steps needed to remove extension Tour from core to contrib. See Remove a core module and move it to a contributed project of the deprecation policy.

The removal of extension Tour was approved in #3325445: [Policy] Remove tour module from core

Remaining tasks

  1. Begin finding someone to maintain the contrib version of the extension. The contrib Tour project is ready with smustgrave as maintainer.
  2. Move integrations implemented by other modules to the extension.
    Create child issues or child meta issues, as needed, to address the following points. Not all points will apply to all extensions.
  3. Do a thorough search of core for any remaining references to the extension. If references are found, outside of the extension, then create issues to remove the references.
  4. Create the contrib project with a stable release.
  5. Deprecate the core extension. #3405672: Deprecate Tour module

Add stream wrappers to access extension files

Problem/Motivation

Starting from #2351919: Replace uses of drupal_get_path() with __DIR__ where possible, when the PHP code needs to include or parse files inside the module or theme directory space, will simply use _DIR_ instead of drupal_get_path(). This is sufficient, intuitive and more performant than calling drupal_get_path().

However, drupal_get_path() is widely used to refer files (.js, .css, images, assets) outside a module or theme. This isn't very intuitive for new developers. Stream wrappers make much more sense and simplify the API for developers trying to refer directories or files from outside the current extension in code.

Proposed resolution

Introduce extension stream wrappers:

SchemeDescription
profile://Points to the installed profile root directory.
module://{name}Points to the module {name} root directory. Only enabled modules can be referred.
theme://{name}Points to the theme {name} root directory. Only installed themes can be referred.

Examples

Profile: profile://

Assuming the standard profile is installed:

  • Referring a directory:
    • Actual: drupal_get_path('profile', 'standard') . '/config'
    • Proposed: profile://config
    • Path: core/profiles/standard/config
  • Referring a file:
    • Actual: drupal_get_path('profile', 'standard') . '/config/install/automated_cron.settings.yml'
    • Proposed: profile://config/install/automated_cron.settings.yml
    • Path: core/profiles/standard/config/install/automated_cron.settings.yml

Module: module://

Assuming the node module is enabled but color module is not:

  • Referring a directory:
    • Actual: drupal_get_path('module', 'node') . '/config'
    • Proposed: module://node/config
    • Path: core/modules/node/config
  • Referring a file:
    • Actual: drupal_get_path('module', 'node') . '/config/install/node.settings.yml'
    • Proposed: module://node/config/install/node.settings.yml
    • Path: core/modules/node/config/install/node.settings.yml
  • Referring a resource in a uninstalled or inexistent module:
    • Actual: drupal_get_path('module', 'color') . '/config'
    • Proposed: module://color/config
    • Path: Throws \RuntimeException

Theme: theme://

Assuming the bartik theme is installed but seven theme is not:

  • Referring a directory
    • Actual: drupal_get_path('theme', 'bartik') . '/config'
    • Proposed: theme://bartik/config
    • Path: core/themes/bartik/config
  • Referring a file
    • Actual: drupal_get_path('theme', 'bartik') . '/color/color.inc'
    • Proposed: theme://bartik/color/color.inc
    • Path: core/themes/bartik/color/color.inc
  • Referring a resource in a uninstalled or inexistent theme:
    • Actual: drupal_get_path('theme', 'seven') . '/config'
    • Proposed: theme://seven/config
    • Path: Throws \RuntimeException

Remaining tasks

  1. Profiling to compare performance of the new code with the old.

API changes

New abstract class for extensions stream wrappers:

  • \Drupal\Core\StreamWrapper\ExtensionStreamBase

New stream wrapper classes:

  • \Drupal\Core\StreamWrapper\ModuleStream
  • \Drupal\Core\StreamWrapper\ThemeStream
  • \Drupal\Core\StreamWrapper\ProfileStream

Data model changes

None.

Deprecated function: preg_quote(): Passing null to parameter #1 ($str)

Problem/Motivation

Deprecated function: preg_quote(): Passing null to parameter #1 ($str) of type string is deprecated in Drupal\Core\Path\PathMatcher->matchPath() (line 82 of core/lib/Drupal/Core/Path/PathMatcher.php). I

Steps to reproduce

I get this o n every site page since today's update to 9.5.0 (but have not looked lately)

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

10.2.0 database update failes with "Error: Call to a member function getConfigDependencyName() on null"

Problem/Motivation

When running the database update script after updating from 10.1.7 to 10.2.0 I get the following error:

In ProcessBase.php line 171:
                                                                                                          
  Unable to decode output into JSON: Syntax error                                                         
                                                                                                          
  Error: Call to a member function getConfigDependencyName() on null in Drupal\editor\Entity\Editor->cal  
  culateDependencies() (line 122 of ../web/core/modules/editor/src/Entity/Edit  
  or.php). 

Can anyone help me? Thank you very much!

[PP-1] Nightwatch output on GitLab not easily readable

Problem/Motivation

The output of the nightwatch job on GitLab CI is not easily readable.

After the first test, the output seems to lack newlines:

┌ ────────────────── ✔  default: Tests/toolbarApiTest.js  ─────────────────────┐│                                                                              ││                                                                              ││   [Tests/Toolbar Api Test] Test Suite                                        ││   ──────────────────────────────────────────────────────────────────────     ││   Using: chrome (106.0.5249.103) on LINUX.                                   ││   - Loading url: http://localhost/subdirectory                               ││   ℹ Loaded url http://localhost/subdirectory in 3603ms                       ││   - Loading url: http://localhost/subdirectory/user/reset/1/1699769393/rAx   ││   XXMRqoilkKkm9F1ftirF9ByGekM_5ilpoeJ7cOds/login                             ││   ℹ Loaded url http://localhost/subdirectory/user/reset/1/1699769393/rAxXX   ││   MRqoilkKkm9F1ftirF9ByGekM_5ilpoeJ7cOds/login                               ││   in 1284ms                                                                  ││   - Loading url: http://localhost/subdirectory/admin/modules                 ││   ℹ Loaded url http://localhost/subdirectory/admin/modules in 1468ms         ││   ✔ Element <form.system-modules [name="modules[toolbar][enable]"]> was      ││   visible after 25 milliseconds.                                             ││   ✔ Element <#system-modules-confirm-form> was present after 1542            ││   milliseconds.                                                              ││   ✔ Element <form.system-modules                                             ││   [name="modules[toolbar][enable]"]:disabled> was present after 45           ││   milliseconds.                                                              ││   - Loading url: http://localhost/subdirectory/user/logout                   ││   ℹ Loaded url http://localhost/subdirectory/user/logout in 245ms            ││   - Loading url: http://localhost/subdirectory/user/reset/1/1699769407/C9F   ││   cHTHML3hD-dyWjgTiXgMSfGlriQJUzj-FSH0GTeE/login                             ││   ℹ Loaded url http://localhost/subdirectory/user/reset/1/1699769407/C9FcH   ││   THML3hD-dyWjgTiXgMSfGlriQJUzj-FSH0GTeE/login                               ││   in 356ms                                                                   ││   - Loading url: http://localhost/subdirectory/admin/people/roles/add        ││   ℹ Loaded url http://localhost/subdirectory/admin/people/roles/add in       ││   421ms                                                                      ││   ✔ Expected element <.user-role-form .machine-name-value> to be visible     ││   in 2000ms (67ms)                                                           ││   - Loading url: http://localhost/subdirectory/admin/people/permissions      ││   ℹ Loaded url http://localhost/subdirectory/admin/people/permissions in     ││   1883ms                                                                     ││   - Loading url: http://localhost/subdirectory/admin/people/permissions      ││   ℹ Loaded url http://localhost/subdirectory/admin/people/permissions in     ││   731ms                                                                      ││   - Loading url: http://localhost/subdirectory/user/logout                   ││   ℹ Loaded url http://localhost/subdirectory/user/logout in 164ms            ││   - Loading url: http://localhost/subdirectory/user/reset/1/1699769414/I2A   ││   V9n1kyOJ9KG70PnB6GJG7qr9sFcw9Ei6gT-6rqNI/login                             ││   ℹ Loaded url http://localhost/subdirectory/user/reset/1/1699769414/I2AV9   ││   n1kyOJ9KG70PnB6GJG7qr9sFcw9Ei6gT-6rqNI/login                               ││   in 269ms                                                                   ││   - Loading url: http://localhost/subdirectory/admin/people/create           ││   ℹ Loaded url http://localhost/subdirectory/admin/people/create in 389ms    ││   ✔ User "user" was created successfully (723ms)                             ││   (node:117) MaxListenersExceededWarning: Possible EventEmitter memory       ││   leak detected. 11 error listeners added to [CommandLoader]. Use            ││   emitter.setMaxListeners() to increase limit                                ││   (Use `node --trace-warnings ...` to show where the warning was created)    ││   - Loading url: http://localhost/subdirectory/user/logout                   ││   ℹ Loaded url http://localhost/subdirectory/user/logout in 145ms            ││   - Loading url: http://localhost/subdirectory/user/login                    ││   ℹ Loaded url http://localhost/subdirectory/user/login in 102ms             ││   (node:117) MaxListenersExceededWarning: Possible EventEmitter memory       ││   leak detected. 11 error listeners added to [CommandLoader]. Use            ││   emitter.setMaxListeners() to increase limit                                ││   ✔ Passed [equal]: The user "user" was logged in.                           ││                                                                              ││   – Drupal.Toolbar.models                                                    ││   - Loading url: http://localhost/subdirectory/                              ││   ℹ Loaded url http://localhost/subdirectory/ in 267ms                       ││   ✔ Element <#toolbar-administration> was present after 18 milliseconds.     ││   ✔ Passed [deepEqual]: Keys to check match                                  ││   ✔ Passed [equal]: has menu model                                           ││   ✔ Passed [equal]: menu model is an object                                  ││   ✔ Passed [equal]: has toolbar model                                        ││   ✔ Passed [equal]: toolbar model is an object                               ││   ✔ Passed [equal]: get("activeTab") has expected result                     ││   ✔ Passed [equal]: get("activeTray") has expected result                    ││   ✔ Passed [equal]: get("isOriented") has expected result                    ││   ✔ Passed [equal]: get("isFixed") has expected result                       ││   ✔ Passed [equal]: get("areSubtreesLoaded") has expected result             ││   ✔ Passed [equal]: get("isViewportOverflowConstrained") has expected        ││   result                                                                     ││   ✔ Passed [equal]: get("orientation") has expected result                   ││   ✔ Passed [equal]: get("locked") has expected result                        ││   ✔ Passed [equal]: get("isTrayToggleVisible") has expected result           ││   ✔ Passed [equal]: get("height") has expected result                        ││   ✔ Passed [equal]: get("offsets") bottom has expected result                ││   ✔ Passed [equal]: get("offsets") left has expected result                  ││   ✔ Passed [equal]: get("offsets") right has expected result                 ││   ✔ Passed [equal]: get("offsets") top has expected result                   ││   ✔ Passed [equal]: get("subtrees") has expected result                      ││   ✔ default: Tests/toolbarApiTest.js [Tests/Toolbar Api Test]                ││   Drupal.Toolbar.models (471ms)                                              ││                                                                              ││   – Change tab                                                               ││   - Loading url: http://localhost/subdirectory/                              ││   ℹ Loaded url http://localhost/subdirectory/ in 185ms                       ││   ✔ Element <#toolbar-administration> was present after 14 milliseconds.     ││   ✔ Passed [deepEqual]: Keys to check match                                  ││   ✔ Passed [equal]: has menu model                                           ││   ✔ Passed [equal]: menu model is an object                                  ││   ✔ Passed [equal]: has toolbar model                                        ││   ✔ Passed [equal]: toolbar model is an object                               ││   ✔ Passed [equal]: get("activeTab") has expected result                     ││   ✔ Passed [equal]: get("activeTray") has expected result                    ││   ✔ default: Tests/toolbarApiTest.js [Tests/Toolbar Api Test] Change tab     ││   (577ms)                                                                    ││                                                                              ││   – Change orientation                                                       ││   - Loading url: http://localhost/subdirectory/                              ││   ℹ Loaded url http://localhost/subdirectory/ in 227ms                       ││   ✔ Element <#toolbar-administration> was present after 42 milliseconds.     ││   ✔ Passed [deepEqual]: Keys to check match                                  ││   ✔ Passed [equal]: get("orientation") has expected result                   ││   ✔ Passed [equal]: changing orientation has expected result                 ││   ✔ default: Tests/toolbarApiTest.js [Tests/Toolbar Api Test] Change         ││   orientation (587ms)                                                        ││                                                                              ││   – Open submenu                                                             ││   - Loading url: http://localhost/subdirectory/                              ││   ℹ Loaded url http://localhost/subdirectory/ in 243ms                       ││   ✔ Element <#toolbar-administration> was present after 21 milliseconds.     ││   ✔ Passed [deepEqual]: Keys to check match                                  ││   ✔ Passed [equal]: get("orientation") has expected result                   ││   ✔ Passed [equal]: opening submenu has expected result                      ││   ✔ default: Tests/toolbarApiTest.js [Tests/Toolbar Api Test] Open submenu   ││   (695ms)                                                                    ││                                                                              │└──────────────────────────────────────────────────────────────────────────────┘

https://git.drupalcode.org/project/drupal/-/jobs/316331#L149 (Yes, this is all just one output line...)
Screenshot here: https://www.drupal.org/files/issues/2023-11-12/before.jpg

Problem comes out of a dependency of nightwatch called boxen (https://www.npmjs.com/package/boxen).

This was fixed in version 7.0.1, however nightwatch is (and also will be in 3.x) using 5.1.2.

Fix PR is here: https://github.com/sindresorhus/boxen/pull/81

Steps to reproduce

Proposed resolution

viewing the source of boxen implies we might be able to use the COLUMNS environment variable to trick it into printing newlines.

@longwave in #14

Also turn off the very verbose output to keep all the tests visible in the GitLab output window-thingy

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Viewing all 296593 articles
Browse latest View live


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