Problem/Motivation

Using non-object services is deprecated as of Symfony 4.4. We create the app.root services as a string in our services file.

Proposed resolution

Replace the string services with container parameters.

Plan for 8.9.x

Commit this patch without the deprecations
Decide whether to convert usages of the services

Plan for 8.8.x

Decide whether to commit a patch adding the new parameters.

Remaining tasks

User interface changes

None

API changes

The app.root, app.root.factory, site.path and site.path.factory services are deprecated. There are new container parameters app.root and site.path that should be used instead.

Data model changes

None

Release notes snippet

The app.root and site.path services are deprecated. Use the app.root and site.path container parameters instead.

CommentFileSizeAuthor
#91 interdiff_89-91.txt443 bytesvsujeetkumar
#91 3074585-91.patch42.98 KBvsujeetkumar
#89 interdiff_87-89.txt433 bytesvsujeetkumar
#89 3074585-89.patch42.41 KBvsujeetkumar
#87 interdiff_85-87.txt1.86 KBvsujeetkumar
#87 3074585-87.patch41.86 KBvsujeetkumar
#85 interdiff_81-85.txt1.65 KBravi.shankar
#85 3074585-85.patch39.83 KBravi.shankar
#81 3074585-89.patch41.32 KBravi.shankar
#69 3074585-param-69.patch48.1 KBalexpott
#69 66-69-interdiff.txt581 bytesalexpott
#66 3074585-param-66.patch48 KBalexpott
#66 63-66-interdiff.txt1001 bytesalexpott
#63 3074585-param-63.patch47.5 KBalexpott
#63 62-63-interdiff.txt1.16 KBalexpott
#62 3074585-param-62.patch47.4 KBalexpott
#62 58-62-interdiff.txt1.03 KBalexpott
#58 3074585-param-58.patch46.91 KBalexpott
#58 57-58-interdiff.txt1.85 KBalexpott
#57 3074585-param-57.patch46.89 KBalexpott
#54 3074585+3111008-54.patch54.18 KBalexpott
#51 3074585-51.drupal-interdiff.txt952 bytesBerdir
#51 3074585-51.drupal.patch56.71 KBBerdir
#49 3074585-49.drupal-interdiff.txt8.18 KBBerdir
#49 3074585-49.drupal.patch57.64 KBBerdir
#39 interdiff.3074585.38-39.txt52.41 KBmikelutz
#39 3074585-39.drupal.patch57.32 KBmikelutz
#38 3074585-38.drupal.patch18.08 KBmikelutz
#38 interdiff.3074585.36-38.txt16.9 KBmikelutz
#36 interdiff.3074585.30-36.txt16.45 KBmikelutz
#36 3074585-36.drupal.patch18.29 KBmikelutz
#30 interdiff.3074585.29-30.txt1.95 KBmikelutz
#30 3074585-30.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch16.25 KBmikelutz
#29 interdiff.3074585.28-29.txt916 bytesmikelutz
#29 3074585-29.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch16.5 KBmikelutz
#28 interdiff.3074585.26-28.txt3.83 KBmikelutz
#28 3074585-28.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch16.39 KBmikelutz
#26 3074585-26.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch14.09 KBmikelutz
#23 3074585-22.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch34.72 KBmikelutz
#22 interdiff.3074585.17-22.txt4.96 KBmikelutz
#22 3074585-22.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch34.76 KBmikelutz
#18 interdiff.3074585.16-17.txt5.3 KBmikelutz
#18 3074585-17.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch32.74 KBmikelutz
#17 interdiff.3074585.16-17.txt5.3 KBmikelutz
#17 3074585-17.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch32.73 KBmikelutz
#16 interdiff.3074585.15-16.txt773 bytesmikelutz
#16 3074585-16.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch28.82 KBmikelutz
#15 interdiff.3074585.9-15.txt740 bytesmikelutz
#15 3074585-15.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch28.06 KBmikelutz
#14 3074585-14.drupal.testing_with_spl.patch1.3 KBmikelutz
#9 interdiff.3074585.6-9.txt616 bytesmikelutz
#9 3074585-9.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch28.04 KBmikelutz
#6 3074585-6.drupal.Symfony-5-Deprecate-approot-and-sitepath-services-and-either-access-DrupalKernalgetAppRoot-and-getSitePath-directly-or-add-other-suitable-alternative.patch28.14 KBmikelutz
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mikelutz created an issue. See original summary.

