The Drupal.org infrastructure uses this by default and so do lots of Drupal shops, so why can't we add this snippet to settings.php (and settings.default.php) by default?

/**
 * Include a local settings file if it exists.
 */
$local_settings = dirname(__FILE__) . '/settings.local.php';
if (file_exists($local_settings)) {
  include $local_settings;
}

This could also be a tiny step forwards for local configuration management.

CommentFileSizeAuthor
#91 drupal-7.x-1118520-90.patch5.01 KBzipymonkey
#88 drupal-7.x-1118520-88.patch4.4 KBhmdnawaz
#84 drupal-7.x-1118520-84.patch1.67 KBzipymonkey
#82 drupal-7.x-1118520-82.patch1.63 KBhmdnawaz
#79 drupal-7.x-dev-1118520-tests.patch2.78 KBsolideogloria
#72 drupal-7.64-1118520.patch1.65 KBzipymonkey
#65 drupal-7.53-1118520.patch2.46 KBPol
#63 add_inclusion_of_a-1118520-63.patch1.83 KBzipymonkey
#60 drupal-add-local-settings-1118520-60.patch1.82 KBPieterDC
#59 drupal-add-local-settings-1118520-59.patch964 bytesmccrodp
#53 add_inclusion_of_a-1118520-50.patch749 bytesSailatha Gaddagunti
#49 add_inclusion_of_a-1118520-49.patch974 bytesnerdcore
#43 add_inclusion_of_a-1118520-43.patch939 bytesjcnventura
#37 1118520-settings-local-uncommented-do-not-test.patch613 bytesDave Reid
#25 drupal8.settings-local.25.patch1.88 KBsun
#22 drupal8.settings-local.22.patch1.88 KBsun
#17 drupal8.settings-local.17.patch1.9 KBsun
#13 1118520-drupal8-settings-local-13.patch1.9 KBmr.baileys
#9 drupal8.settings.local_.9.patch1.83 KBsun
#1 1118520-settings-local.patch552 bytesDave Reid

Issue fork drupal-1118520

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:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Dave Reid’s picture

Status: Active » Needs review
FileSize
552 bytes
tstoeckler’s picture

I like that.

I first thought, whether we should always create an (empty) settings.local.php in the install process to save the file_exists(), but since this is called exactly once per page-load it's probably not worth it. Especially as that would be extra trouble for a lot of users who don't actually use it.

Another question is whether this needs some form of in-code documentation or not. An example usage or something. I'm tending to say no, but not sure. Maybe it's sufficient to mention something like this in the upgrade docs.

Leaving this at needs review for some more opinions.

patcon’s picture

I think in-code documentation would be great. Not sure about everyone else, but for the longest time, the only thing I knew about most anything in settings.php was what was explained inline :)

Glad this got suggested, as I was just coming over to say the same thing!

Damien Tournoud’s picture

Sounds good to me, but I agree with @patcon that we should flesh out the documentation here.

justintime’s picture

Whether it's a bug or a feature is outside the scope of my post, but...

drupal_rewrite_settings() has an undocumented $prefix variable passed into it. If specified, it concatenates the prefix to the settings.php file path. If we go with settings.local.php, then the $prefix var is a bit misleading -- there's no way we can write to that file without changing the logic of the function.

If we went with local.settings.php, that would be compatible with drupal_rewrite_settings(), but that may not be the intention.

Whichever way we go, it should probably be documented.

tstoeckler’s picture

Status: Needs review » Needs work

Well we have default.settings.php so local.settings.php seems to be consistent.

justintime’s picture

Status: Needs work » Needs review

Well, I did some probing of drupal_rewrite_settings(), and I take back what I said earlier.

The $prefix option in drupal_rewrite_settings() does indeed work, but if you call it with the prefix, it will dump all settings to the $prefix.'settings.php file, not just the $settings variable that's passed in.

In short, using $prefix isn't used to add more config to settings.php, it's used to completely replace settings.php.

I'm resetting back to needs review in light of this.

Eric_A’s picture

The Aegir hosting system uses local.settings.php in sites/[site] to inject site specific settings. (The sites/[site]/settings.php file is built based on a global template, which uses $_SERVER vars.)

sun’s picture

Yarrrrrrrrrr!

Status: Needs review » Needs work

