Projekt

Obecné

Profil

Stáhnout (98.7 KB) Statistiky
| Větev: | Tag: | Revize:
1
#!/usr/bin/php -q
2
<?php
3
/* SVN FILE: $Id: bake.php 4409 2007-02-02 13:20:59Z phpnut $ */
4
/**
5
 * Command-line code generation utility to automate programmer chores.
6
 *
7
 * Bake is CakePHP's code generation script, which can help you kickstart
8
 * application development by writing fully functional skeleton controllers,
9
 * models, and views. Going further, Bake can also write Unit Tests for you.
10
 *
11
 * PHP versions 4 and 5
12
 *
13
 * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
14
 * Copyright 2005-2007,	Cake Software Foundation, Inc.
15
 *								1785 E. Sahara Avenue, Suite 490-204
16
 *								Las Vegas, Nevada 89104
17
 *
18
 * Licensed under The MIT License
19
 * Redistributions of files must retain the above copyright notice.
20
 *
21
 * @filesource
22
 * @copyright		Copyright 2005-2007, Cake Software Foundation, Inc.
23
 * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
24
 * @package			cake
25
 * @subpackage		cake.cake.scripts.bake
26
 * @since			CakePHP(tm) v 0.10.0.1232
27
 * @version			$Revision: 4409 $
28
 * @modifiedby		$LastChangedBy: phpnut $
29
 * @lastmodified	$Date: 2007-02-02 07:20:59 -0600 (Fri, 02 Feb 2007) $
30
 * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
31
 */
32
	define ('DS', DIRECTORY_SEPARATOR);
33
	if (function_exists('ini_set')) {
34
		ini_set('display_errors', '1');
35
		ini_set('error_reporting', '7');
36
		ini_set('max_execution_time',60*5);
37
	}
38

    
39
	$app = null;
40
	$root = dirname(dirname(dirname(__FILE__)));
41
	$core = null;
42
	$here = $argv[0];
43
	$help = null;
44
	$project = null;
45

    
46
	for ($i = 1; $i < count($argv); $i += 2) {
47
		switch ($argv[$i]) {
48
			case '-a':
49
			case '-app':
50
				$app = $argv[$i + 1];
51
			break;
52
			case '-c':
53
			case '-core':
54
				$core = $argv[$i + 1];
55
			break;
56
			case '-r':
57
			case '-root':
58
				$root = $argv[$i + 1];
59
			break;
60
			case '-h':
61
			case '-help':
62
				$help = true;
63
			break;
64
			case '-p':
65
			case '-project':
66
				$project = true;
67
				$projectPath = $argv[$i + 1];
68
				$app = $argv[$i + 1];
69
			break;
70
		}
71
	}
72

    
73
	if(!$app && isset($argv[1])) {
74
		$app = $argv[1];
75
	} elseif(!$app) {
76
		$app = 'app';
77
	}
78
	if(!is_dir($app)) {
79
		$project = true;
80
		$projectPath = $app;
81

    
82
	}
83
	if($project) {
84
		$app = $projectPath;
85
	}
86

    
87
	$shortPath = str_replace($root, '', $app);
88
	$shortPath = str_replace('..'.DS, '', $shortPath);
89
	$shortPath = str_replace(DS.DS, DS, $shortPath);
90

    
91
	$pathArray = explode(DS, $shortPath);
92
	if(end($pathArray) != '') {
93
		$appDir = array_pop($pathArray);
94
	} else {
95
		array_pop($pathArray);
96
		$appDir = array_pop($pathArray);
97
	}
98
	$rootDir = implode(DS, $pathArray);
99
	$rootDir = str_replace(DS.DS, DS, $rootDir);
100

    
101
	if(!$rootDir) {
102
		$rootDir = $root;
103
		$projectPath = $root.DS.$appDir;
104
	}
105

    
106
	define ('ROOT', $rootDir);
107
	define ('APP_DIR', $appDir);
108
	define ('DEBUG', 1);
109

    
110
	if(!empty($core)){
111
		define('CAKE_CORE_INCLUDE_PATH', dirname($core));
112
	}else{
113
		define('CAKE_CORE_INCLUDE_PATH', $root);
114
	}
115

    
116
	if(function_exists('ini_set')) {
117
		ini_set('include_path',ini_get('include_path').
118
													PATH_SEPARATOR.CAKE_CORE_INCLUDE_PATH.DS.
119
													PATH_SEPARATOR.ROOT.DS.APP_DIR.DS);
120
		define('APP_PATH', null);
121
		define('CORE_PATH', null);
122
	} else {
123
		define('APP_PATH', ROOT . DS . APP_DIR . DS);
124
		define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
125
	}
126

    
127
	require_once (CORE_PATH.'cake'.DS.'basics.php');
128
	require_once (CORE_PATH.'cake'.DS.'config'.DS.'paths.php');
129
	require_once (CORE_PATH.'cake'.DS.'dispatcher.php');
130
	require_once (CORE_PATH.'cake'.DS.'scripts'.DS.'templates'.DS.'skel'.DS.'config'.DS.'core.php');
131
	/*uses ('inflector', 'model'.DS.'model');
132
	require_once (CORE_PATH.'cake'.DS.'app_model.php');
133
	require_once (CORE_PATH.'cake'.DS.'app_controller.php');*/
134

    
135
	/*uses ('inflector', 'model'.DS.'model');*/
136

    
137
	/*uses ('neat_array', 'model'.DS.'connection_manager', 'controller'.DS.'controller', 'session',
138
			'configure', 'security', DS.'controller'.DS.'scaffold');*/
139

    
140
	uses('session', 'configure', 'inflector', 'model'.DS.'connection_manager');
141

    
142
	$pattyCake = new Bake();
143
	if($help === true)
144
	{
145
		$pattyCake->help();
146
		exit();
147
	}
148
	if($project === true)
149
	{
150
		$pattyCake->project($projectPath);
151
		exit();
152
	}
153
	$pattyCake->main();
154
/**
155
 * Bake is a command-line code generation utility for automating programmer chores.
156
 *
157
 * @package		cake
158
 * @subpackage	cake.cake.scripts
159
 */
160
class Bake {
161

    
162
/**
163
 * Standard input stream.
164
 *
165
 * @var filehandle
166
 */
167
	var $stdin;
168
/**
169
 * Standard output stream.
170
 *
171
 * @var filehandle
172
 */
173
	var $stdout;
174
/**
175
 * Standard error stream.
176
 *
177
 * @var filehandle
178
 */
179
	var $stderr;
180
/**
181
 * Associated controller name.
182
 *
183
 * @var string
184
 */
185
	var $controllerName = null;
186
/**
187
 * If true, Bake will ask for permission to perform actions.
188
 *
189
 * @var boolean
190
 */
191
	var $interactive = false;
192

    
193
	var $__modelAlias = false;
194
/**
195
 * Private helper function for constructor
196
 * @access private
197
 */
198
	function __construct() {
199
		$this->stdin = fopen('php://stdin', 'r');
200
		$this->stdout = fopen('php://stdout', 'w');
201
		$this->stderr = fopen('php://stderr', 'w');
202
		$this->welcome();
203
	}
204
/**
205
 * Constructor.
206
 *
207
 * @return Bake
208
 */
209
	function Bake() {
210
		return $this->__construct();
211
	}
212
/**
213
 * Main-loop method.
214
 *
215
 */
216
	function main() {
217

    
218
		$this->stdout('');
219
		$this->stdout('');
220
		$this->stdout('Baking...');
221
		$this->hr();
222
		$this->stdout('Name: '. APP_DIR);
223
		$this->stdout('Path: '. ROOT.DS.APP_DIR);
224
		$this->hr();
225

    
226
		if(!file_exists(CONFIGS.'database.php')) {
227
			$this->stdout('');
228
			$this->stdout('Your database configuration was not found. Take a moment to create one:');
229
			$this->doDbConfig();
230
		}
231
		require_once (CONFIGS.'database.php');
232
		$this->stdout('[M]odel');
233
		$this->stdout('[C]ontroller');
234
		$this->stdout('[V]iew');
235
		$invalidSelection = true;
236

    
237
		while ($invalidSelection) {
238
			$classToBake = strtoupper($this->getInput('What would you like to Bake?', array('M', 'V', 'C')));
239
			switch($classToBake) {
240
				case 'M':
241
					$invalidSelection = false;
242
					$this->doModel();
243
					break;
244
				case 'V':
245
					$invalidSelection = false;
246
					$this->doView();
247
					break;
248
				case 'C':
249
					$invalidSelection = false;
250
					$this->doController();
251
					break;
252
				default:
253
					$this->stdout('You have made an invalid selection. Please choose a type of class to Bake by entering M, V, or C.');
254
			}
255
		}
256
	}
257
/**
258
 * Database configuration setup.
259
 *
260
 */
261
	function doDbConfig() {
262
		$this->hr();
263
		$this->stdout('Database Configuration:');
264
		$this->hr();
265

    
266
		$driver = '';
267

    
268
		while ($driver == '') {
269
			$driver = $this->getInput('What database driver would you like to use?', array('mysql','mysqli','mssql','sqlite','postgres', 'odbc'), 'mysql');
270
			if ($driver == '') {
271
				$this->stdout('The database driver supplied was empty. Please supply a database driver.');
272
			}
273
		}
274

    
275
		switch($driver) {
276
			case 'mysql':
277
			$connect = 'mysql_connect';
278
			break;
279
			case 'mysqli':
280
			$connect = 'mysqli_connect';
281
			break;
282
			case 'mssql':
283
			$connect = 'mssql_connect';
284
			break;
285
			case 'sqlite':
286
			$connect = 'sqlite_open';
287
			break;
288
			case 'postgres':
289
			$connect = 'pg_connect';
290
			break;
291
			case 'odbc':
292
			$connect = 'odbc_connect';
293
			break;
294
			default:
295
			$this->stdout('The connection parameter could not be set.');
296
			break;
297
		}
298

    
299
		$host = '';
300

    
301
		while ($host == '') {
302
			$host = $this->getInput('What is the hostname for the database server?', null, 'localhost');
303
			if ($host == '') {
304
				$this->stdout('The host name you supplied was empty. Please supply a hostname.');
305
			}
306
		}
307
		$login = '';
308

    
309
		while ($login == '') {
310
			$login = $this->getInput('What is the database username?', null, 'root');
311

    
312
			if ($login == '') {
313
				$this->stdout('The database username you supplied was empty. Please try again.');
314
			}
315
		}
316
		$password = '';
317
		$blankPassword = false;
318

    
319
		while ($password == '' && $blankPassword == false) {
320
			$password = $this->getInput('What is the database password?');
321
			if ($password == '') {
322
				$blank = $this->getInput('The password you supplied was empty. Use an empty password?', array('y', 'n'), 'n');
323
				if($blank == 'y')
324
				{
325
					$blankPassword = true;
326
				}
327
			}
328
		}
329
		$database = '';
330

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

    
334
			if ($database == '')  {
335
				$this->stdout('The database name you supplied was empty. Please try again.');
336
			}
337
		}
338

    
339
		$prefix = '';
340

    
341
		while ($prefix == '') {
342
			$prefix = $this->getInput('Enter a table prefix?', null, 'n');
343
		}
344
		if(low($prefix) == 'n') {
345
			$prefix = '';
346
		}
347

    
348
		$this->stdout('');
349
		$this->hr();
350
		$this->stdout('The following database configuration will be created:');
351
		$this->hr();
352
		$this->stdout("Driver:        $driver");
353
		$this->stdout("Connection:    $connect");
354
		$this->stdout("Host:          $host");
355
		$this->stdout("User:          $login");
356
		$this->stdout("Pass:          " . str_repeat('*', strlen($password)));
357
		$this->stdout("Database:      $database");
358
		$this->stdout("Table prefix:  $prefix");
359
		$this->hr();
360
		$looksGood = $this->getInput('Look okay?', array('y', 'n'), 'y');
361

    
362
		if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
363
			$this->bakeDbConfig($driver, $connect, $host, $login, $password, $database, $prefix);
364
		} else {
365
			$this->stdout('Bake Aborted.');
366
		}
367
	}
368
/**
369
 * Action to create a Model.
370
 *
371
 */
372
	function doModel()
