1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
17:
18: App::uses('AppShell', 'Console/Command');
19:
20: 21: 22: 23: 24:
25: class DbConfigTask extends AppShell {
26:
27: 28: 29: 30: 31:
32: public $path = null;
33:
34: 35: 36: 37: 38:
39: protected $_defaultConfig = array(
40: 'name' => 'default',
41: 'datasource' => 'Database/Mysql',
42: 'persistent' => 'false',
43: 'host' => 'localhost',
44: 'login' => 'root',
45: 'password' => 'password',
46: 'database' => 'project_name',
47: 'schema' => null,
48: 'prefix' => null,
49: 'encoding' => null,
50: 'port' => null
51: );
52:
53: 54: 55: 56: 57: 58:
59: public $databaseClassName = 'DATABASE_CONFIG';
60:
61: 62: 63: 64: 65:
66: public function initialize() {
67: $this->path = APP . 'Config' . DS;
68: }
69:
70: 71: 72: 73: 74:
75: public function execute() {
76: if (empty($this->args)) {
77: $this->_interactive();
78: return $this->_stop();
79: }
80: }
81:
82: 83: 84: 85: 86:
87: protected function _interactive() {
88: $this->hr();
89: $this->out(__d('cake_console', 'Database Configuration:'));
90: $this->hr();
91: $done = false;
92: $dbConfigs = array();
93:
94: while (!$done) {
95: $name = '';
96:
97: while (!$name) {
98: $name = $this->in(__d('cake_console', "Name:"), null, 'default');
99: if (preg_match('/[^a-z0-9_]/i', $name)) {
100: $name = '';
101: $this->out(__d('cake_console', 'The name may only contain unaccented latin characters, numbers or underscores'));
102: } elseif (preg_match('/^[^a-z_]/i', $name)) {
103: $name = '';
104: $this->out(__d('cake_console', 'The name must start with an unaccented latin character or an underscore'));
105: }
106: }
107:
108: $datasource = $this->in(__d('cake_console', 'Datasource:'), array('Mysql', 'Postgres', 'Sqlite', 'Sqlserver'), 'Mysql');
109:
110: $persistent = $this->in(__d('cake_console', 'Persistent Connection?'), array('y', 'n'), 'n');
111: if (strtolower($persistent) === 'n') {
112: $persistent = 'false';
113: } else {
114: $persistent = 'true';
115: }
116:
117: $host = '';
118: while (!$host) {
119: $host = $this->in(__d('cake_console', 'Database Host:'), null, 'localhost');
120: }
121:
122: $port = '';
123: while (!$port) {
124: $port = $this->in(__d('cake_console', 'Port?'), null, 'n');
125: }
126:
127: if (strtolower($port) === 'n') {
128: $port = null;
129: }
130:
131: $login = '';
132: while (!$login) {
133: $login = $this->in(__d('cake_console', 'User:'), null, 'root');
134: }
135: $password = '';
136: $blankPassword = false;
137:
138: while (!$password && !$blankPassword) {
139: $password = $this->in(__d('cake_console', 'Password:'));
140:
141: if (!$password) {
142: $blank = $this->in(__d('cake_console', 'The password you supplied was empty. Use an empty password?'), array('y', 'n'), 'n');
143: if ($blank === 'y') {
144: $blankPassword = true;
145: }
146: }
147: }
148:
149: $database = '';
150: while (!$database) {
151: $database = $this->in(__d('cake_console', 'Database Name:'), null, 'cake');
152: }
153:
154: $prefix = '';
155: while (!$prefix) {
156: $prefix = $this->in(__d('cake_console', 'Table Prefix?'), null, 'n');
157: }
158: if (strtolower($prefix) === 'n') {
159: $prefix = null;
160: }
161:
162: $encoding = '';
163: while (!$encoding) {
164: $encoding = $this->in(__d('cake_console', 'Table encoding?'), null, 'n');
165: }
166: if (strtolower($encoding) === 'n') {
167: $encoding = null;
168: }
169:
170: $schema = '';
171: if ($datasource === 'postgres') {
172: while (!$schema) {
173: $schema = $this->in(__d('cake_console', 'Table schema?'), null, 'n');
174: }
175: }
176: if (strtolower($schema) === 'n') {
177: $schema = null;
178: }
179:
180: $config = compact('name', 'datasource', 'persistent', 'host', 'login', 'password', 'database', 'prefix', 'encoding', 'port', 'schema');
181:
182: while (!$this->_verify($config)) {
183: $this->_interactive();
184: }
185:
186: $dbConfigs[] = $config;
187: $doneYet = $this->in(__d('cake_console', 'Do you wish to add another database configuration?'), null, 'n');
188:
189: if (strtolower($doneYet === 'n')) {
190: $done = true;
191: }
192: }
193:
194: $this->bake($dbConfigs);
195: config('database');
196: return true;
197: }
198:
199: 200: 201: 202: 203: 204:
205: protected function _verify($config) {
206: $config += $this->_defaultConfig;
207: extract($config);
208: $this->out();
209: $this->hr();
210: $this->out(__d('cake_console', 'The following database configuration will be created:'));
211: $this->hr();
212: $this->out(__d('cake_console', "Name: %s", $name));
213: $this->out(__d('cake_console', "Datasource: %s", $datasource));
214: $this->out(__d('cake_console', "Persistent: %s", $persistent));
215: $this->out(__d('cake_console', "Host: %s", $host));
216:
217: if ($port) {
218: $this->out(__d('cake_console', "Port: %s", $port));
219: }
220:
221: $this->out(__d('cake_console', "User: %s", $login));
222: $this->out(__d('cake_console', "Pass: %s", str_repeat('*', strlen($password))));
223: $this->out(__d('cake_console', "Database: %s", $database));
224:
225: if ($prefix) {
226: $this->out(__d('cake_console', "Table prefix: %s", $prefix));
227: }
228:
229: if ($schema) {
230: $this->out(__d('cake_console', "Schema: %s", $schema));
231: }
232:
233: if ($encoding) {
234: $this->out(__d('cake_console', "Encoding: %s", $encoding));
235: }
236:
237: $this->hr();
238: $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n'), 'y');
239:
240: if (strtolower($looksGood) === 'y') {
241: return $config;
242: }
243: return false;
244: }
245:
246: 247: 248: 249: 250: 251:
252: public function bake($configs) {
253: if (!is_dir($this->path)) {
254: $this->err(__d('cake_console', '%s not found', $this->path));
255: return false;
256: }
257:
258: $filename = $this->path . 'database.php';
259: $oldConfigs = array();
260:
261: if (file_exists($filename)) {
262: config('database');
263: $db = new $this->databaseClassName;
264: $temp = get_class_vars(get_class($db));
265:
266: foreach ($temp as $configName => $info) {
267: $info += $this->_defaultConfig;
268:
269: if (!isset($info['schema'])) {
270: $info['schema'] = null;
271: }
272: if (!isset($info['encoding'])) {
273: $info['encoding'] = null;
274: }
275: if (!isset($info['port'])) {
276: $info['port'] = null;
277: }
278:
279: $info['persistent'] = var_export((bool)$info['persistent'], true);
280:
281: $oldConfigs[] = array(
282: 'name' => $configName,
283: 'datasource' => $info['datasource'],
284: 'persistent' => $info['persistent'],
285: 'host' => $info['host'],
286: 'port' => $info['port'],
287: 'login' => $info['login'],
288: 'password' => $info['password'],
289: 'database' => $info['database'],
290: 'prefix' => $info['prefix'],
291: 'schema' => $info['schema'],
292: 'encoding' => $info['encoding']
293: );
294: }
295: }
296:
297: foreach ($oldConfigs as $key => $oldConfig) {
298: foreach ($configs as $config) {
299: if ($oldConfig['name'] === $config['name']) {
300: unset($oldConfigs[$key]);
301: }
302: }
303: }
304:
305: $configs = array_merge($oldConfigs, $configs);
306: $out = "<?php\n";
307: $out .= "class DATABASE_CONFIG {\n\n";
308:
309: foreach ($configs as $config) {
310: $config += $this->_defaultConfig;
311: extract($config);
312:
313: if (strpos($datasource, 'Database/') === false) {
314: $datasource = "Database/{$datasource}";
315: }
316: $out .= "\tpublic \${$name} = array(\n";
317: $out .= "\t\t'datasource' => '{$datasource}',\n";
318: $out .= "\t\t'persistent' => {$persistent},\n";
319: $out .= "\t\t'host' => '{$host}',\n";
320:
321: if ($port) {
322: $out .= "\t\t'port' => {$port},\n";
323: }
324:
325: $out .= "\t\t'login' => '{$login}',\n";
326: $out .= "\t\t'password' => '{$password}',\n";
327: $out .= "\t\t'database' => '{$database}',\n";
328:
329: if ($schema) {
330: $out .= "\t\t'schema' => '{$schema}',\n";
331: }
332:
333: if ($prefix) {
334: $out .= "\t\t'prefix' => '{$prefix}',\n";
335: }
336:
337: if ($encoding) {
338: $out .= "\t\t'encoding' => '{$encoding}'\n";
339: }
340:
341: $out .= "\t);\n";
342: }
343:
344: $out .= "}\n";
345: $filename = $this->path . 'database.php';
346: return $this->createFile($filename, $out);
347: }
348:
349: 350: 351: 352: 353:
354: public function getConfig() {
355: App::uses('ConnectionManager', 'Model');
356: $configs = ConnectionManager::enumConnectionObjects();
357:
358: $useDbConfig = key($configs);
359: if (!is_array($configs) || empty($configs)) {
360: return $this->execute();
361: }
362: $connections = array_keys($configs);
363:
364: if (count($connections) > 1) {
365: $useDbConfig = $this->in(__d('cake_console', 'Use Database Config') . ':', $connections, $useDbConfig);
366: }
367: return $useDbConfig;
368: }
369:
370: 371: 372: 373: 374:
375: public function getOptionParser() {
376: $parser = parent::getOptionParser();
377:
378: $parser->description(
379: __d('cake_console', 'Bake new database configuration settings.')
380: );
381:
382: return $parser;
383: }
384:
385: }
386: