Projekt

Obecné

Profil

Stáhnout (24.5 KB) Statistiky
| Větev: | Tag: | Revize:
1
#!/usr/bin/php -q
2
<?php
3
/* SVN FILE: $Id: acl.php 4409 2007-02-02 13:20:59Z phpnut $ */
4
/**
5
 * Short description for file.
6
 *
7
 * Long description for file
8
 *
9
 * PHP versions 4 and 5
10
 *
11
 * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
12
 * Copyright 2005-2007, Cake Software Foundation, Inc.
13
 *								1785 E. Sahara Avenue, Suite 490-204
14
 *								Las Vegas, Nevada 89104
15
 *
16
 * Licensed under The MIT License
17
 * Redistributions of files must retain the above copyright notice.
18
 *
19
 * @filesource
20
 * @copyright		Copyright 2005-2007, Cake Software Foundation, Inc.
21
 * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
22
 * @package			cake
23
 * @subpackage		cake.cake.scripts
24
 * @since			CakePHP(tm) v 0.10.0.1232
25
 * @version			$Revision: 4409 $
26
 * @modifiedby		$LastChangedBy: phpnut $
27
 * @lastmodified	$Date: 2007-02-02 07:20:59 -0600 (Fri, 02 Feb 2007) $
28
 * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
29
 */
30
/**
31
 * Enter description here...
32
 */
33
	ini_set('display_errors', '1');
34
	ini_set('error_reporting', '7');//bylo 7
35
	define ('DS', DIRECTORY_SEPARATOR);
36
	$app = 'app';
37
	$core = null;
38
	$root = dirname(dirname(dirname(__FILE__)));
39
	$here = $argv[0];
40
	$dataSource = 'default';
41
	$unset = array();
42
	for ($i = 1; $i < count($argv); $i++) {
43
		// Process command-line modifiers here
44
		switch (strtolower($argv[$i])) {
45
			case '-app':
46
				$app = $argv[$i + 1];
47
				$unset[$i] = $argv[$i];
48
				$unset[$i + 1] = $argv[$i + 1];
49
			break;
50
			case '-core':
51
				$core = $argv[$i + 1];
52
				$unset[$i] = $argv[$i];
53
				$unset[$i + 1] = $argv[$i + 1];
54
			break;
55
			case '-root':
56
				$root = $argv[$i + 1];
57
				$unset[$i] = $argv[$i];
58
				$unset[$i + 1] = $argv[$i + 1];
59
			break;
60
			case '-datasource':
61
				$dataSource = $argv[$i + 1];
62
				$unset[$i] = $argv[$i];
63
				$unset[$i + 1] = $argv[$i + 1];
64
			break;
65
		}
66
	}
67

    
68
	if (strlen($app) && $app[0] == DS) {
69
		$cnt = substr_count($root, DS);
70
		$app = str_repeat('..' . DS, $cnt) . $app;
71
	}
72
	define ('ROOT', $root.DS);
73
	define ('APP_DIR', $app);
74
	define ('DEBUG', 1);;
75
	define('CAKE_CORE_INCLUDE_PATH', ROOT);
76
	define('DATASOURCE', $dataSource);
77

    
78
	if(function_exists('ini_set')) {
79
		ini_set('include_path',ini_get('include_path').
80
			PATH_SEPARATOR.CAKE_CORE_INCLUDE_PATH.DS.
81
			PATH_SEPARATOR.CORE_PATH.DS.
82
			PATH_SEPARATOR.ROOT.DS.APP_DIR.DS.
83
			PATH_SEPARATOR.APP_DIR.DS.
84
			PATH_SEPARATOR.APP_PATH);
85
		define('APP_PATH', null);
86
		define('CORE_PATH', null);
87
	} else {
88
		define('APP_PATH', ROOT . DS . APP_DIR . DS);
89
		define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
90
	}
91

    
92
	require ('cake'.DS.'basics.php');
93
	require ('cake'.DS.'config'.DS.'paths.php');
94
	require (CONFIGS.'core.php');