mikelutz’s picture

Looking deeper, it's possible our service.yml implementation is fine, the deprecations I'm seeing might be coming from unit tests setting $container->set('app.root', $this->root) directly. I'm still looking into it.

Gábor Hojtsy’s picture

Title: Deprecate app.root and site.path services and either access DrupalKernal->getAppRoot and ->getSitePath directly, or add other suitable alternative. » [Symfony 5] Deprecate app.root and site.path services and either access DrupalKernal->getAppRoot and ->getSitePath directly, or add other suitable alternative.
Issue tags: -Symfony 4 +Symfony 5

This is Symfony 5 compatibility.

Gábor Hojtsy’s picture

alexpott’s picture

There might be some mileage in doing this in Drupal 8 because we're going to trigger these deprecations an awful lot. These are very very low level services for Drupal.

Some other thoughts:

  • app.root probably should be should be a container parameter - determined during container build. If you move the code you should have to do a container rebuild. The rebuild can determine the new app.root.
  • site.path is determined by the request and should be part of that system - and so should be a service of some sort with the request stack injected. One massive problem we have is that site.path determines which modules can possibly by installed and where their code is and so this does things that the Symfony container is not really optimised for.
  • At the moment both are determined by DrupalKernel - see \Drupal\Core\DrupalKernel::findSitePath and \Drupal\Core\DrupalKernel::guessApplicationRoot
mikelutz’s picture

Let's see what happens if we convert app.root to a container parameter.

I'm thinking that converting app.root and site.path might best be two separate issues.

mikelutz’s picture

Title: [Symfony 5] Deprecate app.root and site.path services and either access DrupalKernal->getAppRoot and ->getSitePath directly, or add other suitable alternative. » [Symfony 5] Deprecate app.root service and replace with a container parameter.
Issue summary: View changes
Related issues: +#3080652: [Symfony 5] Deprecate site.path as a string service and replace with a method on a regular service
alexpott’s picture

I think we need to add the app.root to \Drupal\Core\DrupalKernel::getContainerCacheKey() to avoid the problems that @catch eludes to in #2328111-48: Replace most instances of the DRUPAL_ROOT constant with the app.root container parameter (thanks @chx for the archaeology).

Mile23’s picture

app.root is generated by app.root.factory. The history is here: #2328111-102: Replace most instances of the DRUPAL_ROOT constant with the app.root container parameter

Re: #5:

At the moment both are determined by DrupalKernel - see \Drupal\Core\DrupalKernel::findSitePath and \Drupal\Core\DrupalKernel::guessApplicationRoot

The root path is actually determined by the front controller, which should inject it into the kernel.That's why it's a guess on the part of the kernel if it's not injected. See DrupalKernel::__construct().

In an ideal world, we'd deprecate guessApplicationRoot(), so that we require the root path to be injected, and it can be added to the container as a parameter during container build time. And the site path would be determined by a service provider that acts as a site router.

But the scope here is make things work with Symfony 5, so maybe we don't live in that ideal world. :-)

Mile23’s picture

So core.services.yml says this:

  app.root:
    class: SplString
    factory: app.root.factory:get
    tags:
      - { name: parameter_service }
  app.root.factory:
    class: Drupal\Core\AppRootFactory
    arguments: ['@kernel']
    public: false

And then AppRootFactory::get() says this:

  /**
   * Gets the app root.
   *
   * @return string
   */
  public function get() {
    return $this->drupalKernel->getAppRoot();
  }

...which is not an SplString.

