view.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: view.php 8253 2009-07-23 21:04:40Z DarkAngelBGE $ */
00003 /**
00004  * The View Tasks handles creating and updating view files.
00005  *
00006  * Long description for file
00007  *
00008  * PHP versions 4 and 5
00009  *
00010  * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
00011  * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00018  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package       cake
00020  * @subpackage    cake.cake.console.libs.tasks
00021  * @since         CakePHP(tm) v 1.2
00022  * @version       $Revision: 8253 $
00023  * @modifiedby    $LastChangedBy: DarkAngelBGE $
00024  * @lastmodified  $Date: 2009-07-23 17:04:40 -0400 (Thu, 23 Jul 2009) $
00025  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 App::import('Core', 'Controller');
00028 /**
00029  * Task class for creating and updating view files.
00030  *
00031  * @package       cake
00032  * @subpackage    cake.cake.console.libs.tasks
00033  */
00034 class ViewTask extends Shell {
00035 /**
00036  * Name of plugin
00037  *
00038  * @var string
00039  * @access public
00040  */
00041     var $plugin = null;
00042 /**
00043  * Tasks to be loaded by this Task
00044  *
00045  * @var array
00046  * @access public
00047  */
00048     var $tasks = array('Project', 'Controller');
00049 /**
00050  * path to VIEWS directory
00051  *
00052  * @var array
00053  * @access public
00054  */
00055     var $path = VIEWS;
00056 /**
00057  * Name of the controller being used
00058  *
00059  * @var string
00060  * @access public
00061  */
00062     var $controllerName = null;
00063 /**
00064  * Path to controller to put views
00065  *
00066  * @var string
00067  * @access public
00068  */
00069     var $controllerPath = null;
00070 /**
00071  * The template file to use
00072  *
00073  * @var string
00074  * @access public
00075  */
00076     var $template = null;
00077 /**
00078  * Actions to use for scaffolding
00079  *
00080  * @var array
00081  * @access public
00082  */
00083     var $scaffoldActions = array('index', 'view', 'add', 'edit');
00084 /**
00085  * Override initialize
00086  *
00087  * @access public
00088  */
00089     function initialize() {
00090     }
00091 /**
00092  * Execution method always used for tasks
00093  *
00094  * @access public
00095  */
00096     function execute() {
00097         if (empty($this->args)) {
00098             $this->__interactive();
00099         }
00100 
00101         if (isset($this->args[0])) {
00102             $controller = $action = $alias = null;
00103             $this->controllerName = Inflector::camelize($this->args[0]);
00104             $this->controllerPath = Inflector::underscore($this->controllerName);
00105 
00106             if (isset($this->args[1])) {
00107                 $this->template = $this->args[1];
00108             }
00109 
00110             if (isset($this->args[2])) {
00111                 $action = $this->args[2];
00112             }
00113 
00114             if (!$action) {
00115                 $action = $this->template;
00116             }
00117 
00118             if (in_array($action, $this->scaffoldActions)) {
00119                 $this->bake($action, true);
00120             } elseif ($action) {
00121                 $this->bake($action, true);
00122             } else {
00123                 $vars = $this->__loadController();
00124                 if ($vars) {
00125 
00126                     $methods =  array_diff(
00127                         array_map('strtolower', get_class_methods($this->controllerName . 'Controller')),
00128                         array_map('strtolower', get_class_methods('appcontroller'))
00129                     );
00130                     if (empty($methods)) {
00131                         $methods = $this->scaffoldActions;
00132                     }
00133                     $adminDelete = null;
00134 
00135                     $adminRoute = Configure::read('Routing.admin');
00136                     if (!empty($adminRoute)) {
00137                         $adminDelete = $adminRoute.'_delete';
00138                     }
00139                     foreach ($methods as $method) {
00140                         if ($method{0} != '_' && !in_array($method, array('delete', $adminDelete))) {
00141                             $content = $this->getContent($method, $vars);
00142                             $this->bake($method, $content);
00143                         }
00144                     }
00145                 }
00146             }
00147         }
00148     }
00149 /**
00150  * Handles interactive baking
00151  *
00152  * @access private
00153  */
00154     function __interactive() {
00155         $this->hr();
00156         $this->out(sprintf("Bake View\nPath: %s", $this->path));
00157         $this->hr();
00158         $wannaDoAdmin = 'n';
00159         $wannaDoScaffold = 'y';
00160         $this->interactive = false;
00161 
00162         $this->controllerName = $this->Controller->getName();
00163 
00164         $this->controllerPath = strtolower(Inflector::underscore($this->controllerName));
00165 
00166         $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');
00167 
00168         if (strtolower($interactive) == 'y' || strtolower($interactive) == 'yes') {
00169             $this->interactive = true;
00170             $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');
00171         }
00172 
00173         if (strtolower($wannaDoScaffold) == 'y' || strtolower($wannaDoScaffold) == 'yes') {
00174             $wannaDoAdmin = $this->in("Would you like to create the views for admin routing?", array('y','n'), 'y');
00175         }
00176         $admin = false;
00177 
00178         if ((strtolower($wannaDoAdmin) == 'y' || strtolower($wannaDoAdmin) == 'yes')) {
00179             $admin = $this->getAdmin();
00180         }
00181 
00182         if (strtolower($wannaDoScaffold) == 'y' || strtolower($wannaDoScaffold) == 'yes') {
00183             $actions = $this->scaffoldActions;
00184             if ($admin) {
00185                 foreach ($actions as $action) {
00186                     $actions[] = $admin . $action;
00187                 }
00188             }
00189             $vars = $this->__loadController();
00190             if ($vars) {
00191                 foreach ($actions as $action) {
00192                     $content = $this->getContent($action, $vars);
00193                     $this->bake($action, $content);
00194                 }
00195             }
00196             $this->hr();
00197             $this->out('');
00198             $this->out('View Scaffolding Complete.'."\n");
00199         } else {
00200             $action = '';
00201             while ($action == '') {
00202                 $action = $this->in('Action Name? (use camelCased function name)');
00203                 if ($action == '') {
00204                     $this->out('The action name you supplied was empty. Please try again.');
00205                 }
00206             }
00207             $this->out('');
00208             $this->hr();
00209             $this->out('The following view will be created:');
00210             $this->hr();
00211             $this->out("Controller Name: {$this->controllerName}");
00212             $this->out("Action Name:     {$action}");
00213             $this->out("Path:            ".$this->params['app'] . DS . $this->controllerPath . DS . Inflector::underscore($action) . ".ctp");
00214             $this->hr();
00215             $looksGood = $this->in('Look okay?', array('y','n'), 'y');
00216             if (strtolower($looksGood) == 'y' || strtolower($looksGood) == 'yes') {
00217                 $this->bake($action);
00218                 $this->_stop();
00219             } else {
00220                 $this->out('Bake Aborted.');
00221             }
00222         }
00223     }
00224 /**
00225  * Loads Controller and sets variables for the template
00226  * Available template variables
00227  *  'modelClass', 'primaryKey', 'displayField', 'singularVar', 'pluralVar',
00228  *  'singularHumanName', 'pluralHumanName', 'fields', 'foreignKeys',
00229  *  'belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany'
00230  *
00231  * @return array Returns an variables to be made available to a view template
00232  * @access private
00233  */
00234     function __loadController() {
00235         if (!$this->controllerName) {
00236             $this->err(__('Controller not found', true));
00237         }
00238 
00239         $import = $this->controllerName;
00240         if ($this->plugin) {
00241             $import = $this->plugin . '.' . $this->controllerName;
00242         }
00243 
00244         if (!App::import('Controller', $import)) {
00245             $file = $this->controllerPath . '_controller.php';
00246             $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));
00247             $this->_stop();
00248         }
00249         $controllerClassName = $this->controllerName . 'Controller';
00250         $controllerObj = & new $controllerClassName();
00251         $controllerObj->constructClasses();
00252         $modelClass = $controllerObj->modelClass;
00253         $modelObj =& ClassRegistry::getObject($controllerObj->modelKey);
00254 
00255         if ($modelObj) {
00256             $primaryKey = $modelObj->primaryKey;
00257             $displayField = $modelObj->displayField;
00258             $singularVar = Inflector::variable($modelClass);
00259             $pluralVar = Inflector::variable($this->controllerName);
00260             $singularHumanName = Inflector::humanize($modelClass);
00261             $pluralHumanName = Inflector::humanize($this->controllerName);
00262             $schema = $modelObj->schema();
00263             $fields = array_keys($schema);
00264             $associations = $this->__associations($modelObj);
00265         } else {
00266             $primaryKey = null;
00267             $displayField = null;
00268             $singularVar = Inflector::variable(Inflector::singularize($this->controllerName));
00269             $pluralVar = Inflector::variable($this->controllerName);
00270             $singularHumanName = Inflector::humanize(Inflector::singularize($this->controllerName));
00271             $pluralHumanName = Inflector::humanize($this->controllerName);
00272             $fields = array();
00273             $schema = array();
00274             $associations = array();
00275         }
00276 
00277         return compact('modelClass', 'schema', 'primaryKey', 'displayField', 'singularVar', 'pluralVar',
00278                 'singularHumanName', 'pluralHumanName', 'fields','associations');
00279     }
00280 /**
00281  * Assembles and writes bakes the view file.
00282  *
00283  * @param string $action Action to bake
00284  * @param string $content Content to write
00285  * @return boolean Success
00286  * @access public
00287  */
00288     function bake($action, $content = '') {
00289         if ($content === true) {
00290             $content = $this->getContent();
00291         }
00292         $filename = $this->path . $this->controllerPath . DS . Inflector::underscore($action) . '.ctp';
00293         $Folder =& new Folder($this->path . $this->controllerPath, true);
00294         $errors = $Folder->errors();
00295         if (empty($errors)) {
00296             $path = $Folder->slashTerm($Folder->pwd());
00297             return $this->createFile($filename, $content);
00298         } else {
00299             foreach ($errors as $error) {
00300                 $this->err($error);
00301             }
00302         }
00303         return false;
00304     }
00305 /**
00306  * Builds content from template and variables
00307  *
00308  * @param string $template file to use
00309  * @param array $vars passed for use in templates
00310  * @return string content from template
00311  * @access public
00312  */
00313     function getContent($template = null, $vars = null) {
00314         if (!$template) {
00315             $template = $this->template;
00316         }
00317         $action = $template;
00318 
00319         $adminRoute = Configure::read('Routing.admin');
00320         if (!empty($adminRoute) && strpos($template, $adminRoute) !== false) {
00321             $template = str_replace($adminRoute.'_', '', $template);
00322         }
00323         if (in_array($template, array('add', 'edit'))) {
00324             $action = $template;
00325             $template = 'form';
00326         }
00327         $loaded = false;
00328         foreach ($this->Dispatch->shellPaths as $path) {
00329             $templatePath = $path . 'templates' . DS . 'views' . DS .Inflector::underscore($template).'.ctp';
00330             if (file_exists($templatePath) && is_file($templatePath)) {
00331                 $loaded = true;
00332                 break;
00333             }
00334         }
00335         if (!$vars) {
00336             $vars = $this->__loadController();
00337         }
00338         if ($loaded) {
00339             extract($vars);
00340             ob_start();
00341             ob_implicit_flush(0);
00342             include($templatePath);
00343             $content = ob_get_clean();
00344             return $content;
00345         }
00346         $this->hr();
00347         $this->err(sprintf(__('Template for %s could not be found', true), $template));
00348         return false;
00349     }
00350 /**
00351  * Displays help contents
00352  *
00353  * @access public
00354  */
00355     function help() {
00356         $this->hr();
00357         $this->out("Usage: cake bake view <arg1> <arg2>...");
00358         $this->hr();
00359         $this->out('Commands:');
00360         $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)");
00361         $this->out("\n\tview <controller> <action>\n\t\twill bake a template. core templates: (index, add, edit, view)");
00362         $this->out("\n\tview <controller> <template> <alias>\n\t\twill use the template specified but name the file based on the alias");
00363         $this->out("");
00364         $this->_stop();
00365     }
00366 /**
00367  * Returns associations for controllers models.
00368  *
00369  * @return  array $associations
00370  * @access private
00371  */
00372     function __associations($model) {
00373         $keys = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
00374         $associations = array();
00375 
00376         foreach ($keys as $key => $type) {
00377             foreach ($model->{$type} as $assocKey => $assocData) {
00378                 $associations[$type][$assocKey]['primaryKey'] = $model->{$assocKey}->primaryKey;
00379                 $associations[$type][$assocKey]['displayField'] = $model->{$assocKey}->displayField;
00380                 $associations[$type][$assocKey]['foreignKey'] = $assocData['foreignKey'];
00381                 $associations[$type][$assocKey]['controller'] = Inflector::pluralize(Inflector::underscore($assocData['className']));
00382                 $associations[$type][$assocKey]['fields'] =  array_keys($model->{$assocKey}->schema());
00383             }
00384         }
00385         return $associations;
00386     }
00387 }
00388 
00389 ?>

Generated on Sun Nov 22 00:30:52 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7