bake.php 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118
  1. <?php
  2. /* SVN FILE: $Id$ */
  3. /**
  4. * Command-line code generation utility to automate programmer chores.
  5. *
  6. * Bake is CakePHP's code generation script, which can help you kickstart
  7. * application development by writing fully functional skeleton controllers,
  8. * models, and views. Going further, Bake can also write Unit Tests for you.
  9. *
  10. * PHP versions 4 and 5
  11. *
  12. * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
  13. * Copyright 2005-2007, Cake Software Foundation, Inc.
  14. * 1785 E. Sahara Avenue, Suite 490-204
  15. * Las Vegas, Nevada 89104
  16. *
  17. * Licensed under The MIT License
  18. * Redistributions of files must retain the above copyright notice.
  19. *
  20. * @filesource
  21. * @copyright Copyright 2005-2007, Cake Software Foundation, Inc.
  22. * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
  23. * @package cake
  24. * @subpackage cake.cake.scripts.bake
  25. * @since CakePHP(tm) v 0.10.0.1232
  26. * @version $Revision$
  27. * @modifiedby $LastChangedBy$
  28. * @lastmodified $Date$
  29. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  30. */
  31. /**
  32. * Bake is a command-line code generation utility for automating programmer chores.
  33. *
  34. * @package cake
  35. * @subpackage cake.cake.scripts
  36. */
  37. class BakeScript extends CakeScript {
  38. /**
  39. * Associated controller name.
  40. *
  41. * @var string
  42. */
  43. var $controllerName = null;
  44. /**
  45. * If true, Bake will ask for permission to perform actions.
  46. *
  47. * @var boolean
  48. */
  49. var $interactive = false;
  50. var $__modelAlias = false;
  51. /**
  52. * Private helper function for constructor
  53. * @access private
  54. */
  55. function initialize() {
  56. $this->welcome();
  57. }
  58. /**
  59. * Main-loop method.
  60. *
  61. */
  62. function main() {
  63. $this->out('');
  64. $this->out('');
  65. $this->out('Baking...');
  66. $this->hr();
  67. $this->out('Name: '. APP_DIR);
  68. $this->out('Path: '. ROOT . DS . APP_DIR);
  69. $this->hr();
  70. if(!is_dir(CONFIGS)) {
  71. $this->project($this->params['working']);
  72. }
  73. if(!config('database')) {
  74. $this->out('');
  75. $this->out('Your database configuration was not found. Take a moment to create one:');
  76. $this->doDbConfig();
  77. }
  78. $this->out('[M]odel');
  79. $this->out('[C]ontroller');
  80. $this->out('[V]iew');
  81. $invalidSelection = true;
  82. while ($invalidSelection) {
  83. $classToBake = strtoupper($this->in('What would you like to Bake?', array('M', 'V', 'C')));
  84. switch($classToBake) {
  85. case 'M':
  86. $invalidSelection = false;
  87. $this->doModel();
  88. break;
  89. case 'V':
  90. $invalidSelection = false;
  91. $this->doView();
  92. break;
  93. case 'C':
  94. $invalidSelection = false;
  95. $this->doController();
  96. break;
  97. default:
  98. $this->out('You have made an invalid selection. Please choose a type of class to Bake by entering M, V, or C.');
  99. }
  100. }
  101. }
  102. /**
  103. * Database configuration setup.
  104. *
  105. */
  106. function doDbConfig() {
  107. $this->hr();
  108. $this->out('Database Configuration:');
  109. $this->hr();
  110. $driver = '';
  111. while ($driver == '') {
  112. $driver = $this->in('What database driver would you like to use?', array('mysql','mysqli','mssql','sqlite','postgres', 'odbc'), 'mysql');
  113. if ($driver == '') {
  114. $this->out('The database driver supplied was empty. Please supply a database driver.');
  115. }
  116. }
  117. switch($driver) {
  118. case 'mysql':
  119. $connect = 'mysql_connect';
  120. break;
  121. case 'mysqli':
  122. $connect = 'mysqli_connect';
  123. break;
  124. case 'mssql':
  125. $connect = 'mssql_connect';
  126. break;
  127. case 'sqlite':
  128. $connect = 'sqlite_open';
  129. break;
  130. case 'postgres':
  131. $connect = 'pg_connect';
  132. break;
  133. case 'odbc':
  134. $connect = 'odbc_connect';
  135. break;
  136. default:
  137. $this->out('The connection parameter could not be set.');
  138. break;
  139. }
  140. $host = '';
  141. while ($host == '') {
  142. $host = $this->in('What is the hostname for the database server?', null, 'localhost');
  143. if ($host == '') {
  144. $this->out('The host name you supplied was empty. Please supply a hostname.');
  145. }
  146. }
  147. $login = '';
  148. while ($login == '') {
  149. $login = $this->in('What is the database username?', null, 'root');
  150. if ($login == '') {
  151. $this->out('The database username you supplied was empty. Please try again.');
  152. }
  153. }
  154. $password = '';
  155. $blankPassword = false;
  156. while ($password == '' && $blankPassword == false) {
  157. $password = $this->in('What is the database password?');
  158. if ($password == '') {
  159. $blank = $this->in('The password you supplied was empty. Use an empty password?', array('y', 'n'), 'n');
  160. if($blank == 'y')
  161. {
  162. $blankPassword = true;
  163. }
  164. }
  165. }
  166. $database = '';
  167. while ($database == '') {
  168. $database = $this->in('What is the name of the database you will be using?', null, 'cake');
  169. if ($database == '') {
  170. $this->out('The database name you supplied was empty. Please try again.');
  171. }
  172. }
  173. $prefix = '';
  174. while ($prefix == '') {
  175. $prefix = $this->in('Enter a table prefix?', null, 'n');
  176. }
  177. if(low($prefix) == 'n') {
  178. $prefix = '';
  179. }
  180. $this->out('');
  181. $this->hr();
  182. $this->out('The following database configuration will be created:');
  183. $this->hr();
  184. $this->out("Driver: $driver");
  185. $this->out("Connection: $connect");
  186. $this->out("Host: $host");
  187. $this->out("User: $login");
  188. $this->out("Pass: " . str_repeat('*', strlen($password)));
  189. $this->out("Database: $database");
  190. $this->out("Table prefix: $prefix");
  191. $this->hr();
  192. $looksGood = $this->in('Look okay?', array('y', 'n'), 'y');
  193. if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
  194. $this->bakeDbConfig($driver, $connect, $host, $login, $password, $database, $prefix);
  195. } else {
  196. $this->out('Bake Aborted.');
  197. }
  198. }
  199. /**
  200. * Action to create a Model.
  201. *
  202. */
  203. function doModel()
  204. {
  205. $this->hr();
  206. $this->out('Model Bake:');
  207. $this->hr();
  208. $this->interactive = true;
  209. $useTable = null;
  210. $primaryKey = 'id';
  211. $validate = array();
  212. $associations = array();
  213. /*$usingDefault = $this->in('Will your model be using a database connection setting other than the default?');
  214. if (low($usingDefault) == 'y' || low($usingDefault) == 'yes')
  215. {
  216. $useDbConfig = $this->in('Please provide the name of the connection you wish to use.');
  217. }*/
  218. $useDbConfig = 'default';
  219. $this->__doList($useDbConfig);
  220. $enteredModel = '';
  221. while ($enteredModel == '') {
  222. $enteredModel = $this->in('Enter a number from the list above, or type in the name of another model.');
  223. if ($enteredModel == '' || intval($enteredModel) > count($this->__modelNames)) {
  224. $this->out('Error:');
  225. $this->out("The model name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
  226. $enteredModel = '';
  227. }
  228. }
  229. if (intval($enteredModel) > 0 && intval($enteredModel) <= count($this->__modelNames)) {
  230. $currentModelName = $this->__modelNames[intval($enteredModel) - 1];
  231. } else {
  232. $currentModelName = $enteredModel;
  233. }
  234. $db =& ConnectionManager::getDataSource($useDbConfig);
  235. $useTable = Inflector::tableize($currentModelName);
  236. $fullTableName = $db->fullTableName($useTable, false);
  237. if(array_search($useTable, $this->__tables) === false) {
  238. $this->out("\nGiven your model named '$currentModelName', Cake would expect a database table named '" . $fullTableName . "'.");
  239. $tableIsGood = $this->in('do you want to use this table?', array('y','n'), 'y');
  240. }
  241. if (low($tableIsGood) == 'n' || low($tableIsGood) == 'no') {
  242. $useTable = $this->in('What is the name of the table (enter "null" to use NO table)?');
  243. }
  244. $tableIsGood = false;
  245. while($tableIsGood == false && low($useTable) != 'null') {
  246. if (is_array($this->__tables) && !in_array($useTable, $this->__tables)) {
  247. $fullTableName = $db->fullTableName($useTable, false);
  248. $this->out($fullTableName . ' does not exist.');
  249. $useTable = $this->in('What is the name of the table (enter "null" to use NO table)?');
  250. $tableIsGood = false;
  251. } else {
  252. $tableIsGood = true;
  253. }
  254. }
  255. $wannaDoValidation = $this->in('Would you like to supply validation criteria for the fields in your model?', array('y','n'), 'y');
  256. if(in_array($useTable, $this->__tables)) {
  257. loadModel();
  258. $tempModel = new Model(false, $useTable);
  259. $modelFields = $db->describe($tempModel);
  260. if(isset($modelFields[0]['name']) && $modelFields[0]['name'] != 'id') {
  261. $primaryKey = $this->in('What is the primaryKey?', null, $modelFields[0]['name']);
  262. }
  263. }
  264. $validate = array();
  265. if (array_search($useTable, $this->__tables) !== false && (low($wannaDoValidation) == 'y' || low($wannaDoValidation) == 'yes')) {
  266. foreach($modelFields as $field) {
  267. $this->out('');
  268. $prompt = 'Name: ' . $field['name'] . "\n";
  269. $prompt .= 'Type: ' . $field['type'] . "\n";
  270. $prompt .= '---------------------------------------------------------------'."\n";
  271. $prompt .= 'Please select one of the following validation options:'."\n";
  272. $prompt .= '---------------------------------------------------------------'."\n";
  273. $prompt .= "1- VALID_NOT_EMPTY\n";
  274. $prompt .= "2- VALID_EMAIL\n";
  275. $prompt .= "3- VALID_NUMBER\n";
  276. $prompt .= "4- VALID_YEAR\n";
  277. $prompt .= "5- Do not do any validation on this field.\n\n";
  278. $prompt .= "... or enter in a valid regex validation string.\n\n";
  279. if($field['null'] == 1 || $field['name'] == $primaryKey || $field['name'] == 'created' || $field['name'] == 'modified') {
  280. $validation = $this->in($prompt, null, '5');
  281. } else {
  282. $validation = $this->in($prompt, null, '1');
  283. }
  284. switch ($validation) {
  285. case '1':
  286. $validate[$field['name']] = 'VALID_NOT_EMPTY';
  287. break;
  288. case '2':
  289. $validate[$field['name']] = 'VALID_EMAIL';
  290. break;
  291. case '3':
  292. $validate[$field['name']] = 'VALID_NUMBER';
  293. break;
  294. case '4':
  295. $validate[$field['name']] = 'VALID_YEAR';
  296. break;
  297. case '5':
  298. break;
  299. default:
  300. $validate[$field['name']] = $validation;
  301. break;
  302. }
  303. }
  304. }
  305. $wannaDoAssoc = $this->in('Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)?', array('y','n'), 'y');
  306. if((low($wannaDoAssoc) == 'y' || low($wannaDoAssoc) == 'yes')) {
  307. $this->out('One moment while I try to detect any associations...');
  308. $possibleKeys = array();
  309. //Look for belongsTo
  310. $i = 0;
  311. foreach($modelFields as $field) {
  312. $offset = strpos($field['name'], '_id');
  313. if($field['name'] != $primaryKey && $offset !== false) {
  314. $tmpModelName = $this->__modelNameFromKey($field['name']);
  315. $associations['belongsTo'][$i]['alias'] = $tmpModelName;
  316. $associations['belongsTo'][$i]['className'] = $tmpModelName;
  317. $associations['belongsTo'][$i]['foreignKey'] = $field['name'];
  318. $i++;
  319. }
  320. }
  321. //Look for hasOne and hasMany and hasAndBelongsToMany
  322. $i = 0;
  323. $j = 0;
  324. foreach($this->__tables as $otherTable) {
  325. $tempOtherModel = & new Model(false, $otherTable);
  326. $modelFieldsTemp = $db->describe($tempOtherModel);
  327. foreach($modelFieldsTemp as $field) {
  328. if($field['type'] == 'integer' || $field['type'] == 'string') {
  329. $possibleKeys[$otherTable][] = $field['name'];
  330. }
  331. if($field['name'] != $primaryKey && $field['name'] == $this->__modelKey($currentModelName)) {
  332. $tmpModelName = $this->__modelName($otherTable);
  333. $associations['hasOne'][$j]['alias'] = $tmpModelName;
  334. $associations['hasOne'][$j]['className'] = $tmpModelName;
  335. $associations['hasOne'][$j]['foreignKey'] = $field['name'];
  336. $associations['hasMany'][$j]['alias'] = $tmpModelName;
  337. $associations['hasMany'][$j]['className'] = $tmpModelName;
  338. $associations['hasMany'][$j]['foreignKey'] = $field['name'];
  339. $j++;
  340. }
  341. }
  342. $offset = strpos($otherTable, $useTable . '_');
  343. if($offset !== false) {
  344. $offset = strlen($useTable . '_');
  345. $tmpModelName = $this->__modelName(substr($otherTable, $offset));
  346. $associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
  347. $associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
  348. $associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->__modelKey($currentModelName);
  349. $associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->__modelKey($tmpModelName);
  350. $associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
  351. $i++;
  352. }
  353. $offset = strpos($otherTable, '_' . $useTable);
  354. if ($offset !== false) {
  355. $tmpModelName = $this->__modelName(substr($otherTable, 0, $offset));
  356. $associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
  357. $associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
  358. $associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->__modelKey($currentModelName);
  359. $associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->__modelKey($tmpModelName);
  360. $associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
  361. $i++;
  362. }
  363. }
  364. $this->out('Done.');
  365. $this->hr();
  366. //if none found...
  367. if(empty($associations)) {
  368. $this->out('None found.');
  369. } else {
  370. $this->out('Please confirm the following associations:');
  371. $this->hr();
  372. if(!empty($associations['belongsTo'])) {
  373. $count = count($associations['belongsTo']);
  374. for($i = 0; $i < $count; $i++) {
  375. if($currentModelName == $associations['belongsTo'][$i]['alias']) {
  376. $response = $this->in("{$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');
  377. if('y' == low($response) || 'yes' == low($response)) {
  378. $associations['belongsTo'][$i]['alias'] = $this->in("So what is the alias?", null, $associations['belongsTo'][$i]['alias']);
  379. }
  380. if($currentModelName != $associations['belongsTo'][$i]['alias']) {
  381. $response = $this->in("$currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}?", array('y','n'), 'y');
  382. } else {
  383. $response = 'n';
  384. }
  385. } else {
  386. $response = $this->in("$currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}?", array('y','n'), 'y');
  387. }
  388. if('n' == low($response) || 'no' == low($response)) {
  389. unset($associations['belongsTo'][$i]);
  390. }
  391. }
  392. $associations['belongsTo'] = array_merge($associations['belongsTo']);
  393. }
  394. if(!empty($associations['hasOne'])) {
  395. $count = count($associations['hasOne']);
  396. for($i = 0; $i < $count; $i++) {
  397. if($currentModelName == $associations['hasOne'][$i]['alias']) {
  398. $response = $this->in("{$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');
  399. if('y' == low($response) || 'yes' == low($response)) {
  400. $associations['hasOne'][$i]['alias'] = $this->in("So what is the alias?", null, $associations['hasOne'][$i]['alias']);
  401. }
  402. if($currentModelName != $associations['hasOne'][$i]['alias']) {
  403. $response = $this->in("$currentModelName hasOne {$associations['hasOne'][$i]['alias']}?", array('y','n'), 'y');
  404. } else {
  405. $response = 'n';
  406. }
  407. } else {
  408. $response = $this->in("$currentModelName hasOne {$associations['hasOne'][$i]['alias']}?", array('y','n'), 'y');
  409. }
  410. if('n' == low($response) || 'no' == low($response)) {
  411. unset($associations['hasOne'][$i]);
  412. }
  413. }
  414. $associations['hasOne'] = array_merge($associations['hasOne']);
  415. }
  416. if(!empty($associations['hasMany'])) {
  417. $count = count($associations['hasMany']);
  418. for($i = 0; $i < $count; $i++) {
  419. if($currentModelName == $associations['hasMany'][$i]['alias']) {
  420. $response = $this->in("{$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');
  421. if('y' == low($response) || 'yes' == low($response)) {
  422. $associations['hasMany'][$i]['alias'] = $this->in("So what is the alias?", null, $associations['hasMany'][$i]['alias']);
  423. }
  424. if($currentModelName != $associations['hasMany'][$i]['alias']) {
  425. $response = $this->in("$currentModelName hasMany {$associations['hasMany'][$i]['alias']}?", array('y','n'), 'y');
  426. } else {
  427. $response = 'n';
  428. }
  429. } else {
  430. $response = $this->in("$currentModelName hasMany {$associations['hasMany'][$i]['alias']}?", array('y','n'), 'y');
  431. }
  432. if('n' == low($response) || 'no' == low($response)) {
  433. unset($associations['hasMany'][$i]);
  434. }
  435. }
  436. $associations['hasMany'] = array_merge($associations['hasMany']);
  437. }
  438. if(!empty($associations['hasAndBelongsToMany'])) {
  439. $count = count($associations['hasAndBelongsToMany']);
  440. for($i = 0; $i < $count; $i++) {
  441. if($currentModelName == $associations['hasAndBelongsToMany'][$i]['alias']) {
  442. $response = $this->in("{$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');
  443. if('y' == low($response) || 'yes' == low($response)) {
  444. $associations['hasAndBelongsToMany'][$i]['alias'] = $this->in("So what is the alias?", null, $associations['hasAndBelongsToMany'][$i]['alias']);
  445. }
  446. if($currentModelName != $associations['hasAndBelongsToMany'][$i]['alias']) {
  447. $response = $this->in("$currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}?", array('y','n'), 'y');
  448. } else {
  449. $response = 'n';
  450. }
  451. } else {
  452. $response = $this->in("$currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}?", array('y','n'), 'y');
  453. }
  454. if('n' == low($response) || 'no' == low($response)) {
  455. unset($associations['hasAndBelongsToMany'][$i]);
  456. }
  457. }
  458. $associations['hasAndBelongsToMany'] = array_merge($associations['hasAndBelongsToMany']);
  459. }
  460. }
  461. $wannaDoMoreAssoc = $this->in('Would you like to define some additional model associations?', array('y','n'), 'n');
  462. while((low($wannaDoMoreAssoc) == 'y' || low($wannaDoMoreAssoc) == 'yes')) {
  463. $assocs = array(1=>'belongsTo', 2=>'hasOne', 3=>'hasMany', 4=>'hasAndBelongsToMany');
  464. $bad = true;
  465. while($bad) {
  466. $this->out('What is the association type?');
  467. $prompt = "1- belongsTo\n";
  468. $prompt .= "2- hasOne\n";
  469. $prompt .= "3- hasMany\n";
  470. $prompt .= "4- hasAndBelongsToMany\n";
  471. $assocType = intval($this->in($prompt, null, null));
  472. if(intval($assocType) < 1 || intval($assocType) > 4) {
  473. $this->out('The selection you entered was invalid. Please enter a number between 1 and 4.');
  474. } else {
  475. $bad = false;
  476. }
  477. }
  478. $this->out('For the following options be very careful to match your setup exactly. Any spelling mistakes will cause errors.');
  479. $this->hr();
  480. $associationName = $this->in('What is the name of this association?');
  481. $className = $this->in('What className will '.$associationName.' use?', null, $associationName );
  482. $suggestedForeignKey = null;
  483. if($assocType == '1') {
  484. $showKeys = $possibleKeys[$useTable];
  485. $suggestedForeignKey = $this->__modelKey($associationName);
  486. } else {
  487. $otherTable = Inflector::tableize($className);
  488. if(in_array($otherTable, $this->__tables)) {
  489. if($assocType < '4') {
  490. $showKeys = $possibleKeys[$otherTable];
  491. } else {
  492. $showKeys = null;
  493. }
  494. } else {
  495. $otherTable = $this->in('What is the table for this class?');
  496. $showKeys = $possibleKeys[$otherTable];
  497. }
  498. $suggestedForeignKey = $this->__modelKey($currentModelName);
  499. }
  500. if(!empty($showKeys)) {
  501. $this->out('A helpful List of possible keys');
  502. for ($i = 0; $i < count($showKeys); $i++) {
  503. $this->out($i + 1 . ". " . $showKeys[$i]);
  504. }
  505. $foreignKey = $this->in('What is the foreignKey? Choose a number.');
  506. if (intval($foreignKey) > 0 && intval($foreignKey) <= $i ) {
  507. $foreignKey = $showKeys[intval($foreignKey) - 1];
  508. }
  509. }
  510. if(!isset($foreignKey)) {
  511. $foreignKey = $this->in('What is the foreignKey? Specify your own.', null, $suggestedForeignKey);
  512. }
  513. if($assocType == '4') {
  514. $associationForeignKey = $this->in('What is the associationForeignKey?', null, $this->__modelKey($currentModelName));
  515. $joinTable = $this->in('What is the joinTable?');
  516. }
  517. $associations[$assocs[$assocType]] = array_values($associations[$assocs[$assocType]]);
  518. $count = count($associations[$assocs[$assocType]]);
  519. $i = ($count > 0) ? $count : 0;
  520. $associations[$assocs[$assocType]][$i]['alias'] = $associationName;
  521. $associations[$assocs[$assocType]][$i]['className'] = $className;
  522. $associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey;
  523. if($assocType == '4') {
  524. $associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey;
  525. $associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable;
  526. }
  527. $wannaDoMoreAssoc = $this->in('Define another association?', array('y','n'), 'y');
  528. }
  529. }
  530. $this->out('');
  531. $this->hr();
  532. $this->out('The following model will be created:');
  533. $this->hr();
  534. $this->out("Model Name: $currentModelName");
  535. $this->out("DB Connection: " . ($usingDefault ? 'default' : $useDbConfig));
  536. $this->out("DB Table: " . $fullTableName);
  537. if($primaryKey != 'id') {
  538. $this->out("Primary Key: " . $primaryKey);
  539. }
  540. $this->out("Validation: " . print_r($validate, true));
  541. if(!empty($associations)) {
  542. $this->out("Associations:");
  543. if(count($associations['belongsTo'])) {
  544. for($i = 0; $i < count($associations['belongsTo']); $i++) {
  545. $this->out(" $currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}");
  546. }
  547. }
  548. if(count($associations['hasOne'])) {
  549. for($i = 0; $i < count($associations['hasOne']); $i++) {
  550. $this->out(" $currentModelName hasOne {$associations['hasOne'][$i]['alias']}");
  551. }
  552. }
  553. if(count($associations['hasMany'])) {
  554. for($i = 0; $i < count($associations['hasMany']); $i++) {
  555. $this->out(" $currentModelName hasMany {$associations['hasMany'][$i]['alias']}");
  556. }
  557. }
  558. if(count($associations['hasAndBelongsToMany'])) {
  559. for($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
  560. $this->out(" $currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}");
  561. }
  562. }
  563. }
  564. $this->hr();
  565. $looksGood = $this->in('Look okay?', array('y','n'), 'y');
  566. if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
  567. if ($useTable == Inflector::tableize($currentModelName)) {
  568. // set it to null...
  569. // putting $useTable in the model
  570. // is unnecessary.
  571. $useTable = null;
  572. }
  573. $this->bakeModel($currentModelName, $useDbConfig, $useTable, $primaryKey, $validate, $associations);
  574. if ($this->doUnitTest()) {
  575. $this->bakeUnitTest('model', $currentModelName);
  576. }
  577. } else {
  578. $this->out('Bake Aborted.');
  579. }
  580. }
  581. /**
  582. * Action to create a View.
  583. *
  584. */
  585. function doView() {
  586. $this->hr();
  587. $this->out('View Bake:');
  588. $this->hr();
  589. $uses = array();
  590. $wannaUseSession = 'y';
  591. $wannaDoScaffold = 'y';
  592. $useDbConfig = 'default';
  593. $this->__doList($useDbConfig, 'Controllers');
  594. $enteredController = '';
  595. while ($enteredController == '') {
  596. $enteredController = $this->in('Enter a number from the list above, or type in the name of another controller.');
  597. if ($enteredController == '' || intval($enteredController) > count($this->__controllerNames)) {
  598. $this->out('Error:');
  599. $this->out("The Controller name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
  600. $enteredController = '';
  601. }
  602. }
  603. if (intval($enteredController) > 0 && intval($enteredController) <= count($this->__controllerNames) ) {
  604. $controllerName = $this->__controllerNames[intval($enteredController) - 1];
  605. } else {
  606. $controllerName = Inflector::camelize($enteredController);
  607. }
  608. $controllerPath = low(Inflector::underscore($controllerName));
  609. $doItInteractive = $this->in("Would you like bake to build your views interactively?\nWarning: Choosing no will overwrite {$controllerName} views if it exist.", array('y','n'), 'y');
  610. if (low($doItInteractive) == 'y' || low($doItInteractive) == 'yes') {
  611. $this->interactive = true;
  612. $wannaDoScaffold = $this->in("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');
  613. }
  614. $admin = null;
  615. $admin_url = null;
  616. if (low($wannaDoScaffold) == 'y' || low($wannaDoScaffold) == 'yes') {
  617. $wannaDoAdmin = $this->in("Would you like to create the views for admin routing?", array('y','n'), 'y');
  618. }
  619. if ((low($wannaDoAdmin) == 'y' || low($wannaDoAdmin) == 'yes')) {
  620. if(defined('CAKE_ADMIN')) {
  621. $admin = CAKE_ADMIN . '_';
  622. $admin_url = '/'.CAKE_ADMIN;
  623. } else {
  624. $adminRoute = '';
  625. $this->out('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
  626. $this->out('What would you like the admin route to be?');
  627. $this->out('Example: www.example.com/admin/controller');
  628. while ($adminRoute == '') {
  629. $adminRoute = $this->in("What would you like the admin route to be?", null, 'admin');
  630. }
  631. if($this->__addAdminRoute($adminRoute) !== true){
  632. $this->out('Unable to write to /app/config/core.php.');
  633. $this->out('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
  634. exit();
  635. } else {
  636. $admin = $adminRoute . '_';
  637. $admin_url = '/'.$adminRoute;
  638. }
  639. }
  640. }
  641. if (low($wannaDoScaffold) == 'y' || low($wannaDoScaffold) == 'yes') {
  642. $file = CONTROLLERS . $controllerPath . '_controller.php';
  643. if(!file_exists($file)) {
  644. $shortPath = str_replace(ROOT, null, $file);
  645. $shortPath = str_replace('../', '', $shortPath);
  646. $shortPath = str_replace('//', '/', $shortPath);
  647. $this->out('');
  648. $this->out("The file '$shortPath' could not be found.\nIn order to scaffold, you'll need to first create the controller. ");
  649. $this->out('');
  650. die();
  651. } else {
  652. uses('controller'.DS.'controller');
  653. loadController($controllerName);
  654. //loadModels();
  655. if($admin) {
  656. $this->__bakeViews($controllerName, $controllerPath, $admin, $admin_url);
  657. }
  658. $this->__bakeViews($controllerName, $controllerPath, null, null);
  659. $this->hr();
  660. $this->out('');
  661. $this->out('View Scaffolding Complete.'."\n");
  662. }
  663. } else {
  664. $actionName = '';
  665. while ($actionName == '') {
  666. $actionName = $this->in('Action Name? (use camelCased function name)');
  667. if ($actionName == '') {
  668. $this->out('The action name you supplied was empty. Please try again.');
  669. }
  670. }
  671. $this->out('');
  672. $this->hr();
  673. $this->out('The following view will be created:');
  674. $this->hr();
  675. $this->out("Controller Name: $controllerName");
  676. $this->out("Action Name: $actionName");
  677. $this->out("Path: app/views/" . $controllerPath . DS . Inflector::underscore($actionName) . '.ctp');
  678. $this->hr();
  679. $looksGood = $this->in('Look okay?', array('y','n'), 'y');
  680. if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
  681. $this->bakeView($controllerName, $actionName);
  682. } else {
  683. $this->out('Bake Aborted.');
  684. }
  685. }
  686. }
  687. function __bakeViews($controllerName, $controllerPath, $admin= null, $admin_url = null) {
  688. $controllerClassName = $controllerName.'Controller';
  689. $controllerObj = & new $controllerClassName();
  690. if(!in_array('Html', $controllerObj->helpers)) {
  691. $controllerObj->helpers[] = 'Html';
  692. }
  693. if(!in_array('Form', $controllerObj->helpers)) {
  694. $controllerObj->helpers[] = 'Form';
  695. }
  696. $controllerObj->constructClasses();
  697. $currentModelName = $controllerObj->modelClass;
  698. $this->__modelClass = $currentModelName;
  699. $modelKey = $controllerObj->modelKey;
  700. $modelObj =& ClassRegistry::getObject($modelKey);
  701. $singularName = $this->__singularName($currentModelName);
  702. $pluralName = $this->__pluralName($currentModelName);
  703. $singularHumanName = $this->__singularHumanName($currentModelName);
  704. $pluralHumanName = $this->__pluralHumanName($controllerName);
  705. $fieldNames = $controllerObj->generateFieldNames(null, false);
  706. //-------------------------[INDEX]-------------------------//
  707. $indexView = null;
  708. $indexView .= "<div class=\"{$pluralName}\">\n";
  709. $indexView .= "<h2>List " . $pluralHumanName . "</h2>\n\n";
  710. $indexView .= "<table cellpadding=\"0\" cellspacing=\"0\">\n";
  711. $indexView .= "\t<tr>\n";
  712. foreach ($fieldNames as $fieldName) {
  713. $indexView .= "\t\t<th><?php echo \$paginator->sort('{$fieldName['name']}');?></th>\n";
  714. }
  715. $indexView .= "\t\t<th>Actions</th>\n";
  716. $indexView .= "\t</tr>\n";
  717. $indexView .= "<?php foreach (\${$pluralName} as \${$singularName}): ?>\n";
  718. $indexView .= "\t<tr>\n";
  719. $count = 0;
  720. foreach($fieldNames as $field => $value) {
  721. if(isset($value['foreignKey'])) {
  722. $otherModelName = $this->__modelName($value['model']);
  723. $otherModelKey = Inflector::underscore($value['modelKey']);
  724. $otherModelObj =& ClassRegistry::getObject($otherModelKey);
  725. $otherControllerName = $this->__controllerName($value['modelKey']);
  726. $otherControllerPath = $this->__controllerPath($otherControllerName);
  727. if(is_object($otherModelObj)) {
  728. $displayField = $otherModelObj->getDisplayField();
  729. $indexView .= "\t\t<td><?php echo \$html->link(\$".$singularName."['{$otherModelName}']['{$displayField}'], array('controller'=> '{$otherControllerPath}', 'action'=>'view', \$".$singularName."['{$otherModelName}']['{$otherModelObj->primaryKey}'])); ?></td>\n";
  730. } else {
  731. $indexView .= "\t\t<td><?php echo \$".$singularName."['{$modelObj->name}']['{$field}']; ?></td>\n";
  732. }
  733. $count++;
  734. } else {
  735. $indexView .= "\t\t<td><?php echo \$".$singularName."['{$modelObj->name}']['{$field}']; ?></td>\n";
  736. }
  737. }
  738. $indexView .= "\t\t<td class=\"actions\">\n";
  739. $indexView .= "\t\t\t<?php echo \$html->link('View', array('action'=>'view', \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])); ?>\n";
  740. $indexView .= "\t\t\t<?php echo \$html->link('Edit', array('action'=>'edit', \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])); ?>\n";
  741. $indexView .= "\t\t\t<?php echo \$html->link('Delete', array('action'=>'delete', \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}']), null, 'Are you sure you want to delete #' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}']); ?>\n";
  742. $indexView .= "\t\t</td>\n";
  743. $indexView .= "\t</tr>\n";
  744. $indexView .= "<?php endforeach; ?>\n";
  745. $indexView .= "</table>\n\n";
  746. $indexView .= "</div>\n";
  747. $indexView .= "<div class=\"paging\">\n";
  748. $indexView .= "<?php echo \$paginator->prev('<< previous', array(), null, array('class'=>'disabled'));?>\n";
  749. $indexView .= "|\n";
  750. $indexView .= "<?php echo \$paginator->next('next >>', array(), null, array('class'=>'disabled'));?>\n";
  751. $indexView .= "</div>\n";
  752. $indexView .= "<div class=\"actions\">\n";
  753. $indexView .= "\t<ul>\n";
  754. $indexView .= "\t\t<li><?php echo \$html->link('New {$singularHumanName}', array('action'=>'add')); ?></li>\n";
  755. $indexView .= "\t</ul>\n";
  756. $indexView .= "</div>";
  757. //-------------------------[VIEW]-------------------------//
  758. $viewView = null;
  759. $viewView .= "<div class=\"{$singularName}\">\n";
  760. $viewView .= "<h2>View " . $singularHumanName . "</h2>\n\n";
  761. $viewView .= "\t<dl>\n";
  762. $count = 0;
  763. foreach($fieldNames as $field => $value) {
  764. $viewView .= "\t\t<dt>" . $value['label'] . "</dt>\n";
  765. if(isset($value['foreignKey'])) {
  766. $otherModelName = $this->__modelName($value['model']);
  767. $otherModelKey = Inflector::underscore($value['modelKey']);
  768. $otherModelObj =& ClassRegistry::getObject($value['modelKey']);
  769. $otherControllerName = $this->__controllerName($value['modelKey']);
  770. $otherControllerPath = $this->__controllerPath($otherControllerName);
  771. $displayField = $otherModelObj->getDisplayField();
  772. $viewView .= "\t\t<dd>&nbsp;<?php echo \$html->link(\$".$singularName."['{$otherModelName}']['{$displayField}'], array('controller'=> '{$otherControllerPath}', 'action'=>'view', \$".$singularName."['{$otherModelName}']['{$otherModelObj->primaryKey}'])); ?></dd>\n";
  773. $count++;
  774. } else {
  775. $viewView .= "\t\t<dd>&nbsp;<?php echo \$".$singularName."['{$modelObj->name}']['{$field}']?></dd>\n";
  776. }
  777. }
  778. $viewView .= "\t</dl>\n";
  779. $viewView .= "</div>\n";
  780. $viewView .= "<div class=\"actions\">\n";
  781. $viewView .= "\t<ul>\n";
  782. $viewView .= "\t\t<li><?php echo \$html->link('Edit " . $singularHumanName . "', array('action'=>'edit', \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])); ?> </li>\n";
  783. $viewView .= "\t\t<li><?php echo \$html->link('Delete " . $singularHumanName . "', array('action'=>'delete', \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}']), null, 'Are you sure you want to delete #' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'] . '?'); ?> </li>\n";
  784. $viewView .= "\t\t<li><?php echo \$html->link('List " . $pluralHumanName ."', array('action'=>'index')); ?> </li>\n";
  785. $viewView .= "\t\t<li><?php echo \$html->link('New " . $singularHumanName . "', array('action'=>'add')); ?> </li>\n";
  786. foreach( $fieldNames as $field => $value ) {
  787. if( isset( $value['foreignKey'] ) ) {
  788. $otherModelName = $this->__modelName($value['modelKey']);
  789. if($otherModelName != $currentModelName) {
  790. $otherControllerName = $this->__controllerName($otherModelName);
  791. $otherControllerPath = $this->__controllerPath($otherControllerName);
  792. $otherSingularHumanName = $this->__singularHumanName($value['controller']);
  793. $otherPluralHumanName = $this->__pluralHumanName($value['controller']);
  794. $viewView .= "\t\t<li><?php echo \$html->link('List " . $otherSingularHumanName . "', array('controller'=> '{$otherControllerPath}', 'action'=>'index')); ?> </li>\n";
  795. $viewView .= "\t\t<li><?php echo \$html->link('New " . $otherPluralHumanName . "', array('controller'=> '{$otherControllerPath}', 'action'=>'add')); ?> </li>\n";
  796. }
  797. }
  798. }
  799. $viewView .= "\t</ul>\n\n";
  800. $viewView .= "</div>\n";
  801. foreach ($modelObj->hasOne as $associationName => $relation) {
  802. $new = true;
  803. $otherModelName = $this->__modelName($relation['className']);
  804. $otherControllerName = $this->__controllerName($otherModelName);
  805. $otherControllerPath = $this->__controllerPath($otherControllerName);
  806. $otherSingularName = $this->__singularName($associationName);
  807. $otherPluralHumanName = $this->__pluralHumanName($associationName);
  808. $otherSingularHumanName = $this->__singularHumanName($associationName);
  809. $otherModelKey = Inflector::underscore($relation['className']);
  810. $otherModelObj =& ClassRegistry::getObject($otherModelKey);
  811. $viewView .= "<div class=\"related\">\n";
  812. $viewView .= "<h3>Related " . $otherPluralHumanName . "</h3>\n";
  813. $viewView .= "<?php if(!empty(\${$singularName}['{$associationName}'])): ?>\n";
  814. $viewView .= "\t<dl>\n";
  815. foreach($otherModelObj->_tableInfo->value as $column) {
  816. $viewView .= "\t\t<dt>".Inflector::humanize($column['name'])."</dt>\n";
  817. $viewView .= "\t\t<dd>&nbsp;<?php echo \${$singularName}['{$associationName}']['{$column['name']}'] ?></dd>\n";
  818. }
  819. $viewView .= "\t</dl>\n";
  820. $viewView .= "<?php endif; ?>\n";
  821. $viewView .= "\t<div class=\"actions\">\n";
  822. $viewView .= "\t\t<ul>\n";
  823. $viewView .= "\t\t\t<li><?php echo \$html->link('Edit " . $otherSingularHumanName . "', array('controller'=> '{$otherControllerPath}', 'action'=>'edit', \$".$singularName."['{$associationName}']['" . $modelObj->{$otherModelName}->primaryKey . "']));?></li>\n";
  824. $viewView .= "\t\t</ul>\n";
  825. $viewView .= "\t</div>\n";
  826. $viewView .= "</div>\n";
  827. }
  828. $relations = array_merge($modelObj->hasMany, $modelObj->hasAndBelongsToMany);
  829. foreach($relations as $associationName => $relation) {
  830. $otherModelName = $associationName;
  831. $otherControllerName = $this->__controllerName($relation['className']);
  832. $otherControllerPath = $this->__controllerPath($otherControllerName);
  833. $otherSingularName = $this->__singularName($associationName);
  834. $otherPluralHumanName = $this->__pluralHumanName($associationName);
  835. $otherSingularHumanName = $this->__singularHumanName($associationName);
  836. $otherModelKey = Inflector::underscore($relation['className']);
  837. $otherModelObj =& ClassRegistry::getObject($otherModelKey);
  838. $viewView .= "<div class=\"related\">\n";
  839. $viewView .= "<h3>Related " . $otherPluralHumanName . "</h3>\n";
  840. $viewView .= "<?php if(!empty(\${$singularName}['{$associationName}'])):?>\n";
  841. $viewView .= "<table cellpadding=\"0\" cellspacing=\"0\">\n";
  842. $viewView .= "\t<tr>\n";
  843. foreach($otherModelObj->_tableInfo->value as $column) {
  844. $viewView .= "\t\t<th>".Inflector::humanize($column['name'])."</th>\n";
  845. }
  846. $viewView .= "\t\t<th>Actions</th>\n";
  847. $viewView .= "\t</tr>\n";
  848. $viewView .= "<?php foreach(\${$singularName}['{$associationName}'] as \$".$otherSingularName."):?>\n";
  849. $viewView .= "\t<tr>\n";
  850. foreach($otherModelObj->_tableInfo->value as $column) {
  851. $viewView .= "\t\t<td><?php echo \${$otherSingularName}['{$column['name']}'];?></td>\n";
  852. }
  853. $viewView .= "\t\t<td class=\"actions\">\n";
  854. $viewView .= "\t\t\t<?php echo \$html->link('View', array('controller'=> '{$otherControllerPath}', 'action'=>'view', \$".$otherSingularName."['{$otherModelObj->primaryKey}'])); ?>\n";
  855. $viewView .= "\t\t\t<?php echo \$html->link('Edit', array('controller'=> '{$otherControllerPath}', 'action'=>'edit', \$".$otherSingularName."['{$otherModelObj->primaryKey}'])); ?>\n";
  856. $viewView .= "\t\t\t<?php echo \$html->link('Delete', array('controller'=> '{$otherControllerPath}', 'action'=>'delete', \$".$otherSingularName."['{$otherModelObj->primaryKey}']), null, 'Are you sure you want to delete #' . \$".$otherSingularName."['{$otherModelObj->primaryKey}'] . '?'); ?>\n";
  857. $viewView .= "\t\t</td>\n";
  858. $viewView .= "\t</tr>\n";
  859. $viewView .= "<?php endforeach; ?>\n";
  860. $viewView .= "</table>\n";
  861. $viewView .= "<?php endif; ?>\n\n";
  862. $viewView .= "\t<div class=\"actions\">\n";
  863. $viewView .= "\t\t<ul>\n";
  864. $viewView .= "\t\t\t<li><?php echo \$html->link('New " . $otherSingularHumanName . "', array('controller'=> '{$otherControllerPath}', 'action'=>'add'));?> </li>\n";
  865. $viewView .= "\t\t</ul>\n";
  866. $viewView .= "\t</div>\n";
  867. $viewView .= "</div>\n";
  868. }
  869. $fields = $controllerObj->generateFieldNames(null, true);
  870. //-------------------------[EDIT]-------------------------//
  871. $editView = null;
  872. $editView .= "<div class=\"".$singularName."\">\n";
  873. $editView .= "<h2>Edit " . $singularHumanName . "</h2>\n";
  874. $editView .= "\t<?php echo \$form->create('{$currentModelName}');?>\n";
  875. $editView .= $this->inputs($fields);
  876. $editView .= "\t\t<?php echo \$form->submit('Update');?>\n";
  877. $editView .= "\t</form>\n";
  878. $editView .= "</div>\n";
  879. $editView .= "<div class=\"actions\">\n";
  880. $editView .= "\t<ul>\n";
  881. $editView .= "\t\t<li><?php echo \$html->link('Delete', array('action'=>'delete', \$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}')), null, 'Are you sure you want to delete #' . \$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}')); ?>\n";
  882. $editView .= "\t\t<li><?php echo \$html->link('List {$pluralHumanName}', array('action'=>'index')); ?></li>\n";
  883. foreach ($modelObj->belongsTo as $associationName => $relation) {
  884. $otherModelName = $this->__modelName($relation['className']);
  885. if($otherModelName != $currentModelName) {
  886. $otherControllerName = $this->__controllerName($otherModelName);
  887. $otherControllerPath = $this->__controllerPath($otherControllerName);
  888. $otherSingularName = $this->__singularName($associationName);
  889. $otherPluralName = $this->__pluralHumanName($associationName);
  890. $editView .= "\t\t<li><?php echo \$html->link('View " . $otherPluralName . "', array('controller'=> '{$otherControllerPath}', 'action'=>'view')); ?></li>\n";
  891. $editView .= "\t\t<li><?php echo \$html->link('Add " . $otherPluralName . "', array('controller'=> '{$otherControllerPath}', 'action'=>'add')); ?></li>\n";
  892. }
  893. }
  894. $editView .= "\t</ul>\n";
  895. $editView .= "</div>\n";
  896. //-------------------------[ADD]-------------------------//
  897. unset($fields[$modelObj->primaryKey]);
  898. $addView = null;
  899. $addView .= "<div class=\"".low($singularName)."\">\n";
  900. $addView .= "<h2>New " . $singularHumanName . "</h2>\n";
  901. $addView .= "\t<?php echo \$form->create('{$currentModelName}');?>\n";
  902. $addView .= $this->inputs($fields);
  903. $addView .= "\t\t<?php echo \$form->submit('Add');?>\n";
  904. $addView .= "\t</form>\n";
  905. $addView .= "</div>\n";
  906. $addView .= "<div class=\"actions\">\n";
  907. $addView .= "\t<ul>\n";
  908. $addView .= "\t\t<li><?php echo \$html->link('List {$pluralHumanName}', array('action'=>'index')); ?></li>\n";
  909. foreach ($modelObj->belongsTo as $associationName => $relation) {
  910. $otherModelName = $this->__modelName($relation['className']);
  911. if($otherModelName != $currentModelName) {
  912. $otherControllerName = $this->__controllerName($otherModelName);
  913. $otherControllerPath = $this->__controllerPath($otherControllerName);
  914. $otherSingularName = $this->__singularName($associationName);
  915. $otherPluralName = $this->__pluralHumanName($associationName);
  916. $addView .= "\t\t<li><?php echo \$html->link('View " . $otherPluralName . "', array('controller'=> '{$otherControllerPath}', 'action'=>'view'));?></li>\n";
  917. $addView .= "\t\t<li><?php echo \$html->link('Add " . $otherPluralName . "', array('controller'=> '{$otherControllerPath}', 'action'=>'add')); ?></li>\n";
  918. }
  919. }
  920. $addView .= "\t</ul>\n";
  921. $addView .= "</div>\n";
  922. //------------------------------------------------------------------------------------//
  923. if(!file_exists(VIEWS.$controllerPath)) {
  924. mkdir(VIEWS.$controllerPath);
  925. }
  926. $filename = VIEWS . $controllerPath . DS . $admin . 'index.ctp';
  927. $this->createFile($filename, $indexView);
  928. $filename = VIEWS . $controllerPath . DS . $admin . 'view.ctp';
  929. $this->createFile($filename, $viewView);
  930. $filename = VIEWS . $controllerPath . DS . $admin . 'add.ctp';
  931. $this->createFile($filename, $addView);
  932. $filename = VIEWS . $controllerPath . DS . $admin . 'edit.ctp';
  933. $this->createFile($filename, $editView);
  934. }
  935. /**
  936. * returns the fields to be display in the baked forms.
  937. *
  938. * @access private
  939. * @param array $fields
  940. */
  941. function inputs($fields = array()) {
  942. $displayFields = null;
  943. foreach($fields as $name => $options) {
  944. if(isset($options['tagName'])){
  945. $tag = explode('/', $options['tagName']);
  946. $tagName = $tag[1];
  947. unset($options['tagName']);
  948. }
  949. $formOptions = array();
  950. if(isset($options['type'])){
  951. $type = $options['type'];
  952. unset($options['type']);
  953. //$formOptions['type'] = "'type' => '{$type}'";
  954. }
  955. if(isset($options['class']) && $options['class'] == 'required'){
  956. $class = $options['class'];
  957. unset($options['class']);
  958. $formOptions['class'] = "'class' => '{$class}'";
  959. }
  960. if(isset($options['options'])){
  961. unset($formOptions['type']);
  962. $fieldOptions = $this->__pluralName($options['model']);
  963. unset($options['options']);
  964. $formOptions['options'] = "'options' => \${$fieldOptions}";
  965. if(isset($options['multiple'])){
  966. $formOptions['multiple'] = "'multiple' => 'multiple'";
  967. $tagName = $tagName.'/'.$tagName;
  968. }
  969. }
  970. if(isset($options['size'])){
  971. $size = $options['size'];
  972. unset($options['size']);
  973. //$formOptions['size'] = "'size' => '{$size}'";
  974. }
  975. if(isset($options['cols'])){
  976. $cols = $options['cols'];
  977. unset($options['cols']);
  978. //$formOptions['cols'] = "'cols' => '{$cols}'";
  979. }
  980. if(isset($options['rows'])){
  981. $rows = $options['rows'];
  982. unset($options['rows']);
  983. //$formOptions['rows'] = "'rows' => '{$rows}'";
  984. }
  985. if(!empty($formOptions)) {
  986. $formOptions = ", array(".join(', ', $formOptions).")";
  987. } else {
  988. $formOptions = null;
  989. }
  990. $displayFields .= "\t\t<?php echo \$form->input('{$tagName}'{$formOptions});?>\n";
  991. }
  992. return $displayFields;
  993. }
  994. /**
  995. * Action to create a Controller.
  996. *
  997. */
  998. function doController() {
  999. $this->hr();
  1000. $this->out('Controller Bake:');
  1001. $this->hr();
  1002. $uses = array();
  1003. $helpers = array();
  1004. $components = array();
  1005. $wannaUseSession = 'y';
  1006. $wannaDoScaffolding = 'y';
  1007. $useDbConfig = 'default';
  1008. $this->__doList($useDbConfig, 'Controllers');
  1009. $enteredController = '';
  1010. while ($enteredController == '') {
  1011. $enteredController = $this->in('Enter a number from the list above, or type in the name of another controller.');
  1012. if ($enteredController == '' || intval($enteredController) > count($this->__controllerNames)) {
  1013. $this->out('Error:');
  1014. $this->out("The Controller name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
  1015. $enteredController = '';
  1016. }
  1017. }
  1018. if (intval($enteredController) > 0 && intval($enteredController) <= count($this->__controllerNames) ) {
  1019. $controllerName = $this->__controllerNames[intval($enteredController) - 1];
  1020. } else {
  1021. $controllerName = Inflector::camelize($enteredController);
  1022. }
  1023. $controllerPath = low(Inflector::underscore($controllerName));
  1024. $doItInteractive = $this->in("Would you like bake to build your controller interactively?\nWarning: Choosing no will overwrite {$controllerName} controller if it exist.", array('y','n'), 'y');
  1025. if (low($doItInteractive) == 'y' || low($doItInteractive) == 'yes') {
  1026. $this->interactive = true;
  1027. $wannaUseScaffold = $this->in("Would you like to use scaffolding?", array('y','n'), 'y');
  1028. if (low($wannaUseScaffold) == 'n' || low($wannaUseScaffold) == 'no') {
  1029. $wannaDoScaffolding = $this->in("Would you like to include some basic class methods (index(), add(), view(), edit())?", array('y','n'), 'n');
  1030. if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
  1031. $wannaDoAdmin = $this->in("Would you like to create the methods for admin routing?", array('y','n'), 'n');
  1032. }
  1033. $wannaDoUses = $this->in("Would you like this controller to use other models besides '" . $this->__modelName($controllerName) . "'?", array('y','n'), 'n');
  1034. if (low($wannaDoUses) == 'y' || low($wannaDoUses) == 'yes') {
  1035. $usesList = $this->in("Please provide a comma separated list of the classnames of other models you'd like to use.\nExample: 'Author, Article, Book'");
  1036. $usesListTrimmed = str_replace(' ', '', $usesList);
  1037. $uses = explode(',', $usesListTrimmed);
  1038. }
  1039. $wannaDoHelpers = $this->in("Would you like this controller to use other helpers besides HtmlHelper and FormHelper?", array('y','n'), 'n');
  1040. if (low($wannaDoHelpers) == 'y' || low($wannaDoHelpers) == 'yes') {
  1041. $helpersList = $this->in("Please provide a comma separated list of the other helper names you'd like to use.\nExample: 'Ajax, Javascript, Time'");
  1042. $helpersListTrimmed = str_replace(' ', '', $helpersList);
  1043. $helpers = explode(',', $helpersListTrimmed);
  1044. }
  1045. $wannaDoComponents = $this->in("Would you like this controller to use any components?", array('y','n'), 'n');
  1046. if (low($wannaDoComponents) == 'y' || low($wannaDoComponents) == 'yes') {
  1047. $componentsList = $this->in("Please provide a comma separated list of the component names you'd like to use.\nExample: 'Acl, MyNiftyHelper'");
  1048. $componentsListTrimmed = str_replace(' ', '', $componentsList);
  1049. $components = explode(',', $componentsListTrimmed);
  1050. }
  1051. $wannaUseSession = $this->in("Would you like to use Sessions?", array('y','n'), 'y');
  1052. } else {
  1053. $wannaDoScaffolding = 'n';
  1054. }
  1055. } else {
  1056. $wannaDoScaffolding = $this->in("Would you like to include some basic class methods (index(), add(), view(), edit())?", array('y','n'), 'y');
  1057. if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
  1058. $wannaDoAdmin = $this->in("Would you like to create the methods for admin routing?", array('y','n'), 'y');
  1059. }
  1060. }
  1061. $admin = null;
  1062. $admin_url = null;
  1063. if ((low($wannaDoAdmin) == 'y' || low($wannaDoAdmin) == 'yes')) {
  1064. if(defined('CAKE_ADMIN')) {
  1065. $admin = CAKE_ADMIN.'_';
  1066. $admin_url = '/'.CAKE_ADMIN;
  1067. } else {
  1068. $adminRoute = '';
  1069. $this->out('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
  1070. $this->out('What would you like the admin route to be?');
  1071. $this->out('Example: www.example.com/admin/controller');
  1072. while ($adminRoute == '') {
  1073. $adminRoute = $this->in("What would you like the admin route to be?", null, 'admin');
  1074. }
  1075. if($this->__addAdminRoute($adminRoute) !== true){
  1076. $this->out('Unable to write to /app/config/core.php.');
  1077. $this->out('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
  1078. exit();
  1079. } else {
  1080. $admin = $adminRoute . '_';
  1081. $admin_url = '/'.$adminRoute;
  1082. }
  1083. }
  1084. }
  1085. if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
  1086. //loadModels();
  1087. $actions = $this->__bakeActions($controllerName, null, null, $wannaUseSession);
  1088. if($admin) {
  1089. $actions .= $this->__bakeActions($controllerName, $admin, $admin_url, $wannaUseSession);
  1090. }
  1091. }
  1092. if($this->interactive === true) {
  1093. $this->out('');
  1094. $this->hr();
  1095. $this->out('The following controller will be created:');
  1096. $this->hr();
  1097. $this->out("Controller Name: $controllerName");
  1098. if (low($wannaUseScaffold) == 'y' || low($wannaUseScaffold) == 'yes') {
  1099. $this->out(" var \$scaffold;");
  1100. }
  1101. if(count($uses)) {
  1102. $this->out("Uses: ", false);
  1103. foreach($uses as $use) {
  1104. if ($use != $uses[count($uses) - 1]) {
  1105. $this->out(ucfirst($use) . ", ", false);
  1106. } else {
  1107. $this->out(ucfirst($use));
  1108. }
  1109. }
  1110. }
  1111. if(count($helpers)) {
  1112. $this->out("Helpers: ", false);
  1113. foreach($helpers as $help) {
  1114. if ($help != $helpers[count($helpers) - 1]) {
  1115. $this->out(ucfirst($help) . ", ", false);
  1116. } else {
  1117. $this->out(ucfirst($help));
  1118. }
  1119. }
  1120. }
  1121. if(count($components)) {
  1122. $this->out("Components: ", false);
  1123. foreach($components as $comp) {
  1124. if ($comp != $components[count($components) - 1]) {
  1125. $this->out(ucfirst($comp) . ", ", false);
  1126. } else {
  1127. $this->out(ucfirst($comp));
  1128. }
  1129. }
  1130. }
  1131. $this->hr();
  1132. $looksGood = $this->in('Look okay?', array('y','n'), 'y');
  1133. if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
  1134. $this->bakeController($controllerName, $uses, $helpers, $components, $actions, $wannaUseScaffold);
  1135. if ($this->doUnitTest()) {
  1136. $this->bakeUnitTest('controller', $controllerName);
  1137. }
  1138. } else {
  1139. $this->out('Bake Aborted.');
  1140. }
  1141. } else {
  1142. $this->bakeController($controllerName, $uses, $helpers, $components, $actions, $wannaUseScaffold);
  1143. if ($this->doUnitTest()) {
  1144. $this->bakeUnitTest('controller', $controllerName);
  1145. }
  1146. exit();
  1147. }
  1148. }
  1149. function __bakeActions($controllerName, $admin = null, $admin_url = null, $wannaUseSession = 'y') {
  1150. $currentModelName = $this->__modelName($controllerName);
  1151. if(!loadModel($currentModelName)) {
  1152. $this->out('You must have a model for this class to build scaffold methods. Please try again.');
  1153. exit;
  1154. }
  1155. $modelObj =& new $currentModelName();
  1156. $controllerPath = $this->__controllerPath($controllerName);
  1157. $pluralName = $this->__pluralName($currentModelName);
  1158. $singularName = $this->__singularName($currentModelName);
  1159. $singularHumanName = $this->__singularHumanName($currentModelName);
  1160. $pluralHumanName = $this->__pluralHumanName($controllerName);
  1161. $actions .= "\n";
  1162. $actions .= "\tfunction {$admin}index() {\n";
  1163. $actions .= "\t\t\$this->{$currentModelName}->recursive = 0;\n";
  1164. $actions .= "\t\t\$this->set('{$pluralName}', \$this->paginate());\n";
  1165. $actions .= "\t}\n";
  1166. $actions .= "\n";
  1167. $actions .= "\tfunction {$admin}view(\$id = null) {\n";
  1168. $actions .= "\t\tif(!\$id) {\n";
  1169. if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
  1170. $actions .= "\t\t\t\$this->Session->setFlash('Invalid {$singularHumanName}.');\n";
  1171. $actions .= "\t\t\t\$this->redirect(array('action'=>'index'), null, true);\n";
  1172. } else {
  1173. $actions .= "\t\t\t\$this->flash('Invalid {$singularHumanName}', array('action'=>'index'));\n";
  1174. }
  1175. $actions .= "\t\t}\n";
  1176. $actions .= "\t\t\$this->set('".$singularName."', \$this->{$currentModelName}->read(null, \$id));\n";
  1177. $actions .= "\t}\n";
  1178. $actions .= "\n";
  1179. /* ADD ACTION */
  1180. $compact = array();
  1181. $actions .= "\tfunction {$admin}add() {\n";
  1182. $actions .= "\t\tif(!empty(\$this->data)) {\n";
  1183. $actions .= "\t\t\t\$this->cleanUpFields();\n";
  1184. $actions .= "\t\t\t\$this->{$currentModelName}->create();\n";
  1185. $actions .= "\t\t\tif(\$this->{$currentModelName}->save(\$this->data)) {\n";
  1186. if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
  1187. $actions .= "\t\t\t\t\$this->Session->setFlash('The ".$singularHumanName." has been saved');\n";
  1188. $actions .= "\t\t\t\t\$this->redirect(array('action'=>'index'), null, true);\n";
  1189. } else {
  1190. $actions .= "\t\t\t\t\$this->flash('{$currentModelName} saved.', array('action'=>'index'));\n";
  1191. $actions .= "\t\t\t\texit();\n";
  1192. }
  1193. $actions .= "\t\t\t} else {\n";
  1194. if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
  1195. $actions .= "\t\t\t\t\$this->Session->setFlash('The {$singularHumanName} could not be saved. Please, try again.');\n";
  1196. }
  1197. $actions .= "\t\t\t}\n";
  1198. $actions .= "\t\t}\n";
  1199. foreach($modelObj->hasAndBelongsToMany as $associationName => $relation) {
  1200. if(!empty($associationName)) {
  1201. $habtmModelName = $this->__modelName($associationName);
  1202. $habtmSingularName = $this->__singularName($associationName);
  1203. $habtmPluralName = $this->__pluralName($associationName);
  1204. $actions .= "\t\t\${$habtmPluralName} = \$this->{$currentModelName}->{$habtmModelName}->generateList();\n";
  1205. $compact[] = "'{$habtmPluralName}'";
  1206. }
  1207. }
  1208. foreach($modelObj->belongsTo as $associationName => $relation) {
  1209. if(!empty($associationName)) {
  1210. $belongsToModelName = $this->__modelName($associationName);
  1211. $belongsToPluralName = $this->__pluralName($associationName);
  1212. $actions .= "\t\t\${$belongsToPluralName} = \$this->{$currentModelName}->{$belongsToModelName}->generateList();\n";
  1213. $compact[] = "'{$belongsToPluralName}'";
  1214. }
  1215. }
  1216. if(!empty($compact)) {
  1217. $actions .= "\t\t\$this->set(compact(".join(', ', $compact)."));\n";
  1218. }
  1219. $actions .= "\t}\n";
  1220. $actions .= "\n";
  1221. /* EDIT ACTION */
  1222. $compact = array();
  1223. $actions .= "\tfunction {$admin}edit(\$id = null) {\n";
  1224. $actions .= "\t\tif(!\$id && empty(\$this->data)) {\n";
  1225. if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
  1226. $actions .= "\t\t\t\$this->Session->setFlash('Invalid {$singularHumanName}');\n";
  1227. $actions .= "\t\t\t\$this->redirect(array('action'=>'index'), null, true);\n";
  1228. } else {
  1229. $actions .= "\t\t\t\$this->flash('Invalid {$singularHumanName}', array('action'=>'index'));\n";
  1230. $actions .= "\t\t\texit();\n";
  1231. }
  1232. $actions .= "\t\t}\n";
  1233. $actions .= "\t\tif(!empty(\$this->data)) {\n";
  1234. $actions .= "\t\t\t\$this->cleanUpFields();\n";
  1235. $actions .= "\t\t\tif(\$this->{$currentModelName}->save(\$this->data)) {\n";
  1236. if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
  1237. $actions .= "\t\t\t\t\$this->Session->setFlash('The ".$singularHumanName." saved');\n";
  1238. $actions .= "\t\t\t\t\$this->redirect(array('action'=>'index'), null, true);\n";
  1239. } else {
  1240. $actions .= "\t\t\t\t\$this->flash('The ".$singularHumanName." saved.', array('action'=>'index'));\n";
  1241. $actions .= "\t\t\t\texit();\n";
  1242. }
  1243. $actions .= "\t\t\t} else {\n";
  1244. if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
  1245. $actions .= "\t\t\t\t\$this->Session->setFlash('The {$singularHumanName} could not be saved. Please, try again.');\n";
  1246. }
  1247. $actions .= "\t\t\t}\n";
  1248. $actions .= "\t\t}\n";
  1249. $actions .= "\t\tif(empty(\$this->data)) {\n";
  1250. $actions .= "\t\t\t\$this->data = \$this->{$currentModelName}->read(null, \$id);\n";
  1251. $actions .= "\t\t}\n";
  1252. foreach($modelObj->hasAndBelongsToMany as $associationName => $relation) {
  1253. if(!empty($associationName)) {
  1254. $habtmModelName = $this->__modelName($associationName);
  1255. $habtmSingularName = $this->__singularName($associationName);
  1256. $habtmPluralName = $this->__pluralName($associationName);
  1257. $actions .= "\t\t\${$habtmPluralName} = \$this->{$currentModelName}->{$habtmModelName}->generateList();\n";
  1258. $compact[] = "'{$habtmPluralName}'";
  1259. }
  1260. }
  1261. foreach($modelObj->belongsTo as $associationName => $relation) {
  1262. if(!empty($associationName)) {
  1263. $belongsToModelName = $this->__modelName($associationName);
  1264. $belongsToPluralName = $this->__pluralName($associationName);
  1265. $actions .= "\t\t\${$belongsToPluralName} = \$this->{$currentModelName}->{$belongsToModelName}->generateList();\n";
  1266. $compact[] = "'{$belongsToPluralName}'";
  1267. }
  1268. }
  1269. if(!empty($compact)) {
  1270. $actions .= "\t\t\$this->set(compact(".join(',', $compact)."));\n";
  1271. }
  1272. $actions .= "\t}\n";
  1273. $actions .= "\n";
  1274. $actions .= "\tfunction {$admin}delete(\$id = null) {\n";
  1275. $actions .= "\t\tif(!\$id) {\n";
  1276. if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
  1277. $actions .= "\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}');\n";
  1278. $actions .= "\t\t\t\$this->redirect(array('action'=>'index'), null, true);\n";
  1279. } else {
  1280. $actions .= "\t\t\t\$this->flash('Invalid {$singularHumanName}', array('action'=>'index'));\n";
  1281. }
  1282. $actions .= "\t\t}\n";
  1283. $actions .= "\t\tif(\$this->{$currentModelName}->del(\$id)) {\n";
  1284. if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
  1285. $actions .= "\t\t\t\$this->Session->setFlash('".$singularHumanName." #'.\$id.' deleted');\n";
  1286. $actions .= "\t\t\t\$this->redirect(array('action'=>'index'), null, true);\n";
  1287. } else {
  1288. $actions .= "\t\t\t\$this->flash('".$singularHumanName." #'.\$id.' deleted', array('action'=>'index'));\n";
  1289. }
  1290. $actions .= "\t\t}\n";
  1291. $actions .= "\t}\n";
  1292. $actions .= "\n";
  1293. return $actions;
  1294. }
  1295. /**
  1296. * Action to create a Unit Test.
  1297. *
  1298. * @return Success
  1299. */
  1300. function doUnitTest() {
  1301. if (is_dir(VENDORS.'simpletest') || is_dir(ROOT.DS.APP_DIR.DS.'vendors'.DS.'simpletest')) {
  1302. return true;
  1303. }
  1304. $unitTest = $this->in('Cake test suite not installed. Do you want to bake unit test files anyway?', array('y','n'), 'y');
  1305. $result = low($unitTest) == 'y' || low($unitTest) == 'yes';
  1306. if ($result) {
  1307. $this->out("\nYou can download the Cake test suite from http://cakeforge.org/projects/testsuite/", true);
  1308. }
  1309. return $result;
  1310. }
  1311. /**
  1312. * Creates a database configuration file for Bake.
  1313. *
  1314. * @param string $host
  1315. * @param string $login
  1316. * @param string $password
  1317. * @param string $database
  1318. */
  1319. function bakeDbConfig( $driver, $connect, $host, $login, $password, $database, $prefix) {
  1320. $out = "<?php\n";
  1321. $out .= "class DATABASE_CONFIG {\n\n";
  1322. $out .= "\tvar \$default = array(\n";
  1323. $out .= "\t\t'driver' => '{$driver}',\n";
  1324. $out .= "\t\t'connect' => '{$connect}',\n";
  1325. $out .= "\t\t'host' => '{$host}',\n";
  1326. $out .= "\t\t'login' => '{$login}',\n";
  1327. $out .= "\t\t'password' => '{$password}',\n";
  1328. $out .= "\t\t'database' => '{$database}', \n";
  1329. $out .= "\t\t'prefix' => '{$prefix}' \n";
  1330. $out .= "\t);\n";
  1331. $out .= "}\n";
  1332. $out .= "?>";
  1333. $filename = CONFIGS.'database.php';
  1334. $this->createFile($filename, $out);
  1335. }
  1336. /**
  1337. * Assembles and writes a Model file.
  1338. *
  1339. * @param string $name
  1340. * @param object $useDbConfig
  1341. * @param string $useTable
  1342. * @param string $primaryKey
  1343. * @param array $validate
  1344. * @param array $associations
  1345. */
  1346. function bakeModel($name, $useDbConfig = 'default', $useTable = null, $primaryKey = 'id', $validate=array(), $associations=array()) {
  1347. $out = "<?php\n";
  1348. $out .= "class {$name} extends AppModel {\n\n";
  1349. $out .= "\tvar \$name = '{$name}';\n";
  1350. if ($useDbConfig != 'default') {
  1351. $out .= "\tvar \$useDbConfig = '$useDbConfig';\n";
  1352. }
  1353. if ($useTable != null) {
  1354. $out .= "\tvar \$useTable = '$useTable';\n";
  1355. }
  1356. if ($primaryKey != 'id') {
  1357. $out .= "\tvar \$primaryKey = '$primaryKey';\n";
  1358. }
  1359. if (count($validate)) {
  1360. $out .= "\tvar \$validate = array(\n";
  1361. $keys = array_keys($validate);
  1362. for($i = 0; $i < count($validate); $i++) {
  1363. $out .= "\t\t'" . $keys[$i] . "' => " . $validate[$keys[$i]] . ",\n";
  1364. }
  1365. $out .= "\t);\n";
  1366. }
  1367. $out .= "\n";
  1368. if(!empty($associations)) {
  1369. $out.= "\t//The Associations below have been created with all possible keys, those that are not needed can be removed\n";
  1370. if(!empty($associations['belongsTo'])) {
  1371. $out .= "\tvar \$belongsTo = array(\n";
  1372. for($i = 0; $i < count($associations['belongsTo']); $i++) {
  1373. $out .= "\t\t\t'{$associations['belongsTo'][$i]['alias']}' => ";
  1374. $out .= "array('className' => '{$associations['belongsTo'][$i]['className']}',\n";
  1375. $out .= "\t\t\t\t\t\t\t\t'foreignKey' => '{$associations['belongsTo'][$i]['foreignKey']}',\n";
  1376. $out .= "\t\t\t\t\t\t\t\t'conditions' => '',\n";
  1377. $out .= "\t\t\t\t\t\t\t\t'fields' => '',\n";
  1378. $out .= "\t\t\t\t\t\t\t\t'order' => '',\n";
  1379. $out .= "\t\t\t\t\t\t\t\t'counterCache' => ''";
  1380. $out .= "),\n";
  1381. }
  1382. $out .= "\t);\n\n";
  1383. }
  1384. if(!empty($associations['hasOne'])) {
  1385. $out .= "\tvar \$hasOne = array(\n";
  1386. for($i = 0; $i < count($associations['hasOne']); $i++) {
  1387. $out .= "\t\t\t'{$associations['hasOne'][$i]['alias']}' => ";
  1388. $out .= "array('className' => '{$associations['hasOne'][$i]['className']}',\n";
  1389. $out .= "\t\t\t\t\t\t\t\t'foreignKey' => '{$associations['hasOne'][$i]['foreignKey']}',\n";
  1390. $out .= "\t\t\t\t\t\t\t\t'conditions' => '',\n";
  1391. $out .= "\t\t\t\t\t\t\t\t'fields' => '',\n";
  1392. $out .= "\t\t\t\t\t\t\t\t'order' => '',\n";
  1393. $out .= "\t\t\t\t\t\t\t\t'dependent' => ''";
  1394. $out .= "),\n";
  1395. }
  1396. $out .= "\t);\n\n";
  1397. }
  1398. if(!empty($associations['hasMany'])) {
  1399. $out .= "\tvar \$hasMany = array(\n";
  1400. for($i = 0; $i < count($associations['hasMany']); $i++) {
  1401. $out .= "\t\t\t'{$associations['hasMany'][$i]['alias']}' => ";
  1402. $out .= "array('className' => '{$associations['hasMany'][$i]['className']}',\n";
  1403. $out .= "\t\t\t\t\t\t\t\t'foreignKey' => '{$associations['hasMany'][$i]['foreignKey']}',\n";
  1404. $out .= "\t\t\t\t\t\t\t\t'conditions' => '',\n";
  1405. $out .= "\t\t\t\t\t\t\t\t'fields' => '',\n";
  1406. $out .= "\t\t\t\t\t\t\t\t'order' => '',\n";
  1407. $out .= "\t\t\t\t\t\t\t\t'limit' => '',\n";
  1408. $out .= "\t\t\t\t\t\t\t\t'offset' => '',\n";
  1409. $out .= "\t\t\t\t\t\t\t\t'dependent' => '',\n";
  1410. $out .= "\t\t\t\t\t\t\t\t'exclusive' => '',\n";
  1411. $out .= "\t\t\t\t\t\t\t\t'finderQuery' => '',\n";
  1412. $out .= "\t\t\t\t\t\t\t\t'counterQuery' => ''";
  1413. $out .= "),\n";
  1414. }
  1415. $out .= "\t);\n\n";
  1416. }
  1417. if(!empty($associations['hasAndBelongsToMany'])) {
  1418. $out .= "\tvar \$hasAndBelongsToMany = array(\n";
  1419. for($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
  1420. $out .= "\t\t\t'{$associations['hasAndBelongsToMany'][$i]['alias']}' => ";
  1421. $out .= "array('className' => '{$associations['hasAndBelongsToMany'][$i]['className']}',\n";
  1422. $out .= "\t\t\t\t\t\t'joinTable' => '{$associations['hasAndBelongsToMany'][$i]['joinTable']}',\n";
  1423. $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasAndBelongsToMany'][$i]['foreignKey']}',\n";
  1424. $out .= "\t\t\t\t\t\t'associationForeignKey' => '{$associations['hasAndBelongsToMany'][$i]['associationForeignKey']}',\n";
  1425. $out .= "\t\t\t\t\t\t'conditions' => '',\n";
  1426. $out .= "\t\t\t\t\t\t'fields' => '',\n";
  1427. $out .= "\t\t\t\t\t\t'order' => '',\n";
  1428. $out .= "\t\t\t\t\t\t'limit' => '',\n";
  1429. $out .= "\t\t\t\t\t\t'offset' => '',\n";
  1430. $out .= "\t\t\t\t\t\t'unique' => '',\n";
  1431. $out .= "\t\t\t\t\t\t'finderQuery' => '',\n";
  1432. $out .= "\t\t\t\t\t\t'deleteQuery' => '',\n";
  1433. $out .= "\t\t\t\t\t\t'insertQuery' => ''";
  1434. $out .= "),\n";
  1435. }
  1436. $out .= "\t);\n\n";
  1437. }
  1438. }
  1439. $out .= "}\n";
  1440. $out .= "?>";
  1441. $filename = MODELS.Inflector::underscore($name) . '.php';
  1442. $this->createFile($filename, $out);
  1443. }
  1444. /**
  1445. * Assembles and writes a View file.
  1446. *
  1447. * @param string $controllerName
  1448. * @param string $actionName
  1449. * @param string $content
  1450. */
  1451. function bakeView($controllerName, $actionName, $content = '') {
  1452. $out = "<h2>{$actionName}</h2>\n";
  1453. $out .= $content;
  1454. if(!file_exists(VIEWS.$this->__controllerPath($controllerName))) {
  1455. mkdir(VIEWS.$this->__controllerPath($controllerName));
  1456. }
  1457. $filename = VIEWS . $this->__controllerPath($controllerName) . DS . Inflector::underscore($actionName) . '.ctp';
  1458. $this->createFile($filename, $out);
  1459. }
  1460. /**
  1461. * Assembles and writes a Controller file.
  1462. *
  1463. * @param string $controllerName
  1464. * @param array $uses
  1465. * @param array $helpers
  1466. * @param array $components
  1467. * @param string $actions
  1468. */
  1469. function bakeController($controllerName, $uses, $helpers, $components, $actions = '', $wannaUseScaffold = 'y') {
  1470. $out = "<?php\n";
  1471. $out .= "class $controllerName" . "Controller extends AppController {\n\n";
  1472. $out .= "\tvar \$name = '$controllerName';\n";
  1473. if(low($wannaUseScaffold) == 'y' || low($wannaUseScaffold) == 'yes') {
  1474. $out .= "\tvar \$scaffold;\n";
  1475. } else {
  1476. if (count($uses)) {
  1477. $out .= "\tvar \$uses = array('" . $this->__modelName($controllerName) . "', ";
  1478. foreach($uses as $use) {
  1479. if ($use != $uses[count($uses) - 1]) {
  1480. $out .= "'" . $this->__modelName($use) . "', ";
  1481. } else {
  1482. $out .= "'" . $this->__modelName($use) . "'";
  1483. }
  1484. }
  1485. $out .= ");\n";
  1486. }
  1487. $out .= "\tvar \$helpers = array('Html', 'Form' ";
  1488. if (count($helpers)) {
  1489. foreach($helpers as $help) {
  1490. if ($help != $helpers[count($helpers) - 1]) {
  1491. $out .= ", '" . Inflector::camelize($help) . "'";
  1492. } else {
  1493. $out .= ", '" . Inflector::camelize($help) . "'";
  1494. }
  1495. }
  1496. }
  1497. $out .= ");\n";
  1498. if (count($components)) {
  1499. $out .= "\tvar \$components = array(";
  1500. foreach($components as $comp) {
  1501. if ($comp != $components[count($components) - 1]) {
  1502. $out .= "'" . Inflector::camelize($comp) . "', ";
  1503. } else {
  1504. $out .= "'" . Inflector::camelize($comp) . "'";
  1505. }
  1506. }
  1507. $out .= ");\n";
  1508. }
  1509. }
  1510. $out .= $actions;
  1511. $out .= "}\n";
  1512. $out .= "?>";
  1513. $filename = CONTROLLERS . $this->__controllerPath($controllerName) . '_controller.php';
  1514. $this->createFile($filename, $out);
  1515. }
  1516. /**
  1517. * Assembles and writes a unit test file.
  1518. *
  1519. * @param string $type One of "model", and "controller".
  1520. * @param string $className
  1521. */
  1522. function bakeUnitTest($type, $className) {
  1523. $out = '<?php '."\n\n";
  1524. $error = false;
  1525. switch ($type) {
  1526. case 'model':
  1527. $out .= "loadModel('$className');\n\n";
  1528. $out .= "class {$className}TestCase extends UnitTestCase {\n";
  1529. $out .= "\tvar \$object = null;\n\n";
  1530. $out .= "\tfunction setUp() {\n\t\t\$this->object = new {$className}();\n";
  1531. $out .= "\t}\n\n\tfunction tearDown() {\n\t\tunset(\$this->object);\n\t}\n";
  1532. $out .= "\n\t/*\n\tfunction testMe() {\n";
  1533. $out .= "\t\t\$result = \$this->object->doSomething();\n";
  1534. $out .= "\t\t\$expected = 1;\n";
  1535. $out .= "\t\t\$this->assertEqual(\$result, \$expected);\n\t}\n\t*/\n}";
  1536. $path = MODEL_TESTS;
  1537. $filename = $this->__singularName($className).'.test.php';
  1538. break;
  1539. case 'controller':
  1540. $out .= "loadController('$className');\n\n";
  1541. $out .= "class {$className}ControllerTestCase extends UnitTestCase {\n";
  1542. $out .= "\tvar \$object = null;\n\n";
  1543. $out .= "\tfunction setUp() {\n\t\t\$this->object = new {$className}Controller();\n";
  1544. $out .= "\t}\n\n\tfunction tearDown() {\n\t\tunset(\$this->object);\n\t}\n";
  1545. $out .= "\n\t/*\n\tfunction testMe() {\n";
  1546. $out .= "\t\t\$result = \$this->object->doSomething();\n";
  1547. $out .= "\t\t\$expected = 1;\n";
  1548. $out .= "\t\t\$this->assertEqual(\$result, \$expected);\n\t}\n\t*/\n}";
  1549. $path = CONTROLLER_TESTS;
  1550. $filename = $this->__pluralName($className).'_controller.test.php';
  1551. break;
  1552. default:
  1553. $error = true;
  1554. break;
  1555. }
  1556. $out .= "\n?>";
  1557. if (!$error) {
  1558. $this->out("Baking unit test for $className...");
  1559. $path = explode(DS, $path);
  1560. foreach($path as $i => $val) {
  1561. if ($val == '' || $val == '../') {
  1562. unset($path[$i]);
  1563. }
  1564. }
  1565. $path = implode(DS, $path);
  1566. $unixPath = DS;
  1567. if (strpos(PHP_OS, 'WIN') === 0){
  1568. $unixPath = null;
  1569. }
  1570. if (!is_dir($unixPath.$path)) {
  1571. $create = $this->in("Unit test directory does not exist. Create it?", array('y','n'), 'y');
  1572. if (low($create) == 'y' || low($create) == 'yes') {
  1573. $build = array();
  1574. foreach(explode(DS, $path) as $i => $dir) {
  1575. $build[] = $dir;
  1576. if (!is_dir($unixPath.implode(DS, $build))) {
  1577. mkdir($unixPath.implode(DS, $build));
  1578. }
  1579. }
  1580. } else {
  1581. return false;
  1582. }
  1583. }
  1584. $this->createFile($unixPath.$path.DS.$filename, $out);
  1585. }
  1586. }
  1587. /**
  1588. * Outputs usage text on the standard output.
  1589. *
  1590. */
  1591. function help() {
  1592. $this->out('CakePHP Bake:');
  1593. $this->hr();
  1594. $this->out('The Bake script generates controllers, views and models for your application.');
  1595. $this->out('If run with no command line arguments, Bake guides the user through the class');
  1596. $this->out('creation process. You can customize the generation process by telling Bake');
  1597. $this->out('where different parts of your application are using command line arguments.');
  1598. $this->out('');
  1599. $this->hr('');
  1600. $this->out('usage: php bake.php [command] [path...]');
  1601. $this->out('');
  1602. $this->out('commands:');
  1603. $this->out(' -app [path...] Absolute path to Cake\'s app Folder.');
  1604. $this->out(' -core [path...] Absolute path to Cake\'s cake Folder.');
  1605. $this->out(' -help Shows this help message.');
  1606. $this->out(' -project [path...] Generates a new app folder in the path supplied.');
  1607. $this->out(' -root [path...] Absolute path to Cake\'s \app\webroot Folder.');
  1608. $this->out('');
  1609. }
  1610. /**
  1611. * Checks that given project path does not already exist, and
  1612. * finds the app directory in it. Then it calls __buildDirLayout() with that information.
  1613. *
  1614. * @param string $projectPath
  1615. */
  1616. function project($projectPath = null) {
  1617. if($projectPath != '') {
  1618. while ($this->__checkPath($projectPath) === true && $this->__checkPath(CONFIGS) === true) {
  1619. $response = $this->in('Bake -app in '.$projectPath, array('y','n'), 'y');
  1620. if(low($response) == 'y') {
  1621. $this->main();
  1622. exit();
  1623. } else {
  1624. $projectPath = $this->in("What is the full path for this app including the app directory name?\nExample: ".ROOT.DS."myapp", null, ROOT.DS.'myapp');
  1625. }
  1626. }
  1627. } else {
  1628. while ($projectPath == '') {
  1629. $projectPath = $this->in("What is the full path for this app including the app directory name?\nExample: ".ROOT.DS."myapp", null, ROOT.DS.'myapp');
  1630. if ($projectPath == '') {
  1631. $this->out('The directory path you supplied was empty. Please try again.');
  1632. }
  1633. }
  1634. }
  1635. $newPath = 'n';
  1636. while ($newPath != 'y' && ($this->__checkPath($projectPath) === true || $projectPath == '')) {
  1637. $newPath = $this->in('Directory '.$projectPath.' exists. Overwrite (y) or insert a new path', null, 'y');
  1638. if($newPath != 'y') {
  1639. $projectPath = $newPath;
  1640. }
  1641. while ($projectPath == '') {
  1642. $projectPath = $this->in('The directory path you supplied was empty. Please try again.');
  1643. }
  1644. }
  1645. $parentPath = explode(DS, $projectPath);
  1646. $count = count($parentPath);
  1647. $appName = $parentPath[$count - 1];
  1648. if($appName == '') {
  1649. $appName = $parentPath[$count - 2];
  1650. }
  1651. $this->__buildDirLayout($projectPath, $appName);
  1652. exit();
  1653. }
  1654. /**
  1655. * Returns true if given path is a directory.
  1656. *
  1657. * @param string $projectPath
  1658. * @return True if given path is a directory.
  1659. */
  1660. function __checkPath($projectPath) {
  1661. if(is_dir($projectPath)) {
  1662. return true;
  1663. } else {
  1664. return false;
  1665. }
  1666. }
  1667. /**
  1668. * Looks for a skeleton template of a Cake application,
  1669. * and if not found asks the user for a path. When there is a path
  1670. * this method will make a deep copy of the skeleton to the project directory.
  1671. * A default home page will be added, and the tmp file storage will be chmod'ed to 0777.
  1672. *
  1673. * @param string $projectPath
  1674. * @param string $appName
  1675. */
  1676. function __buildDirLayout($projectPath, $appName) {
  1677. $skel = '';
  1678. if($this->__checkPath(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'console'.DS.'libs'.DS.'templates'.DS.'skel') === true) {
  1679. $skel = CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'console'.DS.'libs'.DS.'templates'.DS.'skel';
  1680. } else {
  1681. while ($skel == '') {
  1682. $skel = $this->in("What is the full path for the cake install app directory?\nExample: ", null, ROOT.DS.'myapp'.DS);
  1683. if ($skel == '') {
  1684. $this->out('The directory path you supplied was empty. Please try again.');
  1685. } else {
  1686. while ($this->__checkPath($skel) === false) {
  1687. $skel = $this->in('Directory path does not exist please choose another:');
  1688. }
  1689. }
  1690. }
  1691. }
  1692. $this->out('');
  1693. $this->hr();
  1694. $this->out("Skel Directory: $skel");
  1695. $this->out("Will be copied to:");
  1696. $this->out("New App Directory: $projectPath");
  1697. $this->hr();
  1698. $looksGood = $this->in('Look okay?', array('y', 'n', 'q'), 'y');
  1699. if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
  1700. $verboseOuptut = $this->in('Do you want verbose output?', array('y', 'n'), 'n');
  1701. $verbose = false;
  1702. if (low($verboseOuptut) == 'y' || low($verboseOuptut) == 'yes') {
  1703. $verbose = true;
  1704. }
  1705. $this->__copydirr($skel, $projectPath, 0755, $verbose);
  1706. $this->hr();
  1707. $this->out('Created: '.$projectPath);
  1708. $this->hr();
  1709. $this->out('Creating welcome page');
  1710. $this->hr();
  1711. $this->__defaultHome($projectPath, $appName);
  1712. $this->out('Welcome page created');
  1713. if($this->__generateHash() === true ){
  1714. $this->out('Random hash key created for CAKE_SESSION_STRING');
  1715. } else {
  1716. $this->out('Unable to generate random hash for CAKE_SESSION_STRING, please change this yourself in ' . CONFIGS . 'core.php');
  1717. }
  1718. if(chmodr($projectPath.DS.'tmp', 0777) === false) {
  1719. $this->out('Could not set permissions on '. $projectPath.DS.'tmp'.DS.'*');
  1720. $this->out('You must manually check that these directories can be wrote to by the server');
  1721. }
  1722. return;
  1723. } elseif (low($looksGood) == 'q' || low($looksGood) == 'quit') {
  1724. $this->out('Bake Aborted.');
  1725. } else {
  1726. $this->project();
  1727. }
  1728. }
  1729. /**
  1730. * Recursive directory copy.
  1731. *
  1732. * @param string $fromDir
  1733. * @param string $toDir
  1734. * @param octal $chmod
  1735. * @param boolean $verbose
  1736. * @return Success.
  1737. */
  1738. function __copydirr($fromDir, $toDir, $chmod = 0755, $verbose = false) {
  1739. $errors=array();
  1740. $messages=array();
  1741. uses('folder');
  1742. $folder = new Folder($toDir, true, 0755);
  1743. if (!is_writable($toDir)) {
  1744. $errors[]='target '.$toDir.' is not writable';
  1745. }
  1746. if (!is_dir($fromDir)) {
  1747. $errors[]='source '.$fromDir.' is not a directory';
  1748. }
  1749. if (!empty($errors)) {
  1750. if ($verbose) {
  1751. foreach($errors as $err) {
  1752. $this->out('Error: '.$err);
  1753. }
  1754. }
  1755. return false;
  1756. }
  1757. $exceptions=array('.','..','.svn');
  1758. $handle = opendir($fromDir);
  1759. while (false!==($item = readdir($handle))) {
  1760. if (!in_array($item,$exceptions)) {
  1761. $from = $folder->addPathElement($fromDir, $item);
  1762. $to = $folder->addPathElement($toDir, $item);
  1763. if (is_file($from)) {
  1764. if (@copy($from, $to)) {
  1765. chmod($to, $chmod);
  1766. touch($to, filemtime($from));
  1767. $messages[]='File copied from '.$from.' to '.$to;
  1768. } else {
  1769. $errors[]='cannot copy file from '.$from.' to '.$to;
  1770. }
  1771. }
  1772. if (is_dir($from)) {
  1773. if (@mkdir($to)) {
  1774. chmod($to,$chmod);
  1775. $messages[]='Directory created: '.$to;
  1776. } else {
  1777. $errors[]='cannot create directory '.$to;
  1778. }
  1779. $this->__copydirr($from,$to,$chmod,$verbose);
  1780. }
  1781. }
  1782. }
  1783. closedir($handle);
  1784. if ($verbose) {
  1785. foreach($errors as $err) {
  1786. $this->out('Error: '.$err);
  1787. }
  1788. foreach($messages as $msg) {
  1789. $this->out($msg);
  1790. }
  1791. }
  1792. return true;
  1793. }
  1794. function __addAdminRoute($name){
  1795. $file = file_get_contents(CONFIGS.'core.php');
  1796. if (preg_match('%([/\\t\\x20]*define\\(\'CAKE_ADMIN\',[\\t\\x20\'a-z]*\\);)%', $file, $match)) {
  1797. $result = str_replace($match[0], 'define(\'CAKE_ADMIN\', \''.$name.'\');', $file);
  1798. if(file_put_contents(CONFIGS.'core.php', $result)){
  1799. return true;
  1800. } else {
  1801. return false;
  1802. }
  1803. } else {
  1804. return false;
  1805. }
  1806. }
  1807. function __generateHash(){
  1808. $file = file_get_contents(CONFIGS.'core.php');
  1809. if (preg_match('/([\\t\\x20]*define\\(\\\'CAKE_SESSION_STRING\\\',[\\t\\x20\'A-z0-9]*\\);)/', $file, $match)) {
  1810. uses('Security');
  1811. $string = Security::generateAuthKey();
  1812. $result = str_replace($match[0], 'define(\'CAKE_SESSION_STRING\', \''.$string.'\');', $file);
  1813. if(file_put_contents(CONFIGS.'core.php', $result)){
  1814. return true;
  1815. } else {
  1816. return false;
  1817. }
  1818. } else {
  1819. return false;
  1820. }
  1821. }
  1822. /**
  1823. * Outputs an ASCII art banner to standard output.
  1824. *
  1825. */
  1826. function welcome()
  1827. {
  1828. $this->out('');
  1829. $this->out(' ___ __ _ _ ___ __ _ _ __ __ __ _ _ ___ ');
  1830. $this->out('| |__| |_/ |__ |__] |__| |__] |__] |__| |_/ |__ ');
  1831. $this->out('|___ | | | \_ |___ | | | | |__] | | | \_ |___ ');
  1832. $this->hr();
  1833. $this->out('');
  1834. }
  1835. /**
  1836. * Writes a file with a default home page to the project.
  1837. *
  1838. * @param string $dir
  1839. * @param string $app
  1840. */
  1841. function __defaultHome($dir, $app) {
  1842. $path = $dir.DS.'views'.DS.'pages'.DS;
  1843. include(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'console'.DS.'libs'.DS.'templates'.DS.'views'.DS.'home.ctp');
  1844. $this->createFile($path.'home.ctp', $output);
  1845. }
  1846. /**
  1847. * creates the proper pluralize controller for the url
  1848. *
  1849. * @param string $name
  1850. * @return string $name
  1851. */
  1852. function __controllerPath($name) {
  1853. return low(Inflector::underscore($name));
  1854. }
  1855. /**
  1856. * creates the proper pluralize controller class name.
  1857. *
  1858. * @param string $name
  1859. * @return string $name
  1860. */
  1861. function __controllerName($name) {
  1862. return Inflector::pluralize(Inflector::camelize($name));
  1863. }
  1864. /**
  1865. * creates the proper singular model name.
  1866. *
  1867. * @param string $name
  1868. * @return string $name
  1869. */
  1870. function __modelName($name) {
  1871. return Inflector::camelize(Inflector::singularize($name));
  1872. }
  1873. /**
  1874. * creates the proper singular model key for associations.
  1875. *
  1876. * @param string $name
  1877. * @return string $name
  1878. */
  1879. function __modelKey($name) {
  1880. return Inflector::underscore(Inflector::singularize($name)).'_id';
  1881. }
  1882. /**
  1883. * creates the proper model name from a foreign key.
  1884. *
  1885. * @param string $key
  1886. * @return string $name
  1887. */
  1888. function __modelNameFromKey($key) {
  1889. $name = str_replace('_id', '',$key);
  1890. return $this->__modelName($name);
  1891. }
  1892. /**
  1893. * creates the singular name for use in views.
  1894. *
  1895. * @param string $name
  1896. * @return string $name
  1897. */
  1898. function __singularName($name) {
  1899. return Inflector::variable(Inflector::singularize($name));
  1900. }
  1901. /**
  1902. * creates the plural name for views.
  1903. *
  1904. * @param string $name
  1905. * @return string $name
  1906. */
  1907. function __pluralName($name) {
  1908. return Inflector::variable(Inflector::pluralize($name));
  1909. }
  1910. /**
  1911. * creates the singular human name used in views
  1912. *
  1913. * @param string $name
  1914. * @return string $name
  1915. */
  1916. function __singularHumanName($name) {
  1917. return Inflector::humanize(Inflector::underscore(Inflector::singularize($name)));
  1918. }
  1919. /**
  1920. * creates the plural humna name used in views
  1921. *
  1922. * @param string $name
  1923. * @return string $name
  1924. */
  1925. function __pluralHumanName($name) {
  1926. return Inflector::humanize(Inflector::underscore(Inflector::pluralize($name)));
  1927. }
  1928. /**
  1929. * outputs the a list of possible models or controllers from database
  1930. *
  1931. * @param string $useDbConfig
  1932. * @param string $type = Models or Controllers
  1933. * @return output
  1934. */
  1935. function __doList($useDbConfig = 'default', $type = 'Models') {
  1936. $db =& ConnectionManager::getDataSource($useDbConfig);
  1937. $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix'];
  1938. if ($usePrefix) {
  1939. $tables = array();
  1940. foreach ($db->listSources() as $table) {
  1941. if (!strncmp($table, $usePrefix, strlen($usePrefix))) {
  1942. $tables[] = substr($table, strlen($usePrefix));
  1943. }
  1944. }
  1945. } else {
  1946. $tables = $db->listSources();
  1947. }
  1948. $this->__tables = $tables;
  1949. $this->out('Possible '.$type.' based on your current database:');
  1950. $this->__controllerNames = array();
  1951. $this->__modelNames = array();
  1952. $count = count($tables);
  1953. for ($i = 0; $i < $count; $i++) {
  1954. if(low($type) == 'controllers') {
  1955. $this->__controllerNames[] = $this->__controllerName($this->__modelName($tables[$i]));
  1956. $this->out($i + 1 . ". " . $this->__controllerNames[$i]);
  1957. } else {
  1958. $this->__modelNames[] = $this->__modelName($tables[$i]);
  1959. $this->out($i + 1 . ". " . $this->__modelNames[$i]);
  1960. }
  1961. }
  1962. }
  1963. }
  1964. ?>