373
	{
374
		$this->hr();
375
		$this->stdout('Model Bake:');
376
		$this->hr();
377
		$this->interactive = true;
378

    
379
		$useTable = null;
380
		$primaryKey = 'id';
381
		$validate = array();
382
		$associations = array();
383
		/*$usingDefault = $this->getInput('Will your model be using a database connection setting other than the default?');
384
		if (low($usingDefault) == 'y' || low($usingDefault) == 'yes')
385
		{
386
			$useDbConfig = $this->getInput('Please provide the name of the connection you wish to use.');
387
		}*/
388
		$useDbConfig = 'default';
389
		$this->__doList($useDbConfig);
390

    
391

    
392
		$enteredModel = '';
393

    
394
		while ($enteredModel == '') {
395
			$enteredModel = $this->getInput('Enter a number from the list above, or type in the name of another model.');
396

    
397
			if ($enteredModel == '' || intval($enteredModel) > count($this->__modelNames)) {
398
				$this->stdout('Error:');
399
				$this->stdout("The model name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
400
				$enteredModel = '';
401
			}
402
		}
403

    
404
		if (intval($enteredModel) > 0 && intval($enteredModel) <= count($this->__modelNames)) {
405
			$currentModelName = $this->__modelNames[intval($enteredModel) - 1];
406
		} else {
407
			$currentModelName = $enteredModel;
408
		}
409

    
410
		$useTable = Inflector::tableize($currentModelName);
411
		if(array_search($useTable, $this->__tables) === false) {
412
			$this->stdout("\nGiven your model named '$currentModelName', Cake would expect a database table named '" . $useTable . "'.");
413
			$tableIsGood = $this->getInput('do you want to use this table?', array('y','n'), 'y');
414
		}
415

    
416
		if (low($tableIsGood) == 'n' || low($tableIsGood) == 'no') {
417
			$useTable = $this->getInput('What is the name of the table (enter "null" to use NO table)?');
418
		}
419
		$tableIsGood = false;
420
		while($tableIsGood == false && low($useTable) != 'null') {
421
			$db =& ConnectionManager::getDataSource($useDbConfig);
422
			$fullTableName = $db->fullTableName($useTable, false);
423
			$sources = $db->listSources();
424
			if (is_array($sources) && !in_array(low($fullTableName), array_map('low', $sources))) {
425
				$this->stdout($fullTableName . ' does not exist.');
426
				$useTable = $this->getInput('What is the name of the table (enter "null" to use NO table)?');
427
				$tableIsGood = false;
428
			} else {
429
				$tableIsGood = true;
430
			}
431
		}
432
		$wannaDoValidation = $this->getInput('Would you like to supply validation criteria for the fields in your model?', array('y','n'), 'y');
433

    
434
		if(array_search($useTable, $this->__tables)) {
435
			$tempModel = new Model(false, $useTable);
436
			$db =& ConnectionManager::getDataSource($useDbConfig);
437
			$modelFields = $db->describe($tempModel);
438
			if(!isset($modelFields[0]['name']) && $modelFields[0]['name'] != 'id') {
439
				$primaryKey = $this->getInput('What is the primaryKey', null, 'id');
440
			}
441
		}
442
		$validate = array();
443

    
444
		if (array_search($useTable, $this->__tables) !== false && (low($wannaDoValidation) == 'y' || low($wannaDoValidation) == 'yes')) {
445
			foreach($modelFields as $field) {
446
				$this->stdout('');
447
				$prompt .= 'Name: ' . $field['name'] . "\n";
448
				$prompt .= 'Type: ' . $field['type'] . "\n";
449
				$prompt .= '---------------------------------------------------------------'."\n";
450
				$prompt .= 'Please select one of the following validation options:'."\n";
451
				$prompt .= '---------------------------------------------------------------'."\n";
452
				$prompt .= "1- VALID_NOT_EMPTY\n";
453
				$prompt .= "2- VALID_EMAIL\n";
454
				$prompt .= "3- VALID_NUMBER\n";
455
				$prompt .= "4- VALID_YEAR\n";
456
				$prompt .= "5- Do not do any validation on this field.\n\n";
457
				$prompt .= "... or enter in a valid regex validation string.\n\n";
458

    
459
				if($field['name'] == 'id' || $field['name'] == 'created' || $field['name'] == 'modified') {
460
					$validation = $this->getInput($prompt, null, '5');
461
				} else {
462
					$validation = $this->getInput($prompt, null, '1');
463
				}
464

    
465
				switch ($validation) {
466
					case '1':
467
						$validate[$field['name']] = 'VALID_NOT_EMPTY';
468
						break;
469
					case '2':
470
						$validate[$field['name']] = 'VALID_EMAIL';
471
						break;
472
					case '3':
473
						$validate[$field['name']] = 'VALID_NUMBER';
474
						break;
475
					case '4':
476
						$validate[$field['name']] = 'VALID_YEAR';
477
						break;
478
					case '5':
479
						break;
480
					default:
481
						$validate[$field['name']] = $validation;
482
					break;
483
				}
484
			}
485
		}
486

    
487
		$wannaDoAssoc = $this->getInput('Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)?', array('y','n'), 'y');
488

    
489
		if((low($wannaDoAssoc) == 'y' || low($wannaDoAssoc) == 'yes')) {
490
			$this->stdout('One moment while I try to detect any associations...');
491
			$possibleKeys = array();
492
			//Look for belongsTo
493
			$i = 0;
494
			foreach($modelFields as $field) {
495
				$offset = strpos($field['name'], '_id');
496
				if($offset !== false) {
497
					$tmpModelName = $this->__modelNameFromKey($field['name']);
498
					$associations['belongsTo'][$i]['alias'] = $tmpModelName;
499
					$associations['belongsTo'][$i]['className'] = $tmpModelName;
500
					$associations['belongsTo'][$i]['foreignKey'] = $field['name'];
501
					$i++;
502
				}
503
			}
504
			//Look for hasOne and hasMany and hasAndBelongsToMany
505
			$i = 0;
506
			$j = 0;
507
			foreach($this->__tables as $otherTable) {
508
				$tempOtherModel = & new Model(false, $otherTable);
509
				$modelFieldsTemp = $db->describe($tempOtherModel);
510
				foreach($modelFieldsTemp as $field) {
511
					if($field['type'] == 'integer' || $field['type'] == 'string') {
512
						$possibleKeys[$otherTable][] = $field['name'];
513
					}
514
					if($field['name'] == $this->__modelKey($currentModelName)) {
515
						$tmpModelName = $this->__modelName($otherTable);
516
						$associations['hasOne'][$j]['alias'] = $tmpModelName;
517
						$associations['hasOne'][$j]['className'] = $tmpModelName;
518
						$associations['hasOne'][$j]['foreignKey'] = $field['name'];
519

    
520
						$associations['hasMany'][$j]['alias'] = $tmpModelName;
521
						$associations['hasMany'][$j]['className'] = $tmpModelName;
522
						$associations['hasMany'][$j]['foreignKey'] = $field['name'];
523
						$j++;
524
					}
525
				}
526
				$offset = strpos($otherTable, $useTable . '_');
527
				if($offset !== false) {
528
					$offset = strlen($useTable . '_');
529
					$tmpModelName = $this->__modelName(substr($otherTable, $offset));
530
					$associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
531
					$associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
532
					$associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->__modelKey($currentModelName);
533
					$associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->__modelKey($tmpModelName);
534
					$associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
535
					$i++;
536
				}
537
				$offset = strpos($otherTable, '_' . $useTable);
538
				if ($offset !== false) {
539
					$tmpModelName = $this->__modelName(substr($otherTable, 0, $offset));
540
					$associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
541
					$associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
542
					$associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->__modelKey($currentModelName);
543
					$associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->__modelKey($tmpModelName);
544
					$associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
545
					$i++;
546
				}
547
			}
548
			$this->stdout('Done.');
549
			$this->hr();
550
			//if none found...
551
			if(empty($associations)) {
552
				$this->stdout('None found.');
553
			} else {
554
				$this->stdout('Please confirm the following associations:');
555
				$this->hr();
556
				if(!empty($associations['belongsTo'])) {
557
					$count = count($associations['belongsTo']);
558
					for($i = 0; $i < $count; $i++) {
559
						if($currentModelName == $associations['belongsTo'][$i]['alias']) {
560
							$response = $this->getInput("{$currentModelName} belongsTo {$associations['belongsTo'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
561
							if('y' == low($response) || 'yes' == low($response)) {
562
								$associations['belongsTo'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['belongsTo'][$i]['alias']);
563
							}
564
							if($currentModelName != $associations['belongsTo'][$i]['alias']) {
565
								$response = $this->getInput("$currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}?", array('y','n'), 'y');
566
							} else {
567
								$response = 'n';
568
							}
569
						} else {
570
							$response = $this->getInput("$currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}?", array('y','n'), 'y');
571
						}
572
						if('n' == low($response) || 'no' == low($response)) {
573
							unset($associations['belongsTo'][$i]);
574
						}
575
					}
576
					$associations['belongsTo'] = array_merge($associations['belongsTo']);
577
				}
578

    
579
				if(!empty($associations['hasOne'])) {
580
					$count = count($associations['hasOne']);
581
					for($i = 0; $i < $count; $i++) {
582
						if($currentModelName == $associations['hasOne'][$i]['alias']) {
583
							$response = $this->getInput("{$currentModelName} hasOne {$associations['hasOne'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
584
							if('y' == low($response) || 'yes' == low($response)) {
585
								$associations['hasOne'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasOne'][$i]['alias']);
586
							}
587
							if($currentModelName != $associations['hasOne'][$i]['alias']) {
588
								$response = $this->getInput("$currentModelName hasOne {$associations['hasOne'][$i]['alias']}?", array('y','n'), 'y');
589
							} else {
590
								$response = 'n';
591
							}
592
						} else {
593
							$response = $this->getInput("$currentModelName hasOne {$associations['hasOne'][$i]['alias']}?", array('y','n'), 'y');
594
						}
595
						if('n' == low($response) || 'no' == low($response)) {
596
							unset($associations['hasOne'][$i]);
597
						}
598
					}
599
					$associations['hasOne'] = array_merge($associations['hasOne']);
600
				}
601

    
602
				if(!empty($associations['hasMany'])) {
603
					$count = count($associations['hasMany']);
604
					for($i = 0; $i < $count; $i++) {
605
						if($currentModelName == $associations['hasMany'][$i]['alias']) {
606
							$response = $this->getInput("{$currentModelName} hasMany {$associations['hasMany'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
607
							if('y' == low($response) || 'yes' == low($response)) {
608
								$associations['hasMany'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasMany'][$i]['alias']);
609
							}
610
							if($currentModelName != $associations['hasMany'][$i]['alias']) {
611
								$response = $this->getInput("$currentModelName hasMany {$associations['hasMany'][$i]['alias']}?", array('y','n'), 'y');
612
							} else {
613
								$response = 'n';
614
							}
615
						} else {
616
							$response = $this->getInput("$currentModelName hasMany {$associations['hasMany'][$i]['alias']}?", array('y','n'), 'y');
617
						}
618
						if('n' == low($response) || 'no' == low($response)) {
619
							unset($associations['hasMany'][$i]);
620
						}
621
					}
622
					$associations['hasMany'] = array_merge($associations['hasMany']);
623
				}
624

    
625
				if(!empty($associations['hasAndBelongsToMany'])) {
626
					$count = count($associations['hasAndBelongsToMany']);
627
					for($i = 0; $i < $count; $i++) {
628
						if($currentModelName == $associations['hasAndBelongsToMany'][$i]['alias']) {
629
							$response = $this->getInput("{$currentModelName} hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
630
							if('y' == low($response) || 'yes' == low($response)) {
631
								$associations['hasAndBelongsToMany'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasAndBelongsToMany'][$i]['alias']);
632
							}
633
							if($currentModelName != $associations['hasAndBelongsToMany'][$i]['alias']) {
634
								$response = $this->getInput("$currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}?", array('y','n'), 'y');
635
							} else {
636
								$response = 'n';
637
							}
638
						} else {
639
							$response = $this->getInput("$currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}?", array('y','n'), 'y');
640
						}
641
						if('n' == low($response) || 'no' == low($response)) {
642
							unset($associations['hasAndBelongsToMany'][$i]);
643
						}
644
					}
645
					$associations['hasAndBelongsToMany'] = array_merge($associations['hasAndBelongsToMany']);
646
				}
647
			}
648
			$wannaDoMoreAssoc = $this->getInput('Would you like to define some additional model associations?', array('y','n'), 'y');
649

    
650
			while((low($wannaDoMoreAssoc) == 'y' || low($wannaDoMoreAssoc) == 'yes')) {
651
				$assocs = array(1=>'belongsTo', 2=>'hasOne', 3=>'hasMany', 4=>'hasAndBelongsToMany');
652
				$bad = true;
653
				while($bad) {
654
					$this->stdout('What is the association type?');
655
					$prompt = "1- belongsTo\n";
656
					$prompt .= "2- hasOne\n";
657
					$prompt .= "3- hasMany\n";
658
					$prompt .= "4- hasAndBelongsToMany\n";
659
					$assocType = intval($this->getInput($prompt, null, null));
660

    
661
					if(intval($assocType) < 1 || intval($assocType) > 4) {
662
						$this->stdout('The selection you entered was invalid. Please enter a number between 1 and 4.');
663
					} else {
664
						$bad = false;
665
					}
666
				}
667
				$this->stdout('For the following options be very careful to match your setup exactly. Any spelling mistakes will cause errors.');
668
				$this->hr();
669
				$associationName = $this->getInput('What is the name of this association?');
670
				$className = $this->getInput('What className will '.$associationName.' use?', null, $associationName );
671
				$suggestedForeignKey = null;
672
				if($assocType == '1') {
673
					$showKeys = $possibleKeys[$useTable];
674
					$suggestedForeignKey = $this->__modelKey($associationName);
675
				} else {
676
					$otherTable = Inflector::tableize($className);
677
					if(in_array($otherTable, $this->__tables)) {
678
						if($assocType < '4') {
679
							$showKeys = $possibleKeys[$otherTable];
680
						} else {
681
							$showKeys = null;
682
						}
683
					} else {
684
						$otherTable = $this->getInput('What is the table for this class?');
685
						$showKeys = $possibleKeys[$otherTable];
686
					}
687
					$suggestedForeignKey = $this->__modelKey($currentModelName);
688
				}
689
				if(!empty($showKeys)) {
690
					$this->stdout('A helpful List of possible keys');
691
					for ($i = 0; $i < count($showKeys); $i++) {
692
						$this->stdout($i + 1 . ". " . $showKeys[$i]);
693
					}
694
					$foreignKey = $this->getInput('What is the foreignKey? Choose a number.');
695
					if (intval($foreignKey) > 0 && intval($foreignKey) <= $i ) {
696
						$foreignKey = $showKeys[intval($foreignKey) - 1];
697
					}
698
				}
699
				if(!isset($foreignKey)) {
700
					$foreignKey = $this->getInput('What is the foreignKey? Specify your own.', null, $suggestedForeignKey);
701
				}
702
				if($assocType == '4') {
703
					$associationForeignKey = $this->getInput('What is the associationForeignKey?', null, $this->__modelKey($currentModelName));
704
					$joinTable = $this->getInput('What is the joinTable?');
705
				}
706
				$associations[$assocs[$assocType]] = array_values($associations[$assocs[$assocType]]);
707
				$count = count($associations[$assocs[$assocType]]);
708
				$i = ($count > 0) ? $count : 0;
709
				$associations[$assocs[$assocType]][$i]['alias'] = $associationName;
710
				$associations[$assocs[$assocType]][$i]['className'] = $className;
711
				$associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey;
712
				if($assocType == '4') {
713
					$associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey;
714
					$associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable;
715
				}
716
				$wannaDoMoreAssoc = $this->getInput('Define another association?', array('y','n'), 'y');
717
			}
718
		}
719
		$this->stdout('');
720
		$this->hr();
721
		$this->stdout('The following model will be created:');
722
		$this->hr();
723
		$this->stdout("Model Name:    $currentModelName");
724
		$this->stdout("DB Connection: " . ($usingDefault ? 'default' : $useDbConfig));
725
		$this->stdout("Model Table:   " . $useTable);
726
		$this->stdout("Validation:    " . print_r($validate, true));
727

    
728
		if(!empty($associations)) {
729
			$this->stdout("Associations:");
730

    
731
			if(count($associations['belongsTo'])) {
732
				for($i = 0; $i < count($associations['belongsTo']); $i++) {
733
					$this->stdout("            $currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}");
734
				}
735
			}
736

    
737
			if(count($associations['hasOne'])) {
738
				for($i = 0; $i < count($associations['hasOne']); $i++) {
739
					$this->stdout("            $currentModelName hasOne	{$associations['hasOne'][$i]['alias']}");
740
				}
741
			}
742

    
743
			if(count($associations['hasMany'])) {
744
				for($i = 0; $i < count($associations['hasMany']); $i++) {
745
					$this->stdout("            $currentModelName hasMany   {$associations['hasMany'][$i]['alias']}");
746
				}
747
			}
748

    
749
			if(count($associations['hasAndBelongsToMany'])) {
750
				for($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
751
					$this->stdout("            $currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}");
752
				}
753
			}
754
		}
755
		$this->hr();
756
		$looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
757

    
758
		if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
759
			if ($useTable == Inflector::tableize($currentModelName)) {
760
				// set it to null...
761
				// putting $useTable in the model
762
				// is unnecessary.
763
				$useTable = null;
764
			}
765
			$this->bakeModel($currentModelName, $useDbConfig, $useTable, $primaryKey, $validate, $associations);
766

    
767
			if ($this->doUnitTest()) {
768
				$this->bakeUnitTest('model', $currentModelName);
769
			}
770
		} else {
771
			$this->stdout('Bake Aborted.');
772
		}
773
	}
774
/**
775
 * Action to create a View.
776
 *
777
 */
778
	function doView() {
779
		$this->hr();
780
		$this->stdout('View Bake:');
781
		$this->hr();
782
		$uses = array();
783
		$wannaUseSession = 'y';
784
		$wannaDoScaffold = 'y';
785

    
786

    
787
		$useDbConfig = 'default';
788
		$this->__doList($useDbConfig, 'Controllers');
789

    
790
		$enteredController = '';
791

    
792
		while ($enteredController == '') {
793
			$enteredController = $this->getInput('Enter a number from the list above, or type in the name of another controller.');
794

    
795
			if ($enteredController == '' || intval($enteredController) > count($this->__controllerNames)) {
796
				$this->stdout('Error:');
797
				$this->stdout("The Controller name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
798
				$enteredController = '';
799
			}
800
		}
801

    
802
		if (intval($enteredController) > 0 && intval($enteredController) <= count($this->__controllerNames) ) {
803
			$controllerName = $this->__controllerNames[intval($enteredController) - 1];
804
		} else {
805
			$controllerName = Inflector::camelize($enteredController);
806
		}
807

    
808
		$controllerPath = low(Inflector::underscore($controllerName));
809

    
810
		$doItInteractive = $this->getInput("Would you like bake to build your views interactively?\nWarning: Choosing no will overwrite {$controllerClassName} views if it exist.", array('y','n'), 'y');
811

    
812
		if (low($doItInteractive) == 'y' || low($doItInteractive) == 'yes') {
813
			$this->interactive = true;
814
			$wannaDoScaffold = $this->getInput("Would you like to create some scaffolded views (index, add, view, edit) for this controller?\nNOTE: Before doing so, you'll need to create your controller and model classes (including associated models).", array('y','n'), 'n');
815
		}
816

    
817
		$admin = null;
818
		$admin_url = null;
819
		if (low($wannaDoScaffold) == 'y' || low($wannaDoScaffold) == 'yes') {
820
			$wannaDoAdmin = $this->getInput("Would you like to create the views for admin routing?", array('y','n'), 'n');
821
		}
822

    
823
		if ((low($wannaDoAdmin) == 'y' || low($wannaDoAdmin) == 'yes')) {
824
			require(CONFIGS.'core.php');
825
			if(defined('CAKE_ADMIN')) {
826
				$admin = CAKE_ADMIN . '_';
827
				$admin_url = '/'.CAKE_ADMIN;
828
			} else {
829
				$adminRoute = '';
830
				$this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
831
				$this->stdout('What would you like the admin route to be?');
832
				$this->stdout('Example: www.example.com/admin/controller');
833
				while ($adminRoute == '') {
834
					$adminRoute = $this->getInput("What would you like the admin route to be?", null, 'admin');
835
				}
836
				if($this->__addAdminRoute($adminRoute) !== true){
837
					$this->stdout('Unable to write to /app/config/core.php.');
838
					$this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
839
					exit();
840
				} else {
841
					$admin = $adminRoute . '_';
842
					$admin_url = '/'.$adminRoute;
843
				}
844
			}
845
		}
846
		if (low($wannaDoScaffold) == 'y' || low($wannaDoScaffold) == 'yes') {
847
			$file = CONTROLLERS . $controllerPath . '_controller.php';
848

    
849
			if(!file_exists($file)) {
850
				$shortPath = str_replace(ROOT, null, $file);
851
				$shortPath = str_replace('../', '', $shortPath);
852
				$shortPath = str_replace('//', '/', $shortPath);
853
				$this->stdout('');
854
				$this->stdout("The file '$shortPath' could not be found.\nIn order to scaffold, you'll need to first create the controller. ");
855
				$this->stdout('');
856
				die();
857
			} else {
858
				loadController($controllerName);
859
				//loadModels();
860
				if($admin) {
861
					$this->__bakeViews($controllerName, $controllerPath, $admin, $admin_url);
862
				}
863
				$this->__bakeViews($controllerName, $controllerPath, null, null);
864

    
865
				$this->hr();
866
				$this->stdout('');
867
				$this->stdout('View Scaffolding Complete.'."\n");
868
			}
869
		} else {
870
			$actionName = '';
871

    
872
			while ($actionName == '') {
873
				$actionName = $this->getInput('Action Name? (use camelCased function name)');
874

    
875
				if ($actionName == '') {
876
					$this->stdout('The action name you supplied was empty. Please try again.');
877
				}
878
			}
879
			$this->stdout('');
880
			$this->hr();
881
			$this->stdout('The following view will be created:');
882
			$this->hr();
883
			$this->stdout("Controller Name: $controllerName");
884
			$this->stdout("Action Name:     $actionName");
885
			$this->stdout("Path:            app/views/" . $controllerPath . DS . Inflector::underscore($actionName) . '.thtml');
886
			$this->hr();
887
			$looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
888

    
889
			if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
890
				$this->bakeView($controllerName, $actionName);
891
			} else {
892
				$this->stdout('Bake Aborted.');
893
			}
894
		}
895
	}
896

    
897
	function __bakeViews($controllerName, $controllerPath, $admin= null, $admin_url = null) {
898
		$controllerClassName = $controllerName.'Controller';
899
		$controllerObj = & new $controllerClassName();
900

    
901
		if(!in_array('Html', $controllerObj->helpers)) {
902
			$controllerObj->helpers[] = 'Html';
903
		}
904
		if(!in_array('Form', $controllerObj->helpers)) {
905
			$controllerObj->helpers[] = 'Form';
906
		}
907

    
908
		$controllerObj->constructClasses();
909
		$currentModelName = $controllerObj->modelClass;
910
		$this->__modelClass = $currentModelName;
911
		$modelKey = Inflector::underscore($currentModelName);
912
		$modelObj =& ClassRegistry::getObject($modelKey);
913
		$singularName = $this->__singularName($currentModelName);
914
		$pluralName = $this->__pluralName($currentModelName);
915
		$singularHumanName = $this->__singularHumanName($currentModelName);
916
		$pluralHumanName = $this->__pluralHumanName($controllerName);
917

    
918
		$fieldNames = $controllerObj->generateFieldNames(null, false);
919

    
920
		//-------------------------[INDEX]-------------------------//
921
		$indexView = null;
922
		if(!empty($modelObj->alias)) {
923
			foreach ($modelObj->alias as $key => $value) {
924
				$alias[] = $key;
925
			}
926
		}
927
		$indexView .= "<div class=\"{$pluralName}\">\n";
928
		$indexView .= "<h2>List " . $pluralHumanName . "</h2>\n\n";
929
		$indexView .= "<table cellpadding=\"0\" cellspacing=\"0\">\n";
930
		$indexView .= "<tr>\n";
931

    
932
		foreach ($fieldNames as $fieldName) {
933
			$indexView .= "\t<th>".$fieldName['prompt']."</th>\n";
934
		}
935
		$indexView .= "\t<th>Actions</th>\n";
936
		$indexView .= "</tr>\n";
937
		$indexView .= "<?php foreach (\${$pluralName} as \${$singularName}): ?>\n";
938
		$indexView .= "<tr>\n";
939
		$count = 0;
940
		foreach($fieldNames as $field => $value) {
941
			if(isset($value['foreignKey'])) {
942
				$otherModelName = $this->__modelName($value['model']);
943
				$otherModelKey = Inflector::underscore($otherModelName);
944
				$otherModelObj =& ClassRegistry::getObject($otherModelKey);
945
				$otherControllerName = $this->__controllerName($otherModelName);
946
				$otherControllerPath = $this->__controllerPath($otherControllerName);
947
				if(is_object($otherModelObj)) {
948
					$displayField = $otherModelObj->getDisplayField();
949
					$indexView .= "\t<td>&nbsp;<?php echo \$html->link(\$".$singularName."['{$alias[$count]}']['{$displayField}'], '{$admin_url}/" . $otherControllerPath . "/view/' .\$".$singularName."['{$alias[$count]}']['{$otherModelObj->primaryKey}'])?></td>\n";
950
				} else {
951
					$indexView .= "\t<td><?php echo \$".$singularName."['{$modelObj->name}']['{$field}']; ?></td>\n";
952
				}
953
				$count++;
954
			} else {
955
				$indexView .= "\t<td><?php echo \$".$singularName."['{$modelObj->name}']['{$field}']; ?></td>\n";
956
			}
957
		}
958
		$indexView .= "\t<td class=\"actions\">\n";
959
		$indexView .= "\t\t<?php echo \$html->link('View','{$admin_url}/{$controllerPath}/view/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
960
		$indexView .= "\t\t<?php echo \$html->link('Edit','{$admin_url}/{$controllerPath}/edit/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
961
		$indexView .= "\t\t<?php echo \$html->link('Delete','{$admin_url}/{$controllerPath}/delete/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'], null, 'Are you sure you want to delete id ' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
962
		$indexView .= "\t</td>\n";
963
		$indexView .= "</tr>\n";
964
		$indexView .= "<?php endforeach; ?>\n";
965
		$indexView .= "</table>\n\n";
966
		$indexView .= "<ul class=\"actions\">\n";
967
		$indexView .= "\t<li><?php echo \$html->link('New {$singularHumanName}', '{$admin_url}/{$controllerPath}/add'); ?></li>\n";
968
		$indexView .= "</ul>\n";
969
		$indexView .= "</div>";
970

    
971
		//-------------------------[VIEW]-------------------------//
972
		$viewView = null;
973

    
974
		$viewView .= "<div class=\"{$singularName}\">\n";
975
		$viewView .= "<h2>View " . $singularHumanName . "</h2>\n\n";
976
		$viewView .= "<dl>\n";
977
		$count = 0;
978
		foreach($fieldNames as $field => $value) {
979
			$viewView .= "\t<dt>" . $value['prompt'] . "</dt>\n";
980
			if(isset($value['foreignKey'])) {
981
				$otherModelName = $this->__modelName($value['model']);
982
				$otherModelKey = Inflector::underscore($otherModelName);
983
				$otherModelObj =& ClassRegistry::getObject($otherModelKey);
984
				$otherControllerName = $this->__controllerName($otherModelName);
985
				$otherControllerPath = $this->__controllerPath($otherControllerName);
986
				$displayField = $otherModelObj->getDisplayField();
987
				$viewView .= "\t<dd>&nbsp;<?php echo \$html->link(\$".$singularName."['{$alias[$count]}']['{$displayField}'], '{$admin_url}/" . $otherControllerPath . "/view/' .\$".$singularName."['{$alias[$count]}']['{$otherModelObj->primaryKey}'])?></dd>\n";
988
				$count++;
989
			} else {
990
				$viewView .= "\t<dd>&nbsp;<?php echo \$".$singularName."['{$modelObj->name}']['{$field}']?></dd>\n";
991
			}
992
		}
993
		$viewView .= "</dl>\n";
994
		$viewView .= "<ul class=\"actions\">\n";
995
		$viewView .= "\t<li><?php echo \$html->link('Edit " . $singularHumanName . "',   '{$admin_url}/{$controllerPath}/edit/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}']) ?> </li>\n";
996
		$viewView .= "\t<li><?php echo \$html->link('Delete " . $singularHumanName . "', '{$admin_url}/{$controllerPath}/delete/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'], null, 'Are you sure you want to delete: id ' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'] . '?') ?> </li>\n";
997
		$viewView .= "\t<li><?php echo \$html->link('List " . $pluralHumanName ."',   '{$admin_url}/{$controllerPath}/index') ?> </li>\n";
998
		$viewView .= "\t<li><?php echo \$html->link('New " . $singularHumanName . "',	'{$admin_url}/{$controllerPath}/add') ?> </li>\n";
999
		foreach( $fieldNames as $field => $value ) {
1000
			if( isset( $value['foreignKey'] ) ) {
1001
				$otherModelName = $this->__modelName($value['model']);
1002
				if($otherModelName != $currentModelName) {
1003
					$otherControllerName = $this->__controllerName($otherModelName);
1004
					$otherControllerPath = $this->__controllerPath($otherControllerName);
1005
					$otherSingularHumanName = $this->__singularHumanName($value['controller']);
1006
					$otherPluralHumanName = $this->__pluralHumanName($value['controller']);
1007
					$viewView .= "\t<li><?php echo \$html->link('List " . $otherSingularHumanName . "', '{$admin_url}/" . $otherControllerPath . "/index/')?> </li>\n";
1008
					$viewView .= "\t<li><?php echo \$html->link('New " . $otherPluralHumanName . "', '{$admin_url}/" . $otherControllerPath . "/add/')?> </li>\n";
1009
				}
1010
			}
1011
		}
1012
		$viewView .= "</ul>\n\n";
1013

    
1014
		$viewView .= "</div>\n";
1015

    
1016

    
1017
		foreach ($modelObj->hasOne as $associationName => $relation) {
1018
			$new = true;
1019

    
1020
			$otherModelName = $this->__modelName($relation['className']);
1021
			$otherControllerName = $this->__controllerName($otherModelName);
1022
			$otherControllerPath = $this->__controllerPath($otherModelName);
1023
			$otherSingularName = $this->__singularName($associationName);
1024
			$otherPluralHumanName = $this->__pluralHumanName($associationName);
1025
			$otherSingularHumanName = $this->__singularHumanName($associationName);
1026

    
1027
			$viewView .= "<div class=\"related\">\n";
1028
			$viewView .= "<h3>Related " . $otherPluralHumanName . "</h3>\n";
1029
			$viewView .= "<?php if(!empty(\$".$singularName."['{$associationName}'])): ?>\n";
1030
			$viewView .= "<dl>\n";
1031
			$viewView .= "\t<?php foreach(\$".$singularName."['{$associationName}'] as \$field => \$value): ?>\n";
1032
			$viewView .= "\t\t<dt><?php echo \$field ?></dt>\n";
1033
			$viewView .= "\t\t<dd>&nbsp;<?php echo \$value ?></dd>\n";
1034
			$viewView .= "\t<?php endforeach; ?>\n";
1035
			$viewView .= "</dl>\n";
1036
			$viewView .= "<?php endif; ?>\n";
1037
			$viewView .= "<ul class=\"actions\">\n";
1038
			$viewView .= "\t<li><?php echo \$html->link('Edit " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/edit/' . \$".$singularName."['{$associationName}']['" . $modelObj->{$otherModelName}->primaryKey . "']);?></li>\n";
1039
			$viewView .= "\t<li><?php echo \$html->link('New " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/add/');?> </li>\n";
1040
			$viewView .= "</ul>\n";
1041
			$viewView .= "</div>\n";
1042
		}
1043
		$relations = array_merge($modelObj->hasMany, $modelObj->hasAndBelongsToMany);
1044

    
1045
		foreach($relations as $associationName => $relation) {
1046
			$otherModelName = $this->__modelName($relation['className']);
1047
			$otherControllerName = $this->__controllerName($otherModelName);
1048
			$otherControllerPath = $this->__controllerPath($otherModelName);
1049
			$otherSingularName = $this->__singularName($associationName);
1050
			$otherPluralHumanName = $this->__pluralHumanName($associationName);
1051
			$otherSingularHumanName = $this->__singularHumanName($associationName);
1052
			$otherModelKey = Inflector::underscore($otherModelName);
1053
			$otherModelObj =& ClassRegistry::getObject($otherModelKey);
1054

    
1055
			$viewView .= "<div class=\"related\">\n";
1056
			$viewView .= "<h3>Related " . $otherPluralHumanName . "</h3>\n";
1057
			$viewView .= "<?php if(!empty(\$".$singularName."['{$associationName}'])):?>\n";
1058
			$viewView .= "<table cellpadding=\"0\" cellspacing=\"0\">\n";
1059
			$viewView .= "<tr>\n";
1060
			$viewView .= "<?php foreach(\$".$singularName."['{$associationName}']['0'] as \$column => \$value): ?>\n";
1061
			$viewView .= "<th><?php echo \$column?></th>\n";
1062
			$viewView .= "<?php endforeach; ?>\n";
1063
			$viewView .= "<th>Actions</th>\n";
1064
			$viewView .= "</tr>\n";
1065
			$viewView .= "<?php foreach(\$".$singularName."['{$associationName}'] as \$".$otherSingularName."):?>\n";
1066
			$viewView .= "<tr>\n";
1067
			$viewView .= "\t<?php foreach(\$".$otherSingularName." as \$column => \$value):?>\n";
1068
			$viewView .= "\t\t<td><?php echo \$value;?></td>\n";
1069
			$viewView .= "\t<?php endforeach;?>\n";
1070
			$viewView .= "\t<td class=\"actions\">\n";
1071
			$viewView .= "\t\t<?php echo \$html->link('View', '{$admin_url}/" . $otherControllerPath . "/view/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}']);?>\n";
1072
			$viewView .= "\t\t<?php echo \$html->link('Edit', '{$admin_url}/" . $otherControllerPath . "/edit/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}']);?>\n";
1073
			$viewView .= "\t\t<?php echo \$html->link('Delete', '{$admin_url}/" . $otherControllerPath . "/delete/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}'], null, 'Are you sure you want to delete: id ' . \$".$otherSingularName."['{$otherModelObj->primaryKey}'] . '?');?>\n";
1074
			$viewView .= "\t</td>\n";
1075
			$viewView .= "</tr>\n";
1076
			$viewView .= "<?php endforeach; ?>\n";
1077
			$viewView .= "</table>\n";
1078
			$viewView .= "<?php endif; ?>\n\n";
1079
			$viewView .= "<ul class=\"actions\">\n";
1080
			$viewView .= "\t<li><?php echo \$html->link('New " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/add/');?> </li>\n";
1081
			$viewView .= "</ul>\n";
1082

    
1083
			$viewView .= "</div>\n";
1084
		}
1085
		//-------------------------[ADD]-------------------------//
1086
		$addView = null;
1087
		$addView .= "<h2>New " . $singularHumanName . "</h2>\n";
1088
		$addView .= "<form action=\"<?php echo \$html->url('{$admin_url}/{$controllerPath}/add'); ?>\" method=\"post\">\n";
1089
		$addView .= $this->generateFields($controllerObj->generateFieldNames(null, true));
1090
		$addView .= $this->generateSubmitDiv('Add');
1091
		$addView .= "</form>\n";
1092
		$addView .= "<ul class=\"actions\">\n";
1093
		$addView .= "<li><?php echo \$html->link('List {$pluralHumanName}', '{$admin_url}/{$controllerPath}/index')?></li>\n";
1094
		foreach ($modelObj->belongsTo as $associationName => $relation) {
1095
			$otherModelName = $this->__modelName($associationName);
1096
			if($otherModelName != $currentModelName) {
1097
				$otherControllerName = $this->__controllerName($otherModelName);
1098
				$otherControllerPath = $this->__controllerPath($otherModelName);
1099
				$otherSingularName = $this->__singularName($associationName);
1100
				$otherPluralName = $this->__pluralHumanName($associationName);
1101
				$addView .= "<li><?php echo \$html->link('View " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/index/');?></li>\n";
1102
				$addView .= "<li><?php echo \$html->link('Add " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/add/');?></li>\n";
1103
			}
1104
		}
1105
		$addView .= "</ul>\n";
1106
		//-------------------------[EDIT]-------------------------//
1107
		$editView = null;
1108
		$editView .= "<h2>Edit " . $singularHumanName . "</h2>\n";
1109
		$editView .= "<form action=\"<?php echo \$html->url('{$admin_url}/{$controllerPath}/edit/'.\$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}')); ?>\" method=\"post\">\n";
1110
		$editView .= $this->generateFields($controllerObj->generateFieldNames(null, true));
1111
		$editView .= "<?php echo \$html->hidden('{$modelObj->name}/{$modelObj->primaryKey}')?>\n";
1112
		$editView .= $this->generateSubmitDiv('Save');
1113
		$editView .= "</form>\n";
1114
		$editView .= "<ul class=\"actions\">\n";
1115
		$editView .= "<li><?php echo \$html->link('Delete','{$admin_url}/{$controllerPath}/delete/' . \$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}'), null, 'Are you sure you want to delete: id ' . \$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}'));?>\n";
1116
		$editView .= "<li><?php echo \$html->link('List {$pluralHumanName}', '{$admin_url}/{$controllerPath}/index')?></li>\n";
1117
		foreach ($modelObj->belongsTo as $associationName => $relation) {
1118
			$otherModelName = $this->__modelName($associationName);
1119
			if($otherModelName != $currentModelName) {
1120
				$otherControllerName = $this->__controllerName($otherModelName);
1121
				$otherControllerPath = $this->__controllerPath($otherModelName);
1122
				$otherSingularName = $this->__singularName($associationName);
1123
				$otherPluralName = $this->__pluralHumanName($associationName);
1124
				$editView .= "<li><?php echo \$html->link('View " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/index/');?></li>\n";
1125
				$editView .= "<li><?php echo \$html->link('Add " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/add/');?></li>\n";
1126
			}
1127
		}
1128
		$editView .= "</ul>\n";
1129

    
1130
		//------------------------------------------------------------------------------------//
1131

    
1132
		if(!file_exists(VIEWS.$controllerPath)) {
1133
			mkdir(VIEWS.$controllerPath);
1134
		}
1135
		$filename = VIEWS . $controllerPath . DS .  $admin . 'index.thtml';
1136
		$this->__createFile($filename, $indexView);
1137
		$filename = VIEWS . $controllerPath . DS . $admin . 'view.thtml';
1138
		$this->__createFile($filename, $viewView);
1139
		$filename = VIEWS . $controllerPath . DS . $admin . 'add.thtml';
1140
		$this->__createFile($filename, $addView);
1141
		$filename = VIEWS . $controllerPath . DS . $admin . 'edit.thtml';
1142
		$this->__createFile($filename, $editView);
1143
	}
1144
/**
1145
 * Action to create a Controller.
1146
 *
1147
 */
1148
	function doController() {
1149
		$this->hr();
1150
		$this->stdout('Controller Bake:');
1151
		$this->hr();
1152
		$uses = array();
1153
		$helpers = array();
1154
		$components = array();
1155
		$wannaUseSession = 'y';
1156
		$wannaDoScaffolding = 'y';
1157

    
1158
		$useDbConfig = 'default';
1159
		$this->__doList($useDbConfig, 'Controllers');
1160

    
1161
		$enteredController = '';
1162

    
1163
		while ($enteredController == '') {
1164
			$enteredController = $this->getInput('Enter a number from the list above, or type in the name of another controller.');
1165

    
1166
			if ($enteredController == '' || intval($enteredController) > count($this->__controllerNames)) {
1167
				$this->stdout('Error:');
1168
				$this->stdout("The Controller name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
1169
				$enteredController = '';
1170
			}
1171
		}
1172

    
1173
		if (intval($enteredController) > 0 && intval($enteredController) <= count($this->__controllerNames) ) {
1174
			$controllerName = $this->__controllerNames[intval($enteredController) - 1];
1175
		} else {
1176
			$controllerName = $enteredController;
1177
		}
1178
		$controllerPath = $this->__controllerPath($controllerName);
1179

    
1180
		$doItInteractive = $this->getInput("Would you like bake to build your controller interactively?\nWarning: Choosing no will overwrite {$controllerClassName} controller if it exist.", array('y','n'), 'y');
1181

    
1182
		if (low($doItInteractive) == 'y' || low($doItInteractive) == 'yes') {
1183
			$this->interactive = true;
1184

    
1185
			$wannaUseScaffold = $this->getInput("Would you like to use scaffolding?", array('y','n'), 'y');
1186

    
1187
			if (low($wannaUseScaffold) == 'n' || low($wannaUseScaffold) == 'no') {
1188

    
1189
				$wannaDoScaffolding = $this->getInput("Would you like to include some basic class methods (index(), add(), view(), edit())?", array('y','n'), 'n');
1190

    
1191
				if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
1192
					$wannaDoAdmin = $this->getInput("Would you like to create the methods for admin routing?", array('y','n'), 'n');
1193
				}
1194

    
1195
				$wannaDoUses = $this->getInput("Would you like this controller to use other models besides '" . $this->__modelName($controllerName) .  "'?", array('y','n'), 'n');
1196

    
1197
				if (low($wannaDoUses) == 'y' || low($wannaDoUses) == 'yes') {
1198
					$usesList = $this->getInput("Please provide a comma separated list of the classnames of other models you'd like to use.\nExample: 'Author, Article, Book'");
1199
					$usesListTrimmed = str_replace(' ', '', $usesList);
1200
					$uses = explode(',', $usesListTrimmed);
1201
				}
1202
				$wannaDoHelpers = $this->getInput("Would you like this controller to use other helpers besides HtmlHelper and FormHelper?", array('y','n'), 'n');
1203

    
1204
				if (low($wannaDoHelpers) == 'y' || low($wannaDoHelpers) == 'yes') {
1205
					$helpersList = $this->getInput("Please provide a comma separated list of the other helper names you'd like to use.\nExample: 'Ajax, Javascript, Time'");
1206
					$helpersListTrimmed = str_replace(' ', '', $helpersList);
1207
					$helpers = explode(',', $helpersListTrimmed);
1208
				}
1209
				$wannaDoComponents = $this->getInput("Would you like this controller to use any components?", array('y','n'), 'n');
1210

    
1211
				if (low($wannaDoComponents) == 'y' || low($wannaDoComponents) == 'yes') {
1212
					$componentsList = $this->getInput("Please provide a comma separated list of the component names you'd like to use.\nExample: 'Acl, MyNiftyHelper'");
1213
					$componentsListTrimmed = str_replace(' ', '', $componentsList);
1214
					$components = explode(',', $componentsListTrimmed);
1215
				}
1216

    
1217
				$wannaUseSession = $this->getInput("Would you like to use Sessions?", array('y','n'), 'y');
1218
			} else {
1219
				$wannaDoScaffolding = 'n';
1220
			}
1221
		} else {
1222
			$wannaDoScaffolding = $this->getInput("Would you like to include some basic class methods (index(), add(), view(), edit())?", array('y','n'), 'y');
1223

    
1224
			if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
1225
				$wannaDoAdmin = $this->getInput("Would you like to create the methods for admin routing?", array('y','n'), 'y');
1226
			}
1227
		}
1228

    
1229
		$admin = null;
1230
		$admin_url = null;
1231
		if ((low($wannaDoAdmin) == 'y' || low($wannaDoAdmin) == 'yes')) {
1232
			require(CONFIGS.'core.php');
1233
			if(defined('CAKE_ADMIN')) {
1234
				$admin = CAKE_ADMIN.'_';
1235
				$admin_url = '/'.CAKE_ADMIN;
1236
			} else {
1237
				$adminRoute = '';
1238
				$this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
1239
				$this->stdout('What would you like the admin route to be?');
1240
				$this->stdout('Example: www.example.com/admin/controller');
1241
				while ($adminRoute == '') {
1242
					$adminRoute = $this->getInput("What would you like the admin route to be?", null, 'admin');
1243
				}
1244
				if($this->__addAdminRoute($adminRoute) !== true){
1245
					$this->stdout('Unable to write to /app/config/core.php.');
1246
					$this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
1247
					exit();
1248
				} else {
1249
					$admin = $adminRoute . '_';
1250
					$admin_url = '/'.$adminRoute;
1251
				}
1252
			}
1253
		}
1254

    
1255
		if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
1256
			//loadModels();
1257
			$actions = $this->__bakeActions($controllerName, null, null, $wannaUseSession);
1258
			if($admin) {
1259
				$actions .= $this->__bakeActions($controllerName, $admin, $admin_url, $wannaUseSession);
1260
			}
1261
		}
1262

    
1263
		if($this->interactive === true) {
1264
			$this->stdout('');
1265
			$this->hr();
1266
			$this->stdout('The following controller will be created:');
1267
			$this->hr();
1268
			$this->stdout("Controller Name:	$controllerName");
1269
			if (low($wannaUseScaffold) == 'y' || low($wannaUseScaffold) == 'yes') {
1270
				$this->stdout("			var \$scaffold;");
1271
			}
1272
			if(count($uses)) {
1273
				$this->stdout("Uses:            ", false);
1274

    
1275
				foreach($uses as $use) {
1276
					if ($use != $uses[count($uses) - 1]) {
1277
						$this->stdout(ucfirst($use) . ", ", false);
1278
					} else {
1279
						$this->stdout(ucfirst($use));
1280
					}
1281
				}
1282
			}
1283

    
1284
			if(count($helpers)) {
1285
				$this->stdout("Helpers:			", false);
1286

    
1287
				foreach($helpers as $help) {
1288
					if ($help != $helpers[count($helpers) - 1]) {
1289
						$this->stdout(ucfirst($help) . ", ", false);
1290
					} else {
1291
						$this->stdout(ucfirst($help));
1292
					}
1293
				}
1294
			}
1295

    
1296
			if(count($components)) {
1297
				$this->stdout("Components:            ", false);
1298

    
1299
				foreach($components as $comp) {
1300
					if ($comp != $components[count($components) - 1]) {
1301
						$this->stdout(ucfirst($comp) . ", ", false);
1302
					} else {
1303
						$this->stdout(ucfirst($comp));
1304
					}
1305
				}
1306
			}
1307
			$this->hr();
1308
			$looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
1309

    
1310
			if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
1311
				$this->bakeController($controllerName, $uses, $helpers, $components, $actions, $wannaUseScaffold);
1312

    
1313
				if ($this->doUnitTest()) {
1314
					$this->bakeUnitTest('controller', $controllerName);
1315
				}
1316
			} else {
1317
				$this->stdout('Bake Aborted.');
1318
			}
1319
		} else {
1320
			$this->bakeController($controllerName, $uses, $helpers, $components, $actions, $wannaUseScaffold);
1321
			if ($this->doUnitTest()) {
1322
				$this->bakeUnitTest('controller', $controllerName);
1323
			}
1324
			exit();
1325
		}
1326
	}
1327

    
1328
	function __bakeActions($controllerName, $admin = null, $admin_url = null, $wannaUseSession = 'y') {
1329
		$currentModelName = $this->__modelName($controllerName);
1330
		loadModel($currentModelName);
1331
		$modelObj =& new $currentModelName();
1332
		$controllerPath = $this->__controllerPath($currentModelName);
1333
		$pluralName = $this->__pluralName($currentModelName);
1334
		$singularName = $this->__singularName($currentModelName);
1335
		$singularHumanName = $this->__singularHumanName($currentModelName);
1336
		$pluralHumanName = $this->__pluralHumanName($controllerName);
1337
		if(!class_exists($currentModelName)) {
1338
			$this->stdout('You must have a model for this class to build scaffold methods. Please try again.');
1339
			exit;
1340
		}
1341
		$actions .= "\n";
1342
		$actions .= "\tfunction {$admin}index() {\n";
1343
		$actions .= "\t\t\$this->{$currentModelName}->recursive = 0;\n";
1344
		$actions .= "\t\t\$this->set('{$pluralName}', \$this->{$currentModelName}->findAll());\n";
1345
		$actions .= "\t}\n";
1346
		$actions .= "\n";
1347
		$actions .= "\tfunction {$admin}view(\$id = null) {\n";
1348
		$actions .= "\t\tif(!\$id) {\n";
1349
		if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
1350
		$actions .= "\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}.');\n";
1351
		$actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
1352
		} else {
1353
		$actions .= "\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
1354
		}
1355
		$actions .= "\t\t}\n";
1356
		$actions .= "\t\t\$this->set('".$singularName."', \$this->{$currentModelName}->read(null, \$id));\n";
1357
		$actions .= "\t}\n";
1358
		$actions .= "\n";
1359
		/* ADD ACTION */
1360
		$actions .= "\tfunction {$admin}add() {\n";
1361
		$actions .= "\t\tif(empty(\$this->data)) {\n";
1362

    
1363
		foreach($modelObj->hasAndBelongsToMany as $associationName => $relation) {
1364
			if(!empty($associationName)) {
1365
				$otherModelName = $this->__modelName($associationName);
1366
				$otherSingularName = $this->__singularName($associationName);
1367
				$otherPluralName = $this->__pluralName($associationName);
1368
				$selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
1369
				$actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
1370
				$actions .= "\t\t\t\$this->set('{$selectedOtherPluralName}', null);\n";
1371
			}
1372
		}
1373
		foreach($modelObj->belongsTo as $associationName => $relation) {
1374
			if(!empty($associationName)) {
1375
				$otherModelName = $this->__modelName($associationName);
1376
				$otherSingularName = $this->__singularName($associationName);
1377
				$otherPluralName = $this->__pluralName($associationName);
1378
				$actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
1379
			}
1380
		}
1381
		$actions .= "\t\t\t\$this->render();\n";
1382
		$actions .= "\t\t} else {\n";
1383
		$actions .= "\t\t\t\$this->cleanUpFields();\n";
1384
		$actions .= "\t\t\tif(\$this->{$currentModelName}->save(\$this->data)) {\n";
1385
		if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
1386
		$actions .= "\t\t\t\t\$this->Session->setFlash('The ".$this->__singularHumanName($currentModelName)." has been saved');\n";
1387
		$actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
1388
		} else {
1389
		$actions .= "\t\t\t\t\$this->flash('{$currentModelName} saved.', '{$admin_url}/{$controllerPath}/index');\n";
1390
		}
1391
		$actions .= "\t\t\t} else {\n";
1392
		if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
1393
		$actions .= "\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
1394
		}
1395

    
1396
		foreach($modelObj->hasAndBelongsToMany as $associationName => $relation) {
1397
			if(!empty($associationName)) {
1398
				$otherModelName = $this->__modelName($associationName);
1399
				$otherSingularName = $this->__singularName($associationName);
1400
				$otherPluralName = $this->__pluralName($associationName);
1401
				$selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
1402
				$actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
1403
				$actions .= "\t\t\t\tif(empty(\$this->data['{$associationName}']['{$associationName}'])) { \$this->data['{$associationName}']['{$associationName}'] = null; }\n";
1404
				$actions .= "\t\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->data['{$associationName}']['{$associationName}']);\n";
1405
			}
1406
		}
1407
		foreach($modelObj->belongsTo as $associationName => $relation) {
1408
			if(!empty($associationName)) {
1409
				$otherModelName = $this->__modelName($associationName);
1410
				$otherSingularName = $this->__singularName($associationName);
1411
				$otherPluralName = $this->__pluralName($associationName);
1412
				$actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
1413
			}
1414
		}
1415
		$actions .= "\t\t\t}\n";
1416
		$actions .= "\t\t}\n";
1417
		$actions .= "\t}\n";
1418
		$actions .= "\n";
1419
		/* EDIT ACTION */
1420
		$actions .= "\tfunction {$admin}edit(\$id = null) {\n";
1421
		$actions .= "\t\tif(empty(\$this->data)) {\n";
1422
		$actions .= "\t\t\tif(!\$id) {\n";
1423
		if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
1424
		$actions .= "\t\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}');\n";
1425
		$actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
1426
		} else {
1427
		$actions .= "\t\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
1428
		}
1429
		$actions .= "\t\t\t}\n";
1430
		$actions .= "\t\t\t\$this->data = \$this->{$currentModelName}->read(null, \$id);\n";
1431

    
1432
		foreach($modelObj->hasAndBelongsToMany as $associationName => $relation) {
1433
			if(!empty($associationName)) {
1434
				$otherModelName = $this->__modelName($associationName);
1435
				$otherSingularName = $this->__singularName($associationName);
1436
				$otherPluralName = $this->__pluralName($associationName);
1437
				$otherModelKey = Inflector::underscore($otherModelName);
1438
				$otherModelObj =& ClassRegistry::getObject($otherModelKey);
1439
				$selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
1440
				$actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
1441
				$actions .= "\t\t\tif(empty(\$this->data['{$associationName}'])) { \$this->data['{$associationName}'] = null; }\n";
1442
				$actions .= "\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->_selectedArray(\$this->data['{$associationName}']));\n";
1443
			}
1444
		}
1445
		foreach($modelObj->belongsTo as $associationName => $relation) {
1446
			if(!empty($associationName)) {
1447
				$otherModelName = $this->__modelName($associationName);
1448
				$otherSingularName = $this->__singularName($associationName);
1449
				$otherPluralName = $this->__pluralName($associationName);
1450
				$actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
1451
			}
1452
		}
1453
		$actions .= "\t\t} else {\n";
1454
		$actions .= "\t\t\t\$this->cleanUpFields();\n";
1455
		$actions .= "\t\t\tif(\$this->{$currentModelName}->save(\$this->data)) {\n";
1456
		if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
1457
		$actions .= "\t\t\t\t\$this->Session->setFlash('The ".Inflector::humanize($currentModelName)." has been saved');\n";
1458
		$actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
1459
		} else {
1460
		$actions .= "\t\t\t\t\$this->flash('{$currentModelName} saved.', '{$admin_url}/{$controllerPath}/index');\n";
1461
		}
