CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.6 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.6
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
      • Validator
    • Network
      • Email
      • Http
    • Routing
      • Filter
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

  • BakeTask
  • CommandTask
  • ControllerTask
  • DbConfigTask
  • ExtractTask
  • FixtureTask
  • ModelTask
  • PluginTask
  • ProjectTask
  • TemplateTask
  • TestTask
  • ViewTask
  1: <?php
  2: /**
  3:  * The View Tasks handles creating and updating view files.
  4:  *
  5:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  6:  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  7:  *
  8:  * Licensed under The MIT License
  9:  * For full copyright and license information, please see the LICENSE.txt
 10:  * Redistributions of files must retain the above copyright notice.
 11:  *
 12:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 13:  * @link          http://cakephp.org CakePHP(tm) Project
 14:  * @since         CakePHP(tm) v 1.2
 15:  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 16:  */
 17: 
 18: App::uses('AppShell', 'Console/Command');
 19: App::uses('Controller', 'Controller');
 20: App::uses('BakeTask', 'Console/Command/Task');
 21: 
 22: /**
 23:  * Task class for creating and updating view files.
 24:  *
 25:  * @package       Cake.Console.Command.Task
 26:  */
 27: class ViewTask extends BakeTask {
 28: 
 29: /**
 30:  * Tasks to be loaded by this Task
 31:  *
 32:  * @var array
 33:  */
 34:     public $tasks = array('Project', 'Controller', 'DbConfig', 'Template');
 35: 
 36: /**
 37:  * path to View directory
 38:  *
 39:  * @var array
 40:  */
 41:     public $path = null;
 42: 
 43: /**
 44:  * Name of the controller being used
 45:  *
 46:  * @var string
 47:  */
 48:     public $controllerName = null;
 49: 
 50: /**
 51:  * The template file to use
 52:  *
 53:  * @var string
 54:  */
 55:     public $template = null;
 56: 
 57: /**
 58:  * Actions to use for scaffolding
 59:  *
 60:  * @var array
 61:  */
 62:     public $scaffoldActions = array('index', 'view', 'add', 'edit');
 63: 
 64: /**
 65:  * An array of action names that don't require templates. These
 66:  * actions will not emit errors when doing bakeActions()
 67:  *
 68:  * @var array
 69:  */
 70:     public $noTemplateActions = array('delete');
 71: 
 72: /**
 73:  * Override initialize
 74:  *
 75:  * @return void
 76:  */
 77:     public function initialize() {
 78:         $this->path = current(App::path('View'));
 79:     }
 80: 
 81: /**
 82:  * Execution method always used for tasks
 83:  *
 84:  * @return mixed
 85:  */
 86:     public function execute() {
 87:         parent::execute();
 88:         if (empty($this->args)) {
 89:             $this->_interactive();
 90:         }
 91:         if (empty($this->args[0])) {
 92:             return;
 93:         }
 94:         if (!isset($this->connection)) {
 95:             $this->connection = 'default';
 96:         }
 97:         $action = null;
 98:         $this->controllerName = $this->_controllerName($this->args[0]);
 99: 
100:         $this->Project->interactive = false;
101:         if (strtolower($this->args[0]) === 'all') {
102:             return $this->all();
103:         }
104: 
105:         if (isset($this->args[1])) {
106:             $this->template = $this->args[1];
107:         }
108:         if (isset($this->args[2])) {
109:             $action = $this->args[2];
110:         }
111:         if (!$action) {
112:             $action = $this->template;
113:         }
114:         if ($action) {
115:             return $this->bake($action, true);
116:         }
117: 
118:         $vars = $this->_loadController();
119:         $methods = $this->_methodsToBake();
120: 
121:         foreach ($methods as $method) {
122:             $content = $this->getContent($method, $vars);
123:             if ($content) {
124:                 $this->bake($method, $content);
125:             }
126:         }
127:     }
128: 
129: /**
130:  * Get a list of actions that can / should have views baked for them.
131:  *
132:  * @return array Array of action names that should be baked
133:  */
134:     protected function _methodsToBake() {
135:         $methods = array_diff(
136:             array_map('strtolower', get_class_methods($this->controllerName . 'Controller')),
137:             array_map('strtolower', get_class_methods('AppController'))
138:         );
139:         $scaffoldActions = false;
140:         if (empty($methods)) {
141:             $scaffoldActions = true;
142:             $methods = $this->scaffoldActions;
143:         }
144:         $adminRoute = $this->Project->getPrefix();
145:         foreach ($methods as $i => $method) {
146:             if ($adminRoute && !empty($this->params['admin'])) {
147:                 if ($scaffoldActions) {
148:                     $methods[$i] = $adminRoute . $method;
149:                     continue;
150:                 } elseif (strpos($method, $adminRoute) === false) {
151:                     unset($methods[$i]);
152:                 }
153:             }
154:             if ($method[0] === '_' || $method === strtolower($this->controllerName . 'Controller')) {
155:                 unset($methods[$i]);
156:             }
157:         }
158:         return $methods;
159:     }
160: 
161: /**
162:  * Bake All views for All controllers.
163:  *
164:  * @return void
165:  */
166:     public function all() {
167:         $this->Controller->interactive = false;
168:         $tables = $this->Controller->listAll($this->connection, false);
169: 
170:         $actions = null;
171:         if (isset($this->args[1])) {
172:             $actions = array($this->args[1]);
173:         }
174:         $this->interactive = false;
175:         foreach ($tables as $table) {
176:             $model = $this->_modelName($table);
177:             $this->controllerName = $this->_controllerName($model);
178:             App::uses($model, 'Model');
179:             if (class_exists($model)) {
180:                 $vars = $this->_loadController();
181:                 if (!$actions) {
182:                     $actions = $this->_methodsToBake();
183:                 }
184:                 $this->bakeActions($actions, $vars);
185:                 $actions = null;
186:             }
187:         }
188:     }
189: 
190: /**
191:  * Handles interactive baking
192:  *
193:  * @return void
194:  */
195:     protected function _interactive() {
196:         $this->hr();
197:         $this->out(sprintf("Bake View\nPath: %s", $this->getPath()));
198:         $this->hr();
199: 
200:         $this->DbConfig->interactive = $this->Controller->interactive = $this->interactive = true;
201: 
202:         if (empty($this->connection)) {
203:             $this->connection = $this->DbConfig->getConfig();
204:         }
205: 
206:         $this->Controller->connection = $this->connection;
207:         $this->controllerName = $this->Controller->getName();
208: 
209:         $prompt = __d('cake_console', "Would you like bake to build your views interactively?\nWarning: Choosing no will overwrite %s views if they exist.", $this->controllerName);
210:         $interactive = $this->in($prompt, array('y', 'n'), 'n');
211: 
212:         if (strtolower($interactive) === 'n') {
213:             $this->interactive = false;
214:         }
215: 
216:         $prompt = __d('cake_console', "Would you like to create some CRUD views\n(index, add, view, edit) for this controller?\nNOTE: Before doing so, you'll need to create your controller\nand model classes (including associated models).");
217:         $wannaDoScaffold = $this->in($prompt, array('y', 'n'), 'y');
218: 
219:         $wannaDoAdmin = $this->in(__d('cake_console', "Would you like to create the views for admin routing?"), array('y', 'n'), 'n');
220: 
221:         if (strtolower($wannaDoScaffold) === 'y' || strtolower($wannaDoAdmin) === 'y') {
222:             $vars = $this->_loadController();
223:             if (strtolower($wannaDoScaffold) === 'y') {
224:                 $actions = $this->scaffoldActions;
225:                 $this->bakeActions($actions, $vars);
226:             }
227:             if (strtolower($wannaDoAdmin) === 'y') {
228:                 $admin = $this->Project->getPrefix();
229:                 $regularActions = $this->scaffoldActions;
230:                 $adminActions = array();
231:                 foreach ($regularActions as $action) {
232:                     $adminActions[] = $admin . $action;
233:                 }
234:                 $this->bakeActions($adminActions, $vars);
235:             }
236:             $this->hr();
237:             $this->out();
238:             $this->out(__d('cake_console', "View Scaffolding Complete.\n"));
239:         } else {
240:             $this->customAction();
241:         }
242:     }
243: 
244: /**
245:  * Loads Controller and sets variables for the template
246:  * Available template variables
247:  *  'modelClass', 'primaryKey', 'displayField', 'singularVar', 'pluralVar',
248:  *  'singularHumanName', 'pluralHumanName', 'fields', 'foreignKeys',
249:  *  'belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany'
250:  *
251:  * @return array Returns a variables to be made available to a view template
252:  */
253:     protected function _loadController() {
254:         if (!$this->controllerName) {
255:             $this->err(__d('cake_console', 'Controller not found'));
256:         }
257: 
258:         $plugin = null;
259:         if ($this->plugin) {
260:             $plugin = $this->plugin . '.';
261:         }
262: 
263:         $controllerClassName = $this->controllerName . 'Controller';
264:         App::uses($controllerClassName, $plugin . 'Controller');
265:         if (!class_exists($controllerClassName)) {
266:             $file = $controllerClassName . '.php';
267:             $this->err(__d('cake_console', "The file '%s' could not be found.\nIn order to bake a view, you'll need to first create the controller.", $file));
268:             return $this->_stop();
269:         }
270:         $controllerObj = new $controllerClassName();
271:         $controllerObj->plugin = $this->plugin;
272:         $controllerObj->constructClasses();
273:         $modelClass = $controllerObj->modelClass;
274:         $modelObj = $controllerObj->{$controllerObj->modelClass};
275: 
276:         if ($modelObj) {
277:             $primaryKey = $modelObj->primaryKey;
278:             $displayField = $modelObj->displayField;
279:             $singularVar = Inflector::variable($modelClass);
280:             $singularHumanName = $this->_singularHumanName($this->controllerName);
281:             $schema = $modelObj->schema(true);
282:             $fields = array_keys($schema);
283:             $associations = $this->_associations($modelObj);
284:         } else {
285:             $primaryKey = $displayField = null;
286:             $singularVar = Inflector::variable(Inflector::singularize($this->controllerName));
287:             $singularHumanName = $this->_singularHumanName($this->controllerName);
288:             $fields = $schema = $associations = array();
289:         }
290:         $pluralVar = Inflector::variable($this->controllerName);
291:         $pluralHumanName = $this->_pluralHumanName($this->controllerName);
292: 
293:         return compact('modelClass', 'schema', 'primaryKey', 'displayField', 'singularVar', 'pluralVar',
294:                 'singularHumanName', 'pluralHumanName', 'fields', 'associations');
295:     }
296: 
297: /**
298:  * Bake a view file for each of the supplied actions
299:  *
300:  * @param array $actions Array of actions to make files for.
301:  * @param array $vars The template variables.
302:  * @return void
303:  */
304:     public function bakeActions($actions, $vars) {
305:         foreach ($actions as $action) {
306:             $content = $this->getContent($action, $vars);
307:             $this->bake($action, $content);
308:         }
309:     }
310: 
311: /**
312:  * handle creation of baking a custom action view file
313:  *
314:  * @return void
315:  */
316:     public function customAction() {
317:         $action = '';
318:         while (!$action) {
319:             $action = $this->in(__d('cake_console', 'Action Name? (use lowercase_underscored function name)'));
320:             if (!$action) {
321:                 $this->out(__d('cake_console', 'The action name you supplied was empty. Please try again.'));
322:             }
323:         }
324:         $this->out();
325:         $this->hr();
326:         $this->out(__d('cake_console', 'The following view will be created:'));
327:         $this->hr();
328:         $this->out(__d('cake_console', 'Controller Name: %s', $this->controllerName));
329:         $this->out(__d('cake_console', 'Action Name:     %s', $action));
330:         $this->out(__d('cake_console', 'Path:            %s', $this->getPath() . $this->controllerName . DS . Inflector::underscore($action) . ".ctp"));
331:         $this->hr();
332:         $looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y', 'n'), 'y');
333:         if (strtolower($looksGood) === 'y') {
334:             $this->bake($action, ' ');
335:             return $this->_stop();
336:         }
337:         $this->out(__d('cake_console', 'Bake Aborted.'));
338:     }
339: 
340: /**
341:  * Assembles and writes bakes the view file.
342:  *
343:  * @param string $action Action to bake
344:  * @param string $content Content to write
345:  * @return bool Success
346:  */
347:     public function bake($action, $content = '') {
348:         if ($content === true) {
349:             $content = $this->getContent($action);
350:         }
351:         if (empty($content)) {
352:             return false;
353:         }
354:         $this->out("\n" . __d('cake_console', 'Baking `%s` view file...', $action), 1, Shell::QUIET);
355:         $path = $this->getPath();
356:         $filename = $path . $this->controllerName . DS . Inflector::underscore($action) . '.ctp';
357:         return $this->createFile($filename, $content);
358:     }
359: 
360: /**
361:  * Builds content from template and variables
362:  *
363:  * @param string $action name to generate content to
364:  * @param array $vars passed for use in templates
365:  * @return string content from template
366:  */
367:     public function getContent($action, $vars = null) {
368:         if (!$vars) {
369:             $vars = $this->_loadController();
370:         }
371: 
372:         $this->Template->set('action', $action);
373:         $this->Template->set('plugin', $this->plugin);
374:         $this->Template->set($vars);
375:         $template = $this->getTemplate($action);
376:         if ($template) {
377:             return $this->Template->generate('views', $template);
378:         }
379:         return false;
380:     }
381: 
382: /**
383:  * Gets the template name based on the action name
384:  *
385:  * @param string $action name
386:  * @return string template name
387:  */
388:     public function getTemplate($action) {
389:         if ($action != $this->template && in_array($action, $this->noTemplateActions)) {
390:             return false;
391:         }
392:         if (!empty($this->template) && $action != $this->template) {
393:             return $this->template;
394:         }
395:         $themePath = $this->Template->getThemePath();
396:         if (file_exists($themePath . 'views' . DS . $action . '.ctp')) {
397:             return $action;
398:         }
399:         $template = $action;
400:         $prefixes = Configure::read('Routing.prefixes');
401:         foreach ((array)$prefixes as $prefix) {
402:             if (strpos($template, $prefix) !== false) {
403:                 $template = str_replace($prefix . '_', '', $template);
404:             }
405:         }
406:         if (in_array($template, array('add', 'edit'))) {
407:             $template = 'form';
408:         } elseif (preg_match('@(_add|_edit)$@', $template)) {
409:             $template = str_replace(array('_add', '_edit'), '_form', $template);
410:         }
411:         return $template;
412:     }
413: 
414: /**
415:  * Gets the option parser instance and configures it.
416:  *
417:  * @return ConsoleOptionParser
418:  */
419:     public function getOptionParser() {
420:         $parser = parent::getOptionParser();
421: 
422:         $parser->description(
423:             __d('cake_console', 'Bake views for a controller, using built-in or custom templates.')
424:         )->addArgument('controller', array(
425:             'help' => __d('cake_console', 'Name of the controller views to bake. Can be Plugin.name as a shortcut for plugin baking.')
426:         ))->addArgument('action', array(
427:             'help' => __d('cake_console', "Will bake a single action's file. core templates are (index, add, edit, view)")
428:         ))->addArgument('alias', array(
429:             'help' => __d('cake_console', 'Will bake the template in <action> but create the filename after <alias>.')
430:         ))->addOption('plugin', array(
431:             'short' => 'p',
432:             'help' => __d('cake_console', 'Plugin to bake the view into.')
433:         ))->addOption('admin', array(
434:             'help' => __d('cake_console', 'Set to only bake views for a prefix in Routing.prefixes'),
435:             'boolean' => true
436:         ))->addOption('theme', array(
437:             'short' => 't',
438:             'help' => __d('cake_console', 'Theme to use when baking code.')
439:         ))->addOption('connection', array(
440:             'short' => 'c',
441:             'help' => __d('cake_console', 'The connection the connected model is on.')
442:         ))->addOption('force', array(
443:             'short' => 'f',
444:             'help' => __d('cake_console', 'Force overwriting existing files without prompting.')
445:         ))->addSubcommand('all', array(
446:             'help' => __d('cake_console', 'Bake all CRUD action views for all controllers. Requires models and controllers to exist.')
447:         ))->epilog(
448:             __d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.')
449:         );
450: 
451:         return $parser;
452:     }
453: 
454: /**
455:  * Returns associations for controllers models.
456:  *
457:  * @param Model $model The Model instance.
458:  * @return array associations
459:  */
460:     protected function _associations(Model $model) {
461:         $keys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
462:         $associations = array();
463: 
464:         foreach ($keys as $type) {
465:             foreach ($model->{$type} as $assocKey => $assocData) {
466:                 list(, $modelClass) = pluginSplit($assocData['className']);
467:                 $associations[$type][$assocKey]['primaryKey'] = $model->{$assocKey}->primaryKey;
468:                 $associations[$type][$assocKey]['displayField'] = $model->{$assocKey}->displayField;
469:                 $associations[$type][$assocKey]['foreignKey'] = $assocData['foreignKey'];
470:                 $associations[$type][$assocKey]['controller'] = Inflector::pluralize(Inflector::underscore($modelClass));
471:                 $associations[$type][$assocKey]['fields'] = array_keys($model->{$assocKey}->schema(true));
472:             }
473:         }
474:         return $associations;
475:     }
476: 
477: }
478: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs