2008-05-30 11:40:08 +00:00
< ? php
/**
* The View Tasks handles creating and updating view files .
*
* Long description for file
*
* PHP versions 4 and 5
*
2009-11-06 06:46:59 +00:00
* CakePHP ( tm ) : Rapid Development Framework ( http :// cakephp . org )
* Copyright 2005 - 2009 , Cake Software Foundation , Inc . ( http :// cakefoundation . org )
2008-05-30 11:40:08 +00:00
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice .
*
2009-11-06 06:46:59 +00:00
* @ copyright Copyright 2005 - 2009 , Cake Software Foundation , Inc . ( http :// cakefoundation . org )
2009-11-06 06:00:11 +00:00
* @ link http :// cakephp . org CakePHP ( tm ) Project
2008-10-30 17:30:26 +00:00
* @ package cake
* @ subpackage cake . cake . console . libs . tasks
* @ since CakePHP ( tm ) v 1.2
2009-11-06 06:51:51 +00:00
* @ license MIT License ( http :// www . opensource . org / licenses / mit - license . php )
2008-05-30 11:40:08 +00:00
*/
2009-07-30 22:01:22 +00:00
App :: import ( 'Controller' , 'Controller' , false );
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Task class for creating and updating view files .
*
2008-10-30 17:30:26 +00:00
* @ package cake
* @ subpackage cake . cake . console . libs . tasks
2008-05-30 11:40:08 +00:00
*/
class ViewTask extends Shell {
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Name of plugin
*
* @ var string
* @ access public
*/
var $plugin = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Tasks to be loaded by this Task
*
* @ var array
* @ access public
*/
2009-06-04 03:18:14 +00:00
var $tasks = array ( 'Project' , 'Controller' , 'DbConfig' , 'Template' );
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* path to VIEWS directory
*
* @ var array
* @ access public
*/
var $path = VIEWS ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Name of the controller being used
*
* @ var string
* @ access public
*/
var $controllerName = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Path to controller to put views
*
* @ var string
* @ access public
*/
var $controllerPath = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* The template file to use
*
* @ var string
* @ access public
*/
var $template = null ;
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Actions to use for scaffolding
*
* @ var array
* @ access public
*/
var $scaffoldActions = array ( 'index' , 'view' , 'add' , 'edit' );
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Override initialize
*
* @ access public
*/
function initialize () {
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Execution method always used for tasks
*
* @ access public
*/
function execute () {
if ( empty ( $this -> args )) {
$this -> __interactive ();
}
2009-07-28 21:49:04 +00:00
if ( empty ( $this -> args [ 0 ])) {
return ;
}
if ( ! isset ( $this -> connection )) {
$this -> connection = 'default' ;
}
$controller = $action = $alias = null ;
$this -> controllerName = Inflector :: camelize ( $this -> args [ 0 ]);
$this -> controllerPath = Inflector :: underscore ( $this -> controllerName );
2008-05-30 11:40:08 +00:00
2009-07-28 21:49:04 +00:00
if ( strtolower ( $this -> args [ 0 ]) == 'all' ) {
return $this -> all ();
}
2008-05-30 11:40:08 +00:00
2009-07-28 21:49:04 +00:00
if ( isset ( $this -> args [ 1 ])) {
$this -> template = $this -> args [ 1 ];
}
if ( isset ( $this -> args [ 2 ])) {
$action = $this -> args [ 2 ];
}
if ( ! $action ) {
$action = $this -> template ;
}
if ( $action ) {
return $this -> bake ( $action , true );
}
2009-06-04 03:18:14 +00:00
2009-07-28 21:49:04 +00:00
$vars = $this -> __loadController ();
$methods = $this -> _methodsToBake ();
2008-05-30 11:40:08 +00:00
2009-07-28 21:49:04 +00:00
foreach ( $methods as $method ) {
$content = $this -> getContent ( $method , $vars );
if ( $content ) {
$this -> bake ( $method , $content );
2008-05-30 11:40:08 +00:00
}
}
}
2009-07-24 19:18:37 +00:00
2009-07-17 03:12:47 +00:00
/**
* Get a list of actions that can / should have views baked for them .
*
* @ return array Array of action names that should be baked
**/
function _methodsToBake () {
$methods = array_diff (
array_map ( 'strtolower' , get_class_methods ( $this -> controllerName . 'Controller' )),
array_map ( 'strtolower' , get_class_methods ( 'appcontroller' ))
);
2009-07-28 21:49:04 +00:00
$scaffoldActions = false ;
2009-07-17 03:12:47 +00:00
if ( empty ( $methods )) {
2009-07-28 21:49:04 +00:00
$scaffoldActions = true ;
2009-07-17 03:12:47 +00:00
$methods = $this -> scaffoldActions ;
}
2009-10-07 05:35:29 +00:00
$adminRoute = $this -> Project -> getPrefix ();
2009-07-17 03:12:47 +00:00
foreach ( $methods as $i => $method ) {
2009-07-28 21:49:04 +00:00
if ( $adminRoute && isset ( $this -> params [ 'admin' ])) {
if ( $scaffoldActions ) {
2009-10-07 05:35:29 +00:00
$methods [ $i ] = $adminRoute . $method ;
2009-07-28 21:49:04 +00:00
continue ;
2009-10-07 05:35:29 +00:00
} elseif ( strpos ( $method , $adminRoute ) === false ) {
2009-07-28 21:49:04 +00:00
unset ( $methods [ $i ]);
}
2009-07-17 03:12:47 +00:00
}
2009-08-02 22:17:31 +00:00
if ( $method [ 0 ] === '_' || $method == strtolower ( $this -> controllerName . 'Controller' )) {
2009-07-17 03:12:47 +00:00
unset ( $methods [ $i ]);
}
}
return $methods ;
}
2009-07-24 19:18:37 +00:00
2009-04-28 03:55:34 +00:00
/**
* Bake All views for All controllers .
*
* @ return void
**/
function all () {
2009-06-05 03:42:06 +00:00
$this -> Controller -> interactive = false ;
2009-06-04 03:18:14 +00:00
$tables = $this -> Controller -> listAll ( $this -> connection , false );
2009-07-29 10:48:31 +00:00
2009-04-28 03:58:36 +00:00
$this -> interactive = false ;
2009-04-28 03:55:34 +00:00
foreach ( $tables as $table ) {
$model = $this -> _modelName ( $table );
$this -> controllerName = $this -> _controllerName ( $model );
$this -> controllerPath = Inflector :: underscore ( $this -> controllerName );
if ( App :: import ( 'Model' , $model )) {
$vars = $this -> __loadController ();
2009-07-29 10:48:31 +00:00
$actions = $this -> _methodsToBake ();
2009-06-05 03:42:06 +00:00
$this -> bakeActions ( $actions , $vars );
2009-04-28 03:55:34 +00:00
}
}
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Handles interactive baking
*
* @ access private
*/
function __interactive () {
$this -> hr ();
$this -> out ( sprintf ( " Bake View \n Path: %s " , $this -> path ));
$this -> hr ();
2009-06-04 01:59:46 +00:00
2009-06-04 03:18:14 +00:00
if ( empty ( $this -> connection )) {
$this -> connection = $this -> DbConfig -> getConfig ();
}
$this -> Controller -> connection = $this -> connection ;
2008-05-30 11:40:08 +00:00
$this -> controllerName = $this -> Controller -> getName ();
2009-05-30 04:34:45 +00:00
$this -> controllerPath = strtolower ( Inflector :: underscore ( $this -> controllerName ));
2008-05-30 11:40:08 +00:00
2009-06-04 03:18:14 +00:00
$prompt = sprintf ( __ ( " Would you like bake to build your views interactively? \n Warning: Choosing no will overwrite %s views if it exist. " , true ), $this -> controllerName );
$interactive = $this -> in ( $prompt , array ( 'y' , 'n' ), 'n' );
2008-05-30 11:40:08 +00:00
2009-06-04 03:18:14 +00:00
if ( strtolower ( $interactive ) == 'n' ) {
$this -> interactive = false ;
2008-05-30 11:40:08 +00:00
}
2009-06-04 03:18:14 +00:00
$prompt = __ ( " Would you like to create some CRUD views \n (index, add, view, edit) for this controller? \n NOTE: Before doing so, you'll need to create your controller \n and model classes (including associated models). " , true );
2009-06-05 03:35:36 +00:00
$wannaDoScaffold = $this -> in ( $prompt , array ( 'y' , 'n' ), 'y' );
2009-06-04 03:18:14 +00:00
2009-06-05 03:35:36 +00:00
$wannaDoAdmin = $this -> in ( __ ( " Would you like to create the views for admin routing? " , true ), array ( 'y' , 'n' ), 'n' );
2008-05-30 11:40:08 +00:00
2009-06-05 03:35:36 +00:00
if ( strtolower ( $wannaDoScaffold ) == 'y' || strtolower ( $wannaDoAdmin ) == 'y' ) {
2008-05-30 11:40:08 +00:00
$vars = $this -> __loadController ();
2009-06-05 03:35:36 +00:00
if ( strtolower ( $wannaDoScaffold ) == 'y' ) {
$actions = $this -> scaffoldActions ;
2009-06-04 02:03:57 +00:00
$this -> bakeActions ( $actions , $vars );
2008-05-30 11:40:08 +00:00
}
2009-06-05 03:35:36 +00:00
if ( strtolower ( $wannaDoAdmin ) == 'y' ) {
2009-10-07 04:46:13 +00:00
$admin = $this -> Project -> getPrefix ();
2009-06-05 03:35:36 +00:00
$regularActions = $this -> scaffoldActions ;
$adminActions = array ();
foreach ( $regularActions as $action ) {
$adminActions [] = $admin . $action ;
}
$this -> bakeActions ( $adminActions , $vars );
}
2008-05-30 11:40:08 +00:00
$this -> hr ();
2009-09-26 21:08:37 +00:00
$this -> out ();
2009-06-04 03:18:14 +00:00
$this -> out ( __ ( " View Scaffolding Complete. \n " , true ));
2008-05-30 11:40:08 +00:00
} else {
2009-06-04 03:18:14 +00:00
$this -> customAction ();
2008-05-30 11:40:08 +00:00
}
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Loads Controller and sets variables for the template
* Available template variables
* 'modelClass' , 'primaryKey' , 'displayField' , 'singularVar' , 'pluralVar' ,
* 'singularHumanName' , 'pluralHumanName' , 'fields' , 'foreignKeys' ,
* 'belongsTo' , 'hasOne' , 'hasMany' , 'hasAndBelongsToMany'
*
* @ return array Returns an variables to be made available to a view template
* @ access private
*/
function __loadController () {
if ( ! $this -> controllerName ) {
$this -> err ( __ ( 'Controller not found' , true ));
}
$import = $this -> controllerName ;
if ( $this -> plugin ) {
$import = $this -> plugin . '.' . $this -> controllerName ;
}
if ( ! App :: import ( 'Controller' , $import )) {
$file = $this -> controllerPath . '_controller.php' ;
$this -> err ( sprintf ( __ ( " The file '%s' could not be found. \n In order to bake a view, you'll need to first create the controller. " , true ), $file ));
2008-06-04 19:04:58 +00:00
$this -> _stop ();
2008-05-30 11:40:08 +00:00
}
$controllerClassName = $this -> controllerName . 'Controller' ;
2009-06-04 03:18:14 +00:00
$controllerObj =& new $controllerClassName ();
2008-05-30 11:40:08 +00:00
$controllerObj -> constructClasses ();
$modelClass = $controllerObj -> modelClass ;
$modelObj =& ClassRegistry :: getObject ( $controllerObj -> modelKey );
if ( $modelObj ) {
$primaryKey = $modelObj -> primaryKey ;
$displayField = $modelObj -> displayField ;
$singularVar = Inflector :: variable ( $modelClass );
2009-08-18 08:29:54 +00:00
$singularHumanName = $this -> _singularHumanName ( $modelClass );
2008-05-30 11:40:08 +00:00
$schema = $modelObj -> schema ();
$fields = array_keys ( $schema );
$associations = $this -> __associations ( $modelObj );
} else {
$primaryKey = null ;
$displayField = null ;
$singularVar = Inflector :: variable ( Inflector :: singularize ( $this -> controllerName ));
2009-08-18 08:29:54 +00:00
$singularHumanName = $this -> _singularHumanName ( $this -> controllerName );
2008-05-30 11:40:08 +00:00
$fields = array ();
$schema = array ();
$associations = array ();
}
2009-08-18 08:29:54 +00:00
$pluralVar = Inflector :: variable ( $this -> controllerName );
$pluralHumanName = $this -> _pluralHumanName ( $this -> controllerName );
2008-05-30 11:40:08 +00:00
return compact ( 'modelClass' , 'schema' , 'primaryKey' , 'displayField' , 'singularVar' , 'pluralVar' ,
'singularHumanName' , 'pluralHumanName' , 'fields' , 'associations' );
}
2009-07-24 19:18:37 +00:00
2009-06-04 01:59:46 +00:00
/**
* Bake a view file for each of the supplied actions
*
* @ param array $actions Array of actions to make files for .
* @ return void
**/
2009-06-04 02:03:57 +00:00
function bakeActions ( $actions , $vars ) {
2009-06-04 01:59:46 +00:00
foreach ( $actions as $action ) {
$content = $this -> getContent ( $action , $vars );
$this -> bake ( $action , $content );
}
}
2009-07-24 19:18:37 +00:00
2009-06-04 03:18:14 +00:00
/**
* handle creation of baking a custom action view file
*
* @ return void
**/
function customAction () {
$action = '' ;
while ( $action == '' ) {
$action = $this -> in ( __ ( 'Action Name? (use lowercase_underscored function name)' , true ));
if ( $action == '' ) {
$this -> out ( __ ( 'The action name you supplied was empty. Please try again.' , true ));
}
}
2009-09-26 21:08:37 +00:00
$this -> out ();
2009-06-04 03:18:14 +00:00
$this -> hr ();
$this -> out ( __ ( 'The following view will be created:' , true ));
$this -> hr ();
$this -> out ( sprintf ( __ ( 'Controller Name: %s' , true ), $this -> controllerName ));
$this -> out ( sprintf ( __ ( 'Action Name: %s' , true ), $action ));
$this -> out ( sprintf ( __ ( 'Path: %s' , true ), $this -> params [ 'app' ] . DS . $this -> controllerPath . DS . Inflector :: underscore ( $action ) . " .ctp " ));
$this -> hr ();
$looksGood = $this -> in ( __ ( 'Look okay?' , true ), array ( 'y' , 'n' ), 'y' );
if ( strtolower ( $looksGood ) == 'y' ) {
$this -> bake ( $action );
$this -> _stop ();
} else {
$this -> out ( __ ( 'Bake Aborted.' , true ));
}
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Assembles and writes bakes the view file .
*
* @ param string $action Action to bake
* @ param string $content Content to write
* @ return boolean Success
* @ access public
*/
function bake ( $action , $content = '' ) {
if ( $content === true ) {
2009-06-05 03:35:36 +00:00
$content = $this -> getContent ( $action );
2008-05-30 11:40:08 +00:00
}
2009-06-07 01:18:34 +00:00
$path = $this -> path ;
if ( isset ( $this -> plugin )) {
$path = $this -> _pluginPath ( $this -> plugin ) . 'views' . DS ;
2008-05-30 11:40:08 +00:00
}
2009-06-07 01:18:34 +00:00
$filename = $path . $this -> controllerPath . DS . Inflector :: underscore ( $action ) . '.ctp' ;
return $this -> createFile ( $filename , $content );
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Builds content from template and variables
*
2009-09-23 15:16:18 +00:00
* @ param string $action name to generate content to
2008-05-30 11:40:08 +00:00
* @ param array $vars passed for use in templates
* @ return string content from template
* @ access public
*/
2009-09-23 15:16:18 +00:00
function getContent ( $action , $vars = null ) {
2008-05-30 11:40:08 +00:00
if ( ! $vars ) {
$vars = $this -> __loadController ();
}
2009-05-30 04:32:57 +00:00
2009-06-04 02:03:57 +00:00
$this -> Template -> set ( 'action' , $action );
$this -> Template -> set ( 'plugin' , $this -> plugin );
2009-05-30 04:32:57 +00:00
$this -> Template -> set ( $vars );
2009-09-23 15:16:18 +00:00
$output = $this -> Template -> generate ( 'views' , $this -> getTemplate ( $action ));
2009-05-30 04:32:57 +00:00
if ( ! empty ( $output )) {
return $output ;
2008-05-30 11:40:08 +00:00
}
return false ;
}
2009-09-23 17:27:47 +00:00
2009-09-23 15:16:18 +00:00
/**
* Gets the template name based on the action name
*
* @ param string $action name
* @ return string template name
* @ access public
*/
function getTemplate ( $action ) {
if ( ! empty ( $this -> template ) && $action != $this -> template ) {
return $this -> template ;
}
$template = $action ;
2009-10-07 05:35:29 +00:00
$prefixes = Configure :: read ( 'Routing.prefixes' );
foreach (( array ) $prefixes as $prefix ) {
if ( strpos ( $template , $prefix ) !== false ) {
$template = str_replace ( $prefix . '_' , '' , $template );
}
2009-09-23 15:16:18 +00:00
}
if ( in_array ( $template , array ( 'add' , 'edit' ))) {
$template = 'form' ;
} elseif ( preg_match ( '@(_add|_edit)$@' , $template )) {
$template = str_replace ( array ( '_add' , '_edit' ), '_form' , $template );
}
return $template ;
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Displays help contents
*
* @ access public
*/
function help () {
$this -> hr ();
$this -> out ( " Usage: cake bake view <arg1> <arg2>... " );
$this -> hr ();
2009-10-04 21:59:12 +00:00
$this -> out ( 'Arguments:' );
$this -> out ();
$this -> out ( " <controller> " );
$this -> out ( " \t Name of the controller views to bake. Can use Plugin.name " );
$this -> out ( " \t as a shortcut for plugin baking. " );
$this -> out ();
2008-05-30 11:40:08 +00:00
$this -> out ( 'Commands:' );
2009-09-26 21:08:37 +00:00
$this -> out ();
2009-05-30 04:46:25 +00:00
$this -> out ( " view <controller> " );
2009-07-17 03:12:47 +00:00
$this -> out ( " \t Will read the given controller for methods " );
2009-05-30 04:46:25 +00:00
$this -> out ( " \t and bake corresponding views. " );
2009-07-17 03:12:47 +00:00
$this -> out ( " \t Using the -admin flag will only bake views for actions " );
$this -> out ( " \t that begin with Routing.admin. " );
2009-06-05 03:43:59 +00:00
$this -> out ( " \t If var scaffold is found it will bake the CRUD actions " );
2009-05-30 04:46:25 +00:00
$this -> out ( " \t (index,view,add,edit) " );
2009-09-26 21:08:37 +00:00
$this -> out ();
2009-05-30 04:46:25 +00:00
$this -> out ( " view <controller> <action> " );
2009-07-17 03:12:47 +00:00
$this -> out ( " \t Will bake a template. core templates: (index, add, edit, view) " );
2009-09-26 21:08:37 +00:00
$this -> out ();
2009-05-30 04:46:25 +00:00
$this -> out ( " view <controller> <template> <alias> " );
2009-07-17 03:12:47 +00:00
$this -> out ( " \t Will use the template specified " );
2009-05-30 04:46:25 +00:00
$this -> out ( " \t but name the file based on the alias " );
2009-09-26 21:08:37 +00:00
$this -> out ();
2009-06-05 03:43:59 +00:00
$this -> out ( " view all " );
$this -> out ( " \t Bake all CRUD action views for all controllers. " );
$this -> out ( " \t Requires that models and controllers exist. " );
2008-06-04 19:04:58 +00:00
$this -> _stop ();
2008-05-30 11:40:08 +00:00
}
2009-07-24 19:18:37 +00:00
2008-05-30 11:40:08 +00:00
/**
* Returns associations for controllers models .
*
* @ return array $associations
* @ access private
*/
2008-06-20 20:17:23 +00:00
function __associations ( $model ) {
$keys = array ( 'belongsTo' , 'hasOne' , 'hasMany' , 'hasAndBelongsToMany' );
$associations = array ();
2008-05-30 11:40:08 +00:00
2008-10-23 00:10:44 +00:00
foreach ( $keys as $key => $type ) {
2008-06-20 20:17:23 +00:00
foreach ( $model -> { $type } as $assocKey => $assocData ) {
$associations [ $type ][ $assocKey ][ 'primaryKey' ] = $model -> { $assocKey } -> primaryKey ;
$associations [ $type ][ $assocKey ][ 'displayField' ] = $model -> { $assocKey } -> displayField ;
$associations [ $type ][ $assocKey ][ 'foreignKey' ] = $assocData [ 'foreignKey' ];
$associations [ $type ][ $assocKey ][ 'controller' ] = Inflector :: pluralize ( Inflector :: underscore ( $assocData [ 'className' ]));
$associations [ $type ][ $assocKey ][ 'fields' ] = array_keys ( $model -> { $assocKey } -> schema ());
}
}
return $associations ;
}
2008-05-30 11:40:08 +00:00
}
?>