The last submitted patch, drupal8.settings.local_.9.patch, failed testing.

sun’s picture

Status: Needs work » Needs review

#9: drupal8.settings.local_.9.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, drupal8.settings.local_.9.patch, failed testing.

mr.baileys’s picture

Status: Needs work » Needs review
FileSize
1.9 KB

Straight re-roll.

sun’s picture

Assigned: Dave Reid » Unassigned
Status: Needs review » Reviewed & tested by the community

Thank you!

Regardless of the configuration system enhancements for D8, settings.php does not seem to go away anytime soon (and #1484690: Implement $conf overrides in the configuration system was fixed just recently to bring back conditional $conf overrides), so I'd still like to see this happening.

Anyone who does not like the additional filestat of the file_exists() can either remove the entire thing from settings.php or include it unconditionally - settings.php is fully customizable after all.

mr.baileys’s picture

Reviewed and tested the patch and all looks good to me, one aspect I'm not sure of:

We currently warn uses if they leave settings.php writable after installation:

Configuration file Not protected
The file sites/default/settings.php is not protected from modifications and poses a security risk. You must change the file's permissions to be non-writable.

I wonder if we should include the same check on settings.local.php if it exists (since the security risk is the same). On the other hand, the only reason we warn for settings.php is because we explicitly request it to be writable during installation, which is not the case for settings.local.php, and we don't go checking other .php files for writability…

catch’s picture

Status: Reviewed & tested by the community » Needs work

I don't see any reason to have this enabled by default, why not in there but commented out? It's a common pattern, but it's not worth the file system hit (file_exists() misses are not cached afaik) for sites that are never going to use it.

sun’s picture

Status: Needs work » Needs review
FileSize
1.9 KB

Alright, comment out by default.

Status: Needs review » Needs work

The last submitted patch, drupal8.settings-local.17.patch, failed testing.

jthorson’s picture

Status: Needs work » Needs review

Testbot issue. Passed on re-test.

tstoeckler’s picture

Status: Needs review » Needs work

All of the other options, that are commented out in settings.php use a leading '#', so let's do that here as well. The rest of them are all $conf overrides, so it's a bit different, but I think consistency makes sense here.

kbell’s picture

I like this patch! (please add this as a favorable Review) - agree with tstoeckler on leading # but except for that, I'm happy to see this patch.
Thank you Dave Reid, sun and mr.baileys!
-Kelly

sun’s picture

Status: Needs work » Needs review
FileSize
1.88 KB

Re-rolled against HEAD, and changed the inline comment syntax as requested.

tstoeckler’s picture

Status: Needs review » Reviewed & tested by the community

Can't find anything wrong with that. I personally would have liked to see this uncommented by default, but I guess catch is right, that this it is not the default use-case.

catch’s picture

Status: Reviewed & tested by the community » Needs work

Sorry can we change if existent to "if available", it's not exactly wrong but it's a bit flowery for a code comment I think.

sun’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
1.88 KB

Prego.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Thanks! Committed/pushed.

Patrick R.’s picture

It might be better checking the existence of the file using is_file() and is_readable() instead of file_exists(). The latter will also return true if you have a directory named settings.local.php with the subsequent inclusion then throwing a warning. No big deal though as this is a very unlikely scenario.

tstoeckler’s picture

We currently use file_exists() all over core in the exact same manner as this patch introduced. It might or might not make sense to turn a bunch of those into is_file() but that should be a different issue.

Dave Reid’s picture

TravisCarden’s picture

patcon’s picture

Maybe I'm not up on Drupal common practice, but shouldn't that followup simply be part of this issue? It would seem that this isn't complete until a test has been written, right? Like why have a separate discussion to follow for "those interested in writing tests"?

Or am I just too caught up in all that "agily" Definition of Done™ business? :)

jthorson’s picture

patcon: You're probably right ... except in this case, the patch being developed in this issue has already been committed.

So the followup issue sort of becomes "Ooops, we forgot to add a test in x". ;)

patcon’s picture

Ah gotcha. regardless, you're all heroes. :)

dww’s picture

The test we added in the other issue is a runtime requirements check on live sites. Could have been part of this, but it was an afterthought. There was no automated test for either issue, which is normally what gets the "no code without tests" rule.

Status: Fixed » Closed (fixed)

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

hackwater’s picture

Issue tags: +documentation bug