95
	uses ('object', 'configure', 'neat_array', 'session', 'security', 'inflector', 'model'.DS.'connection_manager',
96
			'model'.DS.'datasources'.DS.'dbo_source', 'model'.DS.'model');
97
	require(CAKE.'app_model.php');
98
	uses ('controller'.DS.'components'.DS.'acl', 'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aclnode',
99
			'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aco', 'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'acoaction',
100
			'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aro');
101
	//Get and format args: first arg is the name of the script.
102
	$serverArgs = $argv;
103
	if(!empty($unset)) {
104
		$serverArgs = array_values(array_diff($argv, $unset));
105
	}
106

    
107
	$wasted = array_shift($serverArgs);
108
	$command = array_shift($serverArgs);
109
	$args = $serverArgs;
110
	$aclCLI = new AclCLI ($command, $args);
111
/**
112
 * @package		cake
113
 * @subpackage	cake.cake.scritps
114
 */
115
class AclCLI {
116
/**
117
 * Enter description here...
118
 *
119
 * @var unknown_type
120
 */
121
	var $stdin;
122
/**
123
 * Enter description here...
124
 *
125
 * @var unknown_type
126
 */
127
	var $stdout;
128
/**
129
 * Enter description here...
130
 *
131
 * @var unknown_type
132
 */
133
	var $stderr;
134
/**
135
 * Enter description here...
136
 *
137
 * @var unknown_type
138
 */
139
	var $acl;
140
/**
141
 * Enter description here...
142
 *
143
 * @var unknown_type
144
 */
145
	var $args;
146
/**
147
 * Enter description here...
148
 *
149
 * @var unknown_type
150
 */
151
	var $dataSource = 'default';
152
/**
153
 * Enter description here...
154
 *
155
 * @param unknown_type $command
156
 * @param unknown_type $args
157
 * @return AclCLI
158
 */
159
	function AclCLI($command, $args) {
160
		$this->__construct($command, $args);
161
	}
162
/**
163
 * Enter description here...
164
 *
165
 * @param unknown_type $command
166
 * @param unknown_type $args
167
 */
168
	function __construct ($command, $args) {
169
		$this->stdin = fopen('php://stdin', 'r');
170
		$this->stdout = fopen('php://stdout', 'w');
171
		$this->stderr = fopen('php://stderr', 'w');
172

    
173
		if (ACL_CLASSNAME != 'DB_ACL'){
174
			$out = "--------------------------------------------------\n";
175
			$out .= "Error: Your current Cake configuration is set to \n";
176
			$out .= "an ACL implementation other than DB. Please change \n";
177
			$out .= "your core config to reflect your decision to use \n";
178
			$out .= "DB_ACL before attempting to use this script.\n";
179
			$out .= "--------------------------------------------------\n";
180
			$out .= "Current ACL Classname: " . ACL_CLASSNAME . "\n";
181
			$out .= "--------------------------------------------------\n";
182
			fwrite($this->stderr, $out);
183
			exit();
184
		}
185

    
186
		if(!in_array($command, array('help'))) {
187
			if(!file_exists(CONFIGS.'database.php')) {
188
				$this->stdout('');
189
				$this->stdout('Your database configuration was not found.');
190
				$this->stdout('Take a moment to create one:');
191
				$this->doDbConfig();
192
			}
193
			require_once (CONFIGS.'database.php');
194

    
195
			if(!in_array($command, array('initdb'))) {
196
				$this->dataSource = DATASOURCE;
197
				$this->Acl = new AclComponent();
198
				$this->args = $args;
199
				$this->db =& ConnectionManager::getDataSource($this->dataSource);
200
			}
201
		}
202

    
203
		switch ($command) {
204
			case 'create':
205
				$this->create();
206
			break;
207
			case 'delete':
208
				$this->delete();
209
			break;
210
			case 'setParent':
211
				$this->setParent();
212
			break;
213
			case 'getPath':
214
				$this->getPath();
215
			break;
216
			case 'grant':
217
				$this->grant();
218
			break;
219
			case 'deny':
220
				$this->deny();
221
			break;
222
			case 'inherit':
223
				$this->inherit();
224
			break;
225
			case 'view':
226
				$this->view();
227
			break;
228
			case 'initdb':
229
				$this->initdb();
230
			break;
231
			case 'upgrade':
232
				$this->upgradedb();
233
			break;
234
			case 'help':
235
				$this->help();
236
			break;
237
			default:
238
				fwrite($this->stderr, "Unknown ACL command '$command'.\nFor usage, try 'php acl.php help'.\n\n");
239
			break;
240
		}
241
	}
242
/**
243
 * Enter description here...
244
 *
245
 */
246
	function create() {
247
		$this->checkArgNumber(4, 'create');
248
		$this->checkNodeType();
249
		extract($this->__dataVars());
250

    
251
		$parent = (is_numeric($this->args[2])) ? intval($this->args[2]) : $this->args[2];
252
		if(!$this->Acl->{$class}->create(intval($this->args[1]), $parent, $this->args[3])){
253
			$this->displayError("Parent Node Not Found", "There was an error creating the ".$class.", probably couldn't find the parent node.\n If you wish to create a new root node, specify the <parent_id> as '0'.");
254
		}
255
		$this->stdout("New $class '".$this->args[3]."' created.\n\n");
256
	}
257
/**
258
 * Enter description here...
259
 *
260
 */
261
	function delete() {
262
		$this->checkArgNumber(2, 'delete');
263
		$this->checkNodeType();
264
		extract($this->__dataVars());
265
		if(!$this->Acl->{$class}->delete($this->args[1])) {
266
			$this->displayError("Node Not Deleted", "There was an error deleting the ".$class.". Check that the node exists.\n");
267
		}
268
		$this->stdout("{$class} deleted.\n\n");
269
	}
270

    
271
/**
272
 * Enter description here...
273
 *
274
 */
275
	function setParent() {
276
		$this->checkArgNumber(3, 'setParent');
277
		$this->checkNodeType();
278
		extract($this->__dataVars());
279
		if (!$this->Acl->{$class}->setParent($this->args[2], $this->args[1])){
280
			$this->stdout("Error in setting new parent. Please make sure the parent node exists, and is not a descendant of the node specified.\n");
281
		} else {
282
			$this->stdout("Node parent set to ".$this->args[2]."\n\n");
283
		}
284
	}
285
/**
286
 * Enter description here...
287
 *
288
 */
289
	function getPath() {
290
		$this->checkArgNumber(2, 'getPath');
291
		$this->checkNodeType();
292
		extract($this->__dataVars());
293
		$id = (is_numeric($this->args[2])) ? intval($this->args[1]) : $this->args[1];
294
		$nodes = $this->Acl->{$class}->getPath($id);
295
		if (empty($nodes)) {
296
			$this->displayError("Supplied Node '".$this->args[1]."' not found", "No tree returned.");
297
		}
298
		for ($i = 0; $i < count($nodes); $i++) {
299
			$this->stdout(str_repeat('  ', $i) . "[" . $nodes[$i][$class]['id'] . "]" . $nodes[$i][$class]['alias'] . "\n");
300
		}
301
	}
302
/**
303
 * Enter description here...
304
 *
305
 */
306
	function grant() {
307
		$this->checkArgNumber(3, 'grant');
308
		//add existence checks for nodes involved
309
		$aro = (is_numeric($this->args[0])) ? intval($this->args[0]) : $this->args[0];
310
		$aco = (is_numeric($this->args[1])) ? intval($this->args[1]) : $this->args[1];
311
		$this->Acl->allow($aro, $aco, $this->args[2]);
312
		$this->stdout("Permission granted.\n");
313
	}
314
/**
315
 * Enter description here...
316
 *
317
 */
318
	function deny() {
319
		$this->checkArgNumber(3, 'deny');
320
		//add existence checks for nodes involved
321
		$aro = (is_numeric($this->args[0])) ? intval($this->args[0]) : $this->args[0];
322
		$aco = (is_numeric($this->args[1])) ? intval($this->args[1]) : $this->args[1];
323
		$this->Acl->deny($aro, $aco, $this->args[2]);
324
		$this->stdout("Requested permission successfully denied.\n");
325
	}
326
/**
327
 * Enter description here...
328
 *
329
 */
330
	function inherit() {
331
		$this->checkArgNumber(3, 'inherit');
332
		$aro = (is_numeric($this->args[0])) ? intval($this->args[0]) : $this->args[0];
333
		$aco = (is_numeric($this->args[1])) ? intval($this->args[1]) : $this->args[1];
334
		$this->Acl->inherit($aro, $aco, $this->args[2]);
335
		$this->stdout("Requested permission successfully inherited.\n");
336
	}
337
/**
338
 * Enter description here...
339
 *
340
 */
341
	function view() {
342
		$this->checkArgNumber(1, 'view');
343
		$this->checkNodeType();
344
		extract($this->__dataVars());
345
		if (!is_null($this->args[1])) {
346
			$conditions = $this->Acl->{$class}->_resolveID($this->args[1]);
347
		} else {
348
			$conditions = null;
349
		}
350
		$nodes = $this->Acl->{$class}->findAll($conditions, null, 'lft ASC');
351
		if (empty($nodes)) {
352
			$this->displayError($this->args[1]." not found", "No tree returned.");
353
		}
354
		$right = array();
355

    
356
		$this->stdout($class . " tree:\n");
357
		$this->stdout("------------------------------------------------\n");
358

    
359
		for($i = 0; $i < count($nodes); $i++){
360
			if (count($right) > 0){
361
				while ($right[count($right)-1] < $nodes[$i][$class]['rght']){
362
					if ($right[count($right)-1]){
363
						array_pop($right);
364
					} else {
365
						break;
366
					}
367
				}
368
			}
369
			$this->stdout(str_repeat('  ',count($right)) . "[" . $nodes[$i][$class]['id'] . "]" . $nodes[$i][$class]['alias']."\n");
370
			$right[] = $nodes[$i][$class]['rght'];
371
		}
372
		$this->stdout("------------------------------------------------\n");
373
	}
374
/**
375
 * Enter description here...
376
 *
377
 */
378
	function initdb() {
379
		$db =& ConnectionManager::getDataSource($this->dataSource);
380
		$this->stdout("Initializing Database...\n");
381
		$this->stdout("Creating access control objects table (acos)...\n");
382
		$sql = " CREATE TABLE ".$db->fullTableName('acos')." (
383
				".$db->name('id')." ".$db->column($db->columns['primary_key']).",
384
				".$db->name('object_id')." ".$db->column($db->columns['integer'])." default NULL,
385
				".$db->name('alias')." ".$db->column($db->columns['string'])." NOT NULL default '',
386
				".$db->name('lft')." ".$db->column($db->columns['integer'])." default NULL,
387
				".$db->name('rght')." ".$db->column($db->columns['integer'])." default NULL,
388
				PRIMARY KEY  (".$db->name('id').")
389
				);";
390
		if ($db->query($sql) === false) {
391
			die("Error: " . $db->lastError() . "\n\n");
392
		}
393

    
394
		$this->stdout("Creating access request objects table (aros)...\n");
395
		$sql2 = "CREATE TABLE ".$db->fullTableName('aros')." (
396
				".$db->name('id')." ".$db->column($db->columns['primary_key']).",
397
				".$db->name('foreign_key')." ".$db->column($db->columns['integer'])." default NULL,
398
				".$db->name('alias')." ".$db->column($db->columns['string'])." NOT NULL default '',
399
				".$db->name('lft')." ".$db->column($db->columns['integer'])." default NULL,
400
				".$db->name('rght')." ".$db->column($db->columns['integer'])." default NULL,
401
				PRIMARY KEY  (".$db->name('id').")
402
				);";
