1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26: App::import('Core', 'Controller');
27: 28: 29: 30: 31: 32:
33: class ViewTask extends Shell {
34: 35: 36: 37: 38: 39:
40: var $plugin = null;
41: 42: 43: 44: 45: 46:
47: var $tasks = array('Project', 'Controller');
48: 49: 50: 51: 52: 53:
54: var $path = VIEWS;
55: 56: 57: 58: 59: 60:
61: var $controllerName = null;
62: 63: 64: 65: 66: 67:
68: var $controllerPath = null;
69: 70: 71: 72: 73: 74:
75: var $template = null;
76: 77: 78: 79: 80: 81:
82: var $scaffoldActions = array('index', 'view', 'add', 'edit');
83: 84: 85: 86: 87:
88: function initialize() {
89: }
90: 91: 92: 93: 94:
95: function execute() {
96: if (empty($this->args)) {
97: $this->__interactive();
98: }
99:
100: if (isset($this->args[0])) {
101: $controller = $action = $alias = null;
102: $this->controllerName = Inflector::camelize($this->args[0]);
103: $this->controllerPath = Inflector::underscore($this->controllerName);
104:
105: if (isset($this->args[1])) {
106: $this->template = $this->args[1];
107: }
108:
109: if (isset($this->args[2])) {
110: $action = $this->args[2];
111: }
112:
113: if (!$action) {
114: $action = $this->template;
115: }
116:
117: if (in_array($action, $this->scaffoldActions)) {
118: $this->bake($action, true);
119: } elseif ($action) {
120: $this->bake($action, true);
121: } else {
122: $vars = $this->__loadController();
123: if ($vars) {
124:
125: $methods = array_diff(
126: array_map('strtolower', get_class_methods($this->controllerName . 'Controller')),
127: array_map('strtolower', get_class_methods('appcontroller'))
128: );
129: if (empty($methods)) {
130: $methods = $this->scaffoldActions;
131: }
132: $adminDelete = null;
133:
134: $adminRoute = Configure::read('Routing.admin');
135: if (!empty($adminRoute)) {
136: $adminDelete = $adminRoute.'_delete';
137: }
138: foreach ($methods as $method) {
139: if ($method{0} != '_' && !in_array($method, array('delete', $adminDelete))) {
140: $content = $this->getContent($method, $vars);
141: $this->bake($method, $content);
142: }
143: }
144: }
145: }
146: }
147: }
148: 149: 150: 151: 152:
153: function __interactive() {
154: $this->hr();
155: $this->out(sprintf("Bake View\nPath: %s", $this->path));
156: $this->hr();
157: $wannaDoAdmin = 'n';
158: $wannaDoScaffold = 'y';
159: $this->interactive = false;
160:
161: $this->controllerName = $this->Controller->getName();
162:
163: $this->controllerPath = strtolower(Inflector::underscore($this->controllerName));
164:
165: $interactive = $this->in("Would you like bake to build your views interactively?\nWarning: Choosing no will overwrite {$this->controllerName} views if it exist.", array('y','n'), 'y');
166:
167: if (strtolower($interactive) == 'y' || strtolower($interactive) == 'yes') {
168: $this->interactive = true;
169: $wannaDoScaffold = $this->in("Would you like to create some scaffolded views (index, add, view, edit) for this controller?\nNOTE: Before doing so, you'll need to create your controller and model classes (including associated models).", array('y','n'), 'n');
170: }
171:
172: if (strtolower($wannaDoScaffold) == 'y' || strtolower($wannaDoScaffold) == 'yes') {
173: $wannaDoAdmin = $this->in("Would you like to create the views for admin routing?", array('y','n'), 'y');
174: }
175: $admin = false;
176:
177: if ((strtolower($wannaDoAdmin) == 'y' || strtolower($wannaDoAdmin) == 'yes')) {
178: $admin = $this->getAdmin();
179: }
180:
181: if (strtolower($wannaDoScaffold) == 'y' || strtolower($wannaDoScaffold) == 'yes') {
182: $actions = $this->scaffoldActions;
183: if ($admin) {
184: foreach ($actions as $action) {
185: $actions[] = $admin . $action;
186: }
187: }
188: $vars = $this->__loadController();
189: if ($vars) {
190: foreach ($actions as $action) {
191: $content = $this->getContent($action, $vars);
192: $this->bake($action, $content);
193: }
194: }
195: $this->hr();
196: $this->out('');
197: $this->out('View Scaffolding Complete.'."\n");
198: } else {
199: $action = '';
200: while ($action == '') {
201: $action = $this->in('Action Name? (use camelCased function name)');
202: if ($action == '') {
203: $this->out('The action name you supplied was empty. Please try again.');
204: }
205: }
206: $this->out('');
207: $this->hr();
208: $this->out('The following view will be created:');
209: $this->hr();
210: $this->out("Controller Name: {$this->controllerName}");
211: $this->out("Action Name: {$action}");
212: $this->out("Path: ".$this->params['app'] . DS . $this->controllerPath . DS . Inflector::underscore($action) . ".ctp");
213: $this->hr();
214: $looksGood = $this->in('Look okay?', array('y','n'), 'y');
215: if (strtolower($looksGood) == 'y' || strtolower($looksGood) == 'yes') {
216: $this->bake($action);
217: $this->_stop();
218: } else {
219: $this->out('Bake Aborted.');
220: }
221: }
222: }
223: 224: 225: 226: 227: 228: 229: 230: 231: 232:
233: function __loadController() {
234: if (!$this->controllerName) {
235: $this->err(__('Controller not found', true));
236: }
237:
238: $import = $this->controllerName;
239: if ($this->plugin) {
240: $import = $this->plugin . '.' . $this->controllerName;
241: }
242:
243: if (!App::import('Controller', $import)) {
244: $file = $this->controllerPath . '_controller.php';
245: $this->err(sprintf(__("The file '%s' could not be found.\nIn order to bake a view, you'll need to first create the controller.", true), $file));
246: $this->_stop();
247: }
248: $controllerClassName = $this->controllerName . 'Controller';
249: $controllerObj = & new $controllerClassName();
250: $controllerObj->constructClasses();
251: $modelClass = $controllerObj->modelClass;
252: $modelObj =& ClassRegistry::getObject($controllerObj->modelKey);
253:
254: if ($modelObj) {
255: $primaryKey = $modelObj->primaryKey;
256: $displayField = $modelObj->displayField;
257: $singularVar = Inflector::variable($modelClass);
258: $pluralVar = Inflector::variable($this->controllerName);
259: $singularHumanName = Inflector::humanize($modelClass);
260: $pluralHumanName = Inflector::humanize($this->controllerName);
261: $schema = $modelObj->schema();
262: $fields = array_keys($schema);
263: $associations = $this->__associations($modelObj);
264: } else {
265: $primaryKey = null;
266: $displayField = null;
267: $singularVar = Inflector::variable(Inflector::singularize($this->controllerName));
268: $pluralVar = Inflector::variable($this->controllerName);
269: $singularHumanName = Inflector::humanize(Inflector::singularize($this->controllerName));
270: $pluralHumanName = Inflector::humanize($this->controllerName);
271: $fields = array();
272: $schema = array();
273: $associations = array();
274: }
275:
276: return compact('modelClass', 'schema', 'primaryKey', 'displayField', 'singularVar', 'pluralVar',
277: 'singularHumanName', 'pluralHumanName', 'fields','associations');
278: }
279: 280: 281: 282: 283: 284: 285: 286:
287: function bake($action, $content = '') {
288: if ($content === true) {
289: $content = $this->getContent();
290: }
291: $filename = $this->path . $this->controllerPath . DS . Inflector::underscore($action) . '.ctp';
292: $Folder =& new Folder($this->path . $this->controllerPath, true);
293: $errors = $Folder->errors();
294: if (empty($errors)) {
295: $path = $Folder->slashTerm($Folder->pwd());
296: return $this->createFile($filename, $content);
297: } else {
298: foreach ($errors as $error) {
299: $this->err($error);
300: }
301: }
302: return false;
303: }
304: 305: 306: 307: 308: 309: 310: 311:
312: function getContent($template = null, $vars = null) {
313: if (!$template) {
314: $template = $this->template;
315: }
316: $action = $template;
317:
318: $adminRoute = Configure::read('Routing.admin');
319: if (!empty($adminRoute) && strpos($template, $adminRoute) !== false) {
320: $template = str_replace($adminRoute.'_', '', $template);
321: }
322: if (in_array($template, array('add', 'edit'))) {
323: $action = $template;
324: $template = 'form';
325: }
326: $loaded = false;
327: foreach ($this->Dispatch->shellPaths as $path) {
328: $templatePath = $path . 'templates' . DS . 'views' . DS .Inflector::underscore($template).'.ctp';
329: if (file_exists($templatePath) && is_file($templatePath)) {
330: $loaded = true;
331: break;
332: }
333: }
334: if (!$vars) {
335: $vars = $this->__loadController();
336: }
337: if ($loaded) {
338: extract($vars);
339: ob_start();
340: ob_implicit_flush(0);
341: include($templatePath);
342: $content = ob_get_clean();
343: return $content;
344: }
345: $this->hr();
346: $this->err(sprintf(__('Template for %s could not be found', true), $template));
347: return false;
348: }
349: 350: 351: 352: 353:
354: function help() {
355: $this->hr();
356: $this->out("Usage: cake bake view <arg1> <arg2>...");
357: $this->hr();
358: $this->out('Commands:');
359: $this->out("\n\tview <controller>\n\t\twill read the given controller for methods\n\t\tand bake corresponding views.\n\t\tIf var scaffold is found it will bake the scaffolded actions\n\t\t(index,view,add,edit)");
360: $this->out("\n\tview <controller> <action>\n\t\twill bake a template. core templates: (index, add, edit, view)");
361: $this->out("\n\tview <controller> <template> <alias>\n\t\twill use the template specified but name the file based on the alias");
362: $this->out("");
363: $this->_stop();
364: }
365: 366: 367: 368: 369: 370:
371: function __associations($model) {
372: $keys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
373: $associations = array();
374:
375: foreach ($keys as $key => $type) {
376: foreach ($model->{$type} as $assocKey => $assocData) {
377: $associations[$type][$assocKey]['primaryKey'] = $model->{$assocKey}->primaryKey;
378: $associations[$type][$assocKey]['displayField'] = $model->{$assocKey}->displayField;
379: $associations[$type][$assocKey]['foreignKey'] = $assocData['foreignKey'];
380: $associations[$type][$assocKey]['controller'] = Inflector::pluralize(Inflector::underscore($assocData['className']));
381: $associations[$type][$assocKey]['fields'] = array_keys($model->{$assocKey}->schema());
382: }
383: }
384: return $associations;
385: }
386: }
387:
388: ?>