00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 class ConsoleShell extends Shell {
00034
00035
00036
00037
00038
00039
00040 var $associations = array('hasOne', 'hasMany', 'belongsTo', 'hasAndBelongsToMany');
00041
00042
00043
00044
00045
00046
00047 var $badCommandChars = array('$', ';');
00048
00049
00050
00051
00052
00053
00054 var $models = array();
00055
00056
00057
00058
00059
00060 function initialize() {
00061 require_once CAKE . 'dispatcher.php';
00062 $this->Dispatcher = new Dispatcher();
00063 $this->models = Configure::listObjects('model');
00064 App::import('Model', $this->models);
00065
00066 foreach ($this->models as $model) {
00067 $class = Inflector::camelize(r('.php', '', $model));
00068 $this->models[$model] = $class;
00069 $this->{$class} =& new $class();
00070 }
00071 $this->out('Model classes:');
00072 $this->out('--------------');
00073
00074 foreach ($this->models as $model) {
00075 $this->out(" - {$model}");
00076 }
00077 }
00078
00079
00080
00081
00082
00083 function help() {
00084 $this->main('help');
00085 }
00086
00087
00088
00089
00090
00091 function main($command = null) {
00092 while (true) {
00093 if (empty($command)) {
00094 $command = trim($this->in(''));
00095 }
00096
00097 switch($command) {
00098 case 'help':
00099 $this->out('Console help:');
00100 $this->out('-------------');
00101 $this->out('The interactive console is a tool for testing parts of your app before you commit code');
00102 $this->out('');
00103 $this->out('Model testing:');
00104 $this->out('To test model results, use the name of your model without a leading $');
00105 $this->out('e.g. Foo->find("all")');
00106 $this->out('');
00107 $this->out('To dynamically set associations, you can do the following:');
00108 $this->out("\tModelA bind <association> ModelB");
00109 $this->out("where the supported assocations are hasOne, hasMany, belongsTo, hasAndBelongsToMany");
00110 $this->out('');
00111 $this->out('To dynamically remove associations, you can do the following:');
00112 $this->out("\t ModelA unbind <association> ModelB");
00113 $this->out("where the supported associations are the same as above");
00114 $this->out('');
00115 $this->out("To save a new field in a model, you can do the following:");
00116 $this->out("\tModelA->save(array('foo' => 'bar', 'baz' => 0))");
00117 $this->out("where you are passing a hash of data to be saved in the format");
00118 $this->out("of field => value pairs");
00119 $this->out('');
00120 $this->out("To get column information for a model, use the following:");
00121 $this->out("\tModelA columns");
00122 $this->out("which returns a list of columns and their type");
00123 $this->out('');
00124 $this->out('Route testing:');
00125 $this->out('To test URLs against your app\'s route configuration, type:');
00126 $this->out("\tRoute <url>");
00127 $this->out("where url is the path to your your action plus any query parameters, minus the");
00128 $this->out("application's base path");
00129 $this->out('');
00130 $this->out('To reload your routes config (config/routes.php), do the following:');
00131 $this->out("\tRoute reload");
00132 $this->out('');
00133 break;
00134 case 'quit':
00135 case 'exit':
00136 return true;
00137 break;
00138 case 'models':
00139 $this->out('Model classes:');
00140 $this->hr();
00141 foreach ($this->models as $model) {
00142 $this->out(" - {$model}");
00143 }
00144 break;
00145 case (preg_match("/^(\w+) bind (\w+) (\w+)/", $command, $tmp) == true):
00146 foreach ($tmp as $data) {
00147 $data = strip_tags($data);
00148 $data = str_replace($this->badCommandChars, "", $data);
00149 }
00150
00151 $modelA = $tmp[1];
00152 $association = $tmp[2];
00153 $modelB = $tmp[3];
00154
00155 if ($this->__isValidModel($modelA) && $this->__isValidModel($modelB) && in_array($association, $this->associations)) {
00156 $this->{$modelA}->bindModel(array($association => array($modelB => array('className' => $modelB))), false);
00157 $this->out("Created $association association between $modelA and $modelB");
00158 } else {
00159 $this->out("Please verify you are using valid models and association types");
00160 }
00161 break;
00162 case (preg_match("/^(\w+) unbind (\w+) (\w+)/", $command, $tmp) == true):
00163 foreach ($tmp as $data) {
00164 $data = strip_tags($data);
00165 $data = str_replace($this->badCommandChars, "", $data);
00166 }
00167
00168 $modelA = $tmp[1];
00169 $association = $tmp[2];
00170 $modelB = $tmp[3];
00171
00172
00173 $currentAssociations = $this->{$modelA}->getAssociated();
00174 $validCurrentAssociation = false;
00175
00176 foreach ($currentAssociations as $model => $currentAssociation) {
00177 if ($model == $modelB && $association == $currentAssociation) {
00178 $validCurrentAssociation = true;
00179 }
00180 }
00181
00182 if ($this->__isValidModel($modelA) && $this->__isValidModel($modelB) && in_array($association, $this->associations) && $validCurrentAssociation) {
00183 $this->{$modelA}->unbindModel(array($association => array($modelB)));
00184 $this->out("Removed $association association between $modelA and $modelB");
00185 } else {
00186 $this->out("Please verify you are using valid models, valid current association, and valid association types");
00187 }
00188 break;
00189 case (strpos($command, "->find") > 0):
00190
00191 $command = strip_tags($command);
00192 $command = str_replace($this->badCommandChars, "", $command);
00193
00194
00195 list($modelToCheck, $tmp) = explode('->', $command);
00196
00197 if ($this->__isValidModel($modelToCheck)) {
00198 $findCommand = "\$data = \$this->$command;";
00199 @eval($findCommand);
00200
00201 if (is_array($data)) {
00202 foreach ($data as $idx => $results) {
00203 if (is_numeric($idx)) {
00204 foreach ($results as $modelName => $result) {
00205 $this->out("$modelName");
00206
00207 foreach ($result as $field => $value) {
00208 if (is_array($value)) {
00209 foreach ($value as $field2 => $value2) {
00210 $this->out("\t$field2: $value2");
00211 }
00212
00213 $this->out("");
00214 } else {
00215 $this->out("\t$field: $value");
00216 }
00217 }
00218 }
00219 } else {
00220 $this->out($idx);
00221
00222 foreach ($results as $field => $value) {
00223 if (is_array($value)) {
00224 foreach ($value as $field2 => $value2) {
00225 $this->out("\t$field2: $value2");
00226 }
00227
00228 $this->out("");
00229 } else {
00230 $this->out("\t$field: $value");
00231 }
00232 }
00233 }
00234 }
00235 } else {
00236 $this->out("\nNo result set found");
00237 }
00238 } else {
00239 $this->out("$modelToCheck is not a valid model");
00240 }
00241
00242 break;
00243 case (strpos($command, '->save') > 0):
00244
00245 $command = strip_tags($command);
00246 $command = str_replace($this->badCommandChars, "", $command);
00247 list($modelToSave, $tmp) = explode("->", $command);
00248
00249 if ($this->__isValidModel($modelToSave)) {
00250
00251 list($foo, $data) = explode("->save", $command);
00252 $badChars = array("(", ")");
00253 $data = str_replace($badChars, "", $data);
00254 $saveCommand = "\$this->{$modelToSave}->save(array('{$modelToSave}' => array({$data})));";
00255 @eval($saveCommand);
00256 $this->out('Saved record for ' . $modelToSave);
00257 }
00258
00259 break;
00260 case (preg_match("/^(\w+) columns/", $command, $tmp) == true):
00261 $modelToCheck = strip_tags(str_replace($this->badCommandChars, "", $tmp[1]));
00262
00263 if ($this->__isValidModel($modelToCheck)) {
00264
00265 $fieldsCommand = "\$data = \$this->{$modelToCheck}->getColumnTypes();";
00266 @eval($fieldsCommand);
00267
00268 if (is_array($data)) {
00269 foreach ($data as $field => $type) {
00270 $this->out("\t{$field}: {$type}");
00271 }
00272 }
00273 } else {
00274 $this->out("Please verify that you selected a valid model");
00275 }
00276 break;
00277 case (preg_match("/^routes\s+reload/i", $command, $tmp) == true):
00278 $router =& Router::getInstance();
00279 $router->reload();
00280 if (config('routes') && $router->parse('/')) {
00281 $this->out("Routes configuration reloaded, " . count($router->routes) . " routes connected");
00282 }
00283 break;
00284 case (preg_match("/^route\s+(.*)/i", $command, $tmp) == true):
00285 $this->out(Debugger::exportVar(Router::parse($tmp[1])));
00286 break;
00287 default:
00288 $this->out("Invalid command\n");
00289 break;
00290 }
00291 $command = '';
00292 }
00293 }
00294
00295
00296
00297
00298
00299
00300
00301 function __isValidModel($modelToCheck) {
00302 return in_array($modelToCheck, $this->models);
00303 }
00304 }
00305 ?>