403
		if ($db->query($sql2) === false) {
404
			die("Error: " . $db->lastError() . "\n\n");
405
		}
406

    
407
		$this->stdout("Creating relationships table (aros_acos)...\n");
408
		$sql3 = "CREATE TABLE ".$db->fullTableName('aros_acos')." (
409
				".$db->name('id')." ".$db->column($db->columns['primary_key']).",
410
				".$db->name('aro_id')." ".$db->column($db->columns['integer'])." default NULL,
411
				".$db->name('aco_id')." ".$db->column($db->columns['integer'])." default NULL,
412
				".$db->name('_create')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
413
				".$db->name('_read')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
414
				".$db->name('_update')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
415
				".$db->name('_delete')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
416
				PRIMARY KEY  (".$db->name('id').")
417
				);";
418
		if ($db->query($sql3) === false) {
419
			die("Error: " . $db->lastError() . "\n\n");
420
		}
421

    
422
		$this->stdout("\nDone.\n");
423
	}
424

    
425
/**
426
 * Enter description here...
427
 *
428
 */
429
	function upgradedb() {
430
		$db =& ConnectionManager::getDataSource($this->dataSource);
431
		$this->stdout("Initializing Database...\n");
432
		$this->stdout("Upgrading table (aros)...\n");
433
		$sql = "ALTER TABLE ".$db->fullTableName('aros')."
434
				CHANGE ".$db->name('user_id')."
435
				".$db->name('foreign_key')."
436
				INT( 10 ) UNSIGNED NULL DEFAULT NULL;";
437
		$sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_create')
438
				. " " . $db->name('_create') . " CHAR(2) NOT NULL DEFAULT '0';";
439
		$sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_update')
440
				. " " . $db->name('_update') . " CHAR(2) NOT NULL DEFAULT '0';";
441
		$sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_read')
442
				. " " . $db->name('_read') . " CHAR(2) NOT NULL DEFAULT '0';";
443
		$sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_delete')
444
				. " " . $db->name('_delete') . " CHAR(2) NOT NULL DEFAULT '0';";
445
		if ($db->query($sql) === false) {
446
			die("Error: " . $db->lastError() . "\n\n");
447
		}
448
		$this->stdout("\nDatabase upgrade is complete.\n");
449
	}
