統計
| ブランチ: | リビジョン:

pictcode / lib / Cake / Console / Command / Task / PluginTask.php @ 0b1b8047

履歴 | 表示 | アノテート | ダウンロード (6.464 KB)

1 635eef61 spyder1211
<?php
2
/**
3
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice.
9
 *
10
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11
 * @link          http://cakephp.org CakePHP(tm) Project
12
 * @since         CakePHP(tm) v 1.2
13
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
14
 */
15
16
App::uses('AppShell', 'Console/Command');
17
App::uses('File', 'Utility');
18
App::uses('Folder', 'Utility');
19
20
/**
21
 * The Plugin Task handles creating an empty plugin, ready to be used
22
 *
23
 * @package       Cake.Console.Command.Task
24
 */
25
class PluginTask extends AppShell {
26
27
/**
28
 * path to plugins directory
29
 *
30
 * @var array
31
 */
32
        public $path = null;
33
34
/**
35
 * Path to the bootstrap file. Changed in tests.
36
 *
37
 * @var string
38
 */
39
        public $bootstrap = null;
40
41
/**
42
 * initialize
43
 *
44
 * @return void
45
 */
46
        public function initialize() {
47
                $this->path = current(App::path('plugins'));
48
                $this->bootstrap = APP . 'Config' . DS . 'bootstrap.php';
49
        }
50
51
/**
52
 * Execution method always used for tasks
53
 *
54
 * @return void
55
 */
56
        public function execute() {
57
                if (isset($this->args[0])) {
58
                        $plugin = Inflector::camelize($this->args[0]);
59
                        $pluginPath = $this->_pluginPath($plugin);
60
                        if (is_dir($pluginPath)) {
61
                                $this->out(__d('cake_console', 'Plugin: %s already exists, no action taken', $plugin));
62
                                $this->out(__d('cake_console', 'Path: %s', $pluginPath));
63
                                return false;
64
                        }
65
                        $this->_interactive($plugin);
66
                } else {
67
                        return $this->_interactive();
68
                }
69
        }
70
71
/**
72
 * Interactive interface
73
 *
74
 * @param string $plugin The plugin name.
75
 * @return void
76
 */
77
        protected function _interactive($plugin = null) {
78
                while ($plugin === null) {
79
                        $plugin = $this->in(__d('cake_console', 'Enter the name of the plugin in CamelCase format'));
80
                }
81
82
                if (!$this->bake($plugin)) {
83
                        $this->error(__d('cake_console', "An error occurred trying to bake: %s in %s", $plugin, $this->path . $plugin));
84
                }
85
        }
86
87
/**
88
 * Bake the plugin, create directories and files
89
 *
90
 * @param string $plugin Name of the plugin in CamelCased format
91
 * @return bool
92
 */
93
        public function bake($plugin) {
94
                $pathOptions = App::path('plugins');
95
                if (count($pathOptions) > 1) {
96
                        $this->findPath($pathOptions);
97
                }
98
                $this->hr();
99
                $this->out(__d('cake_console', "<info>Plugin Name:</info> %s", $plugin));
100
                $this->out(__d('cake_console', "<info>Plugin Directory:</info> %s", $this->path . $plugin));
101
                $this->hr();
102
103
                $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n', 'q'), 'y');
104
105
                if (strtolower($looksGood) === 'y') {
106
                        $Folder = new Folder($this->path . $plugin);
107
                        $directories = array(
108
                                'Config' . DS . 'Schema',
109
                                'Console' . DS . 'Command' . DS . 'Task',
110
                                'Console' . DS . 'Templates',
111
                                'Controller' . DS . 'Component',
112
                                'Lib',
113
                                'Locale' . DS . 'eng' . DS . 'LC_MESSAGES',
114
                                'Model' . DS . 'Behavior',
115
                                'Model' . DS . 'Datasource',
116
                                'Test' . DS . 'Case' . DS . 'Controller' . DS . 'Component',
117
                                'Test' . DS . 'Case' . DS . 'Lib',
118
                                'Test' . DS . 'Case' . DS . 'Model' . DS . 'Behavior',
119
                                'Test' . DS . 'Case' . DS . 'Model' . DS . 'Datasource',
120
                                'Test' . DS . 'Case' . DS . 'View' . DS . 'Helper',
121
                                'Test' . DS . 'Fixture',
122
                                'View' . DS . 'Elements',
123
                                'View' . DS . 'Helper',
124
                                'View' . DS . 'Layouts',
125
                                'webroot' . DS . 'css',
126
                                'webroot' . DS . 'js',
127
                                'webroot' . DS . 'img',
128
                        );
129
130
                        foreach ($directories as $directory) {
131
                                $dirPath = $this->path . $plugin . DS . $directory;
132
                                $Folder->create($dirPath);
133
                                new File($dirPath . DS . 'empty', true);
134
                        }
135
136
                        foreach ($Folder->messages() as $message) {
137
                                $this->out($message, 1, Shell::VERBOSE);
138
                        }
139
140
                        $errors = $Folder->errors();
141
                        if (!empty($errors)) {
142
                                foreach ($errors as $message) {
143
                                        $this->error($message);
144
                                }
145
                                return false;
146
                        }
147
148
                        $controllerFileName = $plugin . 'AppController.php';
149
150
                        $out = "<?php\n\n";
151
                        $out .= "App::uses('AppController', 'Controller');\n\n";
152
                        $out .= "class {$plugin}AppController extends AppController {\n\n";
153
                        $out .= "}\n";
154
                        $this->createFile($this->path . $plugin . DS . 'Controller' . DS . $controllerFileName, $out);
155
156
                        $modelFileName = $plugin . 'AppModel.php';
157
158
                        $out = "<?php\n\n";
159
                        $out .= "App::uses('AppModel', 'Model');\n\n";
160
                        $out .= "class {$plugin}AppModel extends AppModel {\n\n";
161
                        $out .= "}\n";
162
                        $this->createFile($this->path . $plugin . DS . 'Model' . DS . $modelFileName, $out);
163
164
                        $this->_modifyBootstrap($plugin);
165
166
                        $this->hr();
167
                        $this->out(__d('cake_console', '<success>Created:</success> %s in %s', $plugin, $this->path . $plugin), 2);
168
                }
169
170
                return true;
171
        }
172
173
/**
174
 * Update the app's bootstrap.php file.
175
 *
176
 * @param string $plugin Name of plugin
177
 * @return void
178
 */
179
        protected function _modifyBootstrap($plugin) {
180
                $bootstrap = new File($this->bootstrap, false);
181
                $contents = $bootstrap->read();
182
                if (!preg_match("@\n\s*CakePlugin::loadAll@", $contents)) {
183
                        $bootstrap->append("\nCakePlugin::load('$plugin', array('bootstrap' => false, 'routes' => false));\n");
184
                        $this->out('');
185
                        $this->out(__d('cake_dev', '%s modified', $this->bootstrap));
186
                }
187
        }
188
189
/**
190
 * find and change $this->path to the user selection
191
 *
192
 * @param array $pathOptions The list of paths to look in.
193
 * @return void
194
 */
195
        public function findPath($pathOptions) {
196
                $valid = false;
197
                foreach ($pathOptions as $i => $path) {
198
                        if (!is_dir($path)) {
199
                                unset($pathOptions[$i]);
200
                        }
201
                }
202
                $pathOptions = array_values($pathOptions);
203
204
                $max = count($pathOptions);
205
                while (!$valid) {
206
                        foreach ($pathOptions as $i => $option) {
207
                                $this->out($i + 1 . '. ' . $option);
208
                        }
209
                        $prompt = __d('cake_console', 'Choose a plugin path from the paths above.');
210
                        $choice = $this->in($prompt, null, 1);
211
                        if ((int)$choice > 0 && (int)$choice <= $max) {
212
                                $valid = true;
213
                        }
214
                }
215
                $this->path = $pathOptions[$choice - 1];
216
        }
217
218
/**
219
 * Gets the option parser instance and configures it.
220
 *
221
 * @return ConsoleOptionParser
222
 */
223
        public function getOptionParser() {
224
                $parser = parent::getOptionParser();
225
226
                $parser->description(
227
                        __d('cake_console',        'Create the directory structure, AppModel and AppController classes for a new plugin. ' .
228
                        'Can create plugins in any of your bootstrapped plugin paths.')
229
                )->addArgument('name', array(
230
                        'help' => __d('cake_console', 'CamelCased name of the plugin to create.')
231
                ));
232
233
                return $parser;
234
        }
235
236
}