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

Change PluginNotFoundException to an error message when not use the plugin

$
0
0

Problem/Motivation

When user update drupal, they often get a fatal error PluginNotFoundException,
it is a fatal error , prevent user visit the modules page, which prevent them install a new module that can fix the PluginNotFoundException.

Maybe drupal core can do it very well to prevent this case. But there are so many contributed modules, many of them provide custom plugin type, and may make changes to their plugins. When user update it, get a fatal error.

Only throw PluginNotFoundException when use it, other case show user an error message instead.


Fix the deprecation URL for #3356894 and #3372097

$
0
0

Problem/Motivation

The CRs of #3356894: Make field selection less overwhelming by introducing groups and #3372097: Consider replacing hook_field_type_category_info with YML based plugin discovery were merged into because they are sequential changes of the same feature an someone trying to understand what has been changes should reconstruct the development process as both issues were delivered in 10.2.

So, one CR (https://www.drupal.org/node/3364271) has been deleted and the other contains both changes. But the https://www.drupal.org/node/3364271 is now 404

Steps to reproduce

Go to https://www.drupal.org/node/3364271 (which is the URL from the deprecation message)

Proposed resolution

Fix the deprecation message

Remaining tasks

None.

User interface changes

None.

API changes

None.

Data model changes

None.

Release notes snippet

None.

InvalidArgumentException: Invalid translation language specified.

$
0
0

Problem/Motivation

Drupal throws a fatal error when trying to add a translation to entity which already has a translation on given language.

Original report:
This error occurred when adding an English translation of a German article (node/2/translations/add/de/en):

InvalidArgumentException: Invalid translation language (en) specified. in Drupal\Core\Entity\ContentEntityBase->addTranslation() (line 691 of core\lib\Drupal\Core\Entity\ContentEntityBase.php).

Steps to reproduce

  1. Install using standard profile in English
  2. Log in as a user with "translate any entity" permission - user 1 will do
  3. Create an English article node
  4. Install Content Translation module
  5. Add German language
  6. Enable content translation for article nodes with the default settings
  7. Go to de/node/1/translations/add/en/de and add a translation
  8. Go back to de/node/1/translations/add/en/de
  9. You will get a fatal error

or

  1. Go to content admin and use the filters to find the node I want to translate. Click its Translation operation link.
  2. Add a French translation and save it. This takes me back to the content admin page.
  3. Wait, I forgot to change something! But I can't see my node any more as it's not in the first page of results. I know, I'll just press Back and that'll get me back to the form I was just at, right?
  4. BOOM.

Note there may be other ways to reproduce this such as unchecking Create new revision in the node and translation.

Proposed resolution

Redirect to the translation overview page.

Remaining tasks

  1. Create patch with test
  2. Decide on where to send the user
  3. Review
  4. Commit

User interface changes

API changes

User can't reference unpublished content even when they have access to it

$
0
0

Problem/Motivation

User gets an error when trying to reference an unpublished entity that they have just created and that he has full access to. This basically makes it impossible for a user to submit a set of unpublished interreferencing entities (e.g. artefact/architect/city).

Steps to reproduce:

  1. Create content type A, make sure Published is unchecked in the Publishing options.
  2. Create content type B, add an ER field referencing A, choose Autocomplete widget in Form display.
  3. Create a test user, give permissions to View own unpublished content, to Create A and B, to Edit own A and B.
  4. Log in as that user.
  5. Create a test node of type A, verify that it is Unpublished and the user can see it.
  6. Create a test node of type B, start typing the label of the A node just created, verify that it's not recognised and suggested by the system.
  7. Type the complete label and hit Save, get the "No such entity" error.
  8. Type the entity label followed by its nid in parentheses, still get the "This entity (node: N) cannot be referenced”

This issue also prevents the user w/ appropriate permissions from referencing unpublished entities authored by other users.

Proposed resolution

Allow referencing unpublished entities if the current user has access to them.

Remaining tasks

Resolve what to do for entities that are created via an entity-reference field. (See comments #43–46)

The gist of the problem: The existing kludge that Core had before this patch misleads site builders and content creators into inadvertently exposing private content. Is it more important to fix that, or is it more important to avoid changing existing behaviour (because some people may be relying on that).

Options include:

  • Do not make any changes to entity creation.
  • Roll a separate issue for this, possibly bump to Drupal 10.
  • Decide that fixing the problem is more important than maintaining existing behaviour.

Secondly, some changes to tests were recommended in comment #43 that still need to be addressed.

User interface changes

none

API changes

none

Data model changes

none

Release notes snippet

claroAutocompleteTest passes, but log shows a 404

$
0
0

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?

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

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Error when not prefixing controller with backslash in route definition and registering the controller as service

$
0
0

Problem/Motivation

It's not clear to me whether the leading backslash for controllers in route definitions is required. Example: \Drupal\mymodule\Controller\MyController vs Drupal\mymodule\Controller\MyController. At the moment, both ways work and I see them both used throughout contrib code (even though the first way is more popular).

This hasn't been a problem until now because dependency injection for controllers usually happens through the class implementing \Drupal\Core\DependencyInjection\ContainerInjectionInterface. Once we enable autowiring/autoconfiguration of services, it will be easier to register services in the container and let dependencies be injected that way.

The problem in that case would be that controller definitions are not normalized as they are in a couple places in Symfony code:

This means that if a route definition leaves out the leading slash of its controller, dependencies will not be injected since the class will be registered in the container with a leading backslash, and the page will fail.

Steps to reproduce

  1. Create a route definition where the controller doesn't have a leading backslash, eg. Drupal\mymodule\Controller\MyController
  2. Register the controller as service with a leading backslash

Proposed resolution

Strip any leading backslashes from the controller definition in Drupal\Core\Controller\ControllerResolver::getControllerFromDefinition.

Add validation constraints to block_content.type.*

$
0
0

Problem/Motivation

Date formats have 1 property paths that are not yet validatable:

./vendor/bin/drush config:inspect --filter-keys=block_content.type.banner_block --detail --list-constraints --fields=key,validatability,constraints
➜  🤖 Analyzing…

 ------------------------------------------------------------ ------------- --------------------------------------------------------------------------------------------- 
  Key                                                          Validatable   Validation constraints                                                                       
 ------------------------------------------------------------ ------------- --------------------------------------------------------------------------------------------- 
  block_content.type.banner_block                              91%           ValidKeys: '<infer>'                                                                         
   block_content.type.banner_block:                            Validatable   ValidKeys: '<infer>'                                                                         
   block_content.type.banner_block:_core                       Validatable   ValidKeys:                                                                                   
                                                                               - default_config_hash                                                                      
   block_content.type.banner_block:_core.default_config_hash   Validatable   NotNull: {  }                                                                                
                                                                             Regex: '/^[a-zA-Z0-9\-_]+$/'                                                                 
                                                                             Length: 43                                                                                   
                                                                             ↣ PrimitiveType: {  }                                                                        
   block_content.type.banner_block:dependencies                Validatable   ValidKeys: '<infer>'                                                                         
   block_content.type.banner_block:description                 Validatable   Regex:                                                                                       
                                                                               pattern: '/([^\PC\x09\x0a\x0d])/u'                                                         
                                                                               match: false                                                                               
                                                                               message: 'Text is not allowed to contain control characters, only visible characters.'↣ PrimitiveType: {  }                                                                        
   block_content.type.banner_block:id                          Validatable   Regex:                                                                                       
                                                                               pattern: '/^[a-z0-9_]+$/'                                                                  
                                                                               message: 'The %value machine name is not valid.'                                           
                                                                             Length:                                                                                      
                                                                               max: 166                                                                                   
                                                                             ↣ PrimitiveType: {  }                                                                        
   block_content.type.banner_block:label                       Validatable   Regex:                                                                                       
                                                                               pattern: '/([^\PC])/u'                                                                     
                                                                               match: false                                                                               
                                                                               message: 'Labels are not allowed to span multiple lines or contain control characters.'    
                                                                             NotBlank: {  }                                                                               
                                                                             ↣ PrimitiveType: {  }                                                                        
   block_content.type.banner_block:langcode                    Validatable   NotNull: {  }                                                                                
                                                                             Choice:                                                                                      
                                                                               callback: 'Drupal\Core\TypedData\Plugin\DataType\LanguageReference::getAllValidLangcodes'↣ PrimitiveType: {  }                                                                        
   block_content.type.banner_block:revision                    NOT           ⚠️  @todo Add validation constraints to config entity type: block_content.type.*             
   block_content.type.banner_block:status                      Validatable   ↣ PrimitiveType: {  }                                                                        
   block_content.type.banner_block:uuid                        Validatable   Uuid: {  }                                                                                   
                                                                             ↣ PrimitiveType: {  }                     

On my local umami install, they are also with 4 in the top 10 of config objects the closest to 100% validatability. (See ./vendor/bin/drush config:inspect --todo=50)

Steps to reproduce

  1. Get a local git clone of Drupal core 11.x.
  2. composer require drupal/config_inspector— or manually install https://www.drupal.org/project/config_inspector/releases/2.1.5 or newer (which supports Drupal 11!)
  3. composer require drush/drush
  4. vendor/bin/drush config:inspect --filter-keys=block_content.type.banner_block --detail --list-constraints

Proposed resolution

Add validation constraints to:

  1. block_content.type.*:revision

This requires looking at the existing code and admin UI (if any) to understand which values could be considered valid. Eventually this needs to be reviewed by the relevant subsystem maintainer.

For examples, search *.schema.yml files for the string constraints:😊

Reach out to @borisson_ or @wimleers in the #distributions-and-recipes.

Remaining tasks

  1. block_content.type.*:revision

User interface changes

None.

API changes

None.

Data model changes

More validation 🚀

Release notes snippet

None.

Add validation constraints to field.settings

$
0
0

Problem/Motivation

Field settings have 1 property paths that are not yet validatable:

$ ./vendor/bin/drush config:inspect --filter-keys=field.settings --detail --list-constraints  --fields=key,validatability,constraints
➜  🤖 Analyzing…

 ------------------------------------------- ------------- ------------------------------------------ 
  Key                                         Validatable   Validation constraints                    
 ------------------------------------------- ------------- ------------------------------------------ 
  field.settings                              75%           ValidKeys: '<infer>'                      
                                                            RequiredKeys: '<infer>'                   
   field.settings:                            Validatable   ValidKeys: '<infer>'                      
                                                            RequiredKeys: '<infer>'                   
   field.settings:_core                       Validatable   ValidKeys:                                
                                                              - default_config_hash                   
                                                            RequiredKeys: '<infer>'                   
   field.settings:_core.default_config_hash   Validatable   NotNull: {  }                             
                                                            Regex: '/^[a-zA-Z0-9\-_]+$/'              
                                                            Length: 43                                
                                                            ↣ PrimitiveType: {  }                     
   field.settings:purge_batch_size            NOT           ⚠️  @todo Add validation constraints here  
 ------------------------------------------- ------------- ------------------------------------------ 

Steps to reproduce

  1. Get a local git clone of Drupal core 11.x.
  2. composer require drupal/config_inspector— or manually install https://www.drupal.org/project/config_inspector/releases/2.1.5 or newer (which supports Drupal 11!)
  3. composer require drush/drush
  4. vendor/bin/drush config:inspect --filter-keys=olivero.settings --detail --list-constraints

Proposed resolution

Add validation constraints to:

  1. purge_batch_size

This requires looking at the existing code and admin UI (if any) to understand which values could be considered valid. Eventually this needs to be reviewed by the relevant subsystem maintainer.

For examples, search *.schema.yml files for the string constraints:😊

Reach out to @borisson_ or @wimleers in the #distributions-and-recipes.

Remaining tasks

  1. purge_batch_size

User interface changes

None.

API changes

None.

Data model changes

More validation 🚀

Release notes snippet

None.


Fix PostgeSQL column name escaping in field constraints

$
0
0

Problem/Motivation

The field name for the column that has the great than zero check is not quoted.

Steps to reproduce

Create a custom entity type with entity reference field named "order".
Try to install it.
The following error will be thrown.

Exception thrown while performing a schema update. SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "order"
LINE 5: "order" bigint CHECK (order >= 0) NULL,

Proposed resolution

Add the quotes to the field name.

Remaining tasks

None

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

TBD

Adopt PluginExists validator in relevant places

$
0
0

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

Make CachePluginBase::generateResultsKey() to pass valid data to CacheContextsManager::convertTokensToKeys

$
0
0

Problem/Motivation

https://qa.drupal.org/pifr/test/1076308

According the PHPDocs in the CacheContextsManager the calling method is REQUIRED to send an array of strings. Currently it is not doing so, and the assert statement reveals this. Whether or not this is an underlying cause of a greater issue is unknown.

Steps to reproduce

NA

Proposed resolution

Remaining tasks

Review MR
Commit

User interface changes

N/A

API changes

N/A

Data model changes

N/A

Release notes snippet

N/A

Refactor (if feasible) uses of the jQuery parent function to use vanillaJS

$
0
0

Problem/Motivation

As mentioned in the parent issue #3238306: [META] Where possible, refactor existing jQuery uses to vanillaJS to reduce jQuery footprint, we are working towards reducing our jQuery footprint. One of the ways to accomplish this is to reduce the number of jQuery features used in Drupal core. We have added eslint rules that identify specific features and fail tests when those features are in use.

There are (or will be) individual issues for each jQuery-use eslint rule. This one is specific to jquery/no-parent, which targets the jQuery parent function.

Steps to reproduce

Proposed resolution

Remaining tasks

  • In core/.eslintrc.jquery.json Change "jquery/no-parent": 0, to "jquery/no-parent": 2, to enable eslint checks for uses of jQuery parent(). With this change, you'll be able to see uses of the undesirable jQuery feature by running yarn lint:core-js-passing from the core directory
  • Add the following lines to core/scripts/dev/commit-code-check.sh so the DrupalCI testing script can catch this jQuery usage on all files, not just those which have changed
    # @todo Remove the next chunk of lines before committing. This script only lints
    #  JavaScript files that have changed, so we add this to check all files for
    #  jQuery-specific lint errors.
    cd "$TOP_LEVEL/core"
    node ./node_modules/eslint/bin/eslint.js --quiet --config=.eslintrc.passing.json .
    
    CORRECTJQS=$?
    if [ "$CORRECTJQS" -ne "0" ]; then
      # No need to write any output the node command will do this for us.
      printf "${red}FAILURE ${reset}: unsupported jQuery usage. See errors above."
      STATUS=1
      FINAL_STATUS=1
    fi
    cd $TOP_LEVEL
    # @todo end lines to remove

    Add the block about 10 lines before the end of the file, just before if [[ "$FINAL_STATUS" == "1" ]] && [[ "$DRUPALCI" == "1" ]]; then, then remove it once all the jQuery uses have been refactored.

  • If it's determined to be feasible, refactor those uses of jQuery parent() to use Vanilla (native) JavaScript instead.

User interface changes

API changes

Data model changes

Release notes snippet

Add back "final" to Drupal\big_pipe\StackMiddleware\ContentLength

$
0
0

Problem/Motivation

After the fix in #3410022: Regression from #3295790 content-length header set earlier than expected, running database updates via drush updb throws an uncaught exception. In #3412160: Uncaught exception thrown when running database updates via drush we worked around this by removing final. This issue is for adding

final<code> back.

The underlying issue is that lazy Symfony services do not support <code>final

classes, but this can be worked around with interface proxying:
https://symfony.com/doc/6.4/service_container/lazy_services.html#interface-proxifying

If there is more than one service tagged 'http_middleware' and at least one that is a responder, Drupal\Core\DependencyInjection\Compiler\StackedKernelPass::process() sets all those middleware services as lazy, other than the first responder.

The issue only seems to surface in Drupal (as observed so far) when the kernel's container is an instance of Symfony\Component\DependencyInjection\ContainerBuilder. The Drupal\Core\Update\UpdateKernel has its container set to an instance of ContainerBuilder, and the exception is thrown in the kernel terminate() method, when the call to ::getHttpKernel() leads to $this->container->get('http_kernel'), and as the decorated service is instantiated, the lazy middleware services are proxied, leading to an exception on final classes. Since this exception is thrown during the terminate phase, the exception is not displayed in browser when running updates via browser at update.php. The exception is logged, though. when running updates via drush, the exception stops the command from completing.

Proposed resolution

  1. Add back "final" to Drupal\big_pipe\StackMiddleware\ContentLength
  2. Add 'proxy' tags to http_middleware services set to lazy in Drupal\Core\DependencyInjection\Compiler\StackedKernelPass with the Symfony\Component\HttpKernel\HttpKernelInterface (and possibly Symfony\Component\HttpKernel\TerminableInterface) interfaces

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Add a flag to KernelTestBase to set up test environment only once per test class in setUpBeforeClass()

$
0
0

Problem/Motivation

Some kernel tests could be sped up by installing Drupal only once per test class, rather than for every test method.

Steps to reproduce

Proposed resolution

Add a flag to KernelTestBase which causes the installation to be done in setUpBeforeClass() instead of setUp().

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Replace views_ui_truncate() with Unicode::truncate()

$
0
0

Problem/Motivation

views_ui_truncate() works the same like Unicode::truncate(), but Unicode::truncate() has more features. I think this views_ui_truncate() can be removed.

Steps to reproduce

Proposed resolution

Deprecate views_ui_truncate() and use Unicode::truncate(),

Remaining tasks

Patch
Review
Commit

User interface changes

API changes

Data model changes

Release notes snippet


Allow client side #fragments (e.g. anchor links) for pagination links

$
0
0

Problem/Motivation

On more complex pages tabs (e.g from field_group) are used. Inside each tab is a view.
Tabs can be activated on page load using anchor links.

e.g.
https://site/page -> opens the default tab Tab1
https://site/page#tab_fragment2 -> opens the second tab Tab2

On reloading a filtered view (which resides in a non default tab Tab2) upon clicking on the "next page" of the pager the default tab Tab1 is shown instead of the Tab2 containing the view with the next page.

This prevents a lot of automatic ajax interaction from working correctly.

Steps to reproduce

Proposed resolution

Allow client side #fragments (e.g. anchor links) for views pagination links.
Make an option for the pager called "client side fraqments:" which is added to the pager link.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Active trail gets corrupted in cache_menu for menus with numeric machine names

$
0
0

Problem/Motivation

We have a site where some menus have numeric machine names (i.e. menu title is 'Transport', but its machine name is '583'). I don't know the reason for this (probably they were migrated or created via code to match some legacy system), but this can also be created easily via menu UI.

We noticed occasional problems with these menus, causing them to disappear from the pages where they would normally appear on. After much debugging, I found out that the problem comes from corrupted entries in cache_menu (cid begins with active-trail:....), which affect menus with number-like machine names.

This issue has happened for us on multiple Drupal 9.x versions. I was able to replicate and debug it in Drupal 9.5.11, and then replicate it on 10.1.6 also.

In the following steps to reproduce this bug, I used two menus, which I called 2 and 4. Note that the bug is independent of these values.

Steps to reproduce

Phase 1. Initial corruption of the cached entries

1. install a fresh Drupal site (standard profile is enough)
2. create a basic page (e.g. /node/1)
3. create two menus with numeric machine name (call them 2 and 4 and any title you want) and one link in each:

  2
    link 2.1 (pointing to any url)
  4
    link 4.1 (pointing to any url)

4. place two blocks (e.g. in content area) to display these two menus on /node/1 (i.e. Restrict to certain pages set to /node/1)
5. go to /node/1 and confirm the menus are showing
6. check the cache_menu table and look at the active-trail entry for that page:

drush sql-query "select data from cache_menu where cid='active-trail:route:entity.node.canonical:route_parameters:a:1:{s:4:\"node\";s:1:\"1\";}'"

You should see something like this:

a:4:{s:4:"main";a:2:{s:54:"menu_link_content:53f35910-253f-4c3f-9089-abd5884416a3";s:54:"menu_link_content:53f35910-253f-4c3f-9089-abd5884416a3";s:0:"";s:0:"";}s:7:"account";a:1:{s:0:"";s:0:"";}i:2;a:1:{s:0:"";s:0:"";}i:4;a:1:{s:0:"";s:0:"";}}

Note that the last two entries in this serialized data are i:2 and i:4 (i.e. the machine names of the menus, but converted to integer values).
7. rebuild the cache using drush cr or at least clear these bins drush cc bin menu render page dynamic_page_cache
8. send multiple simultaneous requests for /node/1 page, either via browser using F5 multiple times very fast, or (better) via commands:

wget -qO /dev/null https://drupal.sandbox.local/node/1 &
wget -qO /dev/null https://drupal.sandbox.local/node/1 &
wget -qO /dev/null https://drupal.sandbox.local/node/1 &
wget -qO /dev/null https://drupal.sandbox.local/node/1 &
wget -qO /dev/null https://drupal.sandbox.local/node/1 &
wget -qO /dev/null https://drupal.sandbox.local/node/1 &

9. check again the cache_menu table:

drush sql-query "select data from cache_menu where cid='active-trail:route:entity.node.canonical:route_parameters:a:1:{s:4:\"node\";s:1:\"1\";}'"

This time you will see something like this:

a:6:{s:4:"main";a:1:{s:0:"";s:0:"";}s:7:"account";a:1:{s:0:"";s:0:"";}i:0;a:1:{s:0:"";s:0:"";}i:1;a:1:{s:0:"";s:0:"";}i:2;a:1:{s:0:"";s:0:"";}i:3;a:1:{s:0:"";s:0:"";}}

Note that i:2 and i:4 have been renumbered (by array_merge here https://github.com/drupal/core/blob/11.x/lib/Drupal/Core/Cache/CacheColl...) into i:0 and i:1 and also duplicated as i:2 and i:3. This is according to https://www.php.net/manual/en/function.array-merge.php ("Values in the input arrays with numeric keys will be renumbered with incrementing keys starting from zero in the result array."). Basically, two copies of the active trail (one created by current request and another one cache microseconds before by another request), got merged together: the text-like menus were kept (a single entry for each), but the numeric-like menus were renumbered and duplicated.

If you don't see this, try again to clear the cache and run the wget commands (maybe add some more to simulate a busier site).
Depending on the site load (i.e. number of simultaneous requests that don't find the active-trail cache entry) and the number of menus with numeric machine names, you might see tens or hundreds of such entries.

Phase 2. Additional corruption of the cached entries

Moreover, when entries in the dynamic pages cache expire, this problem will be increased even more. Each request that runs into this use case, will copy again the numeric entries. The steps to replicate this are (run them multiple times):

1. Use the steps from Phase 1. to corrupt the cache.
2. Clear page caches (don't clear entire cache as that will cancel previous step):

drush cc bin dynamic_page_cache page

3. load the /node/1 page (just one page request is enough, no need for parallel ones):

wget -qO /dev/null https://drupal.sandbox.local/node/1

4. view the cached entry

drush sql-query "select data from cache_menu where cid='active-trail:route:entity.node.canonical:route_parameters:a:1:{s:4:\"node\";s:1:\"1\";}'"

You will see this:

a:7:{s:4:"main";a:1:{s:0:"";s:0:"";}s:7:"account";a:1:{s:0:"";s:0:"";}i:0;a:1:{s:0:"";s:0:"";}i:1;a:1:{s:0:"";s:0:"";}i:2;a:1:{s:0:"";s:0:"";}i:3;a:1:{s:0:"";s:0:"";}i:4;a:1:{s:0:"";s:0:"";}}

5. Repeat previous three steps and you will see this:

a:8:{s:4:"main";a:1:{s:0:"";s:0:"";}s:7:"account";a:1:{s:0:"";s:0:"";}i:0;a:1:{s:0:"";s:0:"";}i:1;a:1:{s:0:"";s:0:"";}i:2;a:1:{s:0:"";s:0:"";}i:3;a:1:{s:0:"";s:0:"";}i:4;a:1:{s:0:"";s:0:"";}i:5;a:1:{s:0:"";s:0:"";}}

6. Repeat previous step and will see the cached entry having more and more numeric entries.

Phase 3. Disappearing blocks due to corrupted data

Eventually, if the site runs long enough with corrupted cache, the bad entries start to overwrite the correct entries coming from numeric menus, causing various problems with them (e.g. menus to disappear from site pages). This can be replicated like this:

1. edit the basic content type to allow adding these nodes to menu 2 and 4
2. edit node/1 and add a menu entry for it in menu 4
3. edit menu 4 to look like this (link 4.1 is sublink of node 1 link)

  4
    node 1 (added in step 2 before)
      link 4.1 (pointing to any url)

4. edit the block that displays menu 4 and set Initial visibility level to 2
5. clear the cache (drush cr)
6. visit /node/1 and check that link 4.1 (from menu 4) shows on that page
7. Look at the cached entry:

drush sql-query "select data from cache_menu where cid='active-trail:route:entity.node.canonical:route_parameters:a:1:{s:4:\"node\";s:1:\"1\";}'"

You will see something like this (with different UUIDs):

a:4:{s:4:"main";a:1:{s:0:"";s:0:"";}s:7:"account";a:1:{s:0:"";s:0:"";}i:2;a:1:{s:0:"";s:0:"";}i:4;a:2:{s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:0:"";s:0:"";}}

Notice the value for i:4 (menu 4) is
i:4;a:2:{s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:0:"";s:0:"";}
because the current page request is in the active trail of the menu.
8. corrupt the cache (using the steps 7-8 from Phase 1 above, but use more wget commands. I used 30)
9. visit /node/1 and check that link 4.1 disappeared from the page (you might need to run previous step multiple times to make it happen, or just use more wgets).
10. Look at the cached entry:

drush sql-query "select data from cache_menu where cid='active-trail:route:entity.node.canonical:route_parameters:a:1:{s:4:\"node\";s:1:\"1\";}'"

You will see something like this:

a:12:{s:4:"main";a:1:{s:0:"";s:0:"";}s:7:"account";a:1:{s:0:"";s:0:"";}i:0;a:1:{s:0:"";s:0:"";}i:1;a:2:{s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:0:"";s:0:"";}i:2;a:1:{s:0:"";s:0:"";}i:3;a:2:{s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:0:"";s:0:"";}i:4;a:1:{s:0:"";s:0:"";}i:5;a:2:{s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:0:"";s:0:"";}i:6;a:1:{s:0:"";s:0:"";}i:7;a:2:{s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:0:"";s:0:"";}i:8;a:1:{s:0:"";s:0:"";}i:9;a:2:{s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:54:"menu_link_content:e7935b9c-1992-4752-931c-e017efba0be0";s:0:"";s:0:"";}}

Note that the same values were copied over and over again. Also notice that the entry for i:4 has changed to
i:4;a:1:{s:0:"";s:0:"";} (i.e. an empty array), which means the current page is not in active trail of the menu (which causes the menu block to be hidden instead of visible).
11. clear the cache (drush cr or drush cc bin menu dynamic_page_cache page)
12. visit /node/1 and check that link 4.1 (from menu 4) shows again on that page

Proposed resolution

Apply provided patch (which changes MenuActiveTrail.php to use set method instead of changing directly the storage property).

Remaining tasks

Test patch

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

Fix cache_menu bug affecting menus with numeric machine names

Refactor (if feasible) uses of the jQuery each function to use Vanilla/native

$
0
0

Problem/Motivation

As mentioned in the parent issue #3238306: [META] Where possible, refactor existing jQuery uses to vanillaJS to reduce jQuery footprint, we are working towards reducing our jQuery footprint. One of the ways to accomplish this is to reduce the number of jQuery features used in Drupal core. We have added eslint rules that identify specific features and fail tests when those features are in use.

There are (or will be) individual issues for each jQuery-use eslint rule. This one is specific to jquery/no-each, which targets the jQuery each function.

Steps to reproduce

Proposed resolution

Remaining tasks

  • In core/.eslintrc.jquery.json Change "jquery/no-each": 0, to "jquery/no-each": 2, to enable eslint checks for uses of jQuery .each(). With this change, you'll be able to see uses of the undesirable jQuery feature by running yarn lint:core-js-passing from the core directory
  • Add the following lines to core/scripts/dev/commit-code-check.sh so the DrupalCI testing script can catch this jQuery usage on all files, not just those which have changed
    # @todo Remove the next chunk of lines before committing. This script only lints
    #  JavaScript files that have changed, so we add this to check all files for
    #  jQuery-specific lint errors.
    cd "$TOP_LEVEL/core"
    node ./node_modules/eslint/bin/eslint.js --quiet --config=.eslintrc.passing.json .
    
    CORRECTJQS=$?
    if [ "$CORRECTJQS" -ne "0" ]; then
      # No need to write any output the node command will do this for us.
      printf "${red}FAILURE ${reset}: unsupported jQuery usage. See errors above."
      STATUS=1
      FINAL_STATUS=1
    fi
    cd $TOP_LEVEL
    # @todo end lines to remove

    Add the block about 10 lines before the end of the file, just before if [[ "$FINAL_STATUS" == "1" ]] && [[ "$DRUPALCI" == "1" ]]; then, then remove it once all the jQuery uses have been refactored.

  • If it's determined to be feasible, refactor those uses of jQuery .each() to use Vanilla (native) JavaScript instead.

User interface changes

API changes

Data model changes

Release notes snippet

Term migrations should set revision IDs

$
0
0

Problem/Motivation

The d6_taxonomy_term and d7_taxonomy_term migrations preserver term IDs (tid) but do not set revision IDs (revision_id). At best, this leads to an odd situation: revision IDs for some terms may be smaller than their entity IDs.

Proposed resolution

Since taxonomy terms in Drupal 6 and Drupal 7 do not support revisions, set the revision ID to the same thing as the term ID.

This is consistent with updating a site to Drupal 8.7+ from an earlier version. The update function seems to set the revision ID to the term ID for existing terms.

Remaining tasks

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

N/A

Rewrite jQuery .show() and .hide()

$
0
0

Problem/Motivation

The jQuery .show() and .hide() is used in a few places. It's also specifically mentioned in core/modules/system/css/components/hidden.module.css as a way to toggle hidden elements.

Proposed resolution

Provide an API to toggle visibility of elements. However, we should probably use either .hidden or [hidden] for determining the visibility. As we do that, we should make the CSS rule use !important on the display: none property to ensure that it doesn't get overridden accidentally by arbitrary rules.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Viewing all 291765 articles
Browse latest View live


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