450

    
451
/**
452
 * Enter description here...
453
 *
454
 */
455
	function help() {
456
		$out = "Usage: php acl.php <command> <arg1> <arg2>...\n";
457
		$out .= "-----------------------------------------------\n";
458
		$out .= "Commands:\n";
459
		$out .= "\n";
460
		$out .= "\tcreate aro|aco <link_id> <parent_id> <alias>\n";
461
		$out .= "\t\tCreates a new ACL object under the parent specified by <parent_id>, an id/alias (see\n";
462
		$out .= "\t\t'view'). The link_id allows you to link a user object to Cake's\n";
463
		$out .= "\t\tACL structures. The alias parameter allows you to address your object\n";
464
		$out .= "\t\tusing a non-integer ID. Example: \"\$php acl.php create aro 57 0 John\"\n";
465
		$out .= "\t\twould create a new ARO object at the root of the tree, linked to 57\n";
466
		$out .= "\t\tin your users table, with an internal alias 'John'.";
467
		$out .= "\n";
468
		$out .= "\n";
469
		$out .= "\tdelete aro|aco <id>\n";
470
		$out .= "\t\tDeletes the ACL object with the specified ID (see 'view').\n";
471
		$out .= "\n";
472
		$out .= "\n";
473
		$out .= "\tsetParent aro|aco <id> <parent_id>\n";
474
		$out .= "\t\tUsed to set the parent of the ACL object specified by <id> to the ID\n";
475
		$out .= "\t\tspecified by <parent_id>.\n";
476
		$out .= "\n";
477
		$out .= "\n";
478
		$out .= "\tgetPath aro|aco <id>\n";
479
		$out .= "\t\tReturns the path to the ACL object specified by <id>. This command is\n";
480
		$out .= "\t\tis useful in determining the inhertiance of permissions for a certain\n";
481
		$out .= "\t\tobject in the tree.\n";
482
		$out .= "\n";
483
		$out .= "\n";
484
		$out .= "\tgrant <aro_id> <aco_id> <aco_action>\n";
485
		$out .= "\t\tUse this command to grant ACL permissions. Once executed, the ARO\n";
486
		$out .= "\t\tspecified (and its children, if any) will have ALLOW access to the\n";
487
		$out .= "\t\tspecified ACO action (and the ACO's children, if any).\n";
488
		$out .= "\n";
489
		$out .= "\n";
490
		$out .= "\tdeny <aro_id> <aco_id> <aco_action>\n";
491
		$out .= "\t\tUse this command to deny ACL permissions. Once executed, the ARO\n";
492
		$out .= "\t\tspecified (and its children, if any) will have DENY access to the\n";
493
		$out .= "\t\tspecified ACO action (and the ACO's children, if any).\n";
494
		$out .= "\n";
495
		$out .= "\n";
496
		$out .= "\tinherit <aro_id> <aco_id> <aco_action> \n";
497
		$out .= "\t\tUse this command to force a child ARO object to inherit its\n";
498
		$out .= "\t\tpermissions settings from its parent.\n";
499
		$out .= "\n";
500
		$out .= "\n";
501
		$out .= "\tview aro|aco [id]\n";
502
		$out .= "\t\tThe view command will return the ARO or ACO tree. The optional\n";
503
		$out .= "\t\tid/alias parameter allows you to return only a portion of the requested\n";
504
		$out .= "\t\ttree.\n";
505
		$out .= "\n";
506
		$out .= "\n";
507
		$out .= "\tinitdb\n";
508
		$out .= "\t\tUse this command to create the database tables needed to use DB ACL.\n";
509
		$out .= "\n";
510
		$out .= "\n";
511
		$out .= "\thelp\n";
512
		$out .= "\t\tDisplays this help message.\n";
513
		$out .= "\n";
514
		$out .= "\n";
515
		$this->stdout($out);
516
	}