1462
		$actions .= "\t\t\t} else {\n";
1463
		if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
1464
		$actions .= "\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
1465
		}
1466

    
1467
		foreach($modelObj->hasAndBelongsToMany as $associationName => $relation) {
1468
			if(!empty($associationName)) {
1469
				$otherModelName = $this->__modelName($associationName);
1470
				$otherSingularName = $this->__singularName($associationName);
1471
				$otherPluralName = $this->__pluralName($associationName);
1472
				$selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
1473
				$actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
1474
				$actions .= "\t\t\t\tif(empty(\$this->data['{$associationName}']['{$associationName}'])) { \$this->data['{$associationName}']['{$associationName}'] = null; }\n";
1475
				$actions .= "\t\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->data['{$associationName}']['{$associationName}']);\n";
1476
			}
1477
		}
1478
		foreach($modelObj->belongsTo as $associationName => $relation) {
1479
			if(!empty($associationName)) {
1480
				$otherModelName = $this->__modelName($associationName);
1481
				$otherSingularName = $this->__singularName($associationName);
1482
				$otherPluralName = $this->__pluralName($associationName);
1483
				$actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
1484
			}
1485
		}
1486
		$actions .= "\t\t\t}\n";
1487
		$actions .= "\t\t}\n";
1488
		$actions .= "\t}\n";