So if SplString satisfies our need for an object, then we should modify AppRootFactory::get() to return an SplString.

mikelutz’s picture

Status: Needs work » Needs review
FileSize
1.3 KB

Interesting. Neither locally, nor in any of my hosting environments do I have the SPL_Types php extension installed. Pecl errored out on the one attempt I made to install it locally. None of my goto online php testers support it either. I could go as far as trying to get it running in a container, but I suspect if I don't have it installed by default anywhere, then adding it in as a requirement is going to be problematic. I suspect it's not going to be available on testbot either.

Per the symfony documentation:

When using a factory to create services, the value chosen for class has no effect on the resulting service. The actual class name only depends on the object that is returned by the factory. However, the configured class name may be used by compiler passes and therefore should be set to a sensible value.

mikelutz’s picture

mikelutz’s picture

Okay, injecting the app root into the container cache key, a couple basic tests, cleanup on the app.root service deprecation. I think this is ready for review now, depending on what breaks by changing the cache key or fixing the deprecations.

alexpott’s picture

@mikelutz nice work this looks really good to me. Given that the container has different cache keys for different site roots I think we've got a good answer for the original concern as different site roots will use a different container.

Hmmm this raises an interesting concern - what happens if the containers can out-of-sync? Maybe we're doing this wrong. Maybe instead of adding it to the cache key we need to fail and point people at the rebuild process.

mikelutz’s picture

As in someone moves the site, gets a new container, something changes in the new container definition, and then they move it back and pulls the old container from the cache not realizing it needs a rebuild?

alexpott’s picture

#20 yep that's a very clear expression of my concern.

mikelutz’s picture

Do we need to bail and go to rebuild.php, or can we just catch it from the cached container definition before building the container and force a container rebuild if it has changed?

My main concern here is are we ever creating a temporary kernel with a guessed app.root somewhere I don't know about? If we did, then it could cause the cache to be continuously invalidated, Which I don't want to happen.

alexpott’s picture

I think going to rebuild.php is probably best. Automatically rebuilding could get a set in a very interesting state. Going to rebuild.php would at least allow someone to discover they are in this state.

mikelutz’s picture

mikelutz’s picture

Here's an attempt at a Proof of Concept of another approach, switching them both to objects implementing __toString(). this would allow for minimal disruption, however, I've found a case in core where we use the value of those services as an array key, and php does not like using the new stringable objects as array keys. I casted the places I found in ExtensionDiscovery, but testbot might find more.

No interdiff, as it's pretty much start from scratch.

mikelutz’s picture

catch’s picture

Priority: Normal » Major

This looks like a good minimal change to get rid of the deprecation to me.

mikelutz’s picture

I also just proved that it fixes the APCu issue with the installer in SF4 #2976394-270: Allow Symfony 4.4 to be installed in Drupal 8

catch’s picture

Priority: Major » Critical

Bumping priority again to critical, partly due to it fixing the test failure, partly because it'll be critical for Drupal 9 if not so much 8.

mikelutz’s picture