517
/**
518
 * Enter description here...
519
 *
520
 * @param unknown_type $title
521
 * @param unknown_type $msg
522
 */
523
	function displayError($title, $msg) {
524
		$out = "\n";
525
		$out .= "Error: $title\n";
526
		$out .= "$msg\n";
527
		$out .= "\n";
528
		$this->stdout($out);
529
		exit();
530
	}
531

    
532
/**
533
 * Enter description here...
534
 *
535
 * @param unknown_type $expectedNum
536
 * @param unknown_type $command
537
 */
538
	function checkArgNumber($expectedNum, $command) {
539
		if (count($this->args) < $expectedNum) {
540
			$this->displayError('Wrong number of parameters: '.count($this->args), 'Please type \'php acl.php help\' for help on usage of the '.$command.' command.');
541
		}
542
	}
543
/**
544
 * Enter description here...
545
 *
546
 */
547
	function checkNodeType() {
548
		if ($this->args[0] != 'aco' && $this->args[0] != 'aro') {
549
			$this->displayError("Missing/Unknown node type: '".$this->args[0]."'", 'Please specify which ACL object type you wish to create.');
550
		}
551
	}
552
/**
553
 * Enter description here...
554
 *
555
 * @param unknown_type $type
556
 * @param unknown_type $id
557
 * @return unknown
558
 */