Just a quick documentation note for the settings.local.php description: Instead of "and other things that should not happen on development and testing sites" it should probably read "and other things that should ONLY happen on development and testing sites," unless I'm misunderstanding the settings.local.php documentation's intent.

Dave Reid’s picture

For those of us with makefiles that want to encourage the use of settings.local.php, here's an untestable makefile version.

mikeker’s picture

Issue summary: View changes

FYI: I opened #2419213: Rename settings.local.php to local.settings.php to be consistent with other filenames in hopes of making the file naming more consistent.

nerdcore’s picture

Status: Closed (fixed) » Needs review

I've decided to use the PHP constant DIRECTORY_SEPARATOR instead of "/" because I am sharing this config between a GNU and a Windows server. I suspect the Windows server could interpret "/" correctly, at least in fairly modern versions of PHP. Can anyone confirm this?

Here's my snippet:

if (file_exists(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'settings.local.php')) {
    include dirname(__FILE__) . DIRECTORY_SEPARATOR . 'settings.local.php';
}
nerdcore’s picture

Status: Needs review » Closed (fixed)
mikeker’s picture

@nerdcore: when building paths, you don't need to use DIRECTORY_SEPARATOR, forward-slash is fine. Linux uses forward slashes natively and Windows will accept either forward or backward slashes (PHP translates forward into backward for you so you can mix-and-match if you want). DIRECTORY_SEPARATOR is only needed when parsing a path given to you by the system.

cilefen’s picture

jcnventura’s picture

Version: 8.0.x-dev » 7.x-dev
Status: Closed (fixed) » Needs review
Issue tags: +Needs backport to D7
FileSize
939 bytes

This would be a nice to have back in D7.

I've ported the current code from D8's default.settings.php including having this section commented.

tstoeckler’s picture

Status: Needs review » Reviewed & tested by the community

I think that's a good idea!

TravisCarden’s picture

Status: Reviewed & tested by the community » Needs work

If we're going to do this, we probably need to test the file permissions on that file, like we did when we added the same feature to D8: #1611686: Add test for unprotected settings.local.php.

tstoeckler’s picture

Ah, was completely unaware of that. It totally makes sense to do this in one shot for D7, thanks!

Chi’s picture

+++ b/sites/default/default.settings.php
@@ -584,3 +584,17 @@ $conf['404_fast_html'] = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
+# if (file_exists(__DIR__ . '/settings.local.php')) {

__DIR__ is not available in PHP 5.2 which is minimal required PHP version for Drupal 7.

sierkje’s picture

Status: Needs work » Needs review
nerdcore’s picture

Reroll of #43 in response to comment #47 (using file_exists(dirname(__FILE__) instead of __DIR__ because __FILE__ has existed since PHP 4.0.2)

Status: Needs review » Needs work

The last submitted patch, 49: add_inclusion_of_a-1118520-49.patch, failed testing.

mccrodp’s picture

Shouldn't this be include_once like in core?

boostrap.inc:drupal_settings_initialize() line 731 :

  if (file_exists(DRUPAL_ROOT . '/' . conf_path() . '/settings.php')) {
    include_once DRUPAL_ROOT . '/' . conf_path() . '/settings.php';
  }

The last submitted patch, 49: add_inclusion_of_a-1118520-49.patch, failed testing.

Sailatha Gaddagunti’s picture

Sailatha Gaddagunti’s picture

Assigned: Sailatha Gaddagunti » Unassigned
geerlingguy’s picture

Status: Needs work » Needs review

Setting proper status; note that critique in #51 still applies...

The last submitted patch, 37: 1118520-settings-local-uncommented-do-not-test.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 53: add_inclusion_of_a-1118520-50.patch, failed testing.

mccrodp’s picture

Assigned: Unassigned » mccrodp

I believe this should be on default.settings.php also. I'll reroll with changes suggested in #51.

mccrodp’s picture

Assigned: mccrodp » Unassigned
Status: Needs work » Needs review
FileSize
964 bytes

Reverted back to the dirname instead of DIR changes from #49 and changes suggested in #51 re: include_once.

PieterDC’s picture