1489
		$actions .= "\n";
1490
		$actions .= "\tfunction {$admin}delete(\$id = null) {\n";
1491
		$actions .= "\t\tif(!\$id) {\n";
1492
		if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
1493
		$actions .= "\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}');\n";
1494
		$actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
1495
		} else {
1496
		$actions .= "\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
1497
		}
1498
		$actions .= "\t\t}\n";
1499
		$actions .= "\t\tif(\$this->{$currentModelName}->del(\$id)) {\n";
1500
		if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
1501
			$actions .= "\t\t\t\$this->Session->setFlash('The ".$this->__singularHumanName($currentModelName)." deleted: id '.\$id.'');\n";
1502
			$actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
1503
		} else {
1504
			$actions .= "\t\t\t\$this->flash('{$currentModelName} deleted: id '.\$id.'.', '{$admin_url}/{$controllerPath}/index');\n";
1505
		}
1506
		$actions .= "\t\t}\n";
1507
		$actions .= "\t}\n";
1508
		$actions .= "\n";
1509
		return $actions;
1510
	}
1511
/**
1512
 * Action to create a Unit Test.
1513
 *
1514
 * @return Success
1515
 */
1516
	function doUnitTest() {
1517
		if (is_dir(VENDORS.'simpletest') || is_dir(ROOT.DS.APP_DIR.DS.'vendors'.DS.'simpletest')) {
1518
			return true;
1519
		}
1520
		$unitTest = $this->getInput('Cake test suite not installed.  Do you want to bake unit test files anyway?', array('y','n'), 'y');
1521
		$result = low($unitTest) == 'y' || low($unitTest) == 'yes';
1522

    
1523
		if ($result) {
1524
			$this->stdout("\nYou can download the Cake test suite from http://cakeforge.org/projects/testsuite/", true);
1525
		}
1526
		return $result;
1527
	}