559
	function nodeExists($type, $id) {
560
		//$this->stdout("Check to see if $type with ID = $id exists...\n");
561
		extract($this->__dataVars($type));
562
		$conditions = $this->Acl->{$class}->_resolveID($id);
563
		$possibility = $this->Acl->{$class}->findAll($conditions);
564
		return $possibility;
565
	}
566

    
567
/**
568
 * Enter description here...
569
 *
570
 * @param unknown_type $type
571
 * @return unknown
572
 */
573
	function __dataVars($type = null) {
574
		if ($type == null) {
575
			$type = $this->args[0];
576
		}
577

    
578
		$vars = array();
579
		$class = ucwords($type);
580
		$vars['secondary_id'] = ($class == 'aro' ? 'foreign_key' : 'object_id');
581
		$vars['data_name'] = $type;
582
		$vars['table_name'] = $type . 's';
583
		$vars['class'] = $class;
584
		return $vars;
585
	}
586
/**
587
 * Database configuration setup.
588
 *
589
 */
590
	function doDbConfig() {
591
		$this->hr();
592
		$this->stdout('Database Configuration:');
593
		$this->hr();
594

    
595
		$driver = '';
596

    
597
		while ($driver == '') {
598
			$driver = $this->getInput('What database driver would you like to use?', array('mysql','mysqli','mssql','sqlite','postgres', 'odbc'), 'mysql');
599
			if ($driver == '') {
600
				$this->stdout('The database driver supplied was empty. Please supply a database driver.');
601
			}
602
		}
603

    
604
		switch($driver) {
605
			case 'mysql':
606
			$connect = 'mysql_connect';
607
			break;
608
			case 'mysqli':
609
			$connect = 'mysqli_connect';
610
			break;
611
			case 'mssql':
612
			$connect = 'mssql_connect';
613
			break;
614
			case 'sqlite':
615
			$connect = 'sqlite_open';
616
			break;
617
			case 'postgres':
618
			$connect = 'pg_connect';
619
			break;
620
			case 'odbc':
621
			$connect = 'odbc_connect';
622
			break;
623
			default:
624
			$this->stdout('The connection parameter could not be set.');
625
			break;
626
		}
627

    
628
		$host = '';
629

    
630
		while ($host == '') {
631
			$host = $this->getInput('What is the hostname for the database server?', null, 'localhost');
632
			if ($host == '') {
633
				$this->stdout('The host name you supplied was empty. Please supply a hostname.');
634
			}
635
		}
636
		$login = '';
637

    
638
		while ($login == '') {
639
			$login = $this->getInput('What is the database username?', null, 'root');
640

    
641
			if ($login == '') {
642
				$this->stdout('The database username you supplied was empty. Please try again.');
643
			}
644
		}
645
		$password = '';
646
		$blankPassword = false;
647

    
648
		while ($password == '' && $blankPassword == false) {
649
			$password = $this->getInput('What is the database password?');
650
			if ($password == '') {
651
				$blank = $this->getInput('The password you supplied was empty. Use an empty password?', array('y', 'n'), 'n');
652
				if($blank == 'y')
653
				{
654
					$blankPassword = true;
655
				}
656
			}
657
		}
658
		$database = '';
659

    
660
		while ($database == '') {
661
			$database = $this->getInput('What is the name of the database you will be using?', null, 'cake');
662

    
663
			if ($database == '')  {
664
				$this->stdout('The database name you supplied was empty. Please try again.');
665
			}
666
		}
667

    
668
		$prefix = '';
669

    
670
		while ($prefix == '') {
671
			$prefix = $this->getInput('Enter a table prefix?', null, 'n');
672
		}
673
		if(low($prefix) == 'n') {
674
			$prefix = '';
675
		}
676

    
677
		$this->stdout('');
678
		$this->hr();
679
		$this->stdout('The following database configuration will be created:');
680
		$this->hr();
681
		$this->stdout("Driver:        $driver");
682
		$this->stdout("Connection:    $connect");
683
		$this->stdout("Host:          $host");
684
		$this->stdout("User:          $login");
685
		$this->stdout("Pass:          " . str_repeat('*', strlen($password)));
686
		$this->stdout("Database:      $database");
687
		$this->stdout("Table prefix:  $prefix");
688
		$this->hr();
689
		$looksGood = $this->getInput('Look okay?', array('y', 'n'), 'y');
690

    
691
		if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
692
			$this->bakeDbConfig($driver, $connect, $host, $login, $password, $database, $prefix);
693
		} else {
694
			$this->stdout('Bake Aborted.');
695
		}
