Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\DependencyInjection\ParameterBag; Chris@0: Chris@17: use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; Chris@0: use Symfony\Component\DependencyInjection\Exception\RuntimeException; Chris@0: Chris@0: /** Chris@0: * @author Nicolas Grekas Chris@0: */ Chris@0: class EnvPlaceholderParameterBag extends ParameterBag Chris@0: { Chris@17: private $envPlaceholders = []; Chris@17: private $providedTypes = []; Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function get($name) Chris@0: { Chris@0: if (0 === strpos($name, 'env(') && ')' === substr($name, -1) && 'env()' !== $name) { Chris@0: $env = substr($name, 4, -1); Chris@0: Chris@0: if (isset($this->envPlaceholders[$env])) { Chris@0: foreach ($this->envPlaceholders[$env] as $placeholder) { Chris@0: return $placeholder; // return first result Chris@0: } Chris@0: } Chris@14: if (!preg_match('/^(?:\w++:)*+\w++$/', $env)) { Chris@0: throw new InvalidArgumentException(sprintf('Invalid %s name: only "word" characters are allowed.', $name)); Chris@0: } Chris@0: Chris@0: if ($this->has($name)) { Chris@0: $defaultValue = parent::get($name); Chris@0: Chris@0: if (null !== $defaultValue && !is_scalar($defaultValue)) { Chris@17: throw new RuntimeException(sprintf('The default value of an env() parameter must be scalar or null, but "%s" given to "%s".', \gettype($defaultValue), $name)); Chris@0: } Chris@0: } Chris@0: Chris@0: $uniqueName = md5($name.uniqid(mt_rand(), true)); Chris@14: $placeholder = sprintf('env_%s_%s', str_replace(':', '_', $env), $uniqueName); Chris@0: $this->envPlaceholders[$env][$placeholder] = $placeholder; Chris@0: Chris@0: return $placeholder; Chris@0: } Chris@0: Chris@0: return parent::get($name); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the map of env vars used in the resolved parameter values to their placeholders. Chris@0: * Chris@0: * @return string[][] A map of env var names to their placeholders Chris@0: */ Chris@0: public function getEnvPlaceholders() Chris@0: { Chris@0: return $this->envPlaceholders; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Merges the env placeholders of another EnvPlaceholderParameterBag. Chris@0: */ Chris@0: public function mergeEnvPlaceholders(self $bag) Chris@0: { Chris@0: if ($newPlaceholders = $bag->getEnvPlaceholders()) { Chris@0: $this->envPlaceholders += $newPlaceholders; Chris@0: Chris@0: foreach ($newPlaceholders as $env => $placeholders) { Chris@0: $this->envPlaceholders[$env] += $placeholders; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@14: * Maps env prefixes to their corresponding PHP types. Chris@14: */ Chris@14: public function setProvidedTypes(array $providedTypes) Chris@14: { Chris@14: $this->providedTypes = $providedTypes; Chris@14: } Chris@14: Chris@14: /** Chris@14: * Gets the PHP types corresponding to env() parameter prefixes. Chris@14: * Chris@14: * @return string[][] Chris@14: */ Chris@14: public function getProvidedTypes() Chris@14: { Chris@14: return $this->providedTypes; Chris@14: } Chris@14: Chris@14: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function resolve() Chris@0: { Chris@0: if ($this->resolved) { Chris@0: return; Chris@0: } Chris@0: parent::resolve(); Chris@0: Chris@0: foreach ($this->envPlaceholders as $env => $placeholders) { Chris@14: if (!$this->has($name = "env($env)")) { Chris@0: continue; Chris@0: } Chris@0: if (is_numeric($default = $this->parameters[$name])) { Chris@0: $this->parameters[$name] = (string) $default; Chris@0: } elseif (null !== $default && !is_scalar($default)) { Chris@17: throw new RuntimeException(sprintf('The default value of env parameter "%s" must be scalar or null, %s given.', $env, \gettype($default))); Chris@0: } Chris@0: } Chris@0: } Chris@0: }