Problem/Motivation

https://www.drupal.org/node/3018145
The sync directory is defined in $settings and not $config_directories

Proposed resolution

In #3154341: Doesn't detect the $config_directories deprecation we attempted a runtime check for this, but that turned out to be futile due to how https://git.drupalcode.org/project/drupal/-/blob/8.9.x/core/lib/Drupal/C... copies the value both ways, so once that runs, we cannot tell if the setting was set or the global was set as both will be set. If they are different, $settings['config_sync_directory']; will prevail so they will also never be different. So we cannot really check this by merely looking at runtime values.

Include settings.php and gather values that way.

Remaining tasks

Commit.

User interface changes

When using both values:

When using only the deprecated value:

When using only the non-deprecated value or neither:

API changes

Data model changes

Release notes snippet

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Gábor Hojtsy created an issue. See original summary.

gábor hojtsy’s picture

Carrying reporter credits for #3154341: Doesn't detect the $config_directories deprecation for @tedbow.

gábor hojtsy’s picture

Status: Active » Needs review

I think I have a rough idea. The settings object require's settings.php and encapsulates the values. We could do the same, just need the precise location of the settings file for the request. That could be gained from the DrupalKernel. We need a clean way to get the kernel already constructed for the page. Something along these lines:

function encapsulatedConfigDirectoryCheck() {
  // This is ugly but is defined in index.php :P 
  global $kernel;

  $app_root = $kernel->getAppRoot();
  $site_path = $kernel->getSitePath();
  if (is_readable($app_root . '/' . $site_path . '/settings.php')) {
    require $app_root . '/' . $site_path . '/settings.php';
  }
  
  // Now check values. We cannot check this from Settings::get() because that
  // obscures the deprecated value. Settings:initialise() does trigger an error
  // but that is well before our code has a chance to run.
  if (!empty($config_directories)) {
    return TRUE;
  }
}
gábor hojtsy’s picture

StatusFileSize
new3.12 KB

Here is an untested implementation.

gábor hojtsy’s picture

Issue tags: +Needs manual testing

Consider it lightly tested now :D Needs more manual testing.

gábor hojtsy’s picture

StatusFileSize
new3.11 KB

Whitespace fixes.

gábor hojtsy’s picture

StatusFileSize
new5.12 KB

Apparently it is also registered on the container by itself, so we can also get it from there.

gábor hojtsy’s picture

dydave’s picture

Status: Needs review » Needs work
StatusFileSize
new53.43 KB

Hi Gabor,

Thanks very much for the patch.
Just tested it on:

  • Drupal: 8.9.17
  • Upgrade status: 8.x-3.8

Patch from #8 applied fine but I'm getting the following messages now:

Use of $config_directories in settings.php is deprecated. Use $settings['config_sync_directory'] instead.	Deprecated configuration used
Use of $config_directories in settings.php is deprecated.	Not used

 
See screenshot:

When I'm actually using the following in settings.php:

// Config sync directory.
$settings['config_sync_directory'] = '../config/sync';

With this code in settings.php, I would expect the warnings to be gone, or green, since this is what is recommended at:
The sync directory is defined in $settings and not $config_directories

Please let me know if there's anything I've been doing wrong or missed, in the config or the usage of the module.
Sorry, but I haven't had time to look further in code where the problem could come from.

Thanks in advance for your help.

gábor hojtsy’s picture

Status: Needs work » Postponed (maintainer needs more info)

Wow, how would both of them appear?! I think you applied this on top of 3.8 which did have an older and incorrect version of this check. Can you try with the dev version instead? Thanks!

dydave’s picture

Status: Postponed (maintainer needs more info) » Reviewed & tested by the community
StatusFileSize
new47.24 KB

Thanks a lot Gabor for your prompt and clear reply it's greatly appreciated.

I've tested again with your advice with the dev version: drupal/upgrade_status (dev-3.x 04edb37)
with the patch from #8, which applied nicely...

and it worked! See screenshot below:

Thanks a lot Gabor, once again.

As far as I'm concerned, this can be considered RTBC.

alison’s picture

Same here! -- applied the patch from #8 to upgrade_status (drupal/upgrade_status:3.x-dev@dev) -- the $config_directories requirement on the upgrade status report page accurately lists a status of "✅ Not used" 🎉

lomale@bluewin.ch’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new42.34 KB

The Dev Version has made the error message gone.

#10 -> #12

But I have a problem with the scan function. I already had that before.
see picture Scan button

The Button is not activated.

Thanks Lothar

gábor hojtsy’s picture

@lomale@bluewin.ch: in this case you should see an error message at the top of the page explaining why is it not possible.

gábor hojtsy’s picture

