pictcode / lib / Cake / Console / Command / ApiShell.php @ f4a6dc2c
履歴 | 表示 | アノテート | ダウンロード (7.067 KB)
| 1 | 635eef61 | spyder1211 | <?php
 | 
      
|---|---|---|---|
| 2 | /**
 | 
      ||
| 3 |  * API shell to get CakePHP core method signatures.
 | 
      ||
| 4 |  *
 | 
      ||
| 5 |  * Implementation of a Cake Shell to show CakePHP core method signatures.
 | 
      ||
| 6 |  *
 | 
      ||
| 7 |  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 | 
      ||
| 8 |  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 | 
      ||
| 9 |  *
 | 
      ||
| 10 |  * Licensed under The MIT License
 | 
      ||
| 11 |  * For full copyright and license information, please see the LICENSE.txt
 | 
      ||
| 12 |  * Redistributions of files must retain the above copyright notice.
 | 
      ||
| 13 |  *
 | 
      ||
| 14 |  * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 | 
      ||
| 15 |  * @link          http://cakephp.org CakePHP(tm) Project
 | 
      ||
| 16 |  * @since         CakePHP(tm) v 1.2.0.5012
 | 
      ||
| 17 |  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 | 
      ||
| 18 |  */
 | 
      ||
| 19 | |||
| 20 | App::uses('AppShell', 'Console/Command');  | 
      ||
| 21 | App::uses('File', 'Utility');  | 
      ||
| 22 | |||
| 23 | /**
 | 
      ||
| 24 |  * API shell to show method signatures of CakePHP core classes.
 | 
      ||
| 25 |  *
 | 
      ||
| 26 |  * Implementation of a Cake Shell to show CakePHP core method signatures.
 | 
      ||
| 27 |  *
 | 
      ||
| 28 |  * @package       Cake.Console.Command
 | 
      ||
| 29 |  */
 | 
      ||