To comply to the remarks of #51, I rerolled #25 against Drupal 7.x

  • catch committed 9ba8724 on 8.3.x
    Issue #1118520 by sun, Dave Reid, mr.baileys: Added inclusion of a...

  • catch committed 9ba8724 on 8.3.x
    Issue #1118520 by sun, Dave Reid, mr.baileys: Added inclusion of a...
zipymonkey’s picture

This patch in #60 does not apply cleanly for with Drupal 7.51. Rerolling the patch.

Status: Needs review » Needs work

The last submitted patch, 63: add_inclusion_of_a-1118520-63.patch, failed testing.

Pol’s picture

Status: Needs review » Needs work

The last submitted patch, 65: drupal-7.53-1118520.patch, failed testing.

mikeker’s picture

Status: Needs work » Needs review

Test failures seem unrelated...

Status: Needs review » Needs work

The last submitted patch, 65: drupal-7.53-1118520.patch, failed testing.

  • catch committed 9ba8724 on 8.4.x
    Issue #1118520 by sun, Dave Reid, mr.baileys: Added inclusion of a...

  • catch committed 9ba8724 on 8.4.x
    Issue #1118520 by sun, Dave Reid, mr.baileys: Added inclusion of a...
keramsey’s picture

The 65: drupal-7.53-1118520.patch fails on drupal-7.64. I am trying to install the patch as part of an installation profile.

Can someone reroll the patch for drupal-7.64 or point me to directions on how I can do that? Thanks.

zipymonkey’s picture

I've re-rolled the patch for Drupal 7.64.

@keramsey There are instructions for rerolling patches here: https://www.drupal.org/patch/reroll.

solideogloria’s picture

Status: Needs work » Needs review
keramsey’s picture

Thanks for the link and patch @zipymonkey!

sveldkamp’s picture

Just applied patch in #72 to 7.67 for 2 of my sites (PHP 7.2 though) and it works great.
This is a pretty simple patch, is it not? I would love to see it committed.

jcnventura’s picture

Status: Needs review » Needs work

I think we never addressed #45.

Gnanasampandan Velmurgan’s picture

I Have tested and reviewed the #72 patch it works Perfect. Thanks.

solideogloria’s picture

Per #45, I ported the Drupal 8 hook_requirements changes to Drupal 7, in order to test the configuration file permissions.

I also looked at the current version of the tests/requirements in Drupal 8, but I decided against incorporating any of the other changes that have been made, such as adding an option to disable file permissions checking.

I tested to make sure the code displays the requirements correctly, but I didn't test it with patch #72 or with a non-empty settings.local.php file.

solideogloria’s picture

Status: Needs work » Needs review

  • catch committed 9ba8724 on 9.1.x
    Issue #1118520 by sun, Dave Reid, mr.baileys: Added inclusion of a...
hmdnawaz’s picture

The patch in #72 is working for Drupal version 7.72

hmdnawaz’s picture

zipymonkey’s picture

Rerolled the 7.x patch to work with Drupal 7.x-7.77.

solideogloria’s picture

@hmdnawaz @zipymonkey If you read #45 and #46, the tests I added are needed if this is to ever get committed.

zipymonkey’s picture

I rerolled the patch to work with 7.79/7.80 and added the testings to system.install recommended by @solideogloria and @TravisCarden. I opened a merge request for review.

hmdnawaz’s picture

@zipmonkey

I have uploaded your latest patch here so that it can be used in projects from here.

zipymonkey’s picture

@hmdnawaz You can get the raw patch file from the merge diff by adding ".patch" to the url. Example:

leymannx’s picture

@zipmonkey – I wanted to say the same but consider that there is no way (yet) to integrate commits in the Composer patch workflow.

Means https://git.drupalcode.org/project/drupal/-/merge_requests/586.patch can change if new commits get added and you wouldn't even notice when your local site runs with a different version of the patch while your live site runs on another – and maybe breaks because of it.

https://www.drupal.org/files/issues/2021-04-23/drupal-7.x-1118520-88.patch doesn't change.

See https://drupal.stackexchange.com/q/298567/15055 for example where this has been asked already.

It would be nice to be able to pin the MR patch to a certain commit. Like https://git.drupalcode.org/project/drupal/-/merge_requests/586-[LATEST-C... and later if more commits come in https://git.drupalcode.org/project/drupal/-/merge_requests/586-[UPDATED-... for example.

zipymonkey’s picture

I rerolled the patch and attached a copy of the updated patched file.