Issue summary: View changes
Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs manual testing
StatusFileSize
new321.5 KB
new335 KB
new292.54 KB

I used drupalpod.com to test this out properly. Here is the rundown of how it looks in various settings.php configurations:

When using both values:

When using only the deprecated value:

When using only the non-deprecated value or neither:

Also updated the issue summary.

gábor hojtsy’s picture

Issue summary: View changes

Further update issue summary to include links.

gábor hojtsy’s picture

laura.gates’s picture

StatusFileSize
new96.31 KB

I'm not sure if this was expected or not... but running ddev on my project and it has several different settings for settings.ddev.php that run if (version_compare) resulting in this being flagged twice.

// This specifies the default configuration sync directory.
// For D8 before 8.8.0, we set $config_directories[CONFIG_SYNC_DIRECTORY] if not set
if (version_compare(Drupal::VERSION, "8.8.0", '<') &&
  empty($config_directories[CONFIG_SYNC_DIRECTORY])) {
  $config_directories[CONFIG_SYNC_DIRECTORY] = 'sites/default/files/sync';
}
// For D8.8/D8.9, set $settings['config_sync_directory'] if neither
// $config_directories nor $settings['config_sync_directory is set
if (version_compare(DRUPAL::VERSION, "8.8.0", '>=') &&
  version_compare(DRUPAL::VERSION, "9.0.0", '<') &&
  empty($config_directories[CONFIG_SYNC_DIRECTORY]) &&
  empty($settings['config_sync_directory'])) {
  $settings['config_sync_directory'] = 'sites/default/files/sync';
}
// For Drupal9, it's always $settings['config_sync_directory']
if (version_compare(DRUPAL::VERSION, "9.0.0", '>=') &&
  empty($settings['config_sync_directory'])) {
  $settings['config_sync_directory'] = 'sites/default/files/sync';

For what it's worth, it may be good to tell upgrade status to ignore docker+ applications (lando, docksal, ddev, etc) to ignore managed php files.

gábor hojtsy’s picture

Status: Reviewed & tested by the community » Needs work

Based on that code, ddev will only set the deprecated value if on prior to Drupal 8.8.0, and that is neither supported in terms of upgrade path to Drupal 9 as per the first line item in Upgrade Status' environment report, neither receives security support anymore. We could add an extra condition to not check for this variable if the site is pre-Drupal 8.8.0 to be extra careful (so people don't update a setting that their site does not yet support).

nessunluogo’s picture

Just for reporting, I'm having a similar issue as DYdave in #10. I just don't have the double message but only the "Use of $config_directories in settings.php is deprecated..." error. I'm also using ddev as laura.gates does.

Updating to the dev version fixed the issue.

BTW I think #20 is a good idea.

shaal made their first commit to this issue’s fork.

gábor hojtsy’s picture

Status: Needs work » Needs review
StatusFileSize
new5.49 KB

Wrapped the new code in this condition so that should be ddev-friendly now :)

    // Check deprecated $config_directories if after Drupal 8.8.0. On older
    // Drupal versions, the replacement is not supported and the setting may
    // be generated by platforms like ddev, leading to false positives that
    // the user should not even resolve yet before updating core.
    if (version_compare(\Drupal::VERSION, '8.8.0') >= 0) {
      // ...
    }

  • a08c59e committed on 8.x-3.x
    Issue #3224660 by Gábor Hojtsy, shaal, DYdave, laura.gates, tedbow,...
gábor hojtsy’s picture

Status: Needs review » Fixed

Committed that!

esthertempel’s picture

Updating from the 3.8.0 release to 3.x-dev@dev fixed the issue for me.
The upgrade status report page shows a status of "Not used"

Thanks!

seismicmike’s picture

Composer wouldn't install the dev version for me for some reason, so I rolled the following patch. This can be applied to the current release (8.x-3.8) until a new release with this fix and the rollback from https://www.drupal.org/project/upgrade_status/issues/3154341 is provided. This patch will roll back the previous fix and apply the fix from this issue.

dave reid’s picture

This is causing a fatal error in some of our sites where we are using some anonymous functions in our settings.php to modify the $settings and $config objects, possibly due to re-loading the settings.php file on the same request.

gábor hojtsy’s picture

@Dave Reid: there is a similar problem at #3227807: Notice: Constant already defined due to constants defined in settings.php. I did not quite expect settings.php to have side effects like either of yours, but since that is happening, any bright ideas as to how could we detect this deprecation while (a) not including the settings twice (b) unable to check if the setting was in fact migrated due to the backwards compatibility layer as we explored in #3154341: Doesn't detect the $config_directories deprecation previously.

dave reid’s picture

