Subversion-Projekte lars-tiefland.cakephp

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/* SVN FILE: $Id: console.php 7945 2008-12-19 02:16:01Z gwoo $ */
3
/**
4
 * Short description for file.
5
 *
6
 * Long description for file
7
 *
8
 * PHP versions 4 and 5
9
 *
10
 * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
11
 * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
12
 *
13
 * Licensed under The MIT License
14
 * Redistributions of files must retain the above copyright notice.
15
 *
16
 * @filesource
17
 * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
18
 * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
19
 * @package       cake
20
 * @subpackage    cake.cake.console.libs
21
 * @since         CakePHP(tm) v 1.2.0.5012
22
 * @version       $Revision: 7945 $
23
 * @modifiedby    $LastChangedBy: gwoo $
24
 * @lastmodified  $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
25
 * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
26
 */
27
/**
28
 * @package       cake
29
 * @subpackage    cake.cake.console.libs
30
 */
31
class ConsoleShell extends Shell {
32
/**
33
 * Available binding types
34
 *
35
 * @var array
36
 * @access public
37
 */
38
	var $associations = array('hasOne', 'hasMany', 'belongsTo', 'hasAndBelongsToMany');
39
/**
40
 * Chars that describe invalid commands
41
 *
42
 * @var array
43
 * @access public
44
 */
45
	var $badCommandChars = array('$', ';');
46
/**
47
 * Available models
48
 *
49
 * @var array
50
 * @access public
51
 */
52
	var $models = array();
53
/**
54
 * Override intialize of the Shell
55
 *
56
 * @access public
57
 */
58
	function initialize() {
59
		require_once CAKE . 'dispatcher.php';
60
		$this->Dispatcher = new Dispatcher();
61
		$this->models = Configure::listObjects('model');
62
		App::import('Model', $this->models);
63
 
64
		foreach ($this->models as $model) {
65
			$class = Inflector::camelize(r('.php', '', $model));
66
			$this->models[$model] = $class;
67
			$this->{$class} =& new $class();
68
		}
69
		$this->out('Model classes:');
70
		$this->out('--------------');
71
 
72
		foreach ($this->models as $model) {
73
			$this->out(" - {$model}");
74
		}
75
		$this->__loadRoutes();
76
	}
77
/**
78
 * Prints the help message
79
 *
80
 * @access public
81
 */
82
	function help() {
83
		$this->main('help');
84
	}
85
/**
86
 * Override main() to handle action
87
 *
88
 * @access public
89
 */
90
	function main($command = null) {
91
		while (true) {
92
			if (empty($command)) {
93
				$command = trim($this->in(''));
94
			}
95
 
96
			switch ($command) {
97
				case 'help':
98
					$this->out('Console help:');
99
					$this->out('-------------');
100
					$this->out('The interactive console is a tool for testing parts of your app before you commit code');
101
					$this->out('');
102
					$this->out('Model testing:');
103
					$this->out('To test model results, use the name of your model without a leading $');
104
					$this->out('e.g. Foo->find("all")');
105
					$this->out('');
106
					$this->out('To dynamically set associations, you can do the following:');
107
					$this->out("\tModelA bind <association> ModelB");
108
					$this->out("where the supported assocations are hasOne, hasMany, belongsTo, hasAndBelongsToMany");
109
					$this->out('');
110
					$this->out('To dynamically remove associations, you can do the following:');
111
					$this->out("\t ModelA unbind <association> ModelB");
112
					$this->out("where the supported associations are the same as above");
113
					$this->out('');
114
					$this->out("To save a new field in a model, you can do the following:");
115
					$this->out("\tModelA->save(array('foo' => 'bar', 'baz' => 0))");
116
					$this->out("where you are passing a hash of data to be saved in the format");
117
					$this->out("of field => value pairs");
118
					$this->out('');
119
					$this->out("To get column information for a model, use the following:");
120
					$this->out("\tModelA columns");
121
					$this->out("which returns a list of columns and their type");
122
					$this->out('');
123
					$this->out('Route testing:');
124
					$this->out('To test URLs against your app\'s route configuration, type:');
125
					$this->out("\tRoute <url>");
126
					$this->out("where url is the path to your your action plus any query parameters, minus the");
127
					$this->out("application's base path");
128
					$this->out('');
129
					$this->out('To reload your routes config (config/routes.php), do the following:');
130
					$this->out("\tRoutes reload");
131
					$this->out('');
132
					$this->out('');
133
					$this->out('To show all connected routes, do the following:');
134
					$this->out("\tRoutes show");
135
					$this->out('');
136
				break;
137
				case 'quit':
138
				case 'exit':
139
					return true;
140
				break;
141
				case 'models':
142
					$this->out('Model classes:');
143
					$this->hr();
144
					foreach ($this->models as $model) {
145
						$this->out(" - {$model}");
146
					}
147
				break;
148
				case (preg_match("/^(\w+) bind (\w+) (\w+)/", $command, $tmp) == true):
149
					foreach ($tmp as $data) {
150
						$data = strip_tags($data);
151
						$data = str_replace($this->badCommandChars, "", $data);
152
					}
153
 
154
					$modelA = $tmp[1];
155
					$association = $tmp[2];
156
					$modelB = $tmp[3];
157
 
158
					if ($this->__isValidModel($modelA) && $this->__isValidModel($modelB) && in_array($association, $this->associations)) {
159
						$this->{$modelA}->bindModel(array($association => array($modelB => array('className' => $modelB))), false);
160
						$this->out("Created $association association between $modelA and $modelB");
161
					} else {
162
						$this->out("Please verify you are using valid models and association types");
163
					}
164
				break;
165
				case (preg_match("/^(\w+) unbind (\w+) (\w+)/", $command, $tmp) == true):
166
					foreach ($tmp as $data) {
167
						$data = strip_tags($data);
168
						$data = str_replace($this->badCommandChars, "", $data);
169
					}
170
 
171
					$modelA = $tmp[1];
172
					$association = $tmp[2];
173
					$modelB = $tmp[3];
174
 
175
					// Verify that there is actually an association to unbind
176
					$currentAssociations = $this->{$modelA}->getAssociated();
177
					$validCurrentAssociation = false;
178
 
179
					foreach ($currentAssociations as $model => $currentAssociation) {
180
						if ($model == $modelB && $association == $currentAssociation) {
181
							$validCurrentAssociation = true;
182
						}
183
					}
184
 
185
					if ($this->__isValidModel($modelA) && $this->__isValidModel($modelB) && in_array($association, $this->associations) && $validCurrentAssociation) {
186
						$this->{$modelA}->unbindModel(array($association => array($modelB)));
187
						$this->out("Removed $association association between $modelA and $modelB");
188
					} else {
189
						$this->out("Please verify you are using valid models, valid current association, and valid association types");
190
					}
191
				break;
192
				case (strpos($command, "->find") > 0):
193
					// Remove any bad info
194
					$command = strip_tags($command);
195
					$command = str_replace($this->badCommandChars, "", $command);
196
 
197
					// Do we have a valid model?
198
					list($modelToCheck, $tmp) = explode('->', $command);
199
 
200
					if ($this->__isValidModel($modelToCheck)) {
201
						$findCommand = "\$data = \$this->$command;";
202
						@eval($findCommand);
203
 
204
						if (is_array($data)) {
205
							foreach ($data as $idx => $results) {
206
								if (is_numeric($idx)) { // findAll() output
207
									foreach ($results as $modelName => $result) {
208
										$this->out("$modelName");
209
 
210
										foreach ($result as $field => $value) {
211
											if (is_array($value)) {
212
												foreach ($value as $field2 => $value2) {
213
													$this->out("\t$field2: $value2");
214
												}
215
 
216
												$this->out("");
217
											} else {
218
												$this->out("\t$field: $value");
219
											}
220
										}
221
									}
222
								} else { // find() output
223
									$this->out($idx);
224
 
225
									foreach ($results as $field => $value) {
226
										if (is_array($value)) {
227
											foreach ($value as $field2 => $value2) {
228
												$this->out("\t$field2: $value2");
229
											}
230
 
231
											$this->out("");
232
										} else {
233
											$this->out("\t$field: $value");
234
										}
235
									}
236
								}
237
							}
238
						} else {
239
							$this->out("\nNo result set found");
240
						}
241
					} else {
242
						$this->out("$modelToCheck is not a valid model");
243
					}
244
 
245
				break;
246
				case (strpos($command, '->save') > 0):
247
					// Validate the model we're trying to save here
248
					$command = strip_tags($command);
249
					$command = str_replace($this->badCommandChars, "", $command);
250
					list($modelToSave, $tmp) = explode("->", $command);
251
 
252
					if ($this->__isValidModel($modelToSave)) {
253
						// Extract the array of data we are trying to build
254
						list($foo, $data) = explode("->save", $command);
255
						$badChars = array("(", ")");
256
						$data = str_replace($badChars, "", $data);
257
						$saveCommand = "\$this->{$modelToSave}->save(array('{$modelToSave}' => array({$data})));";
258
						@eval($saveCommand);
259
						$this->out('Saved record for ' . $modelToSave);
260
					}
261
				break;
262
				case (preg_match("/^(\w+) columns/", $command, $tmp) == true):
263
					$modelToCheck = strip_tags(str_replace($this->badCommandChars, "", $tmp[1]));
264
 
265
					if ($this->__isValidModel($modelToCheck)) {
266
						// Get the column info for this model
267
						$fieldsCommand = "\$data = \$this->{$modelToCheck}->getColumnTypes();";
268
						@eval($fieldsCommand);
269
 
270
						if (is_array($data)) {
271
							foreach ($data as $field => $type) {
272
								$this->out("\t{$field}: {$type}");
273
							}
274
						}
275
					} else {
276
						$this->out("Please verify that you selected a valid model");
277
					}
278
				break;
279
				case (preg_match("/^routes\s+reload/i", $command, $tmp) == true):
280
					$router =& Router::getInstance();
281
					if (!$this->__loadRoutes()) {
282
						$this->out("There was an error loading the routes config.  Please check that the file");
283
						$this->out("exists and is free of parse errors.");
284
						break;
285
					}
286
					$this->out("Routes configuration reloaded, " . count($router->routes) . " routes connected");
287
				break;
288
				case (preg_match("/^routes\s+show/i", $command, $tmp) == true):
289
					$router =& Router::getInstance();
290
					$this->out(join("\n", Set::extract($router->routes, '{n}.0')));
291
				break;
292
				case (preg_match("/^route\s+(.*)/i", $command, $tmp) == true):
293
					$this->out(var_export(Router::parse($tmp[1]), true));
294
				break;
295
				default:
296
					$this->out("Invalid command\n");
297
				break;
298
			}
299
			$command = '';
300
		}
301
	}
302
/**
303
 * Tells if the specified model is included in the list of available models
304
 *
305
 * @param string $modelToCheck
306
 * @return boolean true if is an available model, false otherwise
307
 * @access private
308
 */
309
	function __isValidModel($modelToCheck) {
310
		return in_array($modelToCheck, $this->models);
311
	}
312
/**
313
 * Reloads the routes configuration from config/routes.php, and compiles
314
 * all routes found
315
 *
316
 * @return boolean True if config reload was a success, otherwise false
317
 * @access private
318
 */
319
	function __loadRoutes() {
320
		$router =& Router::getInstance();
321
 
322
		$router->reload();
323
		extract($router->getNamedExpressions());
324
 
325
		if (!@include(CONFIGS . 'routes.php')) {
326
			return false;
327
		}
328
		$router->parse('/');
329
 
330
		foreach (array_keys($router->getNamedExpressions()) as $var) {
331
			unset(${$var});
332
		}
333
		for ($i = 0; $i < count($router->routes); $i++) {
334
			$router->compile($i);
335
		}
336
		return true;
337
	}
338
}
339
?>