1528
/**
1529
 * Creates a database configuration file for Bake.
1530
 *
1531
 * @param string $host
1532
 * @param string $login
1533
 * @param string $password
1534
 * @param string $database
1535
 */
1536
	function bakeDbConfig( $driver, $connect, $host, $login, $password, $database, $prefix) {
1537
		$out = "<?php\n";
1538
		$out .= "class DATABASE_CONFIG {\n\n";
1539
		$out .= "\tvar \$default = array(\n";
1540
		$out .= "\t\t'driver' => '{$driver}',\n";
1541
		$out .= "\t\t'connect' => '{$connect}',\n";
1542
		$out .= "\t\t'host' => '{$host}',\n";
1543
		$out .= "\t\t'login' => '{$login}',\n";
1544
		$out .= "\t\t'password' => '{$password}',\n";
1545
		$out .= "\t\t'database' => '{$database}', \n";
1546
		$out .= "\t\t'prefix' => '{$prefix}' \n";
1547
		$out .= "\t);\n";
1548
		$out .= "}\n";
1549
		$out .= "?>";
1550
		$filename = CONFIGS.'database.php';
1551
		$this->__createFile($filename, $out);
1552
	}
1553
/**
1554
 * Assembles and writes a Model file.
1555
 *
1556
 * @param string $name
1557
 * @param object $useDbConfig
1558
 * @param string $useTable
1559
 * @param string $primaryKey
1560
 * @param array $validate
1561
 * @param array $associations
1562
 */
