ControllerCommand.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <?php
  2. /**
  3. * ControllerCommand class file.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright 2008-2013 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * ControllerCommand generates a controller class.
  12. *
  13. * @author Qiang Xue <qiang.xue@gmail.com>
  14. * @package system.cli.commands.shell
  15. * @since 1.0
  16. */
  17. class ControllerCommand extends CConsoleCommand
  18. {
  19. /**
  20. * @var string the directory that contains templates for the model command.
  21. * Defaults to null, meaning using 'framework/cli/views/shell/controller'.
  22. * If you set this path and some views are missing in the directory,
  23. * the default views will be used.
  24. */
  25. public $templatePath;
  26. public function getHelp()
  27. {
  28. return <<<EOD
  29. USAGE
  30. controller <controller-ID> [action-ID] ...
  31. DESCRIPTION
  32. This command generates a controller and views associated with
  33. the specified actions.
  34. PARAMETERS
  35. * controller-ID: required, controller ID, e.g., 'post'.
  36. If the controller should be located under a subdirectory,
  37. please specify the controller ID as 'path/to/ControllerID',
  38. e.g., 'admin/user'.
  39. If the controller belongs to a module, please specify
  40. the controller ID as 'ModuleID/ControllerID' or
  41. 'ModuleID/path/to/Controller' (assuming the controller is
  42. under a subdirectory of that module).
  43. * action-ID: optional, action ID. You may supply one or several
  44. action IDs. A default 'index' action will always be generated.
  45. EXAMPLES
  46. * Generates the 'post' controller:
  47. controller post
  48. * Generates the 'post' controller with additional actions 'contact'
  49. and 'about':
  50. controller post contact about
  51. * Generates the 'post' controller which should be located under
  52. the 'admin' subdirectory of the base controller path:
  53. controller admin/post
  54. * Generates the 'post' controller which should belong to
  55. the 'admin' module:
  56. controller admin/post
  57. NOTE: in the last two examples, the commands are the same, but
  58. the generated controller file is located under different directories.
  59. Yii is able to detect whether 'admin' refers to a module or a subdirectory.
  60. EOD;
  61. }
  62. /**
  63. * Execute the action.
  64. * @param array $args command line parameters specific for this command
  65. * @return integer|null non zero application exit code for help or null on success
  66. */
  67. public function run($args)
  68. {
  69. if(!isset($args[0]))
  70. {
  71. echo "Error: controller name is required.\n";
  72. echo $this->getHelp();
  73. return 1;
  74. }
  75. $module=Yii::app();
  76. $controllerID=$args[0];
  77. if(($pos=strrpos($controllerID,'/'))===false)
  78. {
  79. $controllerClass=ucfirst($controllerID).'Controller';
  80. $controllerFile=$module->controllerPath.DIRECTORY_SEPARATOR.$controllerClass.'.php';
  81. $controllerID[0]=strtolower($controllerID[0]);
  82. }
  83. else
  84. {
  85. $last=substr($controllerID,$pos+1);
  86. $last[0]=strtolower($last[0]);
  87. $pos2=strpos($controllerID,'/');
  88. $first=substr($controllerID,0,$pos2);
  89. $middle=$pos===$pos2?'':substr($controllerID,$pos2+1,$pos-$pos2);
  90. $controllerClass=ucfirst($last).'Controller';
  91. $controllerFile=($middle===''?'':$middle.'/').$controllerClass.'.php';
  92. $controllerID=$middle===''?$last:$middle.'/'.$last;
  93. if(($m=Yii::app()->getModule($first))!==null)
  94. $module=$m;
  95. else
  96. {
  97. $controllerFile=$first.'/'.$controllerClass.'.php';
  98. $controllerID=$first.'/'.$controllerID;
  99. }
  100. $controllerFile=$module->controllerPath.DIRECTORY_SEPARATOR.str_replace('/',DIRECTORY_SEPARATOR,$controllerFile);
  101. }
  102. $args[]='index';
  103. $actions=array_unique(array_splice($args,1));
  104. $templatePath=$this->templatePath===null?YII_PATH.'/cli/views/shell/controller':$this->templatePath;
  105. $list=array(
  106. basename($controllerFile)=>array(
  107. 'source'=>$templatePath.DIRECTORY_SEPARATOR.'controller.php',
  108. 'target'=>$controllerFile,
  109. 'callback'=>array($this,'generateController'),
  110. 'params'=>array($controllerClass, $actions),
  111. ),
  112. );
  113. $viewPath=$module->viewPath.DIRECTORY_SEPARATOR.str_replace('/',DIRECTORY_SEPARATOR,$controllerID);
  114. foreach($actions as $name)
  115. {
  116. $list[$name.'.php']=array(
  117. 'source'=>$templatePath.DIRECTORY_SEPARATOR.'view.php',
  118. 'target'=>$viewPath.DIRECTORY_SEPARATOR.$name.'.php',
  119. 'callback'=>array($this,'generateAction'),
  120. 'params'=>array('controller'=>$controllerClass, 'action'=>$name),
  121. );
  122. }
  123. $this->copyFiles($list);
  124. if($module instanceof CWebModule)
  125. $moduleID=$module->id.'/';
  126. else
  127. $moduleID='';
  128. echo <<<EOD
  129. Controller '{$controllerID}' has been created in the following file:
  130. $controllerFile
  131. You may access it in the browser using the following URL:
  132. http://hostname/path/to/index.php?r={$moduleID}{$controllerID}
  133. EOD;
  134. }
  135. public function generateController($source,$params)
  136. {
  137. if(!is_file($source)) // fall back to default ones
  138. $source=YII_PATH.'/cli/views/shell/controller/'.basename($source);
  139. return $this->renderFile($source,array('className'=>$params[0],'actions'=>$params[1]),true);
  140. }
  141. public function generateAction($source,$params)
  142. {
  143. if(!is_file($source)) // fall back to default ones
  144. $source=YII_PATH.'/cli/views/shell/controller/'.basename($source);
  145. return $this->renderFile($source,$params,true);
  146. }
  147. }