Resolver.php 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. <?php
  2. declare(strict_types=1);
  3. namespace Dotenv\Loader;
  4. use Dotenv\Parser\Value;
  5. use Dotenv\Repository\RepositoryInterface;
  6. use Dotenv\Util\Regex;
  7. use Dotenv\Util\Str;
  8. use PhpOption\Option;
  9. final class Resolver
  10. {
  11. /**
  12. * This class is a singleton.
  13. *
  14. * @codeCoverageIgnore
  15. *
  16. * @return void
  17. */
  18. private function __construct()
  19. {
  20. //
  21. }
  22. /**
  23. * Resolve the nested variables in the given value.
  24. *
  25. * Replaces ${varname} patterns in the allowed positions in the variable
  26. * value by an existing environment variable.
  27. *
  28. * @param \Dotenv\Repository\RepositoryInterface $repository
  29. * @param \Dotenv\Parser\Value $value
  30. *
  31. * @return string
  32. */
  33. public static function resolve(RepositoryInterface $repository, Value $value)
  34. {
  35. return \array_reduce($value->getVars(), static function (string $s, int $i) use ($repository) {
  36. return Str::substr($s, 0, $i).self::resolveVariable($repository, Str::substr($s, $i));
  37. }, $value->getChars());
  38. }
  39. /**
  40. * Resolve a single nested variable.
  41. *
  42. * @param \Dotenv\Repository\RepositoryInterface $repository
  43. * @param string $str
  44. *
  45. * @return string
  46. */
  47. private static function resolveVariable(RepositoryInterface $repository, string $str)
  48. {
  49. return Regex::replaceCallback(
  50. '/\A\${([a-zA-Z0-9_.]+)}/',
  51. static function (array $matches) use ($repository) {
  52. return Option::fromValue($repository->get($matches[1]))
  53. ->getOrElse($matches[0]);
  54. },
  55. $str,
  56. 1
  57. )->success()->getOrElse($str);
  58. }
  59. }