| 30 | class ApiShell extends AppShell {  | 
      ||
| 31 | |||
| 32 | /**
 | 
      ||
| 33 |  * Map between short name for paths and real paths.
 | 
      ||
| 34 |  *
 | 
      ||
| 35 |  * @var array
 | 
      ||
| 36 |  */
 | 
      ||
| 37 | public $paths = array();  | 
      ||
| 38 | |||
| 39 | /**
 | 
      ||
| 40 |  * Override initialize of the Shell
 | 
      ||
| 41 |  *
 | 
      ||
| 42 |  * @return void
 | 
      ||
| 43 |  */
 | 
      ||
| 44 | public function initialize() {  | 
      ||
| 45 | $this->paths = array_merge($this->paths, array(  | 
      ||
| 46 | 'behavior' => CAKE . 'Model' . DS . 'Behavior' . DS,  | 
      ||
| 47 | 'cache' => CAKE . 'Cache' . DS,  | 
      ||
| 48 | 'controller' => CAKE . 'Controller' . DS,  | 
      ||
| 49 | 'component' => CAKE . 'Controller' . DS . 'Component' . DS,  | 
      ||
| 50 | 'helper' => CAKE . 'View' . DS . 'Helper' . DS,  | 
      ||
| 51 | 'model' => CAKE . 'Model' . DS,  | 
      ||
| 52 | 'view' => CAKE . 'View' . DS,  | 
      ||
| 53 | 'core' => CAKE  | 
      ||
| 54 | ));  | 
      ||
| 55 | }  | 
      ||
| 56 | |||
| 57 | /**
 | 
      ||
| 58 |  * Override main() to handle action
 | 
      ||
| 59 |  *
 | 
      ||
| 60 |  * @return void
 | 
      ||
| 61 |  */
 | 
      ||
| 62 | public function main() {  | 
      ||
| 63 | if (empty($this->args)) {  | 
      ||
| 64 | return $this->out($this->OptionParser->help());  | 
      ||
| 65 | }  | 
      ||
| 66 | |||
| 67 | $type = strtolower($this->args[0]);  | 
      ||
| 68 | |||
| 69 | if (isset($this->paths[$type])) {  | 
      ||
| 70 | $path = $this->paths[$type];  | 
      ||
| 71 |                 } else {
 | 
      ||
| 72 | $path = $this->paths['core'];  | 
      ||
| 73 | }  | 
      ||
| 74 | |||
| 75 | $count = count($this->args);  | 
      ||
| 76 | if ($count > 1) {  | 
      ||
| 77 | $file = Inflector::underscore($this->args[1]);  | 
      ||
| 78 | $class = Inflector::camelize($this->args[1]);  | 
      ||
| 79 | } elseif ($count) {  | 
      ||
| 80 | $file = $type;  | 
      ||
| 81 | $class = Inflector::camelize($type);  | 
      ||
| 82 | }  | 
      ||
| 83 | $objects = App::objects('class', $path);  | 
      ||
| 84 | if (in_array($class, $objects)) {  | 
      ||
| 85 | if (in_array($type, array('behavior', 'component', 'helper')) && $type !== $file) {  | 
      ||
| 86 | if (!preg_match('/' . Inflector::camelize($type) . '$/', $class)) {  | 
      ||
| 87 | $class .= Inflector::camelize($type);  | 
      ||
| 88 | }  | 
      ||
| 89 | }  | 
      ||
| 90 | |||
| 91 |                 } else {
 | 
      ||
| 92 | $this->error(__d('cake_console', '%s not found', $class));  | 
      ||
| 93 | }  | 
      ||
| 94 | |||
| 95 | $parsed = $this->_parseClass($path . $class . '.php', $class);  | 
      ||
| 96 | |||
| 97 | if (!empty($parsed)) {  | 
      ||
| 98 | if (isset($this->params['method'])) {  | 
      ||
| 99 | if (!isset($parsed[$this->params['method']])) {  | 
      ||
| 100 | $this->err(__d('cake_console', '%s::%s() could not be found', $class, $this->params['method']));  | 
      ||
| 101 | return $this->_stop();  | 
      ||
| 102 | }  | 
      ||
| 103 | $method = $parsed[$this->params['method']];  | 
      ||
| 104 | $this->out($class . '::' . $method['method'] . $method['parameters']);  | 
      ||
| 105 |                                 $this->hr();
 | 
      ||
| 106 | $this->out($method['comment'], true);  | 
      ||
| 107 |                         } else {
 | 
      ||
| 108 | $this->out(ucwords($class));  | 
      ||
| 109 |                                 $this->hr();
 | 
      ||
| 110 | $i = 0;  | 
      ||
| 111 | foreach ($parsed as $method) {  | 
      ||
| 112 | $list[] = ++$i . ". " . $method['method'] . $method['parameters'];  | 
      ||
| 113 | }  | 
      ||
| 114 | $this->out($list);  | 
      ||
| 115 | |||
| 116 | $methods = array_keys($parsed);  | 
      ||
| 117 | while ($number = strtolower($this->in(__d('cake_console', 'Select a number to see the more information about a specific method. q to quit. l to list.'), null, 'q'))) {  | 
      ||
| 118 | if ($number === 'q') {  | 
      ||
| 119 | $this->out(__d('cake_console', 'Done'));  | 
      ||
| 120 | return $this->_stop();  | 
      ||
| 121 | }  | 
      ||
| 122 | |||
| 123 | if ($number === 'l') {  | 
      ||
| 124 | $this->out($list);  | 
      ||
| 125 | }  | 
      ||
| 126 | |||
| 127 | if (isset($methods[--$number])) {  | 
      ||
| 128 | $method = $parsed[$methods[$number]];  | 
      ||
| 129 |                                                 $this->hr();
 | 
      ||
| 130 | $this->out($class . '::' . $method['method'] . $method['parameters']);  | 
      ||
| 131 |                                                 $this->hr();
 | 
      ||
| 132 | $this->out($method['comment'], true);  | 
      ||
| 133 | }  | 
      ||
| 134 | }  | 
      ||
| 135 | }  | 
      ||
| 136 | }  | 
      ||
| 137 | }  | 
      ||
| 138 | |||
| 139 | /**
 | 
      ||
| 140 |  * Gets the option parser instance and configures it.
 | 
      ||
| 141 |  *
 | 
      ||
| 142 |  * @return ConsoleOptionParser
 | 
      ||
| 143 |  */
 | 
      ||
| 144 | public function getOptionParser() {  | 
      ||
| 145 | $parser = parent::getOptionParser();  | 
      ||
| 146 | |||
| 147 |                 $parser->description(
 | 
      ||
| 148 | __d('cake_console', 'Lookup doc block comments for classes in CakePHP.')  | 
      ||
| 149 | )->addArgument('type', array(  | 
      ||
| 150 | 'help' => __d('cake_console', 'Either a full path or type of class (model, behavior, controller, component, view, helper)')  | 
      ||
| 151 | ))->addArgument('className', array(  | 
      ||
| 152 | 'help' => __d('cake_console', 'A CakePHP core class name (e.g: Component, HtmlHelper).')  | 
      ||
| 153 | ))->addOption('method', array(  | 
      ||
| 154 | 'short' => 'm',  | 
      ||
| 155 | 'help' => __d('cake_console', 'The specific method you want help on.')  | 
      ||
| 156 | ));  | 
      ||
| 157 | |||
| 158 | return $parser;  | 
      ||
| 159 | }  | 
      ||
| 160 | |||
| 161 | /**
 | 
      ||
| 162 |  * Show help for this shell.
 | 
      ||
| 163 |  *
 | 
      ||
| 164 |  * @return void
 | 
      ||
| 165 |  */
 | 
      ||
| 166 | public function help() {  | 
      ||
| 167 | $head = "Usage: cake api [<type>] <className> [-m <method>]\n";  | 
      ||
| 168 | $head .= "-----------------------------------------------\n";  | 
      ||
| 169 | $head .= "Parameters:\n\n";  | 
      ||
| 170 | |||
| 171 | $commands = array(  | 
      ||
| 172 | 'path' => "\t<type>\n" .  | 
      ||
| 173 |                                 "\t\tEither a full path or type of class (model, behavior, controller, component, view, helper).\n" .
 | 
      ||
| 174 |                                 "\t\tAvailable values:\n\n" .
 | 
      ||
| 175 |                                 "\t\tbehavior\tLook for class in CakePHP behavior path\n" .
 | 
      ||
| 176 |                                 "\t\tcache\tLook for class in CakePHP cache path\n" .
 | 
      ||
| 177 |                                 "\t\tcontroller\tLook for class in CakePHP controller path\n" .
 | 
      ||
| 178 |                                 "\t\tcomponent\tLook for class in CakePHP component path\n" .
 | 
      ||
| 179 |                                 "\t\thelper\tLook for class in CakePHP helper path\n" .
 | 
      ||
| 180 |                                 "\t\tmodel\tLook for class in CakePHP model path\n" .
 | 
      ||
| 181 |                                 "\t\tview\tLook for class in CakePHP view path\n",
 | 
      ||
| 182 | 'className' => "\t<className>\n" .  | 
      ||
| 183 |                                 "\t\tA CakePHP core class name (e.g: Component, HtmlHelper).\n"
 | 
      ||
| 184 | );  | 
      ||
| 185 | |||
| 186 | $this->out($head);  | 
      ||
| 187 | if (!isset($this->args[1])) {  | 
      ||
| 188 | foreach ($commands as $cmd) {  | 
      ||
| 189 | $this->out("{$cmd}\n\n");  | 
      ||
| 190 | }  | 
      ||
| 191 | } elseif (isset($commands[strtolower($this->args[1])])) {  | 
      ||
| 192 | $this->out($commands[strtolower($this->args[1])] . "\n\n");  | 
      ||
| 193 |                 } else {
 | 
      ||
| 194 | $this->out(__d('cake_console', 'Command %s not found', $this->args[1]));  | 
      ||
| 195 | }  | 
      ||
| 196 | }  | 
      ||
| 197 | |||
| 198 | /**
 | 
      ||
| 199 |  * Parse a given class (located on given file) and get public methods and their
 | 
      ||
| 200 |  * signatures.
 | 
      ||
| 201 |  *
 | 
      ||
| 202 |  * @param string $path File path
 | 
      ||
| 203 |  * @param string $class Class name
 | 
      ||
| 204 |  * @return array Methods and signatures indexed by method name
 | 
      ||
| 205 |  */
 | 
      ||
| 206 | protected function _parseClass($path, $class) {  | 
      ||
| 207 | $parsed = array();  | 
      ||
| 208 | |||
| 209 | if (!class_exists($class)) {  | 
      ||
| 210 | if (!include_once $path) {  | 
      ||
| 211 | $this->err(__d('cake_console', '%s could not be found', $path));  | 
      ||
| 212 | }  | 
      ||
| 213 | }  | 
      ||
| 214 | |||
| 215 | $reflection = new ReflectionClass($class);  | 
      ||
| 216 | |||
| 217 | foreach ($reflection->getMethods() as $method) {  | 
      ||
| 218 | if (!$method->isPublic() || strpos($method->getName(), '_') === 0) {  | 
      ||
| 219 |                                 continue;
 | 
      ||
| 220 | }  | 
      ||
| 221 | if ($method->getDeclaringClass()->getName() != $class) {  | 
      ||
| 222 |                                 continue;
 | 
      ||
| 223 | }  | 
      ||
| 224 | $args = array();  | 
      ||
| 225 | foreach ($method->getParameters() as $param) {  | 
      ||
| 226 | $paramString = '$' . $param->getName();  | 
      ||
| 227 | if ($param->isDefaultValueAvailable()) {  | 
      ||
| 228 | $paramString .= ' = ' . str_replace("\n", '', var_export($param->getDefaultValue(), true));  | 
      ||
| 229 | }  | 
      ||
| 230 | $args[] = $paramString;  | 
      ||
| 231 | }  | 
      ||
| 232 | $parsed[$method->getName()] = array(  | 
      ||
| 233 | 'comment' => str_replace(array('/*', '*/', '*'), '', $method->getDocComment()),  | 
      ||
| 234 | 'method' => $method->getName(),  | 
      ||
| 235 | 'parameters' => '(' . implode(', ', $args) . ')'  | 
      ||
| 236 | );  | 
      ||
| 237 | }  | 
      ||
| 238 | ksort($parsed);  | 
      ||
| 239 | return $parsed;  | 
      ||
| 240 | }  | 
      ||
| 241 | |||
| 242 | }  |