1563
	function bakeModel($name, $useDbConfig = 'default', $useTable = null, $primaryKey = 'id', $validate=array(), $associations=array()) {
1564
		$out = "<?php\n";
1565
		$out .= "class {$name} extends AppModel {\n\n";
1566
		$out .= "\tvar \$name = '{$name}';\n";
1567

    
1568
		if ($useDbConfig != 'default') {
1569
			$out .= "\tvar \$useDbConfig = '$useDbConfig';\n";
1570
		}
1571

    
1572
		if ($useTable != null) {
1573
			$out .= "\tvar \$useTable = '$useTable';\n";
1574
		}
1575

    
1576
		if ($primaryKey != 'id') {
1577
			$out .= "\tvar \$primaryKey = '$primaryKey';\n";
1578
		}
1579

    
1580

    
1581
		if (count($validate)) {
1582
			$out .= "\tvar \$validate = array(\n";
1583
			$keys = array_keys($validate);
1584
			for($i = 0; $i < count($validate); $i++) {
1585
				$out .= "\t\t'" . $keys[$i] . "' => " . $validate[$keys[$i]] . ",\n";
1586
			}
1587
			$out .= "\t);\n";
1588
		}
1589
		$out .= "\n";
1590

    
1591
		if(!empty($associations)) {
1592
			$out.= "\t//The Associations below have been created with all possible keys, those that are not needed can be removed\n";
1593
			if(!empty($associations['belongsTo'])) {
1594
				$out .= "\tvar \$belongsTo = array(\n";
1595

    
1596
				for($i = 0; $i < count($associations['belongsTo']); $i++) {
1597
					$out .= "\t\t\t'{$associations['belongsTo'][$i]['alias']}' =>\n";
1598
					$out .= "\t\t\t\tarray('className' => '{$associations['belongsTo'][$i]['className']}',\n";
1599
					$out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['belongsTo'][$i]['foreignKey']}',\n";
1600
					$out .= "\t\t\t\t\t\t'conditions' => '',\n";
1601
					$out .= "\t\t\t\t\t\t'fields' => '',\n";
1602
					$out .= "\t\t\t\t\t\t'order' => '',\n";
1603
					$out .= "\t\t\t\t\t\t'counterCache' => ''\n";
1604
					$out .= "\t\t\t\t),\n\n";
1605
				}
1606
				$out .= "\t);\n\n";
1607
			}
1608

    
1609
			if(!empty($associations['hasOne'])) {
1610
				$out .= "\tvar \$hasOne = array(\n";
1611

    
1612
				for($i = 0; $i < count($associations['hasOne']); $i++) {
1613
					$out .= "\t\t\t'{$associations['hasOne'][$i]['alias']}' =>\n";
1614
					$out .= "\t\t\t\tarray('className' => '{$associations['hasOne'][$i]['className']}',\n";
1615
					$out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasOne'][$i]['foreignKey']}',\n";
1616
					$out .= "\t\t\t\t\t\t'conditions' => '',\n";
1617
					$out .= "\t\t\t\t\t\t'fields' => '',\n";
1618
					$out .= "\t\t\t\t\t\t'order' => '',\n";
1619
					$out .= "\t\t\t\t\t\t'dependent' => ''\n";
1620
					$out .= "\t\t\t\t),\n\n";
1621
				}
1622
				$out .= "\t);\n\n";
1623
			}
1624

    
1625
			if(!empty($associations['hasMany'])) {
1626
				$out .= "\tvar \$hasMany = array(\n";
1627

    
1628
				for($i = 0; $i < count($associations['hasMany']); $i++) {
1629
					$out .= "\t\t\t'{$associations['hasMany'][$i]['alias']}' =>\n";
1630
					$out .= "\t\t\t\tarray('className' => '{$associations['hasMany'][$i]['className']}',\n";
1631
					$out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasMany'][$i]['foreignKey']}',\n";
1632
					$out .= "\t\t\t\t\t\t'conditions' => '',\n";
1633
					$out .= "\t\t\t\t\t\t'fields' => '',\n";
1634
					$out .= "\t\t\t\t\t\t'order' => '',\n";
1635
					$out .= "\t\t\t\t\t\t'limit' => '',\n";
1636
					$out .= "\t\t\t\t\t\t'offset' => '',\n";
1637
					$out .= "\t\t\t\t\t\t'dependent' => '',\n";
1638
					$out .= "\t\t\t\t\t\t'exclusive' => '',\n";
1639
					$out .= "\t\t\t\t\t\t'finderQuery' => '',\n";
1640
					$out .= "\t\t\t\t\t\t'counterQuery' => ''\n";
1641
					$out .= "\t\t\t\t),\n\n";
1642
				}
1643
				$out .= "\t);\n\n";
1644
			}
1645

    
1646
			if(!empty($associations['hasAndBelongsToMany'])) {
1647
				$out .= "\tvar \$hasAndBelongsToMany = array(\n";
1648

    
1649
				for($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
1650
					$out .= "\t\t\t'{$associations['hasAndBelongsToMany'][$i]['alias']}' =>\n";
1651
					$out .= "\t\t\t\tarray('className' => '{$associations['hasAndBelongsToMany'][$i]['className']}',\n";
1652
					$out .= "\t\t\t\t\t\t'joinTable' => '{$associations['hasAndBelongsToMany'][$i]['joinTable']}',\n";
1653
					$out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasAndBelongsToMany'][$i]['foreignKey']}',\n";
1654
					$out .= "\t\t\t\t\t\t'associationForeignKey' => '{$associations['hasAndBelongsToMany'][$i]['associationForeignKey']}',\n";
1655
					$out .= "\t\t\t\t\t\t'conditions' => '',\n";
1656
					$out .= "\t\t\t\t\t\t'fields' => '',\n";
1657
					$out .= "\t\t\t\t\t\t'order' => '',\n";
1658
					$out .= "\t\t\t\t\t\t'limit' => '',\n";
1659
					$out .= "\t\t\t\t\t\t'offset' => '',\n";
1660
					$out .= "\t\t\t\t\t\t'unique' => '',\n";
1661
					$out .= "\t\t\t\t\t\t'finderQuery' => '',\n";
1662
					$out .= "\t\t\t\t\t\t'deleteQuery' => '',\n";
1663
					$out .= "\t\t\t\t\t\t'insertQuery' => ''\n";
1664
					$out .= "\t\t\t\t),\n\n";
1665
				}
1666
				$out .= "\t);\n\n";
1667
			}
1668
		}
1669
		$out .= "}\n";
1670
		$out .= "?>";
1671
		$filename = MODELS.Inflector::underscore($name) . '.php';
1672
		$this->__createFile($filename, $out);
1673
	}
1674
/**
1675
 * Assembles and writes a View file.
1676
 *
1677
 * @param string $controllerName
1678
 * @param string $actionName
1679
 * @param string $content
1680
 */
1681
	function bakeView($controllerName, $actionName, $content = '') {
1682
		$out = "<h2>{$actionName}</h2>\n";
1683
		$out .= $content;
1684
		if(!file_exists(VIEWS.$this->__controllerPath($controllerName))) {
1685
			mkdir(VIEWS.$this->__controllerPath($controllerName));
1686
		}
1687
		$filename = VIEWS . $this->__controllerPath($controllerName) . DS . Inflector::underscore($actionName) . '.thtml';
1688
		$this->__createFile($filename, $out);
1689
	}
1690
/**
1691
 * Assembles and writes a Controller file.
1692
 *
1693
 * @param string $controllerName
1694
 * @param array $uses
1695
 * @param array $helpers
1696
 * @param array $components
1697
 * @param string $actions
1698
 */
1699
	function bakeController($controllerName, $uses, $helpers, $components, $actions = '', $wannaUseScaffold = 'y') {
1700
		$out = "<?php\n";
1701
		$out .= "class $controllerName" . "Controller extends AppController {\n\n";
1702
		$out .= "\tvar \$name = '$controllerName';\n";
1703
		if(low($wannaUseScaffold) == 'y' || low($wannaUseScaffold) == 'yes') {
1704
		$out .= "\tvar \$scaffold;\n";
1705
		} else {
1706

    
1707
			if (count($uses)) {
1708
				$out .= "\tvar \$uses = array('" . $this->__modelName($controllerName) . "', ";
1709

    
1710
				foreach($uses as $use) {
1711
					if ($use != $uses[count($uses) - 1]) {
1712
						$out .= "'" . $this->__modelName($use) . "', ";
1713
					} else {
1714
						$out .= "'" . $this->__modelName($use) . "'";
1715
					}
1716
				}
1717
				$out .= ");\n";
1718
			}
1719

    
1720
				$out .= "\tvar \$helpers = array('Html', 'Form' ";
1721
				if (count($helpers)) {
1722
					foreach($helpers as $help) {
1723
						if ($help != $helpers[count($helpers) - 1]) {
1724
							$out .= ", '" . Inflector::camelize($help) . "'";
1725
						} else {
1726
							$out .= ", '" . Inflector::camelize($help) . "'";
1727
						}
1728
					}
1729
				}
1730
				$out .= ");\n";
1731

    
1732
			if (count($components)) {
1733
				$out .= "\tvar \$components = array(";
1734

    
1735
				foreach($components as $comp) {
1736
					if ($comp != $components[count($components) - 1]) {
1737
						$out .= "'" . Inflector::camelize($comp) . "', ";
1738
					} else {
1739
						$out .= "'" . Inflector::camelize($comp) . "'";
1740
					}
1741
				}
1742
				$out .= ");\n";
1743
			}
1744
		}
1745
		$out .= $actions;
1746
		$out .= "}\n";
1747
		$out .= "?>";
1748
		$filename = CONTROLLERS . $this->__controllerPath($controllerName) . '_controller.php';
1749
		$this->__createFile($filename, $out);
1750
	}
1751
/**
1752
 * Assembles and writes a unit test file.
1753
 *
1754
 * @param string $type One of "model", and "controller".
1755
 * @param string $className
1756
 */
1757
	function bakeUnitTest($type, $className) {
1758
		$out = '<?php '."\n\n";
1759
		$error = false;
1760
		switch ($type) {
1761
			case 'model':
1762
				$out .= "loadModel('$className');\n\n";
1763
				$out .= "class {$className}TestCase extends UnitTestCase {\n";
1764
				$out .= "\tvar \$object = null;\n\n";
1765
				$out .= "\tfunction setUp() {\n\t\t\$this->object = new {$className}();\n";
1766
				$out .= "\t}\n\n\tfunction tearDown() {\n\t\tunset(\$this->object);\n\t}\n";
1767
				$out .= "\n\t/*\n\tfunction testMe() {\n";
1768
				$out .= "\t\t\$result = \$this->object->doSomething();\n";
1769
				$out .= "\t\t\$expected = 1;\n";
1770
				$out .= "\t\t\$this->assertEqual(\$result, \$expected);\n\t}\n\t*/\n}";
1771
				$path = MODEL_TESTS;
1772
				$filename = $this->__singularName($className).'.test.php';
1773
			break;
1774
			case 'controller':
1775
				$out .= "loadController('$className');\n\n";
1776
				$out .= "class {$className}ControllerTestCase extends UnitTestCase {\n";
1777
				$out .= "\tvar \$object = null;\n\n";
1778
				$out .= "\tfunction setUp() {\n\t\t\$this->object = new {$className}Controller();\n";
1779
				$out .= "\t}\n\n\tfunction tearDown() {\n\t\tunset(\$this->object);\n\t}\n";
1780
				$out .= "\n\t/*\n\tfunction testMe() {\n";
1781
				$out .= "\t\t\$result = \$this->object->doSomething();\n";
1782
				$out .= "\t\t\$expected = 1;\n";
1783
				$out .= "\t\t\$this->assertEqual(\$result, \$expected);\n\t}\n\t*/\n}";
1784
				$path = CONTROLLER_TESTS;
1785
				$filename = $this->__pluralName($className).'_controller.test.php';
1786
			break;
1787
			default:
1788
				$error = true;
1789
			break;
1790
		}
1791
		$out .= "\n?>";
1792

    
1793
		if (!$error) {
1794
			$this->stdout("Baking unit test for $className...");
1795
			$path = explode(DS, $path);
1796
			foreach($path as $i => $val) {
1797
				if ($val == '' || $val == '../') {
1798
					unset($path[$i]);
1799
				}
1800
			}
1801
			$path = implode(DS, $path);
1802
			$unixPath = DS;
1803
			if (strpos(PHP_OS, 'WIN') === 0){
1804
				$unixPath = null;
1805
			}
1806
			if (!is_dir($unixPath.$path)) {
1807
				$create = $this->getInput("Unit test directory does not exist.  Create it?", array('y','n'), 'y');
1808
				if (low($create) == 'y' || low($create) == 'yes') {
1809
					$build = array();
1810

    
1811
					foreach(explode(DS, $path) as $i => $dir) {
1812
						$build[] = $dir;
1813
						if (!is_dir($unixPath.implode(DS, $build))) {
1814
							mkdir($unixPath.implode(DS, $build));
1815
						}
1816
					}
1817
				} else {
1818
					return false;
1819
				}
1820
			}
1821
			$this->__createFile($unixPath.$path.DS.$filename, $out);
1822
		}
1823
	}
1824
/**
1825
 * Prompts the user for input, and returns it.
1826
 *
1827
 * @param string $prompt Prompt text.
1828
 * @param mixed $options Array or string of options.
1829
 * @param string $default Default input value.
1830
 * @return Either the default value, or the user-provided input.
1831
 */
1832
	function getInput($prompt, $options = null, $default = null) {
1833
		if (!is_array($options)) {
1834
			$print_options = '';
1835
		} else {
1836
			$print_options = '(' . implode('/', $options) . ')';
1837
		}
1838

    
1839
		if($default == null) {
1840
			$this->stdout('');
1841
			$this->stdout($prompt . " $print_options \n" . '> ', false);
1842
		} else {
1843
			$this->stdout('');
1844
			$this->stdout($prompt . " $print_options \n" . "[$default] > ", false);
1845
		}
1846
		$result = trim(fgets($this->stdin));
1847

    
1848
		if($default != null && empty($result)) {
1849
			return $default;
1850
		} else {
1851
			return $result;
1852
		}
1853
	}
1854
/**
1855
 * Outputs to the stdout filehandle.
1856
 *
1857
 * @param string $string String to output.
1858
 * @param boolean $newline If true, the outputs gets an added newline.
1859
 */
1860
	function stdout($string, $newline = true) {
1861
		if ($newline) {
1862
			fwrite($this->stdout, $string . "\n");
1863
		} else {
1864
			fwrite($this->stdout, $string);
1865
		}
1866
	}
1867
/**
1868
 * Outputs to the stderr filehandle.
1869
 *
1870
 * @param string $string Error text to output.
1871
 */
1872
	function stderr($string) {
1873
		fwrite($this->stderr, $string, true);
1874
	}
1875
/**
1876
 * Outputs a series of minus characters to the standard output, acts as a visual separator.
1877
 *
1878
 */
1879
	function hr() {
1880
		$this->stdout('---------------------------------------------------------------');
1881
	}
1882
/**
1883
 * Creates a file at given path.
1884
 *
1885
 * @param string $path		Where to put the file.
1886
 * @param string $contents Content to put in the file.
1887
 * @return Success
1888
 */
1889
	function __createFile ($path, $contents) {
1890
		$path = str_replace('//', '/', $path);
1891
		echo "\nCreating file $path\n";
1892
		if (is_file($path) && $this->interactive === true) {
1893
			fwrite($this->stdout, __("File exists, overwrite?", true). " {$path} (y/n/q):");
1894
			$key = trim(fgets($this->stdin));
1895

    
1896
			if ($key=='q') {
1897
				fwrite($this->stdout, __("Quitting.", true) ."\n");
1898
				exit;
1899
			} elseif ($key == 'a') {
1900
				$this->dont_ask = true;
1901
			} elseif ($key == 'y') {
1902
			} else {
1903
				fwrite($this->stdout, __("Skip", true) ." {$path}\n");
1904
				return false;
1905
			}
1906
		}
1907

    
1908
		if ($f = fopen($path, 'w')) {
1909
			fwrite($f, $contents);
1910
			fclose($f);
1911
			fwrite($this->stdout, __("Wrote", true) ."{$path}\n");
1912
			return true;
1913
		} else {
1914
			fwrite($this->stderr, __("Error! Could not write to", true)." {$path}.\n");
1915
			return false;
1916
		}
1917
	}
