diff --git a/lib/MT/ConfigMgr.pm b/lib/MT/ConfigMgr.pm index 5c9efdbf77..efd11b6c06 100644 --- a/lib/MT/ConfigMgr.pm +++ b/lib/MT/ConfigMgr.pm @@ -24,6 +24,7 @@ sub new { __paths => [], __dirty => 0, __overwritable_keys => {}, + __env => {}, }, $_[0]; $mgr->init; @@ -31,6 +32,14 @@ sub new { } sub init { + my $mgr = shift; + for my $key (grep /^MT_CONFIG_/i, keys %ENV) { + (my $name = $key) =~ s/^MT_CONFIG_//i; + $name =~ s/_//g; + my $value = $ENV{$key}; + $value = '' if $value eq q{''}; + $mgr->{__env}{lc $name} = $value; + } } sub define { @@ -95,6 +104,8 @@ sub get_internal { return $mgr->get($alias); } + return $mgr->{__env}{$var} if exists $mgr->{__env}{$var}; + $val = $mgr->{__dbvar}{$var} if $mgr->is_overwritable($var); $val = $mgr->{__var}{$var} unless defined($val); $val = { %{ $mgr->{__dbvar}{$var} }, %$val } if ($mgr->type($var) eq 'HASH' && $val && $mgr->{__dbvar}{$var}); @@ -110,6 +121,7 @@ sub get_internal { sub get { my $mgr = shift; my $var = lc shift; + return $mgr->{__env}{$var} if exists $mgr->{__env}{$var}; if ( my $h = $mgr->{__settings}{$var}{handler} ) { $h = MT->handler_to_coderef($h) unless ref $h; return $h->($mgr); @@ -151,6 +163,7 @@ sub set_internal { my $mgr = shift; my ( $var, $val, $db_flag ) = @_; $var = lc $var; + return $mgr->{__env}{$var} if exists $mgr->{__env}{$var}; $mgr->set_dirty() if defined($db_flag) && $db_flag; my $set = $db_flag ? '__dbvar' : '__var'; if ( defined( my $alias = $mgr->{__settings}{$var}{alias} ) ) { @@ -194,6 +207,7 @@ sub set { my $mgr = shift; my ( $var, $val, $db_flag ) = @_; $var = lc $var; + return $mgr->{__env}{$var} if exists $mgr->{__env}{$var}; $mgr->set_dirty($var); if ( my $h = $mgr->{__settings}{$var}{handler} ) { $h = MT->handler_to_coderef($h) unless ref $h; diff --git a/php/mt.php b/php/mt.php index d5f1587dae..e1693f50ae 100644 --- a/php/mt.php +++ b/php/mt.php @@ -49,6 +49,7 @@ class MT { protected $blog_id; protected $db; protected $config; + protected $config_env; protected $debugging = false; protected $caching = false; protected $conditional = false; @@ -127,6 +128,7 @@ function init($blog_id = null, $cfg_file = null) { } $this->configure($cfg_file); + $this->configure_from_env(); $this->init_addons(); $this->configure_from_db(); @@ -286,6 +288,9 @@ public function clear_cache_driver() { public function config($id, $value = null) { $id = strtolower($id); + if (isset($this->config_env[$id])) { + return $this->config_env[$id]; + } if (isset($value)) $this->config[$id] = $value; return isset($this->config[$id]) ? $this->config[$id] : null; @@ -389,6 +394,22 @@ function configure($file = null) { } } + function configure_from_env() { + $cfg =& $this->config_env; + foreach(array_keys($_ENV) as $i => $name) { + $lc_name = strtolower($name); + if (strpos($lc_name, 'mt_config_') === 0) { + $lc_name = preg_replace('/^mt_config_/', '', $lc_name); + $lc_name = preg_replace('/_/', '', $lc_name); + $value = $_ENV[$name]; + if (isset($value) && $value === "''") { + $value = ''; + } + $cfg[$lc_name] = $value; + } + } + } + function configure_from_db() { $cfg =& $this->config; $mtdb =& $this->db(); diff --git a/t/tag/config_env.t b/t/tag/config_env.t new file mode 100644 index 0000000000..c16aee8e7a --- /dev/null +++ b/t/tag/config_env.t @@ -0,0 +1,65 @@ +use strict; +use warnings; +use FindBin; +use lib "$FindBin::Bin/../lib"; # t/lib +use Test::More; +use MT::Test::Env; +our $test_env; + +BEGIN { + $test_env = MT::Test::Env->new; + $ENV{MT_CONFIG} = $test_env->config_file; + + # config directive set by MT::Test::Env + $ENV{MT_CONFIG_EMAIL_ADDRESS_MAIN} = 'mt_test@localhost.localdomain'; + + # config directive that has a default value + $ENV{MT_CONFIG_CMSSEARCHLIMIT} = 1000; + + # config_directive that has no default value + $ENV{MT_CONFIG_RsyncOptions} = '-v'; +} + +use MT::Test::PHP; +use MT::Test::Tag; + +$test_env->prepare_fixture('db'); + +my $cnf = MT->config; +is $cnf->EmailAddressMain => $ENV{MT_CONFIG_EMAIL_ADDRESS_MAIN}, "EmailAddressMain is overriden by the env"; +is $cnf->CMSSearchLimit => $ENV{MT_CONFIG_CMSSEARCHLIMIT}, "CMSSearchLimit is overriden by the env"; +is $cnf->RsyncOptions => $ENV{MT_CONFIG_RsyncOptions}, "RsyncOptions is overriden by the env"; + +$cnf->EmailAddressMain('something different', 1); +$cnf->CMSSearchLimit('something different', 1); +$cnf->RsyncOptions('something different', 1); +$cnf->save_config; + +is $cnf->EmailAddressMain => $ENV{MT_CONFIG_EMAIL_ADDRESS_MAIN}, "EmailAddressMain is still overriden by the env"; +is $cnf->CMSSearchLimit => $ENV{MT_CONFIG_CMSSEARCHLIMIT}, "CMSSearchLimit is still overriden by the env"; +is $cnf->RsyncOptions => $ENV{MT_CONFIG_RsyncOptions}, "RsyncOptions is still overriden by the env"; + +MT::Test::Tag->run_perl_tests(1); +MT::Test::Tag->run_php_tests(1); + +done_testing; + +__DATA__ + +=== env with underscores +--- template + +--- expected eval +$ENV{MT_CONFIG_EMAIL_ADDRESS_MAIN} + +=== env without underscores +--- template + +--- expected eval +$ENV{MT_CONFIG_CMSSEARCHLIMIT} + +=== env with mixed cases +--- template + +--- expected eval +$ENV{MT_CONFIG_RsyncOptions}