696
	}
697
/**
698
 * Creates a database configuration file for Bake.
699
 *
700
 * @param string $host
701
 * @param string $login
702
 * @param string $password
703
 * @param string $database
704
 */
705
	function bakeDbConfig( $driver, $connect, $host, $login, $password, $database, $prefix) {
706
		$out = "<?php\n";
707
		$out .= "class DATABASE_CONFIG {\n\n";
708
		$out .= "\tvar \$default = array(\n";
709
		$out .= "\t\t'driver' => '{$driver}',\n";
710
		$out .= "\t\t'connect' => '{$connect}',\n";
711
		$out .= "\t\t'host' => '{$host}',\n";
712
		$out .= "\t\t'login' => '{$login}',\n";
713
		$out .= "\t\t'password' => '{$password}',\n";
714
		$out .= "\t\t'database' => '{$database}', \n";
715
		$out .= "\t\t'prefix' => '{$prefix}' \n";
716
		$out .= "\t);\n";
717
		$out .= "}\n";
718
		$out .= "?>";
719
		$filename = CONFIGS.'database.php';
720
		$this->__createFile($filename, $out);
721
	}
722
/**
723
 * Prompts the user for input, and returns it.
724
 *
725
 * @param string $prompt Prompt text.
726
 * @param mixed $options Array or string of options.
727
 * @param string $default Default input value.
728
 * @return Either the default value, or the user-provided input.
729
 */