1918
/**
1919
 * Takes an array of database fields, and generates an HTML form for a View.
1920
 * This is an extraction from the Scaffold functionality.
1921
 *
1922
 * @param array $fields
1923
 * @param boolean $readOnly
1924
 * @return Generated HTML and PHP.
1925
 */
1926
	function generateFields( $fields, $readOnly = false ) {
1927
		$strFormFields = '';
1928
		foreach( $fields as $field ) {
1929
			if(isset( $field['type'])) {
1930
				if(!isset($field['required'])) {
1931
					$field['required'] = false;
1932
				}
1933

    
1934
				if(!isset( $field['errorMsg'])) {
1935
					$field['errorMsg'] = null;
1936
				}
1937

    
1938
				if(!isset( $field['htmlOptions'])) {
1939
					$field['htmlOptions'] = array();
1940
				}
1941

    
1942
				if( $readOnly ) {
1943
					$field['htmlOptions']['READONLY'] = "readonly";
1944
				}
1945

    
1946
				switch( $field['type'] ) {
1947
					case "input" :
1948
						if(!isset( $field['size'])) {
1949
							$field['size'] = 60;
1950
						}
1951
						$strFormFields = $strFormFields.$this->generateInputDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['size'], $field['htmlOptions'] );
1952
					break;
1953
					case "checkbox" :
1954
						$strFormFields = $strFormFields.$this->generateCheckboxDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['htmlOptions'] );
1955
					break;
1956
					case "select";
1957
					case "selectMultiple";
1958
						if( "selectMultiple" == $field['type'] ) {
1959
							$field['selectAttr']['multiple'] = 'multiple';
1960
							$field['selectAttr']['class'] = 'selectMultiple';
1961
						}
1962
						if(!isset( $field['selected'])) {
1963
							$field['selected'] = null;
1964
						}
1965
						if(!isset( $field['selectAttr'])) {
1966
							$field['selectAttr'] = null;
1967
						}
1968
						if(!isset( $field['optionsAttr'])) {
1969
							$field['optionsAttr'] = null;
1970
						}
1971
						if($readOnly) {
1972
							$field['selectAttr']['DISABLED'] = true;
1973
						}
1974
						if(!isset( $field['options'])) {
1975
							$field['options'] = null;
1976
						}
1977
						$this->__modelAlias = null;
1978
						if(isset($field['foreignKey'])) {
1979
							$modelKey = Inflector::underscore($this->__modelClass);
1980
							$modelObj =& ClassRegistry::getObject($modelKey);
1981
							foreach($modelObj->belongsTo as $associationName => $value) {
1982
								if($field['model'] == $value['className']) {
1983
									$this->__modelAlias = $this->__modelName($associationName);
1984
									break;
1985
								}
1986
							}
1987
						}
1988
						$strFormFields = $strFormFields.$this->generateSelectDiv( $field['tagName'], $field['prompt'], $field['options'], $field['selected'], $field['selectAttr'], $field['optionsAttr'], $field['required'], $field['errorMsg'] );
1989
					break;
1990
					case "area";
1991
						if(!isset( $field['rows'])) {
1992
							$field['rows'] = 10;
1993
						}
1994
						if(!isset( $field['cols'])) {
1995
							$field['cols'] = 60;
1996
						}
1997
						$strFormFields = $strFormFields.$this->generateAreaDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['cols'], $field['rows'], $field['htmlOptions'] );
1998
					break;
1999
					case "fieldset";
2000
						$strFieldsetFields = $this->generateFields( $field['fields'] );
2001
						$strFieldSet = sprintf( '
2002
						<fieldset><legend>%s</legend><div class="notes"><h4>%s</h4><p class="last">%s</p></div>%s</fieldset>',
2003
						$field['legend'], $field['noteHeading'], $field['note'], $strFieldsetFields );
2004
						$strFormFields = $strFormFields.$strFieldSet;
2005
					break;
2006
					case "hidden";
2007
						//$strFormFields = $strFormFields . $this->Html->hiddenTag( $field['tagName']);
2008
					break;
2009
					case "date":
2010
						if (!isset($field['selected'])) {
2011
							$field['selected'] = null;
2012
						}
2013
						$strFormFields = $strFormFields . $this->generateDate($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
2014
					break;
2015
					case "datetime":
2016
						if (!isset($field['selected'])) {
2017
							$field['selected'] = null;
2018
						}
2019
						$strFormFields = $strFormFields . $this->generateDateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
2020
					break;
2021
					case "time":
2022
						if (!isset($field['selected'])) {
2023
							$field['selected'] = null;
2024
						}
2025
						$strFormFields = $strFormFields . $this->generateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
2026
					break;
2027
					default:
2028
					break;
2029
				}
2030
			}
2031
		}
2032
		return $strFormFields;
2033
	}
2034
/**
2035
 * Generates PHP code for a View file that makes a textarea.
2036
 *
2037
 * @param string $tagName
2038
 * @param string $prompt
2039
 * @param boolean $required
2040
 * @param string $errorMsg
2041
 * @param integer $cols
2042
 * @param integer $rows
2043
 * @param array $htmlOptions
2044
 * @return Generated HTML and PHP.
2045
 */
2046
	function generateAreaDiv($tagName, $prompt, $required=false, $errorMsg=null, $cols=60, $rows=10,  $htmlOptions=null ) {
2047
		$htmlAttributes = $htmlOptions;
2048
		$htmlAttributes['cols'] = $cols;
2049
		$htmlAttributes['rows'] = $rows;
2050
		$str = "\t<?php echo \$html->textarea('{$tagName}', " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
2051
		$str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please enter the {$prompt}.');?>\n";
2052
		$strLabel = "\n\t<?php echo \$form->labelTag( '{$tagName}', '{$prompt}' );?>\n";
2053
		$divClass = "optional";
2054

    
2055
		if( $required ) {
2056
			$divClass = "required";
2057
		}
2058
		$strError = "";// initialize the error to empty.
2059
		$divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
2060
		return $this->divTag( $divClass, $divTagInside );
2061
	}
2062
/**
2063
 * Generates PHP code for a View file that makes a checkbox, wrapped in a DIV.
2064
 *
2065
 * @param string $tagName
2066
 * @param string $prompt
2067
 * @param boolean $required
2068
 * @param string $errorMsg
2069
 * @param array $htmlOptions
2070
 * @return Generated HTML and PHP.
2071
 */
2072
	function generateCheckboxDiv($tagName, $prompt, $required=false, $errorMsg=null, $htmlOptions=null ) {
2073
		$htmlAttributes = $htmlOptions;
2074
		$strLabel = "\n\t<?php echo \$html->checkbox('{$tagName}', null, " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
2075
		$strLabel .= "\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
2076
		$str = "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please check the {$prompt}.');?>\n";
2077
		$divClass = "optional";
2078

    
2079
		if($required) {
2080
			$divClass = "required";
2081
		}
2082
		$strError = "";// initialize the error to empty.
2083
		$divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str);
2084
		return $this->divTag( $divClass, $divTagInside );
2085
	}
2086
/**
2087
 * Generates PHP code for a View file that makes a date-picker, wrapped in a DIV.
2088
 *
2089
 * @param string $tagName
2090
 * @param string $prompt
2091
 * @param boolean $required
2092
 * @param string $errorMsg
2093
 * @param integer $size
2094
 * @param array $htmlOptions
2095
 * @param string $selected
2096
 * @return Generated HTML and PHP.
2097
 */
2098
	function generateDate($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null, $selected=null ) {
2099
		$str = "\t<?php echo \$html->dateTimeOptionTag('{$tagName}', 'MDY' , 'NONE', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
2100
		$str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
2101
		$strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
2102
		$divClass = "optional";
2103

    
2104
		if($required) {
2105
			$divClass = "required";
2106
		}
2107
		$strError = "";// initialize the error to empty.
2108
		$divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
2109
		return $this->divTag( $divClass, $divTagInside );
2110
	}
2111
/**
2112
 * Generates PHP code for a View file that makes a time-picker, wrapped in a DIV.
2113
 *
2114
 * @param string $tagName
2115
 * @param string $prompt
2116
 * @param boolean $required
2117
 * @param string $errorMsg
2118
 * @param integer $size
2119
 * @param array $htmlOptions
2120
 * @param string $selected
2121
 * @return Generated HTML and PHP.
2122
 */
2123
	function generateTime($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
2124
		$str = "\n\t\<?php echo \$html->dateTimeOptionTag('{$tagName}', 'NONE', '24', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
2125
		$strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
2126
		$divClass = "optional";
2127
		if ($required) {
2128
			$divClass = "required";
2129
		}
2130
		$strError = "";
2131
		$divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
2132
		return $this->divTag($divClass, $divTagInside);
2133
	}
2134
/**
2135
 * EGenerates PHP code for a View file that makes a datetime-picker, wrapped in a DIV.
2136
 *
2137
 * @param string $tagName
2138
 * @param string $prompt
2139
 * @param boolean $required
2140
 * @param string $errorMsg
2141
 * @param integer $size
2142
 * @param array $htmlOptions
2143
 * @param string $selected
2144
 * @return Generated HTML and PHP.
2145
 */
2146
	function generateDateTime($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null, $selected = null ) {
2147
		$str = "\t<?php echo \$html->dateTimeOptionTag('{$tagName}', 'MDY' , '12', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
2148
		$str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
2149
		$strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
2150
		$divClass = "optional";
2151

    
2152
		if($required) {
2153
			$divClass = "required";
2154
		}
2155
		$strError = "";// initialize the error to empty.
2156
		$divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
2157
		return $this->divTag( $divClass, $divTagInside );
2158
	}
2159
/**
2160
 * Generates PHP code for a View file that makes an INPUT field, wrapped in a DIV.
2161
 *
2162
 * @param string $tagName
2163
 * @param string $prompt
2164
 * @param boolean $required
2165
 * @param string $errorMsg
2166
 * @param integer $size
2167
 * @param array $htmlOptions
2168
 * @return Generated HTML and PHP.
2169
 */
2170
	function generateInputDiv($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null ) {
2171
		$htmlAttributes = $htmlOptions;
2172
		$htmlAttributes['size'] = $size;
2173
		$str = "\t<?php echo \$html->input('{$tagName}', " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
2174
		$str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please enter the {$prompt}.');?>\n";
2175
		 $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
2176
		$divClass = "optional";
2177

    
2178
		if($required) {
2179
			$divClass = "required";
2180
		}
2181
		$strError = "";// initialize the error to empty.
2182
		$divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
2183
		return $this->divTag( $divClass, $divTagInside );
2184
	}
2185

    
2186
/**
2187
 * Generates PHP code for a View file that makes a SELECT box, wrapped in a DIV.
2188
 *
2189
 * @param string $tagName
2190
 * @param string $prompt
2191
 * @param array $options
2192
 * @param string $selected
2193
 * @param array $selectAttr
2194
 * @param array $optionAttr
2195
 * @param boolean $required
2196
 * @param string $errorMsg
2197
 * @return Generated HTML and PHP.
2198
 */
2199
	function generateSelectDiv($tagName, $prompt, $options, $selected=null, $selectAttr=null, $optionAttr=null, $required=false,  $errorMsg=null) {
2200

    
2201
		if($this->__modelAlias) {
2202
			$pluralName = $this->__pluralName($this->__modelAlias);
2203
		} else {
2204
			$tagArray = explode('/', $tagName);
2205
			$pluralName = $this->__pluralName($this->__modelNameFromKey($tagArray[1]));
2206
		}
2207
		$showEmpty = 'true';
2208
		if($required) {
2209
			$showEmpty = 'false';
2210
		}
2211
		if($selectAttr['multiple'] != 'multiple') {
2212
			$str = "\t<?php echo \$html->selectTag('{$tagName}', " . "\${$pluralName}, \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($selectAttr) . ", " . $this->__attributesToArray($optionAttr) . ", " . $showEmpty . ");?>\n";
2213
			$str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.') ?>\n";
2214
		} else {
2215
			$selectedPluralName = 'selected' . ucfirst($pluralName);
2216
			$selectAttr = am(array('multiple' => 'multiple', 'class' => 'selectMultiple'), $selectAttr);
2217
			$str = "\t<?php echo \$html->selectTag('{$tagName}', \${$pluralName}, \${$selectedPluralName}, " . $this->__attributesToArray($selectAttr) . ", " . $this->__attributesToArray($optionAttr) . ", " . $showEmpty . ");?>\n";
2218
			$str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
2219
		}
2220
		$strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
2221
		$divClass = "optional";
2222

    
2223
		if($required) {
2224
			$divClass = "required";
2225
		}
2226
		$strError = "";// initialize the error to empty.
2227
		$divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
2228
		return $this->divTag( $divClass, $divTagInside );
2229
	}
2230
/**
2231
 * Generates PHP code for a View file that makes a submit button, wrapped in a DIV.
2232
 *
2233
 * @param string $displayText
2234
 * @param array $htmlOptions
2235
 * @return Generated HTML.
2236
 */
2237
	function generateSubmitDiv($displayText, $htmlOptions = null) {
2238
		$str = "\n\t<?php echo \$html->submit('{$displayText}');?>\n";
2239
		$divTagInside = sprintf( "%s", $str );
2240
		return $this->divTag( 'submit', $divTagInside);
2241
	}
2242
/**
2243
 * Returns the text wrapped in an HTML DIV, followed by a newline.
2244
 *
2245
 * @param string $class
2246
 * @param string $text
2247
 * @return Generated HTML.
2248
 */
2249
	function divTag($class, $text) {
2250
		return sprintf('<div class="%s">%s</div>', $class, $text ) . "\n";
2251
	}
2252
/**
2253
 * Parses the HTML attributes array, which is a common data structure in View files.
2254
 * Returns PHP code for initializing this array in a View file.
2255
 *
2256
 * @param array $htmlAttributes
2257
 * @return Generated PHP code.
2258
 */
