PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Phinx/Config/Config.php

https://gitlab.com/kps007/phinx
PHP | 334 lines | 212 code | 29 blank | 93 comment | 15 complexity | 0a077978e0524f8ce6478fd5c57b55bf MD5 | raw file
  1. <?php
  2. /**
  3. * Phinx
  4. *
  5. * (The MIT license)
  6. * Copyright (c) 2015 Rob Morgan
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated * documentation files (the "Software"), to
  10. * deal in the Software without restriction, including without limitation the
  11. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  12. * sell copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  23. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  24. * IN THE SOFTWARE.
  25. *
  26. * @package Phinx
  27. * @subpackage Phinx\Config
  28. */
  29. namespace Phinx\Config;
  30. use Symfony\Component\Yaml\Yaml;
  31. /**
  32. * Phinx configuration class.
  33. *
  34. * @package Phinx
  35. * @author Rob Morgan
  36. */
  37. class Config implements ConfigInterface
  38. {
  39. /**
  40. * @var array
  41. */
  42. private $values = array();
  43. /**
  44. * @var string
  45. */
  46. protected $configFilePath;
  47. /**
  48. * {@inheritdoc}
  49. */
  50. public function __construct(array $configArray, $configFilePath = null)
  51. {
  52. $this->configFilePath = $configFilePath;
  53. $this->values = $this->replaceTokens($configArray);
  54. }
  55. /**
  56. * Create a new instance of the config class using a Yaml file path.
  57. *
  58. * @param string $configFilePath Path to the Yaml File
  59. * @throws \RuntimeException
  60. * @return Config
  61. */
  62. public static function fromYaml($configFilePath)
  63. {
  64. $configArray = Yaml::parse(file_get_contents($configFilePath));
  65. if (!is_array($configArray)) {
  66. throw new \RuntimeException(sprintf(
  67. 'File \'%s\' must be valid YAML',
  68. $configFilePath
  69. ));
  70. }
  71. return new static($configArray, $configFilePath);
  72. }
  73. /**
  74. * Create a new instance of the config class using a JSON file path.
  75. *
  76. * @param string $configFilePath Path to the JSON File
  77. * @throws \RuntimeException
  78. * @return Config
  79. */
  80. public static function fromJson($configFilePath)
  81. {
  82. $configArray = json_decode(file_get_contents($configFilePath), true);
  83. if (!is_array($configArray)) {
  84. throw new \RuntimeException(sprintf(
  85. 'File \'%s\' must be valid JSON',
  86. $configFilePath
  87. ));
  88. }
  89. return new static($configArray, $configFilePath);
  90. }
  91. /**
  92. * Create a new instance of the config class using a PHP file path.
  93. *
  94. * @param string $configFilePath Path to the PHP File
  95. * @throws \RuntimeException
  96. * @return Config
  97. */
  98. public static function fromPhp($configFilePath)
  99. {
  100. ob_start();
  101. /** @noinspection PhpIncludeInspection */
  102. $configArray = include($configFilePath);
  103. // Hide console output
  104. ob_end_clean();
  105. if (!is_array($configArray)) {
  106. throw new \RuntimeException(sprintf(
  107. 'PHP file \'%s\' must return an array',
  108. $configFilePath
  109. ));
  110. }
  111. return new static($configArray, $configFilePath);
  112. }
  113. /**
  114. * {@inheritdoc}
  115. */
  116. public function getEnvironments()
  117. {
  118. if (isset($this->values) && isset($this->values['environments'])) {
  119. $environments = array();
  120. foreach ($this->values['environments'] as $key => $value) {
  121. if (is_array($value)) {
  122. $environments[$key] = $value;
  123. }
  124. }
  125. return $environments;
  126. }
  127. return null;
  128. }
  129. /**
  130. * {@inheritdoc}
  131. */
  132. public function getEnvironment($name)
  133. {
  134. $environments = $this->getEnvironments();
  135. if (isset($environments[$name])) {
  136. if (isset($this->values['environments']['default_migration_table'])) {
  137. $environments[$name]['default_migration_table'] =
  138. $this->values['environments']['default_migration_table'];
  139. }
  140. return $environments[$name];
  141. }
  142. return null;
  143. }
  144. /**
  145. * {@inheritdoc}
  146. */
  147. public function hasEnvironment($name)
  148. {
  149. return (!(null === $this->getEnvironment($name)));
  150. }
  151. /**
  152. * {@inheritdoc}
  153. */
  154. public function getDefaultEnvironment()
  155. {
  156. // The $PHINX_ENVIRONMENT variable overrides all other default settings
  157. $env = getenv('PHINX_ENVIRONMENT');
  158. if (!empty($env)) {
  159. if ($this->hasEnvironment($env)) {
  160. return $env;
  161. }
  162. throw new \RuntimeException(sprintf(
  163. 'The environment configuration (read from $PHINX_ENVIRONMENT) for \'%s\' is missing',
  164. $env
  165. ));
  166. }
  167. // if the user has configured a default database then use it,
  168. // providing it actually exists!
  169. if (isset($this->values['environments']['default_database'])) {
  170. if ($this->getEnvironment($this->values['environments']['default_database'])) {
  171. return $this->values['environments']['default_database'];
  172. }
  173. throw new \RuntimeException(sprintf(
  174. 'The environment configuration for \'%s\' is missing',
  175. $this->values['environments']['default_database']
  176. ));
  177. }
  178. // else default to the first available one
  179. if (is_array($this->getEnvironments()) && count($this->getEnvironments()) > 0) {
  180. $names = array_keys($this->getEnvironments());
  181. return $names[0];
  182. }
  183. throw new \RuntimeException('Could not find a default environment');
  184. }
  185. /**
  186. * {@inheritdoc}
  187. */
  188. public function getConfigFilePath()
  189. {
  190. return $this->configFilePath;
  191. }
  192. /**
  193. * {@inheritdoc}
  194. */
  195. public function getMigrationPath()
  196. {
  197. if (!isset($this->values['paths']['migrations'])) {
  198. throw new \UnexpectedValueException('Migrations path missing from config file');
  199. }
  200. return $this->values['paths']['migrations'];
  201. }
  202. /**
  203. * Gets the base class name for migrations.
  204. *
  205. * @param boolean $dropNamespace Return the base migration class name without the namespace.
  206. * @return string
  207. */
  208. public function getMigrationBaseClassName($dropNamespace = true)
  209. {
  210. $className = !isset($this->values['migration_base_class']) ? 'Phinx\Migration\AbstractMigration' : $this->values['migration_base_class'];
  211. return $dropNamespace ? substr(strrchr($className, '\\'), 1) : $className;
  212. }
  213. /**
  214. * Replace tokens in the specified array.
  215. *
  216. * @param array $arr Array to replace
  217. * @return array
  218. */
  219. protected function replaceTokens($arr)
  220. {
  221. // Get environment variables
  222. // $_ENV is empty because variables_order does not include it normally
  223. $tokens = array();
  224. foreach ($_SERVER as $varname => $varvalue) {
  225. if (0 === strpos($varname, 'PHINX_')) {
  226. $tokens['%%' . $varname . '%%'] = $varvalue;
  227. }
  228. }
  229. // Phinx defined tokens (override env tokens)
  230. $tokens['%%PHINX_CONFIG_PATH%%'] = $this->getConfigFilePath();
  231. $tokens['%%PHINX_CONFIG_DIR%%'] = dirname($this->getConfigFilePath());
  232. // Recurse the array and replace tokens
  233. if (is_array($arr)) {
  234. return $this->recurseArrayForTokens($arr, $tokens);
  235. }
  236. return $arr;
  237. }
  238. /**
  239. * Recurse an array for the specified tokens and replace them.
  240. *
  241. * @param array $arr Array to recurse
  242. * @param array $tokens Array of tokens to search for
  243. * @return array
  244. */
  245. protected function recurseArrayForTokens($arr, $tokens)
  246. {
  247. $out = array();
  248. foreach ($arr as $name => $value) {
  249. if (is_array($value)) {
  250. $out[$name] = $this->recurseArrayForTokens($value, $tokens);
  251. continue;
  252. }
  253. if (is_string($value)) {
  254. foreach ($tokens as $token => $tval) {
  255. $value = str_replace($token, $tval, $value);
  256. }
  257. $out[$name] = $value;
  258. continue;
  259. }
  260. $out[$name] = $value;
  261. }
  262. return $out;
  263. }
  264. /**
  265. * {@inheritdoc}
  266. */
  267. public function offsetSet($id, $value)
  268. {
  269. $this->values[$id] = $value;
  270. }
  271. /**
  272. * {@inheritdoc}
  273. */
  274. public function offsetGet($id)
  275. {
  276. if (!array_key_exists($id, $this->values)) {
  277. throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
  278. }
  279. return $this->values[$id] instanceof \Closure ? $this->values[$id]($this) : $this->values[$id];
  280. }
  281. /**
  282. * {@inheritdoc}
  283. */
  284. public function offsetExists($id)
  285. {
  286. return isset($this->values[$id]);
  287. }
  288. /**
  289. * {@inheritdoc}
  290. */
  291. public function offsetUnset($id)
  292. {
  293. unset($this->values[$id]);
  294. }
  295. }