Spaces:
No application file
No application file
namespace Mautic\CoreBundle\Loader; | |
use Symfony\Component\Dotenv\Dotenv; | |
use Symfony\Component\Filesystem\Path; | |
use Symfony\Component\Finder\Finder; | |
use Symfony\Component\HttpFoundation\ParameterBag; | |
class ParameterLoader | |
{ | |
private string $configBaseDir; | |
private ParameterBag $parameterBag; | |
private ParameterBag $localParameterBag; | |
/** | |
* @var array<string, mixed> | |
*/ | |
private array $localParameters = []; | |
/** | |
* @var array<string, mixed> | |
*/ | |
private static $defaultParameters = []; | |
public function __construct( | |
private string $rootPath = __DIR__.'/../../../' | |
) { | |
$this->configBaseDir = static::getLocalConfigBaseDir($this->rootPath); | |
$this->loadDefaultParameters(); | |
$this->loadLocalParameters(); | |
$this->createParameterBags(); | |
} | |
/** | |
* @return array<string, mixed> | |
*/ | |
public function getDefaultParameters(): array | |
{ | |
return self::$defaultParameters; | |
} | |
public function getParameterBag(): ParameterBag | |
{ | |
return $this->parameterBag; | |
} | |
public function getLocalParameterBag(): ParameterBag | |
{ | |
return $this->localParameterBag; | |
} | |
public function loadIntoEnvironment(): void | |
{ | |
$envVariables = new ParameterBag(); | |
$defaultParameters = new ParameterBag(self::$defaultParameters); | |
// Load from local configuration file first | |
EnvVars\ConfigEnvVars::load($this->parameterBag, $defaultParameters, $envVariables); | |
// Load special values used in Mautic configuration files in app/config | |
EnvVars\ApiEnvVars::load($this->parameterBag, $defaultParameters, $envVariables); | |
EnvVars\ElFinderEnvVars::load($this->parameterBag, $defaultParameters, $envVariables); | |
EnvVars\MigrationsEnvVars::load($this->parameterBag, $defaultParameters, $envVariables); | |
EnvVars\SAMLEnvVars::load($this->parameterBag, $defaultParameters, $envVariables); | |
EnvVars\SessionEnvVars::load($this->parameterBag, $defaultParameters, $envVariables); | |
EnvVars\SiteUrlEnvVars::load($this->parameterBag, $defaultParameters, $envVariables); | |
EnvVars\TwigEnvVars::load($this->parameterBag, $defaultParameters, $envVariables); | |
// Load the values into the environment for cache use | |
$dotenv = new Dotenv(MAUTIC_ENV); | |
foreach ($envVariables->all() as $key => $value) { | |
if (null === $value) { | |
$envVariables->set($key, ''); | |
} | |
} | |
$dotenv->populate($envVariables->all()); | |
} | |
public static function getLocalConfigFile(string $root, bool $updateDefaultParameters = true): string | |
{ | |
$root = realpath($root); | |
$projectRoot = self::getProjectDirByRoot($root); | |
/** @var array<string> $paths */ | |
$paths = []; | |
include $root.'/config/paths.php'; | |
if (!isset($paths['local_config'])) { | |
if ($updateDefaultParameters) { | |
self::$defaultParameters['local_config_path'] = $projectRoot.'/config/local.php'; | |
} | |
return $projectRoot.'/config/local.php'; | |
} | |
$newConfigPath = str_replace('%kernel.project_dir%', $projectRoot, $paths['local_config']); | |
$oldConfigPath = str_replace('%kernel.project_dir%', $root, $paths['local_config']); | |
$paths['local_config'] = $newConfigPath; | |
// Check if the local config files are still present in the /app/config dir, instead of the /config dir | |
if (!file_exists($newConfigPath) && file_exists($oldConfigPath)) { | |
$paths['local_config'] = $oldConfigPath; | |
} | |
if ($updateDefaultParameters) { | |
self::$defaultParameters['local_config_path'] = $paths['local_config']; | |
} | |
// We need this for the file manager | |
if (isset($paths['local_root'])) { | |
if ($updateDefaultParameters) { | |
self::$defaultParameters['local_root'] = $paths['local_root']; | |
} | |
} | |
return $paths['local_config']; | |
} | |
private function loadDefaultParameters(): void | |
{ | |
if (self::$defaultParameters) { | |
// This is loaded within and outside the container so use static variable to prevent recompiling | |
// multiple times | |
return; | |
} | |
$finder = (new Finder()) | |
->files() | |
->followLinks() | |
->depth('== 0') | |
->in(__DIR__.'/../../../bundles/*/Config') | |
->in(__DIR__.'/../../../../plugins/*/Config') | |
->name('config.php'); | |
/** @var \SplFileInfo $file */ | |
foreach ($finder as $file) { | |
/** @var array<string, mixed> $config */ | |
$config = include $file->getPathname(); | |
$parameters = $config['parameters'] ?? []; | |
self::$defaultParameters = array_merge(self::$defaultParameters, $parameters); | |
} | |
} | |
private function loadLocalParameters(): void | |
{ | |
$compiledParameters = []; | |
$localConfigFile = self::getLocalConfigFile($this->rootPath); | |
// Load parameters array from local configuration | |
if (file_exists($localConfigFile)) { | |
/** @var array<string, mixed> $parameters */ | |
$parameters = []; | |
include $localConfigFile; | |
// Override default with local | |
$compiledParameters = array_merge($compiledParameters, $parameters); | |
} | |
// Force local specific params | |
$localParametersFile = $this->getLocalParametersFile(); | |
if (file_exists($localParametersFile)) { | |
include $localParametersFile; | |
/** @var array<string, mixed> $parameters */ | |
// override default with forced | |
$compiledParameters = array_merge($compiledParameters, $parameters); | |
} | |
// Load from environment | |
$envParameters = getenv('MAUTIC_CONFIG_PARAMETERS'); | |
if ($envParameters) { | |
$compiledParameters = array_merge($compiledParameters, json_decode($envParameters, true)); | |
} | |
// Hardcode the db_driver to pdo_mysql, as it is currently the only supported driver. | |
// We set in here, to ensure it is always set to this value. | |
$compiledParameters['db_driver'] = 'pdo_mysql'; | |
$this->localParameters = $compiledParameters; | |
} | |
private function createParameterBags(): void | |
{ | |
$this->localParameterBag = new ParameterBag($this->localParameters); | |
$this->parameterBag = new ParameterBag(array_merge(self::$defaultParameters, $this->localParameters)); | |
} | |
private function getLocalParametersFile(): string | |
{ | |
// load the local parameter file from the same dir as the local config file. | |
return $this->configBaseDir.'/config/parameters_local.php'; | |
} | |
public static function getLocalConfigBaseDir(string $root): string | |
{ | |
$rootDir = Path::canonicalize($root); | |
$projectDir = self::getProjectDirByRoot($rootDir); | |
$localConfigFile = self::getLocalConfigFile($root, false); | |
if (Path::isBasePath($rootDir, $localConfigFile)) { | |
return $rootDir; | |
} elseif (Path::isBasePath($projectDir, $localConfigFile)) { | |
return $projectDir; | |
} | |
return $root; | |
} | |
public static function getProjectDirByRoot(string $root): string | |
{ | |
$dir = $rootDir = \dirname($root, 1); | |
while (!is_file($dir.'/composer.json')) { | |
if ($dir === \dirname($dir)) { | |
return $rootDir; | |
} | |
$dir = \dirname($dir); | |
} | |
return $dir; | |
} | |
} | |