/cake/console/libs/tasks/project.php

https://github.com/hardsshah/bookmarks · PHP · 282 lines · 181 code · 18 blank · 83 comment · 55 complexity · b268b278267b0c08ae082d29619487d0 MD5 · raw file

  1. <?php
  2. /* SVN FILE: $Id$ */
  3. /**
  4. * The Project Task handles creating the base application
  5. *
  6. * Long description for file
  7. *
  8. * PHP versions 4 and 5
  9. *
  10. * CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
  11. * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
  12. *
  13. * Licensed under The MIT License
  14. * Redistributions of files must retain the above copyright notice.
  15. *
  16. * @filesource
  17. * @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
  18. * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
  19. * @package cake
  20. * @subpackage cake.cake.scripts.bake
  21. * @since CakePHP(tm) v 1.2
  22. * @version $Revision$
  23. * @modifiedby $LastChangedBy$
  24. * @lastmodified $Date$
  25. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  26. */
  27. if (!class_exists('File')) {
  28. uses('file');
  29. }
  30. /**
  31. * Task class for creating new project apps and plugins
  32. *
  33. * @package cake
  34. * @subpackage cake.cake.console.libs.tasks
  35. */
  36. class ProjectTask extends Shell {
  37. /**
  38. * Checks that given project path does not already exist, and
  39. * finds the app directory in it. Then it calls bake() with that information.
  40. *
  41. * @param string $project Project path
  42. * @access public
  43. */
  44. function execute($project = null) {
  45. if ($project === null) {
  46. if (isset($this->args[0])) {
  47. $project = $this->args[0];
  48. $this->Dispatch->shiftArgs();
  49. }
  50. }
  51. if ($project) {
  52. $this->Dispatch->parseParams(array('-app', $project));
  53. $project = $this->params['working'];
  54. }
  55. if (empty($this->params['skel'])) {
  56. $this->params['skel'] = '';
  57. if (is_dir(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'console'.DS.'libs'.DS.'templates'.DS.'skel') === true) {
  58. $this->params['skel'] = CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'console'.DS.'libs'.DS.'templates'.DS.'skel';
  59. }
  60. }
  61. while (!$project) {
  62. $project = $this->in("What is the full path for this app including the app directory name?\nExample: ".$this->params['working'] . DS . "myapp", null, $this->params['working'] . DS . 'myapp');
  63. }
  64. if ($project) {
  65. $response = false;
  66. while ($response == false && is_dir($project) === true && file_exists($project . 'config' . 'core.php')) {
  67. $response = $this->in('A project already exists in this location: '.$project.' Overwrite?', array('y','n'), 'n');
  68. if (strtolower($response) === 'n') {
  69. $response = $project = false;
  70. }
  71. }
  72. }
  73. if ($this->bake($project)) {
  74. $path = Folder::slashTerm($project);
  75. if ($this->createHome($path)) {
  76. $this->out(__('Welcome page created', true));
  77. } else {
  78. $this->out(__('The Welcome page was NOT created', true));
  79. }
  80. if ($this->securitySalt($path) === true ) {
  81. $this->out(__('Random hash key created for \'Security.salt\'', true));
  82. } else {
  83. $this->err(sprintf(__('Unable to generate random hash for \'Security.salt\', you should change it in %s', true), CONFIGS . 'core.php'));
  84. }
  85. $corePath = $this->corePath($path);
  86. if ($corePath === true ) {
  87. $this->out(sprintf(__('CAKE_CORE_INCLUDE_PATH set to %s in webroot/index.php', true), CAKE_CORE_INCLUDE_PATH));
  88. $this->out(sprintf(__('CAKE_CORE_INCLUDE_PATH set to %s in webroot/test.php', true), CAKE_CORE_INCLUDE_PATH));
  89. $this->out(__('Remember to check these value after moving to production server', true));
  90. } elseif ($corePath === false) {
  91. $this->err(sprintf(__('Unable to set CAKE_CORE_INCLUDE_PATH, you should change it in %s', true), $path . 'webroot' .DS .'index.php'));
  92. }
  93. $Folder = new Folder($path);
  94. if (!$Folder->chmod($path . 'tmp', 0777)) {
  95. $this->err(sprintf(__('Could not set permissions on %s', true), $path . DS .'tmp'));
  96. $this->out(sprintf(__('chmod -R 0777 %s', true), $path . DS .'tmp'));
  97. }
  98. $this->params['working'] = $path;
  99. $this->params['app'] = basename($path);
  100. return true;
  101. }
  102. }
  103. /**
  104. * Looks for a skeleton template of a Cake application,
  105. * and if not found asks the user for a path. When there is a path
  106. * this method will make a deep copy of the skeleton to the project directory.
  107. * A default home page will be added, and the tmp file storage will be chmod'ed to 0777.
  108. *
  109. * @param string $path Project path
  110. * @param string $skel Path to copy from
  111. * @param string $skip array of directories to skip when copying
  112. * @access private
  113. */
  114. function bake($path, $skel = null, $skip = array('empty')) {
  115. if (!$skel) {
  116. $skel = $this->params['skel'];
  117. }
  118. while (!$skel) {
  119. $skel = $this->in(sprintf(__("What is the path to the directory layout you wish to copy?\nExample: %s"), APP, null, ROOT . DS . 'myapp' . DS));
  120. if ($skel == '') {
  121. $this->out(__('The directory path you supplied was empty. Please try again.', true));
  122. } else {
  123. while (is_dir($skel) === false) {
  124. $skel = $this->in(__('Directory path does not exist please choose another:', true));
  125. }
  126. }
  127. }
  128. $app = basename($path);
  129. $this->out('Bake Project');
  130. $this->out("Skel Directory: $skel");
  131. $this->out("Will be copied to: {$path}");
  132. $this->hr();
  133. $looksGood = $this->in('Look okay?', array('y', 'n', 'q'), 'y');
  134. if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
  135. $verbose = $this->in(__('Do you want verbose output?', true), array('y', 'n'), 'n');
  136. $Folder = new Folder($skel);
  137. if ($Folder->copy(array('to' => $path, 'skip' => $skip))) {
  138. $this->hr();
  139. $this->out(sprintf(__("Created: %s in %s", true), $app, $path));
  140. $this->hr();
  141. } else {
  142. $this->err(" '".$app."' could not be created properly");
  143. return false;
  144. }
  145. if (low($verbose) == 'y' || low($verbose) == 'yes') {
  146. foreach ($Folder->messages() as $message) {
  147. $this->out($message);
  148. }
  149. }
  150. return true;
  151. } elseif (low($looksGood) == 'q' || low($looksGood) == 'quit') {
  152. $this->out('Bake Aborted.');
  153. } else {
  154. $this->execute(false);
  155. return false;
  156. }
  157. }
  158. /**
  159. * Writes a file with a default home page to the project.
  160. *
  161. * @param string $dir Path to project
  162. * @return boolean Success
  163. * @access public
  164. */
  165. function createHome($dir) {
  166. $app = basename($dir);
  167. $path = $dir . 'views' . DS . 'pages' . DS;
  168. include(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'console'.DS.'libs'.DS.'templates'.DS.'views'.DS.'home.ctp');
  169. return $this->createFile($path.'home.ctp', $output);
  170. }
  171. /**
  172. * Generates and writes 'Security.salt'
  173. *
  174. * @param string $path Project path
  175. * @return boolean Success
  176. * @access public
  177. */
  178. function securitySalt($path) {
  179. $File =& new File($path . 'config' . DS . 'core.php');
  180. $contents = $File->read();
  181. if (preg_match('/([\\t\\x20]*Configure::write\\(\\\'Security.salt\\\',[\\t\\x20\'A-z0-9]*\\);)/', $contents, $match)) {
  182. if (!class_exists('Security')) {
  183. uses('Security');
  184. }
  185. $string = Security::generateAuthKey();
  186. $result = str_replace($match[0], "\t" . 'Configure::write(\'Security.salt\', \''.$string.'\');', $contents);
  187. if ($File->write($result)) {
  188. return true;
  189. }
  190. return false;
  191. }
  192. return false;
  193. }
  194. /**
  195. * Generates and writes CAKE_CORE_INCLUDE_PATH
  196. *
  197. * @param string $path Project path
  198. * @return boolean Success
  199. * @access public
  200. */
  201. function corePath($path) {
  202. if (dirname($path) !== CAKE_CORE_INCLUDE_PATH) {
  203. $File =& new File($path . 'webroot' . DS . 'index.php');
  204. $contents = $File->read();
  205. if (preg_match('/([\\t\\x20]*define\\(\\\'CAKE_CORE_INCLUDE_PATH\\\',[\\t\\x20\'A-z0-9]*\\);)/', $contents, $match)) {
  206. $result = str_replace($match[0], "\t\tdefine('CAKE_CORE_INCLUDE_PATH', '".CAKE_CORE_INCLUDE_PATH."');", $contents);
  207. if (!$File->write($result)) {
  208. return false;
  209. }
  210. } else {
  211. return false;
  212. }
  213. $File =& new File($path . 'webroot' . DS . 'test.php');
  214. $contents = $File->read();
  215. if (preg_match('/([\\t\\x20]*define\\(\\\'CAKE_CORE_INCLUDE_PATH\\\',[\\t\\x20\'A-z0-9]*\\);)/', $contents, $match)) {
  216. $result = str_replace($match[0], "\t\tdefine('CAKE_CORE_INCLUDE_PATH', '".CAKE_CORE_INCLUDE_PATH."');", $contents);
  217. if (!$File->write($result)) {
  218. return false;
  219. }
  220. } else {
  221. return false;
  222. }
  223. return true;
  224. }
  225. }
  226. /**
  227. * Enables Configure::read('Routing.admin') in /app/config/core.php
  228. *
  229. * @param string $name Name to use as admin routing
  230. * @return boolean Success
  231. * @access public
  232. */
  233. function cakeAdmin($name) {
  234. $File =& new File(CONFIGS . 'core.php');
  235. $contents = $File->read();
  236. if (preg_match('%([/\\t\\x20]*Configure::write\(\'Routing.admin\',[\\t\\x20\'a-z]*\\);)%', $contents, $match)) {
  237. $result = str_replace($match[0], "\t" . 'Configure::write(\'Routing.admin\', \''.$name.'\');', $contents);
  238. if ($File->write($result)) {
  239. Configure::write('Routing.admin', $name);
  240. return true;
  241. } else {
  242. return false;
  243. }
  244. } else {
  245. return false;
  246. }
  247. }
  248. /**
  249. * Help
  250. *
  251. * @return void
  252. * @access public
  253. */
  254. function help() {
  255. $this->hr();
  256. $this->out("Usage: cake bake project <arg1>");
  257. $this->hr();
  258. $this->out('Commands:');
  259. $this->out("\n\tproject <name>\n\t\tbakes app directory structure.\n\t\tif <name> begins with '/' path is absolute.");
  260. $this->out("");
  261. $this->_stop();
  262. }
  263. }
  264. ?>