/local/php_interface/classes/vendor/talesoft/tale-config/Config.php

https://gitlab.com/Andrey_rus86/kruzenshtern · PHP · 213 lines · 111 code · 46 blank · 56 comment · 15 complexity · 8af0b82d2fcc1a2f7ae1e9797054a503 MD5 · raw file

  1. <?php
  2. namespace Tale;
  3. use Tale\Config\Format\Ini;
  4. use Tale\Config\Format\Json;
  5. use Tale\Config\Format\Php;
  6. use Tale\Config\Format\Xml;
  7. use Tale\Config\Format\Yaml;
  8. use Tale\Config\FormatInterface;
  9. use Tale\Factory\SingletonFactory;
  10. final class Config
  11. {
  12. private static $formats = [
  13. 'ini' => Ini::class,
  14. 'json' => Json::class,
  15. 'php' => Php::class,
  16. 'xml' => Xml::class,
  17. 'yaml' => Yaml::class
  18. ];
  19. private static $formatFactory = null;
  20. public static function createFormatFactory(array $formats = null)
  21. {
  22. return new SingletonFactory(FormatInterface::class, $formats);
  23. }
  24. public static function getFormatFactory()
  25. {
  26. if (self::$formatFactory === null)
  27. self::$formatFactory = self::createFormatFactory(
  28. self::$formats
  29. );
  30. return self::$formatFactory;
  31. }
  32. public static function resolve($path)
  33. {
  34. $factory = self::getFormatFactory();
  35. $ext = pathinfo($path, PATHINFO_EXTENSION);
  36. if (!empty($ext) && file_exists($path))
  37. return $path;
  38. /** @var FormatInterface[] $aliases */
  39. $aliases = $factory->getAliases();
  40. foreach ($aliases as $extension => $className) {
  41. $extPath = "$path.$extension";
  42. if (file_exists($extPath))
  43. return $extPath;
  44. }
  45. return null;
  46. }
  47. public static function load($path, $optional = false)
  48. {
  49. $path = self::resolve($path);
  50. $factory = self::getFormatFactory();
  51. if (!$path) {
  52. if ($optional)
  53. return [];
  54. throw new ConfigException(
  55. "Failed to resolve configuration file $path: ".
  56. "The file was not found, even with any of the following ".
  57. "registered extensions: ".implode(', ', array_keys($factory->getAliases()))
  58. );
  59. }
  60. return $factory->get(pathinfo($path, PATHINFO_EXTENSION))->load($path);
  61. }
  62. /**
  63. * Resolves a key.subKey.subSubKey-style string to a deep array value
  64. *
  65. * The function accesses multi-dimensional keys with a delimiter given (Default: Dot (.))
  66. *
  67. * @protip If you want to throw an exception if no key is found, pass the exception as the default value
  68. * and throw it, if the result is an Exception-type
  69. *
  70. * @param string $key The input key to operate on
  71. * @param array $source The array to search values in
  72. * @param mixed $defaultValue The default value if no key is found
  73. * @param string|null $delimiter The delimeter to access dimensions (Default: Dot (.))
  74. *
  75. * @return array|null The found value or the default value, if none found (Default: null)
  76. */
  77. public static function get($key, array $source, $defaultValue = null, $delimiter = null)
  78. {
  79. $delimiter = $delimiter ?: '.';
  80. $current = &$source;
  81. $keys = explode($delimiter, $key);
  82. foreach ($keys as $key) {
  83. if (is_numeric($key))
  84. $key = intval($key);
  85. if (!isset($current[$key]))
  86. return $defaultValue;
  87. $current = &$current[$key];
  88. }
  89. return $current;
  90. }
  91. /**
  92. * Resolves a key.subKey.subSubKey-style string to a deep array value
  93. *
  94. * The function accesses multi-dimensional keys with a delimiter given (Default: Dot (.))
  95. *
  96. * @protip If you want to throw an exception if no key is found, pass the exception as the default value
  97. * and throw it, if the result is an Exception-type
  98. *
  99. * @param string $key The input key to operate on
  100. * @param mixed $value The default value if no key is found
  101. * @param array $source The array to search values in
  102. * @param string|null $delimiter The delimeter to access dimensions (Default: Dot (.))
  103. *
  104. * @return array|null The found value or the default value, if none found (Default: null)
  105. */
  106. public static function set($key, $value, array &$source, $delimiter = null)
  107. {
  108. $delimiter = $delimiter ?: '.';
  109. $current = &$source;
  110. $keys = explode($delimiter, $key);
  111. $lastKey = array_pop($keys);
  112. foreach ($keys as $key) {
  113. if (is_numeric($key))
  114. $key = intval($key);
  115. if (!isset($current[$key]))
  116. $current[$key] = [];
  117. $current = &$current[$key];
  118. }
  119. $current[$lastKey] = $value;
  120. }
  121. /**
  122. * Interpolates {{var.subVar}}-style based on a source array given
  123. *
  124. * Dimensions in the source array are accessed with a passed delimeter (Default: Dot (.))
  125. *
  126. * @param string $string The input string to operate on
  127. * @param array $source The associative source array
  128. * @param mixed $defaultValue The default value for indices that dont exist
  129. * @param string|null $delimiter The delimeter for multi-dimension access (Default: Dot (.))
  130. *
  131. * @return string The interpolated string with the variables replaced with their values
  132. */
  133. public static function interpolate($string, array $source, $defaultValue = null, $delimiter = null)
  134. {
  135. $defaultValue = $defaultValue ?: '';
  136. return preg_replace_callback('/\{\{([^\}]+)\}\}/i', function ($m) use ($source, $defaultValue, $delimiter) {
  137. $key = $m[1];
  138. if (defined($key))
  139. return constant($key);
  140. return self::get($key, $source, $defaultValue, $delimiter);
  141. }, $string);
  142. }
  143. /**
  144. * Interpolates a multi-dimensional array with another array recursively
  145. *
  146. * If no source is given, you get a live interpolation where you can directly interpolate
  147. * variables that have just been interpolated before
  148. *
  149. * This is mostly used for option arrays, e.g. config-files
  150. *
  151. * @param array $array The array to interpolate (Passed by reference)
  152. * @param array|null $source The source array for variables. If none given, the input array is taken
  153. * @param null $defaultValue The default value for indices that couldnt be resolved
  154. * @param string $delimiter The delimeter used for multi-dimension access (Default: Dot (.))
  155. */
  156. public static function interpolateArray(array &$array, array &$source = null, $defaultValue = null, $delimiter = null)
  157. {
  158. if (!$source)
  159. $source = &$array;
  160. foreach ($array as $key => &$val) {
  161. if (is_array($val))
  162. self::interpolateArray($val, $source, $defaultValue, $delimiter);
  163. else if (is_string($val))
  164. $array[$key] = self::interpolate($val, $source, $defaultValue, $delimiter);
  165. }
  166. }
  167. }