2259
	function __attributesToArray($htmlAttributes) {
2260
		if (is_array($htmlAttributes)) {
2261
			$keys = array_keys($htmlAttributes);
2262
			$vals = array_values($htmlAttributes);
2263
			$out = "array(";
2264

    
2265
			for($i = 0; $i < count($htmlAttributes); $i++) {
2266
				//don't put vars in quotes
2267
				if(substr($vals[$i], 0, 1) != '$') {
2268
					$out .= "'{$keys[$i]}' => '{$vals[$i]}', ";
2269
				} else {
2270
					$out .= "'{$keys[$i]}' => {$vals[$i]}, ";
2271
				}
2272
			}
2273
			//Chop off last comma
2274
			if(substr($out, -2, 1) == ',') {
2275
				$out = substr($out, 0, strlen($out) - 2);
2276
			}
2277
			$out .= ")";
2278
			return $out;
2279
		} else {
2280
			return 'array()';
2281
		}
2282
	}
2283
/**
2284
 * Outputs usage text on the standard output.
2285
 *
2286
 */
2287
	function help() {
2288
		$this->stdout('CakePHP Bake:');
2289
		$this->hr();
2290
		$this->stdout('The Bake script generates controllers, views and models for your application.');
2291
		$this->stdout('If run with no command line arguments, Bake guides the user through the class');
2292
		$this->stdout('creation process. You can customize the generation process by telling Bake');
2293
		$this->stdout('where different parts of your application are using command line arguments.');
2294
		$this->stdout('');
2295
		$this->hr('');
2296
		$this->stdout('usage: php bake.php [command] [path...]');
2297
		$this->stdout('');
2298
		$this->stdout('commands:');
2299
		$this->stdout('   -app [path...] Absolute path to Cake\'s app Folder.');
2300
		$this->stdout('   -core [path...] Absolute path to Cake\'s cake Folder.');
2301
		$this->stdout('   -help Shows this help message.');
2302
		$this->stdout('   -project [path...]  Generates a new app folder in the path supplied.');
2303
		$this->stdout('   -root [path...] Absolute path to Cake\'s \app\webroot Folder.');
2304
		$this->stdout('');
2305
	}
2306
/**
2307
 * Checks that given project path does not already exist, and
2308
 * finds the app directory in it. Then it calls __buildDirLayout() with that information.
2309
 *
2310
 * @param string $projectPath
2311
 */
2312
	function project($projectPath = null) {
2313
		if($projectPath != '') {
2314
			while ($this->__checkPath($projectPath) === true) {
2315
				$response = $this->getInput('Bake -app in '.$projectPath, array('y','n'), 'y');
2316
				if(low($response) == 'y') {
2317
					$this->main();
2318
				} else {
2319
					$projectPath = $this->getInput("What is the full path for this app including the app directory name?\nExample: ".ROOT.DS."myapp", null, ROOT.DS.'myapp');
2320
				}
2321
			}
2322
		} else {
2323
			while ($projectPath == '') {
2324
				$projectPath = $this->getInput("What is the full path for this app including the app directory name?\nExample: ".ROOT.DS."myapp", null, ROOT.DS.'myapp');
2325

    
2326
				if ($projectPath == '') {
2327
					$this->stdout('The directory path you supplied was empty. Please try again.');
2328
				}
2329
			}
2330
		}
2331
		while ($this->__checkPath($projectPath) === true || $projectPath == '') {
2332
				$projectPath = $this->getInput('Directory '.$projectPath.'  exists please choose another:');
2333
			while ($projectPath == '') {
2334
				$projectPath = $this->getInput('The directory path you supplied was empty. Please try again.');
2335
			}
2336
		}
2337
		$parentPath = explode(DS, $projectPath);
2338
		$count = count($parentPath);
2339
		$appName = $parentPath[$count - 1];
2340
		if($appName == '') {
2341
			$appName = $parentPath[$count - 2];
2342
		}
2343
		$this->__buildDirLayout($projectPath, $appName);
2344
		exit();
2345
	}
2346
/**
2347
 * Returns true if given path is a directory.
2348
 *
2349
 * @param string $projectPath
2350
 * @return True if given path is a directory.
2351
 */
2352
	function __checkPath($projectPath) {
2353
		if(is_dir($projectPath)) {
2354
			return true;
2355
		} else {
2356
			return false;
2357
		}
2358
	}
2359
/**
2360
 * Looks for a skeleton template of a Cake application,
2361
 * and if not found asks the user for a path. When there is a path
2362
 * this method will make a deep copy of the skeleton to the project directory.
2363
 * A default home page will be added, and the tmp file storage will be chmod'ed to 0777.
2364
 *
2365
 * @param string $projectPath
2366
 * @param string $appName
2367
 */
2368
	function __buildDirLayout($projectPath, $appName) {
2369
		$skel = '';
2370
		if($this->__checkPath(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'skel') === true) {
2371
			$skel = CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'skel';
2372
		} else {
2373

    
2374
			while ($skel == '') {
2375
				$skel = $this->getInput("What is the full path for the cake install app directory?\nExample: ", null, ROOT.'myapp'.DS);
2376

    
2377
				if ($skel == '') {
2378
					$this->stdout('The directory path you supplied was empty. Please try again.');
2379
				} else {
2380
					while ($this->__checkPath($skel) === false) {
2381
						$skel = $this->getInput('Directory path does not exist please choose another:');
2382
					}
2383
				}
2384
			}
2385
		}
2386
		$this->stdout('');
2387
		$this->hr();
2388
		$this->stdout("Skel Directory: $skel");
2389
		$this->stdout("Will be copied to:");
2390
		$this->stdout("New App Directory: $projectPath");
2391
		$this->hr();
2392
		$looksGood = $this->getInput('Look okay?', array('y', 'n', 'q'), 'y');
2393

    
2394
		if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
2395
			$verboseOuptut = $this->getInput('Do you want verbose output?', array('y', 'n'), 'n');
2396
			$verbose = false;
2397

    
2398
			if (low($verboseOuptut) == 'y' || low($verboseOuptut) == 'yes') {
2399
				$verbose = true;
2400
			}
2401
			$this->__copydirr($skel, $projectPath, 0755, $verbose);
2402
			$this->hr();
2403
			$this->stdout('Created: '.$projectPath);
2404
			$this->hr();
2405
			$this->stdout('Creating welcome page');
2406
			$this->hr();
2407
			$this->__defaultHome($projectPath, $appName);
2408
			$this->stdout('Welcome page created');
2409
			if(chmodr($projectPath.DS.'tmp', 0777) === false) {
2410
				$this->stdout('Could not set permissions on '. $projectPath.DS.'tmp'.DS.'*');
2411
				$this->stdout('You must manually check that these directories can be wrote to by the server');
2412
			}
2413
			return;
2414
		} elseif (low($looksGood) == 'q' || low($looksGood) == 'quit') {
2415
			$this->stdout('Bake Aborted.');
2416
		} else {
2417
			$this->project();
2418
		}
2419
	}
2420
/**
2421
 * Recursive directory copy.
2422
 *
2423
 * @param string $fromDir
2424
 * @param string $toDir
2425
 * @param octal $chmod
2426
 * @param boolean	 $verbose
2427
 * @return Success.
2428
 */
2429
	function __copydirr($fromDir, $toDir, $chmod = 0755, $verbose = false) {
2430
		$errors=array();
2431
		$messages=array();
2432

    
2433
		if (!is_dir($toDir)) {
2434
			uses('folder');
2435
			$folder = new Folder();
2436
			$folder->mkdirr($toDir, 0755);
2437
		}
2438

    
2439
		if (!is_writable($toDir)) {
2440
			$errors[]='target '.$toDir.' is not writable';
2441
		}
2442

    
2443
		if (!is_dir($fromDir)) {
2444
			$errors[]='source '.$fromDir.' is not a directory';
2445
		}
2446

    
2447
		if (!empty($errors)) {
2448
			if ($verbose) {
2449
				foreach($errors as $err) {
2450
					$this->stdout('Error: '.$err);
2451
				}
2452
			}
2453
			return false;
2454
		}
2455
		$exceptions=array('.','..','.svn');
2456
		$handle = opendir($fromDir);
2457

    
2458
		while (false!==($item = readdir($handle))) {
2459
			if (!in_array($item,$exceptions)) {
2460
				$from = str_replace('//','/',$fromDir.'/'.$item);
2461
				$to = str_replace('//','/',$toDir.'/'.$item);
2462
				if (is_file($from)) {
2463
					if (@copy($from, $to)) {
2464
						chmod($to, $chmod);
2465
						touch($to, filemtime($from));
2466
						$messages[]='File copied from '.$from.' to '.$to;
2467
					} else {
2468
						$errors[]='cannot copy file from '.$from.' to '.$to;
2469
					}
2470
				}
2471

    
2472
				if (is_dir($from)) {
2473
					if (@mkdir($to)) {
2474
						chmod($to,$chmod);
2475
						$messages[]='Directory created: '.$to;
2476
					} else {
2477
						$errors[]='cannot create directory '.$to;
2478
					}
2479
					$this->__copydirr($from,$to,$chmod,$verbose);
2480
				}
2481
			}
2482
		}
2483
		closedir($handle);
2484

    
2485
		if ($verbose) {
2486
			foreach($errors as $err) {
2487
				$this->stdout('Error: '.$err);
2488
			}
2489
			foreach($messages as $msg) {
2490
				$this->stdout($msg);
2491
			}
2492
		}
2493
		return true;
2494
	}
2495

    
2496
	function __addAdminRoute($name){
2497
		$file = file_get_contents(CONFIGS.'core.php');
2498
		if (preg_match('%([/\\t\\x20]*define\\(\'CAKE_ADMIN\',[\\t\\x20\'a-z]*\\);)%', $file, $match)) {
2499
			$result = str_replace($match[0], 'define(\'CAKE_ADMIN\', \''.$name.'\');', $file);
2500

    
2501
			if(file_put_contents(CONFIGS.'core.php', $result)){
2502
				return true;
2503
			} else {
2504
				return false;
2505
			}
2506
		} else {
2507
			return false;
2508
		}
2509
	}
2510
/**
2511
 * Outputs an ASCII art banner to standard output.
2512
 *
2513
 */
2514
	function welcome()
2515
	{
2516
		$this->stdout('');
2517
		$this->stdout(' ___  __  _  _  ___  __  _  _  __      __   __  _  _  ___ ');
2518
		$this->stdout('|    |__| |_/  |__  |__] |__| |__]    |__] |__| |_/  |__ ');
2519
		$this->stdout('|___ |  | | \_ |___ |    |  | |       |__] |  | | \_ |___ ');
2520
		$this->hr();
2521
		$this->stdout('');
2522
	}
2523
/**
2524
 * Writes a file with a default home page to the project.
2525
 *
2526
 * @param string $dir
2527
 * @param string $app
2528
 */
2529
	function __defaultHome($dir, $app) {
2530
		$path = $dir.DS.'views'.DS.'pages'.DS;
2531
		include(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'views'.DS.'home.thtml');
2532
		$this->__createFile($path.'home.thtml', $output);
2533
	}
2534
/**
2535
 * creates the proper pluralize controller for the url
2536
 *
2537
 * @param string $name
2538
 * @return string $name
2539
 */
2540
	function __controllerPath($name) {
2541
		return low(Inflector::underscore($name));
2542
	}
2543
/**
2544
 * creates the proper pluralize controller class name.
2545
 *
2546
 * @param string $name
2547
 * @return string $name
2548
 */
2549
	function __controllerName($name) {
2550
		return Inflector::pluralize(Inflector::camelize($name));
2551
	}
2552
/**
2553
 * creates the proper singular model name.
2554
 *
2555
 * @param string $name
2556
 * @return string $name
2557
 */
2558
	function __modelName($name) {
2559
		return Inflector::camelize(Inflector::singularize($name));
2560
	}
2561
/**
2562
 * creates the proper singular model key for associations.
2563
 *
2564
 * @param string $name
2565
 * @return string $name
2566
 */
2567
	function __modelKey($name) {
2568
		return Inflector::underscore(Inflector::singularize($name)).'_id';
2569
	}
2570
/**
2571
 * creates the proper model name from a foreign key.
2572
 *
2573
 * @param string $key
2574
 * @return string $name
2575
 */
2576
	function __modelNameFromKey($key) {
2577
		$name = str_replace('_id', '',$key);
2578
		return $this->__modelName($name);
2579
	}
2580
/**
2581
 * creates the singular name for use in views.
2582
 *
2583
 * @param string $name
2584
 * @return string $name
2585
 */
2586
	function __singularName($name) {
2587
		return Inflector::variable(Inflector::singularize($name));
2588
	}
2589
/**
2590
 * creates the plural name for views.
2591
 *
2592
 * @param string $name
2593
 * @return string $name
2594
 */
2595
	function __pluralName($name) {
2596
		return Inflector::variable(Inflector::pluralize($name));
2597
	}
2598
/**
2599
 * creates the singular human name used in views
2600
 *
2601
 * @param string $name
2602
 * @return string $name
2603
 */
2604
	function __singularHumanName($name) {
2605
		return Inflector::humanize(Inflector::underscore(Inflector::singularize($name)));
2606
	}
2607
/**
2608
 * creates the plural humna name used in views
2609
 *
2610
 * @param string $name
2611
 * @return string $name
2612
 */
2613
	function __pluralHumanName($name) {
2614
		return Inflector::humanize(Inflector::underscore(Inflector::pluralize($name)));
2615
	}
2616
/**
2617
 * outputs the a list of possible models or controllers from database
2618
 *
2619
 * @param string $useDbConfig
2620
 * @param string $type = Models or Controllers
2621
 * @return output
2622
 */
2623
	function __doList($useDbConfig = 'default', $type = 'Models') {
2624
		$db =& ConnectionManager::getDataSource($useDbConfig);
2625
		$usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix'];
2626
		if ($usePrefix) {
2627
			$tables = array();
2628
			foreach ($db->listSources() as $table) {
2629
				if (!strncmp($table, $usePrefix, strlen($usePrefix))) {
2630
					$tables[] = substr($table, strlen($usePrefix));
2631
				}
2632
			}
2633
		} else {
2634
			$tables = $db->listSources();
2635
		}
2636
		$this->__tables = $tables;
2637
		$this->stdout('Possible '.$type.' based on your current database:');
2638
		$this->__controllerNames = array();
2639
		$this->__modelNames = array();
2640
		$count = count($tables);
2641
		for ($i = 0; $i < $count; $i++) {
2642
			if(low($type) == 'controllers') {
2643
				$this->__controllerNames[] = $this->__controllerName($tables[$i]);
2644
				$this->stdout($i + 1 . ". " . $this->__controllerNames[$i]);
2645
			} else {
2646
				$this->__modelNames[] = $this->__modelName($tables[$i]);
2647
				$this->stdout($i + 1 . ". " . $this->__modelNames[$i]);
2648
			}
2649
		}
2650
	}
2651

    
2652
}
2653
?>
(2-2/2)