Title: [Symfony 5] Deprecate app.root service and replace with a container parameter. » [Symfony 5] Replace app.root and site.path string services with objects implementing __toString()
Issue summary: View changes
alexpott’s picture

  1. +++ b/core/lib/Drupal/Core/AppRootFactory.php
    @@ -30,7 +30,7 @@ public function __construct(DrupalKernelInterface $drupal_kernel) {
        * @return string
        */
       public function get() {
    -    return $this->drupalKernel->getAppRoot();
    +    return new StringableObject($this->drupalKernel->getAppRoot());
    

    I think we should update the return documentation

  2. +++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
    @@ -104,7 +104,7 @@ class ExtensionDiscovery {
       public function __construct($root, $use_file_cache = TRUE, $profile_directories = NULL, $site_path = NULL) {
    -    $this->root = $root;
    +    $this->root = (string) $root;
    

    Do we want to deprecate passing in a string $root and $site_path?

  3. +++ b/core/lib/Drupal/Core/SitePathFactory.php
    @@ -31,7 +31,7 @@ public function __construct(DrupalKernelInterface $drupal_kernel) {
        *   The site path.
        */
       public function get() {
    -    return $this->drupalKernel->getSitePath();
    +    return new StringableObject($this->drupalKernel->getSitePath());
       }
    

    Need to update the return documentation

  4. +++ b/core/lib/Drupal/Core/StringableObject.php
    @@ -0,0 +1,34 @@
    +namespace Drupal\Core;
    +
    +/**
    + * An object to hold a string value.
    + */
    +class StringableObject {
    

    I'd be tempted to put this in core/lib/Drupal/Core/DependencyInjection as this exists for the purposes of the container. In and of itself I don't think we want usage of this case to spread.

mikelutz’s picture

WRT #35-2, I think I'd rather just typehint the string in the constructor to automatically cast it, since we really want to be working with a string anyway.

alexpott’s picture

  1. +++ b/core/lib/Drupal/Core/DependencyInjection/StringableServiceObject.php
    @@ -1,11 +1,11 @@
    -class StringableObject {
    +class StringableServiceObject {
    
    @@ -15,7 +15,7 @@ class StringableObject {
    -   * Constructs a StringableObject object.
    +   * Constructs a StringableServiceObject object.
    

    Maybe the word object is now redundant so maybe StringableService - I mean in some ways both service and object are pretty meaningless but I think here the word service does have some meaning as this object is only mean to be used where we need a service on the container that represents a string.

  2. +++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
    @@ -103,8 +103,8 @@ class ExtensionDiscovery {
    +  public function __construct(string $root, $use_file_cache = TRUE, array $profile_directories = NULL, string $site_path = NULL) {
    

    +1 for the primitive type hints. It makes the code quite elegant.

  3. One thought though is that this is a breaking change where contrib / custom is expecting a string. Perhaps we should take the opportunity to create new service names and leave the old service string alone and deprecate them?
mikelutz’s picture

It is a breaking change. In most cases, the object will simply be typecast to a string where needed. The big exception will be if the value happens to be used as an array key, in which case it will need to be explicitly cast.

Deprecating and replacing is probably the right way to go, but the practical considerations at this point (at least in terms of trying to deprecate in Drupal 8 and remove in Drupal 9) give me pause.

Switching to these objects from the existing strings might hard break a small percentage of code that uses these services.

Deprecating and replacing will require all code that uses these services to be updated.

There is also the time constraint of actually getting a patch written, RTBCed and committed by the 8.8 alpha deadline in two days.

So maybe we need to deprecate for removal in Drupal 10, sometime before 9.0.0 alpha. That solves the time constraint, and reduces the disruption, giving everyone much more time to update.

mikelutz’s picture

Here's a first attempt at deprecate and replace via search and replace. I haven't yet really read through the resulting patch yet, I just wanted to throw it at testbot.

mikelutz’s picture

Well, then there you go... We could probably avoid the factories and even the StringableService class and make custom new services that depend on the kernel, but that makes mocking/replacing them tougher.

mikelutz’s picture

Version: 8.8.x-dev » 9.0.x-dev
andypost’s picture

larowlan’s picture

Wim Leers’s picture

  1. +++ b/core/core.services.yml
    @@ -196,7 +196,7 @@ services:
    -    arguments: ['@app.root', '@site.path', '@cache_tags.invalidator.checksum']
    +    arguments: ['@application.root', '@site.sitepath', '@cache_tags.invalidator.checksum']
    
    @@ -706,8 +706,14 @@ services:
       app.root:
    -    class: SplString
    +    class: \SplString
         factory: app.root.factory:get
    +    deprecated: The "%service_id%" service is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the application.root service instead. See https://www.drupal.org/node/3080612
    +    tags:
    +      - { name: parameter_service }
    +  application.root:
    +    class: Drupal\Core\DependencyInjection\StringableService
    +    factory: app.root.factory:getService
         tags:
           - { name: parameter_service }
    

    The issue summary does not explain the rationale for this rename?

  2. +++ b/core/core.services.yml
    @@ -706,8 +706,14 @@ services:
       app.root.factory:
    

    🤔 It's odd to app.root.factory and application.root. Weirdly inconsistent?

  3. +++ b/core/core.services.yml
    @@ -715,8 +721,14 @@ services:
       site.path:
    -    class: SplString
    +    class: \SplString
         factory: site.path.factory:get
    +    deprecated: The "%service_id%" service is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the site.sitepath service instead. See https://www.drupal.org/node/3080612
    +    tags:
    +      - { name: parameter_service }
    +  site.sitepath:
    +    class: Drupal\Core\DependencyInjection\StringableService
    +    factory: site.path.factory:getService
         tags:
           - { name: parameter_service }
       site.path.factory:
    

    Same remarks here.

neclimdul’s picture

A lot of this is rehashes of the discussion on #2536012: The app.root and site.path services are invalid so linking it. The generic utility class over there makes a lot of sense as well instead of a one off. :shrug:

effulgentsia’s picture

I'm wondering how to reconcile this issue with #3088246-20: [policy, no patch] How to handle Drupal 8.9.x deprecations (see also https://groups.drupal.org/node/535670). Is this something that's ok to punt to 9.1, or is it necessary to make 9.0 (and 8.9?) not invoke any Symfony 4.4 deprecations?

If it's necessary to make 9.0/8.9 not invoke Symfony 4.4 deprecations, is it reasonable to add the new services (and use them in core), but not yet mark the old ones as deprecated until 9.1?

Or, do we need to discuss making this (Critical) issue an exception to the policy in https://groups.drupal.org/node/535670?

catch’s picture

We haven't got a deprecation message for this listed in DeprecationListenerTrait::getSkippedDeprecations() so it seems like resolving it wasn't a blocker for moving to Symfony 4.4. Apart from the issue in #2536012: The app.root and site.path services are invalid which is a general bug, I'm not sure exactly what the issue is here so we definitely need an issue summary update.

I do think we should consider making exceptions for Symfony 4.4/5.0 compatibility issues for 8.9.x/9.0.x deprecations so that there's less change later on, just not clear whether this really is one or not.

Berdir’s picture

When I run a test on D9 that expects a certain deprecation message then I get this output:

Failed asserting that string matches format description.
--- Expected
+++ Actual
@@ @@
 @expectedDeprecation:
-%A  Drupal\system\Plugin\views\field\BulkForm is deprecated in drupal:8.5.0, will be removed before drupal:9.0.0. Use \Drupal\views\Plugin\views\field\BulkForm instead. See https://www.drupal.org/node/2916716.
-  The "Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser" class is deprecated since Symfony 4.3, use "Symfony\Component\Mime\FileBinaryMimeTypeGuesser" instead.
+  The "Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser" class is deprecated since Symfony 4.3, use "Symfony\Component\Mime\MimeTypes" instead.
+  The "Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser" class is deprecated since Symfony 4.3, use "Symfony\Component\Mime\FileBinaryMimeTypeGuesser" instead.
+  The "Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser" class is deprecated since Symfony 4.3, use "Symfony\Component\Mime\FileinfoMimeTypeGuesser" instead.
+  The "Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory" class is deprecated since symfony/psr-http-message-bridge 1.2, use PsrHttpFactory instead.
+  The "psr7.http_message_factory" service relies on the deprecated "Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory" class. It should either be deprecated or its implementation upgraded.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "app.root" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.
+  Non-object services are deprecated since Symfony 4.4, please fix the "site.path" service which is of type "string" right now.

Took me a while to find them too but the problem is that they are dynamic, so we put it in \Drupal\Tests\Listeners\DeprecationListenerTrait::isDeprecationSkipped.

But I'm not sure if we should be doing that, as this suppresses it for all other string services too that custom/contrib code might add?

Berdir’s picture

Starting with a reroll, I assume that this is a D9 issue now as there's no reason to fix this in D8 anymore, as we'll never update to symfony 4 there.

While rerolling, I did remove a large chunk (mostly comment) in \Drupal\KernelTests\Core\Theme\BaseThemeDefaultDeprecationTest that apparently isn't needed anymore to pass the test.

And of course a few changes were for code that is now removed in D9.

I also removed the skipped deprecation messages now and fixed a few new instances that use app.root. Still quite a bit of cleanup to do.

Status: Needs review » Needs work

The last submitted patch, 49: 3074585-49.drupal.patch, failed testing. View results

Berdir’s picture

Status: Needs work » Needs review
FileSize
56.71 KB
952 bytes

That was an accidental leftover where I tested that the deprecation message is gone.

shrop’s picture

Issue summary: View changes
mikelutz’s picture

But I'm not sure if we should be doing that, as this suppresses it for all other string services too that custom/contrib code might add?

In. retrospec, those shouldn't have been dynamically skipped like that, although the plan was and is to get rid of all of these SF5 skipped deprecations early enough in the D9 cycle to surface those deprecations for contrib/custom code in plenty of time for D10.

alexpott’s picture

So here's one idea that builds on #3111008: Use native Symfony YamlLoader + Config and brings in the Symfony expression language.

However I have a few concerns about this - namely the additional complexity. I thought I'd leave it here in case it inspires any thoughts... I'm not a huge fan of StringableService - it seems way too parameter like for my taste.

This patch will fail at least a few tests but Drupal installs and at least 1 functional test passes.

Status: Needs review » Needs work

The last submitted patch, 54: 3074585+3111008-54.patch, failed testing. View results

alexpott’s picture

So #54 is possible :) - but as I said we're adding a tonne of complexity and at least the first get to each version of the expression needs work. It's cached afterwards in a static array cache - almost certainly possible to store the parsed expression in our db dumped container so that would save this work.

alexpott’s picture

Status: Needs work » Needs review
FileSize
46.89 KB

Here's a simpler solution using parameters again like #23 but importantly without the downsides. Because it sets the parameters on the compiled container dynamically prior to re-instantiating it.

alexpott’s picture

It seems there's an instance where we have a container without a kernel - interesting. But not the fault of this patch...

The last submitted patch, 57: 3074585-param-57.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 58: 3074585-param-58.patch, failed testing. View results

mikelutz’s picture

I haven't reviewed the patch fully, but I wasn't a fan of stringable service either. At the time I was playing with it, it was an easy way to try to make the move in D8 quickly with minimal disruption. If we've moved on to fixing this in D9 as we should be at this point, a more robust and correct solution makes a lot more sense, as we have time to deprecate and fix the system properly like this.

alexpott’s picture

Status: Needs work » Needs review
FileSize
1.03 KB
47.4 KB

So delved into why

we have a container without a kernel

- see fails in #57 and the fix n #58. It's because we have extension objects stored in the FileCache and we use this when compiling the container. So right now in HEAD when compiling the container we fallback to DRUPAL_ROOT in \Drupal\Core\Extension\Extension::__wakeup() when it is called during initialising service providers as part of the very very early code in the container compilation. This occurs even before the container as the kernel service set! The funny thing is that we could cache these objects with the app root here because it is stored in the file cache and therefore cached by the absolute path. However we can't assume that all caches that store extension objects are keyed by something that represents the absolute path.

Since the above is all happening in HEAD atm - I've changed change \Drupal\Core\Extension\Extension::__wakeup() in the patch to behave in the same way - ie. falling back to DRUPAL_ROOT at this point. I've also added docs so that we eventually try to remove \Drupal we'll be aware that we have to handle this in some way.

alexpott’s picture

The comment in the code in #62 is not my best. Trying again.

alexpott’s picture

I've opened #3116858: Don't cache whole extension objects in FileCache to address the Extension object relying on DRUPAL_ROOT issue.

alexpott’s picture

Title: [Symfony 5] Replace app.root and site.path string services with objects implementing __toString() » [Symfony 5] Replace app.root and site.path string services with container parameters
Issue summary: View changes

Updating the issue summary.

Also I think we should consider backporting without the deprecations to 8.9.x. To that end we should reimplement the services to return the container parameter.

alexpott’s picture

mikelutz’s picture

+1 to this approach, and the code looks good to me. I'll leave it to someone else to RTBC since I started down the parameter route in #23

heddn’s picture

Status: Needs review » Reviewed & tested by the community

Using the parameters makes sense to me. CR looks good. One small nit (can be fixed on commit):

+++ b/core/core.services.yml
@@ -1,4 +1,8 @@
+  # The app.root and site.path parameters are dynamically by

"are dynamically provided" or something like that. Seems to be missing some words.

alexpott’s picture

Fixed the comment and went into a bit more detail why it's worth listed them there.

heddn’s picture

+1 on the comment updates

catch’s picture

Issue summary: View changes

  • catch committed e79723c on 9.0.x
    Issue #3074585 by mikelutz, alexpott, Berdir, Mile23, heddn,...
catch’s picture

Committed/pushed to 9.0.x, thanks!

Removing the deprecations for 8.9.x seems good, not 100% sure on the conversions.

catch’s picture

Version: 9.0.x-dev » 8.9.x-dev
Status: Reviewed & tested by the community » Needs work

Moving to needs work for the 8.9.x backport.

alexpott’s picture

Issue summary: View changes

Filling out the 8.9.x and 8.8.x plans after discussing with @catch a bit.

I think we have two decisions to make:

  • Whether to convert the service usages to the params in 8.9.x - I'm in favour of that because it keeps 8.9.x and 9.0.0 closer making patches easier.
  • What to do about 8.8.x - I think we should consider adding the parameters there to make it easier for contrib to support 8.8.x -> 9.0.0.
andypost’s picture

Looks it missing post update hook to cause rebuild of container

alexpott’s picture

@andypost the container is keyed by \Drupal::VERSION - we don't need post updates to do that.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

ravi.shankar’s picture

Assigned: Unassigned » ravi.shankar

Working on this.

ravi.shankar’s picture

Assigned: ravi.shankar » Unassigned
Status: Needs work » Needs review
FileSize
41.32 KB

Here I have added reroll of patch #69 for Drupal 8.9.x.

Status: Needs review » Needs work

The last submitted patch, 81: 3074585-89.patch, failed testing. View results

alexpott’s picture

+++ b/core/core.services.yml
@@ -717,23 +722,27 @@ services:
-    class: SplString
+    class: \SplString
     factory: app.root.factory:get
+    deprecated: The "%service_id%" service is deprecated in drupal:9.0.0 and is removed from drupal:10.0.0. Use the app.root parameter instead. See https://www.drupal.org/node/3080612
     tags:
       - { name: parameter_service }
   app.root.factory:
     class: Drupal\Core\AppRootFactory
     arguments: ['@kernel']
     public: false
+    deprecated: The "%service_id%" service is deprecated in drupal:9.0.0 and is removed from drupal:10.0.0. Use the app.root parameter instead. See https://www.drupal.org/node/3080612
   site.path:
-    class: SplString
+    class: \SplString
     factory: site.path.factory:get
+    deprecated: The "%service_id%" service is deprecated in drupal:9.0.0 and is removed from drupal:10.0.0. Use the site.path parameter instead. See https://www.drupal.org/node/3080612
     tags:
       - { name: parameter_service }
   site.path.factory:
     class: Drupal\Core\SitePathFactory
     arguments: ['@kernel']
     public: false
+    deprecated: The "%service_id%" service is deprecated in drupal:9.0.0 and is removed from drupal:10.0.0. Use the site.path parameter instead. See https://www.drupal.org/node/3080612

We should not be deprecating these service in D8. None of this should change.

alexpott’s picture

Also I think that now we have 8.9.0 what we should backport has changed. I think we need to follow the plan for 8.8.x. I.e. I think we should consider adding the parameters there to make it easier for contrib to support 8.8.x -> 9.0.0.

We shouldn't change any existing services. All we need to ensure is that the container has the new parameters and they are correct.

Note given that the services still exist in D9 the other option is to close this issue. If you want to be be D8 and D9 compatible use the deprecated services.

ravi.shankar’s picture

Here I have made changes as suggested in comment #83.

We still need to address comment #84.

catch’s picture

Title: [Symfony 5] Replace app.root and site.path string services with container parameters » [backport] [Symfony 5] Replace app.root and site.path string services with container parameters

Retitling to make it clearer when scanning the issue queue that we're only discussing the backport here.

Technically it's too late to add the new services to 8.9.x, but we might want to make an exception and backport anyway.

vsujeetkumar’s picture

Status: Needs work » Needs review
FileSize
41.86 KB
1.86 KB

Fixing test, Please review.

Status: Needs review » Needs work

The last submitted patch, 87: 3074585-87.patch, failed testing. View results

vsujeetkumar’s picture

Status: Needs work » Needs review
FileSize
42.41 KB
433 bytes

Fixed test, Please review.

Status: Needs review » Needs work

The last submitted patch, 89: 3074585-89.patch, failed testing. View results

vsujeetkumar’s picture

Status: Needs work » Needs review
FileSize
42.98 KB
443 bytes

Fixed test, Please review.

longwave’s picture

Status: Needs review » Needs work

If we are to backport this now we can't make all these changes, we can only add the new services as in #84. But at this stage, perhaps this is just "won't fix" for 8.9.x and can be closed as fixed in D9?

catch’s picture

Title: [backport] [Symfony 5] Replace app.root and site.path string services with container parameters » [Symfony 5] Replace app.root and site.path string services with container parameters
Version: 8.9.x-dev » 9.0.x-dev
Status: Needs work » Fixed

At this point I think we should just mark this fixed against 9.0.x - the window for supporting both 8.9.x and 9.1.x is already half gone since this was originally committed.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

Wim Leers’s picture

Wim Leers’s picture

FYI: this is how you can be compatible with Drupal 8 and 9 while not triggering any Drupal 10 deprecation notices (i.e. be compatible with Drupal 8, 9 and 10):

diff --git a/cdn.services.yml b/cdn.services.yml
index da9db27..c12756d 100644
--- a/cdn.services.yml
+++ b/cdn.services.yml
@@ -5,7 +5,7 @@ services:
 
   cdn.file_url_generator:
     class: Drupal\cdn\File\FileUrlGenerator
-    arguments: ['@app.root', '@stream_wrapper_manager', '@request_stack', '@private_key', '@cdn.settings']
+    arguments: ['%app.root%', '@stream_wrapper_manager', '@request_stack', '@private_key', '@cdn.settings']
 
   # Event subscribers.
   cdn.config_subscriber:
diff --git a/src/CdnServiceProvider.php b/src/CdnServiceProvider.php
index aec1a4b..365b133 100644
--- a/src/CdnServiceProvider.php
+++ b/src/CdnServiceProvider.php
@@ -29,6 +29,12 @@ class CdnServiceProvider implements ServiceProviderInterface {
         //   banned, without having to run this middleware.
         ->addTag('http_middleware', ['priority' => 230]);
     }
+    // @todo Delete this when dropping Drupal 8 support in https://www.drupal.org/project/cdn/issues/3103682.
+    if (version_compare(\Drupal::VERSION, '9.0', '<')) {
+      // @see https://www.drupal.org/project/drupal/issues/3074585
+      $container->getDefinition('cdn.file_url_generator')
+        ->setArgument(0, '@app.root');
+    }
   }
 
   /**

Also added this to the change record.

(Developed in #3228162: Fix Drupal 9-only deprecation notices while retaining Drupal 8 compatibility.)