Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16591 anikendra 1
<?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
}