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

Entity lazy multiple front loading

$
0
0

Problem/Motivation

Drupal 7 introduced multiple loading of entities and the controller classes. This means that especially when building lists of content, the best case can be a single multiget from cache to get all the fully populated entity objects (when using entitycache module) or that all nodes are loaded with a flat number of database queries regardless of the number of nodes. This improved on the situation in Drupal 6 where each load was loaded individually, and each node_load() could execute a decent number of database queries each.

For this to work, there is a general pattern of "get the IDs, multiple load the nodes based on the IDs, do stuff with them" - this is great for content listing, however it does not work if for example you need to load 7 different nodes in seven different blocks - those still get grabbed one at a time.

For the WSCCI iniatiative (especially after the irc meeting last night and discussions in #1177246: Context values: Keys or objects?), there is a desire to have the publicly accessible context properties be either literals or objects. In the case of entities, this would be $context['node'] or $context['user'] most likely.

There is also a desire to improve block caching, so that from just context, you can build a cache key and load a block from cache (core already allows you to do this via drupal_render(), #cache, and pre_render callbacks although it is only partly formalized).

This means that if we just got an $nid from somewhere, use the $nid as part of a cache key, then get a cache hit, we won't actually need to load the node (or a 'parent' page won't need to load the node, but an ESI callback might on a cache miss in a different PHP process altogether).

But... passing around $node objects, and yet only needing $nid to generate a cache key seem mutually exclusive I hear you say!

Proposed resolution

There has been a lot of discussion about making entities into proper classes (rather than stdClass) with methods etc. Additionally, that we should keep the Load controller (and associated other controllers as they come into play) as separate classes to the actual entity class (so $entity->save() calls a method from an EntitySave class, the code wouldn't be baked into the Entity class). Details are not fully worked out yet but that is the general direction.

This means I think we should be able to construct an entity object like this:

$entity = new Entity($type, $id); // $id likely optional so that mock entities can be created, potentially new ones.

This means I can do $node = new Entity('node', $nid); $node->id (or $node->id() or whatever), and that will work fine.

What occurred to me yesterday, is there may well be a way to reconcile this with multiple load, would look something like this:

* When you instantiate the class with an $id, the $id gets added to the EntityLoad controller - which maintains a list of $ids of that type that are in use.

* (two options), when you call $entity->load(), or just access a property that is missing (triggering __get() or similar), the $entity object calls back to the EntityLoad controller to fetch the actual loaded node. I am not yet tied to the magic method vs. the explicit ->load() method for this, the internal implementation in terms of this issue could be very similar.

* When ->load() (either directly called or via magic) asks the EntityLoad controller, it inspects the list of entity IDs that it has, vs. the ones that are already loaded. At this point, it is able to multiple load all of the nodes that weren't loaded already - so they're ready for later when requested. (we could also add a method or property to disable this behaviour, allow the default to be overridden or similar).

This would give us the following:

- for lists, multiple load works more or less the same as now, except you could just foreach over $nids, instantiate the class and load it - no get $nids, load, then foreach pattern. So it should be a simpler for people who just want to load nodes and do stuff with them. The front-loading would be encapsulated in the class logic rather than a pattern that has to be copy/pasted around.

- for non lists (like multiple blocks on a page with different nodes based on different relationships), if we build the context for the blocks, then go through and execute the block handlers in sequence (either building the actual render array or rendering the string, doesn't matter for this), multiple load will work for this case too, whereas it currently doesn't.

- For sites using ESI/big pipe or similar, processes that don't need to load entities won't do so just to generate cache keys or similar.

- There are advantages for doing things like mocking the context object too (i.e. a block callback never has to call $node = node_load($nid); it just acts on a class that was passed into it), so dependency injection, consistency etc. It keeps us closer to menu_get_object() and passing parameters vs. node_load(arg(1));

- This approach should very compatible with adding an LRU cache for entities, see #375494: Restrict the number of nodes held in the node_load() static cache and #1199866: Add an in-memory LRU cache.

Remaining tasks

No patch yet, we really need to get #1018602: Move entity system to a module in.

User interface changes

None.

API changes

Probably.


Add a cache prewarm API

$
0
0

Problem/Motivation

After a full cache clear, Drupal has to build up various caches before it can serve a request. Element info, route preloading, menu links, library info, various plugin registries, theme registry, twig templates, CSS assets (#1014086: Stampedes and cold cache performance issues with css/js aggregation) etc.

This both takes a long time, and massively increases the memory usage of a request.

Steps to reproduce

drush cr, load a heavy-ish page, watch that spinny wheel / check mem_get_usage()

Proposed resolution

PHP 8.1 adds Fibers https://php.watch/versions/8.1/fibers / https://wiki.php.net/rfc/fibers

In DrupalKernel::handle(), execute HttpKernerl::handleRequest()in a fiber. This allows any code, anywhere in core, to suspend itself using Fiber::suspend(), the place we suspend is for now after entering lock wait or getting a cache miss in particular services - this should only be done for cache items that are used to build most pages - plugins and registries, but not render caching or anywhere like that. But it could also be after executing an async query once we have a database driver that supports it.

At the same time, services can tag themselves using the cache_prewarmable service tag and implement PreWarmableInterface. This is not mutually exclusive with calling suspend on a cache miss, some services can do both.

When a fiber has suspended, DrupalKernel is then able to call the cache_prewarmer service, which gets a list of tagged service IDs. It calls the ::prewarm() method of one of these services at random, then resumes the original fiber and the request continues as normal. The prewarm method will usually just call a different method on the service, this needs to be one that both checks and sets the cache - we always want to assume it might have been set before we got there.

If the fiber gets suspended again later in the request, we'll go back to the cache prewarmer service and pick a different one.

This is complementary to #3377570: Add PHP Fibers support to BigPipe and in general is designed to speed up the part of request handling that precedes having bigpipe placeholders to render, but since different pages hit different caches at different times, sometimes the 'same' Fiber::suspend() call will result in going back to DrupalKernel and warming a cache, sometimes it will result in moving onto a different BigPipe placheholder. This is fine and by design, the code inside the fiber doesn't care what happens in between suspending itself and being resumed, it's just anticipating that something might be able to happen and then bigpipe and the prewarmer service take care of what that 'something' is.

The big advantage of Fibers is that as long as the code executing a fiber handles them correctly, and as long as the code that might be executing inside a fiber checks its inside a fiber first before suspending, they don't need to know anything about each other at all. The 'parent' starts and resumes, and the 'child' suspends, and it doesn't need to be any more entangled than that.

Here's a very simplified visual indication of what stampedes look like in terms of service cache get misses, building, and setting:

Each letter represents a service.
Aget (cache get)
A-set (build and cache set).

Extra hyphens means a longer period of time building the cache item.

C and D are nested services with one calling the other, equivalent to the views examples above. When C is warm, D doesn't get requested.

When we have one request, it just builds each service sequentially.

AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setFget-Fset

In HEAD, when we get a stampede. All the requests build and set each cache sequentially. The requests with Z and F at the end represent different pages (node vs. front vs. user or whatever), which may have different caches to build.

[NO-PRE-WARMING-] is a space filler because suspend and resume take up space on the line..

[NO-PRE-WARMING-]
[SUSPEND][RESUME]
<code>
AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setFgetF-set
AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setFgetF-set
AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setFgetF-set
AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setZgetZ-set
AgetA-set[NO-PRE-WARMING-]BgetB--------setCgetDgetD-setC--setEgetE----setZgetZ-set

With the patch, if we get two requests at the same time, we start to see a benefit (without any async):

AgetA-set[SUSPEND]BgetB--------set[RESUME]BgetCgetDgetC--setEgetFgetF-set
AgetA-set[SUSPEND]DgetD-set[RESUME]BgetCgetDgetC--setEgetE---setFgetF-set

Now with five requests, it's making much more difference:

AgetA-set[SUSPEND]BgetB--------set[RESUME]BgetCgetEgetZget
AgetA-set[SUSPEND]FgetF-set[RESUME]BgetCgetEgetZgetZ-set
AgetA-set[SUSPEND]FgetF-set[RESUME]BgetCgetEgetFget
AgetA-set[SUSPEND]CgetDgetD-setC--Set[RESUME]CgetEgetFget
AgetA-set[SUSPEND]EgetE---set[RESUME]BgetCgetEgetFget

Note also that because B and D take different amounts of time, in this case even though Z isn't prewarmed, the two requests that need it get there at different times, so only one builds it and the other gets a cache hit - this is an effect of the offsetting/shuffling that the prewarmer does. Say one prewarmable cache takes 800ms to build and the other takes 8ms, the one that's done with prewarming after 8ms will get a lot more done before the 800ms prewarming is finished.

Remaining tasks

Once there are enough prewarmable services defined, we should be able to manually test this by clearing the cache then using ab -n1 -c10, probably with the standard profile, to see if there's a measurable performance improvement.

Once the API is in core, we can potentially add full async cache prewarming support to drush. I think drush could then build all the prewarmable caches at the same time immediately after a cache clear.
https://github.com/drush-ops/drush/issues/5724

User interface changes

API changes

Adds PreWarmableInterface

Data model changes

Release notes snippet

[random test failure] CommentPreviewTest::testCommentPreview

$
0
0

Problem/Motivation

    Comment Preview (Drupal\Tests\comment\Functional\CommentPreview)
     ✘ Comment preview
       ┐
       ├ Failed asserting that a string is an instance of interface Drupal\Component\Render\MarkupInterface.
       │
       │ /builds/issue/drupal-3496259/core/modules/comment/tests/src/Functional/CommentPreviewTest.php:59
       ┴
     ✔ Comment preview duplicate submission
     ✔ Comment edit preview save

Steps to reproduce

Example: https://git.drupalcode.org/issue/drupal-3496259/-/jobs/3829641#L1340

Proposed resolution

Replace calls to State with KeyValue.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Add assertions to OpenTelemetryNodePagePerformanceTest::testNodePageCoolCache()

$
0
0

Problem/Motivation

Note: this issue was initially created for a performance testing workshop at DrupalCon Barcelona.

OpenTelemetryNodePagePerformanceTest::testNodePageCoolCache() doesn't have assertions for cache gets/sets, database queries, and Javascript and CSS requests.

Steps to reproduce

Proposed resolution

Using OpenTelemetryFrontPagePerformanceTest::testFrontPageHotCache(), AssetAggregationAcrossPagesTest::testFrontAndRecipesPages(), and OpenTelemetryAuthenticatedPerformanceTest::testFrontPageAuthenticatedWarmCache() as examples, add assertions to these test methods for database queries, cache operations, and CSS/JS requests - the tests should continue to pass with the assertions that are added.

Remaining tasks

User interface changes

N/A

Introduced terminology

N/A

API changes

N/A

Data model changes

N/A

Release notes snippet

N/A

Move all system_update_N() methods next to each other

$
0
0

Problem/Motivation

#3442009: OOP hooks using attributes and event dispatcher added system_update_11100() to the 11.x branch, but at a weird spot in system.install. Instead of putting it at the bottom of the file, it's interspersed between system_update_last_removed() and _system_advisories_requirements() (a "private" helper called by system_requirements().

Meanwhile, #3463226: Use the new equivalent updates API to prevent updates from 10.4.0 to 11.0.0 is about to add system_update_11101(), but will put it at the bottom of the file. So the system_update_N() implementations will not be in a contiguous chunk of this file, potentially leading to confusion.

Steps to reproduce

Look at system.install in the 11.x branch.

Proposed resolution

Put all system_update_N() implementations together at the bottom of system.install.

Remaining tasks

Land #3463226: Use the new equivalent updates API to prevent updates from 10.4.0 to 11.0.0 (urgently needed)
Move system_update_11100() and system_update_11101() next to each other at the bottom of system.install

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Render children in fibers

[random test failure] BlockCacheTest::testCachePermissions()

$
0
0

Problem/Motivation

Seen this a few times recently, there's no recent changes to the test so it might be a timing issue or an underlying change or something:

1) Drupal\Tests\block\Functional\BlockCacheTest::testCachePermissions
Behat\Mink\Exception\ResponseTextException: The text "ztmxv7uw" was not
found anywhere in the text of the current page.
/builds/project/drupal/vendor/behat/mink/src/WebAssert.php:907
/builds/project/drupal/vendor/behat/mink/src/WebAssert.php:293
/builds/project/drupal/core/tests/Drupal/Tests/WebAssert.php:975
/builds/project/drupal/core/modules/block/tests/src/Functional/BlockCacheTest.php:159

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Update ComponentValidator to always include the component ID

$
0
0

Problem/Motivation

When a component defines a property with an enum value and is rendered with a value that is not an enum, the error message is unhelpful.

Drupal\Core\Render\Component\Exception\InvalidComponentException: [example] Does not have a value in the enumeration ["foo","bar"] in Drupal\Core\Theme\Component\ComponentValidator->validateProps() (line 223 of core/lib/Drupal/Core/Theme/Component/ComponentValidator.php).

How do you understand what component is causing the problem? There can be multiple components with the same enum values. For example, buttons, inputs, etc., with a variant or color enum property.

This is especially annoying when the enum value is removed from the component after some time and the value for it can be a twig variable and not a direct definition.

Steps to reproduce

$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
name: Example
props:
  type: object
  properties:
    example:
      title: Example
      enum:
        - foo
        - bar

{% include 'foo:foo' with { example: 'baz' } only %}

Drupal\Core\Render\Component\Exception\InvalidComponentException: [example] Does not have a value in the enumeration ["foo","bar"] in Drupal\Core\Theme\Component\ComponentValidator->validateProps() (line 223 of core/lib/Drupal/Core/Theme/Component/ComponentValidator.php).

Proposed resolution

Add the component ID to the error message. It will help a lot. At least, you can check all component usage.


Catch potential exception when calling Request::create() in PathBasedBreadcrumbBuilder

$
0
0

Problem/Motivation

Due to https://github.com/advisories/GHSA-mrqx-rp3w-jpjp symfony/http-foundation 7.1.7 and 6.4.14 patched Request::create() to throw a BadRequestException exception on certain invalid URLs. When processing such an invalid path, PathBasedBreadcrumbBuilder now throws this new exception.

Steps to reproduce

Visit certain invalid paths such as /:123/foo - an exception will be thrown by PathBasedBreadcrumbBuilder (as can be seen by inspecting the stacktrace of one of the chained exceptions)

Proposed resolution

PathBasedBreadcrumbBuilder should instead catch the new exception and return NULL, which indicates "the path couldn't be matched" and skips this breadcrumb, as it did before the symfony/http-foundation update.

Remaining tasks

Backport/reapply to the 10.5.x and 10.4.x branches.

User interface changes

Sites will once again respond with the 404 error page when such invalid URLs are requested, as they did before the symfony/http-foundation update.

Introduced terminology

API changes

Data model changes

Release notes snippet

Form cache causes issues with media library widget

$
0
0

Problem/Motivation

Seems to be some issue with the form cache interaction with the media library widget, and possibly other complex widgets. Not sure where the issue is exactly though. The problem is that after clicking the "remove" button in the media library widget to remove an already-selected item, the form builder doesn't know that the remove button was clicked, and it instead assumes the first button in the form was clicked, which could be anything. On a simple node form with just a media library widget, the button it clicks is the "add media" button so the media library selection modal opens up incorrectly.

Steps to reproduce

  1. Clean install of Drupal with the Media Library module enabled
  2. Create a content type with a media reference field with all default settings
  3. Create a node of that type, select a media item (upload one), and save the node
  4. Edit the node and click the "remove" button in the media library widget. Observe the correct behavior of the item being removed and the widget reverting to its original empty state
  5. Don't save the node, reload the form in your browser
  6. Again, click the "remove" button in the media library widget. Observe that instead of removing the item and reverting the widget to its original state, the media library selection modal opens up incorrectly.

Here's a video demonstrating the steps above. I started with a fresh form load (no form cache set in key value).

If you have a more complex node form, like one with a paragraphs field on it, what might end up happening instead of the media library modal opening is it that the entire media library widget gets replaced with a paragraph form for a paragraph item!

The wrong behavior is because of this code in FormBuilder:

      // If a form contains a single textfield, and the ENTER key is pressed
      // within it, Internet Explorer submits the form with no POST data
      // identifying any submit button. Other browsers submit POST data as
      // though the user clicked the first button. Therefore, to be as
      // consistent as we can be across browsers, if no 'triggering_element' has
      // been identified yet, default it to the first button.
      $buttons = $form_state->getButtons();
      if (!$form_state->isProgrammed() && !$form_state->getTriggeringElement() && !empty($buttons)) {
        $form_state->setTriggeringElement($buttons[0]);
      }

The wrong element is set as the triggering element for the form submission. Why? Because the form object that's being acted on is used a cached version of the form (cached after step #4 above) which is missing the "remove" button for the media library widget. When the form is being processed, and input elements in the form are checked to see if they were pressed and were the triggering element, the "remove" button doesn't exist in the form so it never sets itself as the triggering element, so it falls back to that logic pasted in above which just picks the first button.

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Logout confirmation form shows inappropriate confirmation description

$
0
0

Problem/Motivation

#144538 added a confirm form to the user logout process that is used in certain circumstances. This form uses the base class' getDescription() method, which populates the form with the default warning "This action cannot be undone". This is inappropriate for the process of logging out, which is not a destructive action.

Steps to reproduce

As a logged in user, directly visit user/logout on a site (to trigger the CSRF protection and use the confirm form). The misleading text will be visible above the confirm/cancel buttons.

Proposed resolution

Override the description in the new confirm form to contain empty text.

Remaining tasks

  1. Create a MR with updated description
  2. Add a test (?)
  3. Review
  4. Commit!

User interface changes

Before:

After:

Allow `title_display` override for parts of `datelist` form element

$
0
0

Problem/Motivation

`Datelist` field is a composite field that has various parts like day, month, year etc.
Users can override the display of main field title using `#title_display` but can't override the title display for parts.

We should allow users to do that.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

admin-toolbar-wrapper: Uncaught TypeError: doc.querySelector(...) is null

$
0
0

Problem/Motivation

For anonymous users, the javascript file admin-toolbar-wrapper.js gets loaded for some reason that I could figure out. That then issues the following error on the browser console:

Uncaught TypeError: doc.querySelector(...) is null
    attach https://www.example.com/core/modules/navigation/js/admin-toolbar-wrapper.js?v=10.4.0:71
    attach https://www.example.com/core/modules/navigation/js/admin-toolbar-wrapper.js?v=10.4.0:158
    attachBehaviors https://www.example.com/core/misc/drupal.js?v=10.4.0:166
    attachBehaviors https://www.example.com/core/misc/drupal.js?v=10.4.0:162
    <anonymous> https://www.example.com/core/misc/drupal.init.js?v=10.4.0:32
    listener https://www.example.com/core/misc/drupal.init.js?v=10.4.0:20

This is due to the following code:

              doc.querySelector('.admin-toolbar').dispatchEvent(
                new CustomEvent(SIDEBAR_CONTENT_EVENT, {
                  detail: {
                    state: newState,
                  },
                }),
              );

Proposed resolution

Check for .admin-toolbar being present.

ModuleHandler::invokeAllWith() does not check listener is actually callable at the moment

$
0
0

Problem/Motivation

In my case, I'm getting this scenario in monitoring tests #3495046: Fix test fails on Drupal 11 because I need to simulate that hooks are going away to rebuild my sensors accordingly. I can work around it there with a container rebuild.

However, I believe this can happen in real-world scenarios as well, typically when updating a module without properly rebuilding the container. You should of course do that, but we know that people often don't.

Steps to reproduce

Visit the status report. Delete one of the requirements hook, refresh the page.

Proposed resolution

Add an is_callable() check to invokeAll. maybe invoke() too.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Allow generic config entities to opt in to the entity specific Manage Permissions form

$
0
0

Problem/Motivation

As part of #2934995: Add a "Manage permissions" tab for each bundle that has associated permissions& #3253955: Let modules opt in to the bundle-specific permissions form, a nice UI to manage bundle-specific permissions directly from the bundle management page was added.

However, according to the Change Record ([#3242827]), it is not possible to provide this feature to generic config entities that provide permissions, like core's Text Formats or Dashboards provided by Dashboard module.

The aim of this issue is to give the possibility to opt-in to include a similar tab for generic config entities.

As an example of this feature, Text Formats opt-in to provide the Manage permissions tab-

Proposed resolution

Provide a way for generic config entities to opt-in the Manage permissions tab.

Remaining tasks

User interface changes

Manage permissions tab is added to Text Formats.

Introduced terminology

API changes

Data model changes

Release notes snippet


Uninstalling a module deletes all views that have third-party settings by that module

$
0
0

Problem/Motivation

When a module saves third-party settings on a view, uninstalling that module will delete the view (instead of just removing the third-party settings).

This exact problem is normally taken care of by \Drupal\Core\Config\Entity\ConfigEntityBase::onDependencyRemoval(). However, the Views entity class overrides the method but fails to call the parent (or fix the problem itself).

Steps to reproduce

  1. Write a small module that adds third-party settings to a view.
  2. Go to the “Uninstall” page and select your module.
  3. On the confirm form, you will see that the view will get deleted.

Proposed resolution

Unless there is a good reason not to do that, I would suggest just calling the parent method.

Remaining tasks

  • Agree on the solution.
  • Implement it.

User interface changes

None.

Introduced terminology

None.

API changes

None.

Data model changes

None.

Release notes snippet

N/A

Rewrite as URL adding equals sign to end of url.

$
0
0

Problem/Motivation

Currently drupal_get_query_array does't support a syntax like that 'http://domain.org?flag' because it sets the value
of flag to "". If drupal_http_build_query is called on this it is converted to 'http://domain.org?flag=' which is wrong.

Proposed resolution

Convert empty string values from keys not containing an equal sign to NULL, so the URL is kept as expected.

Remaining tasks

Convert #64 patch to a MR.
Review

Original report by [robit8deb]

// Text of original report here.
(for legacy issues whose initial post was not the issue summary)
I have a scenario where a customer is using an external website in correlation with his drupal site. The external vendor is using poorly formatted urls that are getting (correctly) rewritten with and = sign at the end because it is expecting a value. For example, http:///foo.cgi?foo gets rewritten to http:///foo.cgi?foo=. I need to turn off this validation because the resulting url with the = sign at the end takes the user to page cannot be displayed.

I fixed this behavior on link cck fields using this patch:

http://drupal.org/node/1306352

However, the field that i am rewriting now is a Boolean field where, when on, gets rewritten to a link.

Please advise.

TypeError: Cannot access offset of type Drupal\Core\StringTranslation\TranslatableMarkup in isset or empty in Drupal\update\ProjectCoreCompatibility->getPossibleCoreUpdateVersions when enabling this module

$
0
0

my D11 site is composer installed/managed,

drush status | grep -i version
	Drupal version   : 11.1.0
	PHP version      : 8.4.2
	Drush version    : 13.3.3.0

served up on a linux instance of nginx/1.27.3.

it's got a few added modules installed, and some dummy content populating it.
so, a real-world use case, but not a _large_ install by any stretch.

as advised here

https://www.drupal.org/docs/develop/core-modules-and-themes/core-modules...

"If you installed Drupal with Composer, you will need to update with Composer (https://www.drupal.org/docs/develop/using-composer/manage-dependencies)"

all good, that's the goal; `update_manager` module is DISabled.

but, a site status check reports:

"Update notifications are not enabled. It is highly recommended that you install the Update Manager module from the module administration page in order to stay up-to-date on new releases. For more information, Update status handbook page."

the site _seems_ to be behaving without it through install and inital use.
until _after_ i enable update_manager.

enabling is fine; but subsequently any site access sees this FATAL error:

The website encountered an unexpected error. Try again later.

TypeError: Cannot access offset of type Drupal\Core\StringTranslation\TranslatableMarkup in isset or empty in Drupal\update\ProjectCoreCompatibility->getPossibleCoreUpdateVersions() (line 83 of core/modules/update/src/ProjectCoreCompatibility.php).

Drupal\update\ProjectCoreCompatibility->__construct(Array, Array, Array) (Line: 106)
update_calculate_project_data(Array) (Line: 40)
update_requirements('runtime')
call_user_func_array('\update_requirements', Array) (Line: 355)
Drupal\Core\Extension\ModuleHandler->{closure:Drupal\Core\Extension\ModuleHandler::invokeAll():354}('\update_requirements', 'update') (Line: 307)
Drupal\Core\Extension\ModuleHandler->invokeAllWith('requirements', Object) (Line: 354)
Drupal\Core\Extension\ModuleHandler->invokeAll('requirements', Array) (Line: 109)
Drupal\system\SystemManager->listRequirements() (Line: 93)
Drupal\system\SystemManager->checkRequirements() (Line: 122)
Drupal\system\Controller\SystemController->overview('system.admin_config')
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->{closure:Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber::wrapControllerExecutionInRenderContext():121}() (Line: 593)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 121)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->{closure:Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber::onController():96}() (Line: 183)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 53)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 28)
Drupal\Core\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 32)
Drupal\big_pipe\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 116)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 90)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 36)
Drupal\Core\StackMiddleware\AjaxPageState->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 709)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

simply DISabling (drush pm:uninstall udpate) fixes the issue, and the site's immediately accessible & functional as before.

i suspect (?), but don't yet know, this is due to php version 8.4.2, which i understand Drupal is NOT compatible with.
yet.
but IS on the roadmap.
there's not specific indication of a php problem -- that i've found so far.

not sure if this

Hide and restrict package_manager (and update_manager) behind a dev/prod toggle so that they can be alpha stability in tagged releases
https://www.drupal.org/project/drupal/issues/3483481

includes an option to disable the complaint (?).

Add note to log when site put into and taken out of Offline mode

$
0
0

It's useful to know when a site went into and came back out of maintenance mode, so it would be nice if this information was added to the admin log when it happened.

Consider a more substantial shortcuts placeholder

$
0
0

Problem/Motivation

The shortcuts links are rendered via a placeholder (and hence bigpipe), which is good.

However due to the &nsbbp; placeholder the parent link pops in after the page is loaded. Because it is generally quite high above the fold, this can be quite obvious.

Steps to reproduce

Proposed resolution

Can we just render the shortcuts top level link as a placeholder? This doesn't need any special caching and it means there is no visual effect when the placeholder/lazy builder is replaced.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Viewing all 298646 articles
Browse latest View live


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