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.1 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.1
      • 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
    • Network
      • Email
      • Http
    • Routing
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

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