So I think that system_requirements has a check for this as well, and it does not trigger this error for us when we load that page. It looks like it just checks the $GLOBALS variable without re-loading settings.php:

  // Handle other configuration directories. This will be removed in Drupal 9.
  // See https://www.drupal.org/node/3018145.
  $bc_config_directories = isset($GLOBALS['config_directories']) ? $GLOBALS['config_directories'] : [];
  unset($bc_config_directories['sync']);
  foreach (array_keys(array_filter($bc_config_directories)) as $type) {
    @trigger_error("Automatic creation of '{$type}' configuration directory will be removed from drupal:9.0.0. See https://www.drupal.org/node/3018145.", E_USER_DEPRECATED);
    ...
dave reid’s picture

I don't think there's a need to even load the settings file again, we should be able to accomplish the same using $GLOBALS and the \Drupal\Core\Site\Settings class:

  protected function isDeprecatedConfigDirectorySettingUsed() {
    if (!empty($GLOBALS['config_directories'])) {
      if (Settings::get('config_sync_directory', FALSE)) {
        // Both are set. The $settings copy will prevail in Settings::initialise().
        return NULL;
      }
      // Only the deprecated variable is set.
      return TRUE;
    }

    // The deprecated variable is not set.
    return FALSE;
  }
gábor hojtsy’s picture

@Dave Reid: hm, we tried checking $GLOBALS but figured out in #3224551: Warning about $config_directories deprecation will never get resolved, roll it back that is always set as per https://git.drupalcode.org/project/drupal/-/blob/8.9.x/core/includes/boo... when/if config_get_config_directory() is called. Yes that itself is a deprecated function but we cannot know if that was invoked or not in the environment where we assume various deprecated things get called.

dave reid’s picture

Oh that's truly unfortunate that the old global was filled in with the new value and not the other way around, that's just not great, oof.

dave reid’s picture

Status: Fixed » Needs review
StatusFileSize
new588 bytes

So the specific error I'm seeing in our settings.php is that when we attempt to include it the second time, the variable $config is NULL, instead of an array. It looks like setting the same three variables to empty arrays, just like \Drupal\Core\Site\Settings::initialize() does resolves it locally for me. And gives a cleaner inspection of the actual settings as well.

This could also be fixed by using include_once or require_once in our settings.php file of our sub-settings files, which we will also do in our code, but the attached patch I would suggest for inclusion and release.

gábor hojtsy’s picture

Status: Needs review » Fixed

@Dave Reid: Thanks! I opened #3228576: Fix variable errors when including settings file the second time for tracking purposes and credited you there. Moved the patch to there.

gábor hojtsy’s picture

mccoolai’s picture

Hi Gábor,

I am having a similar issue that was stated in comment #10. I uninstalled the module and used composer to download drupal/upgrade_status 3.x-dev@dev and reinstalled it in my Drupal project.

I was expecting to clear the error status but it was still present, I dumped the value and for some reason, the global variable $config_directories still has a value assigned to it.

  protected function isDeprecatedConfigDirectorySettingUsed() {
    $app_root = $this->kernel->getAppRoot();
    $site_path = $this->kernel->getSitePath();
    if (is_readable($app_root . '/' . $site_path . '/settings.php')) {
      // Reset the "global" variables expected to exist for settings.
      $settings = [];
      $config = [];
      $databases = [];
      require $app_root . '/' . $site_path . '/settings.php';
    }

    echo "<pre>";
    var_dump($config_directories);
    echo "</pre>";
    exit(1);
    if (!empty($config_directories)) {
      if (!empty($settings['config_sync_directory'])) {
        // Both are set. The $settings copy will prevail in Settings::initialise().
        return NULL;
      }
      // Only the deprecated variable is set.
      return TRUE;
    }

    // The deprecated variable is not set.
    return FALSE;
  }

I even cleared the cache and truncated the tables in the DB just to be sure it's not cache but to no avail. Please see screenshots below:

 
Also, a note - I am using DevDesktop by Acquia for my local environment. There might be something that I missed but any guidance would be much appreciated.

gábor hojtsy’s picture

@mccoolai: thanks for reporting your issue at #3229552: Deprecated $config_directories still detected with 3.x-dev even though it should not, we can keep discussing there.

Status: Fixed » Closed (fixed)

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

sam.foster’s picture

Hi folks

I too was getting this issue and found it to be the fault of the

$config_directories['sync'] = $repo_root . "/config/default";

line that was in my /vendor/acquia/blt/settings/config.settings.php file

I'm using BLT 11.5, but I suspect I should have upgraded that to a higher version and will be doing that shortly as part of the move to Drupal9

I was getting the reported config_directory error on my local (not deployed yet - just working locally with the upgrade status module)

HTH

Sam