730
	function getInput($prompt, $options = null, $default = null) {
731
		if (!is_array($options)) {
732
			$print_options = '';
733
		} else {
734
			$print_options = '(' . implode('/', $options) . ')';
735
		}
736

    
737
		if($default == null) {
738
			$this->stdout('');
739
			$this->stdout($prompt . " $print_options \n" . '> ', false);
740
		} else {
741
			$this->stdout('');
742
			$this->stdout($prompt . " $print_options \n" . "[$default] > ", false);
743
		}
744
		$result = trim(fgets($this->stdin));
745

    
746
		if($default != null && empty($result)) {
747
			return $default;
748
		} else {
749
			return $result;
750
		}
751
	}
752
/**
753
 * Outputs to the stdout filehandle.
754
 *
755
 * @param string $string String to output.
756
 * @param boolean $newline If true, the outputs gets an added newline.
757
 */
758
	function stdout($string, $newline = true) {
759
		if ($newline) {
760
			fwrite($this->stdout, $string . "\n");
761
		} else {
762
			fwrite($this->stdout, $string);
763
		}
764
	}
765
/**
766
 * Outputs to the stderr filehandle.
767
 *
768
 * @param string $string Error text to output.
769
 */
770
	function stderr($string) {
771
		fwrite($this->stderr, $string);
772
	}
773
/**
774
 * Outputs a series of minus characters to the standard output, acts as a visual separator.
775
 *
776
 */
777
	function hr() {
778
		$this->stdout('---------------------------------------------------------------');
779
	}
780
/**
781
 * Creates a file at given path.
782
 *
783
 * @param string $path		Where to put the file.
784
 * @param string $contents Content to put in the file.
785
 * @return Success
786
 */
787
	function __createFile ($path, $contents) {
788
		$path = str_replace('//', '/', $path);
789
		echo "\nCreating file $path\n";
790
		if (is_file($path) && $this->interactive === true) {
791
			fwrite($this->stdout, "File exists, overwrite?" . " {$path} (y/n/q):");
792
			$key = trim(fgets($this->stdin));
793

    
794
			if ($key=='q') {
795
				fwrite($this->stdout, "Quitting.\n");
796
				exit;
797
			} elseif ($key == 'a') {
798
				$this->dont_ask = true;
799
			} elseif ($key == 'y') {
800
			} else {
801
				fwrite($this->stdout, "Skip" . " {$path}\n");
802
				return false;
803
			}
804
		}
805

    
806
		if ($f = fopen($path, 'w')) {
807
			fwrite($f, $contents);
808
			fclose($f);
809
			fwrite($this->stdout, "Wrote" . "{$path}\n");
810
			return true;
811
		} else {
812
			fwrite($this->stderr, "Error! Could not write to" . " {$path}.\n");
813
			return false;
814
		}
815
	}
816
}
817
?>
(1-1/2)