PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Cake/Console/Command/Task/DbConfigTask.php

https://github.com/suzuki/candycane
PHP | 384 lines | 252 code | 58 blank | 74 comment | 68 complexity | 5ad78aee03a9f1507f23cdf0a40dd8a5 MD5 | raw file
  1. <?php
  2. /**
  3. * The DbConfig Task handles creating and updating the database.php
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8. * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice.
  12. *
  13. * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://cakephp.org CakePHP(tm) Project
  15. * @since CakePHP(tm) v 1.2
  16. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  17. */
  18. App::uses('AppShell', 'Console/Command');
  19. /**
  20. * Task class for creating and updating the database configuration file.
  21. *
  22. * @package Cake.Console.Command.Task
  23. */
  24. class DbConfigTask extends AppShell {
  25. /**
  26. * path to CONFIG directory
  27. *
  28. * @var string
  29. */
  30. public $path = null;
  31. /**
  32. * Default configuration settings to use
  33. *
  34. * @var array
  35. */
  36. protected $_defaultConfig = array(
  37. 'name' => 'default',
  38. 'datasource' => 'Database/Mysql',
  39. 'persistent' => 'false',
  40. 'host' => 'localhost',
  41. 'login' => 'root',
  42. 'password' => 'password',
  43. 'database' => 'project_name',
  44. 'schema' => null,
  45. 'prefix' => null,
  46. 'encoding' => null,
  47. 'port' => null
  48. );
  49. /**
  50. * String name of the database config class name.
  51. * Used for testing.
  52. *
  53. * @var string
  54. */
  55. public $databaseClassName = 'DATABASE_CONFIG';
  56. /**
  57. * initialization callback
  58. *
  59. * @return void
  60. */
  61. public function initialize() {
  62. $this->path = APP . 'Config' . DS;
  63. }
  64. /**
  65. * Execution method always used for tasks
  66. *
  67. * @return void
  68. */
  69. public function execute() {
  70. if (empty($this->args)) {
  71. $this->_interactive();
  72. $this->_stop();
  73. }
  74. }
  75. /**
  76. * Interactive interface
  77. *
  78. * @return void
  79. */
  80. protected function _interactive() {
  81. $this->hr();
  82. $this->out(__d('cake_console', 'Database Configuration:'));
  83. $this->hr();
  84. $done = false;
  85. $dbConfigs = array();
  86. while ($done == false) {
  87. $name = '';
  88. while ($name == '') {
  89. $name = $this->in(__d('cake_console', "Name:"), null, 'default');
  90. if (preg_match('/[^a-z0-9_]/i', $name)) {
  91. $name = '';
  92. $this->out(__d('cake_console', 'The name may only contain unaccented latin characters, numbers or underscores'));
  93. } elseif (preg_match('/^[^a-z_]/i', $name)) {
  94. $name = '';
  95. $this->out(__d('cake_console', 'The name must start with an unaccented latin character or an underscore'));
  96. }
  97. }
  98. $datasource = $this->in(__d('cake_console', 'Datasource:'), array('Mysql', 'Postgres', 'Sqlite', 'Sqlserver'), 'Mysql');
  99. $persistent = $this->in(__d('cake_console', 'Persistent Connection?'), array('y', 'n'), 'n');
  100. if (strtolower($persistent) == 'n') {
  101. $persistent = 'false';
  102. } else {
  103. $persistent = 'true';
  104. }
  105. $host = '';
  106. while ($host == '') {
  107. $host = $this->in(__d('cake_console', 'Database Host:'), null, 'localhost');
  108. }
  109. $port = '';
  110. while ($port == '') {
  111. $port = $this->in(__d('cake_console', 'Port?'), null, 'n');
  112. }
  113. if (strtolower($port) == 'n') {
  114. $port = null;
  115. }
  116. $login = '';
  117. while ($login == '') {
  118. $login = $this->in(__d('cake_console', 'User:'), null, 'root');
  119. }
  120. $password = '';
  121. $blankPassword = false;
  122. while ($password == '' && $blankPassword == false) {
  123. $password = $this->in(__d('cake_console', 'Password:'));
  124. if ($password == '') {
  125. $blank = $this->in(__d('cake_console', 'The password you supplied was empty. Use an empty password?'), array('y', 'n'), 'n');
  126. if ($blank == 'y') {
  127. $blankPassword = true;
  128. }
  129. }
  130. }
  131. $database = '';
  132. while ($database == '') {
  133. $database = $this->in(__d('cake_console', 'Database Name:'), null, 'cake');
  134. }
  135. $prefix = '';
  136. while ($prefix == '') {
  137. $prefix = $this->in(__d('cake_console', 'Table Prefix?'), null, 'n');
  138. }
  139. if (strtolower($prefix) == 'n') {
  140. $prefix = null;
  141. }
  142. $encoding = '';
  143. while ($encoding == '') {
  144. $encoding = $this->in(__d('cake_console', 'Table encoding?'), null, 'n');
  145. }
  146. if (strtolower($encoding) == 'n') {
  147. $encoding = null;
  148. }
  149. $schema = '';
  150. if ($datasource == 'postgres') {
  151. while ($schema == '') {
  152. $schema = $this->in(__d('cake_console', 'Table schema?'), null, 'n');
  153. }
  154. }
  155. if (strtolower($schema) == 'n') {
  156. $schema = null;
  157. }
  158. $config = compact('name', 'datasource', 'persistent', 'host', 'login', 'password', 'database', 'prefix', 'encoding', 'port', 'schema');
  159. while ($this->_verify($config) == false) {
  160. $this->_interactive();
  161. }
  162. $dbConfigs[] = $config;
  163. $doneYet = $this->in(__d('cake_console', 'Do you wish to add another database configuration?'), null, 'n');
  164. if (strtolower($doneYet == 'n')) {
  165. $done = true;
  166. }
  167. }
  168. $this->bake($dbConfigs);
  169. config('database');
  170. return true;
  171. }
  172. /**
  173. * Output verification message and bake if it looks good
  174. *
  175. * @param array $config
  176. * @return boolean True if user says it looks good, false otherwise
  177. */
  178. protected function _verify($config) {
  179. $config = array_merge($this->_defaultConfig, $config);
  180. extract($config);
  181. $this->out();
  182. $this->hr();
  183. $this->out(__d('cake_console', 'The following database configuration will be created:'));
  184. $this->hr();
  185. $this->out(__d('cake_console', "Name: %s", $name));
  186. $this->out(__d('cake_console', "Datasource: %s", $datasource));
  187. $this->out(__d('cake_console', "Persistent: %s", $persistent));
  188. $this->out(__d('cake_console', "Host: %s", $host));
  189. if ($port) {
  190. $this->out(__d('cake_console', "Port: %s", $port));
  191. }
  192. $this->out(__d('cake_console', "User: %s", $login));
  193. $this->out(__d('cake_console', "Pass: %s", str_repeat('*', strlen($password))));
  194. $this->out(__d('cake_console', "Database: %s", $database));
  195. if ($prefix) {
  196. $this->out(__d('cake_console', "Table prefix: %s", $prefix));
  197. }
  198. if ($schema) {
  199. $this->out(__d('cake_console', "Schema: %s", $schema));
  200. }
  201. if ($encoding) {
  202. $this->out(__d('cake_console', "Encoding: %s", $encoding));
  203. }
  204. $this->hr();
  205. $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n'), 'y');
  206. if (strtolower($looksGood) == 'y') {
  207. return $config;
  208. }
  209. return false;
  210. }
  211. /**
  212. * Assembles and writes database.php
  213. *
  214. * @param array $configs Configuration settings to use
  215. * @return boolean Success
  216. */
  217. public function bake($configs) {
  218. if (!is_dir($this->path)) {
  219. $this->err(__d('cake_console', '%s not found', $this->path));
  220. return false;
  221. }
  222. $filename = $this->path . 'database.php';
  223. $oldConfigs = array();
  224. if (file_exists($filename)) {
  225. config('database');
  226. $db = new $this->databaseClassName;
  227. $temp = get_class_vars(get_class($db));
  228. foreach ($temp as $configName => $info) {
  229. $info = array_merge($this->_defaultConfig, $info);
  230. if (!isset($info['schema'])) {
  231. $info['schema'] = null;
  232. }
  233. if (!isset($info['encoding'])) {
  234. $info['encoding'] = null;
  235. }
  236. if (!isset($info['port'])) {
  237. $info['port'] = null;
  238. }
  239. if ($info['persistent'] === false) {
  240. $info['persistent'] = 'false';
  241. } else {
  242. $info['persistent'] = ($info['persistent'] == true) ? 'true' : 'false';
  243. }
  244. $oldConfigs[] = array(
  245. 'name' => $configName,
  246. 'datasource' => $info['datasource'],
  247. 'persistent' => $info['persistent'],
  248. 'host' => $info['host'],
  249. 'port' => $info['port'],
  250. 'login' => $info['login'],
  251. 'password' => $info['password'],
  252. 'database' => $info['database'],
  253. 'prefix' => $info['prefix'],
  254. 'schema' => $info['schema'],
  255. 'encoding' => $info['encoding']
  256. );
  257. }
  258. }
  259. foreach ($oldConfigs as $key => $oldConfig) {
  260. foreach ($configs as $key1 => $config) {
  261. if ($oldConfig['name'] == $config['name']) {
  262. unset($oldConfigs[$key]);
  263. }
  264. }
  265. }
  266. $configs = array_merge($oldConfigs, $configs);
  267. $out = "<?php\n";
  268. $out .= "class DATABASE_CONFIG {\n\n";
  269. foreach ($configs as $config) {
  270. $config = array_merge($this->_defaultConfig, $config);
  271. extract($config);
  272. $out .= "\tpublic \${$name} = array(\n";
  273. $out .= "\t\t'datasource' => 'Database/{$datasource}',\n";
  274. $out .= "\t\t'persistent' => {$persistent},\n";
  275. $out .= "\t\t'host' => '{$host}',\n";
  276. if ($port) {
  277. $out .= "\t\t'port' => {$port},\n";
  278. }
  279. $out .= "\t\t'login' => '{$login}',\n";
  280. $out .= "\t\t'password' => '{$password}',\n";
  281. $out .= "\t\t'database' => '{$database}',\n";
  282. if ($schema) {
  283. $out .= "\t\t'schema' => '{$schema}',\n";
  284. }
  285. if ($prefix) {
  286. $out .= "\t\t'prefix' => '{$prefix}',\n";
  287. }
  288. if ($encoding) {
  289. $out .= "\t\t'encoding' => '{$encoding}'\n";
  290. }
  291. $out .= "\t);\n";
  292. }
  293. $out .= "}\n";
  294. $filename = $this->path . 'database.php';
  295. return $this->createFile($filename, $out);
  296. }
  297. /**
  298. * Get a user specified Connection name
  299. *
  300. * @return void
  301. */
  302. public function getConfig() {
  303. App::uses('ConnectionManager', 'Model');
  304. $configs = ConnectionManager::enumConnectionObjects();
  305. $useDbConfig = key($configs);
  306. if (!is_array($configs) || empty($configs)) {
  307. return $this->execute();
  308. }
  309. $connections = array_keys($configs);
  310. if (count($connections) > 1) {
  311. $useDbConfig = $this->in(__d('cake_console', 'Use Database Config') . ':', $connections, $useDbConfig);
  312. }
  313. return $useDbConfig;
  314. }
  315. /**
  316. * get the option parser
  317. *
  318. * @return ConsoleOptionParser
  319. */
  320. public function getOptionParser() {
  321. $parser = parent::getOptionParser();
  322. return $parser->description(
  323. __d('cake_console', 'Bake new database configuration settings.')
  324. );
  325. }
  326. }