merging changes from [683] [684] [685] [686] [688] [689] [690]

git-svn-id: https://svn.cakephp.org/repo/trunk/cake@691 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
phpnut 2005-08-25 03:45:14 +00:00
parent e9358bacbe
commit cdf8fd5812
10 changed files with 219 additions and 102 deletions

View file

@ -46,6 +46,18 @@ class TestsController extends TestsHelper {
$this->layout = null;
require_once TESTS.'index.php';
}
function groups ()
{
$this->layout = null;
require_once TESTS.'index.php';
}
function cases ()
{
$this->layout = null;
require_once TESTS.'index.php';
}
/**
* Runs all library and application tests
*

View file

@ -54,7 +54,7 @@ hidden = "<input type="hidden" name="data[%s][%s]"%s/>"
textarea = "<textarea name="data[%s][%s]"%s>%s</textarea>"
; Tag template for a input type='checkbox ' tag.
checkbox = "<input type="checkbox" name="data[%s][%s]" id="tag_%s"%s/>"
checkbox = "<input type="checkbox" name="data[%s][%s]" id="tag_%s" %s/>"
; Tag template for a input type='radio' tag.
radio = "<input type="radio" name="data[%s][%s]" id="tag_%s"%s/>"

View file

@ -2,9 +2,7 @@
/* SVN FILE: $Id$ */
/**
* Short description for file.
*
* Long description for file
* Base controller class.
*
* PHP versions 4 and 5
*
@ -18,7 +16,7 @@
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @filesource
* @author CakePHP Authors/Developers
* @copyright Copyright (c) 2005, CakePHP Authors/Developers
* @link https://trac.cakephp.org/wiki/Authors Authors/Developers
@ -32,7 +30,7 @@
*/
/**
* Enter description here...
* Include files
*/
uses('model', 'inflector', 'folder', 'view', 'helper');
@ -40,9 +38,9 @@ uses('model', 'inflector', 'folder', 'view', 'helper');
/**
* Controller
*
* Application controller (controllers are where you put all the actual code)
* Application controller (controllers are where you put all the actual code)
* Provides basic functionality, such as rendering views (aka displaying templates).
* Automatically selects model name from on singularized object class name
* Automatically selects model name from on singularized object class name
* and creates the model object if proper class exists.
*
* @package cake
@ -115,7 +113,7 @@ class Controller extends Object
var $_viewVars = array();
/**
* Enter description here...
* Web page title
*
* @var boolean
* @access private
@ -140,7 +138,7 @@ class Controller extends Object
var $base = null;
/**
* Enter description here...
* Layout file to use (see /app/views/layouts/default.thtml)
*
* @var string
* @access public
@ -148,7 +146,7 @@ class Controller extends Object
var $layout = 'default';
/**
* Enter description here...
* Automatically render the view (the dispatcher checks for this variable before running render())
*
* @var boolean
* @access public
@ -164,13 +162,13 @@ class Controller extends Object
var $autoLayout = true;
/**
* Enter description here...
* Database configuration to use (see /config/database.php)
*
* @var string
* @access public
*/
var $useDbConfig = 'default';
/**
* Enter description here...
*
@ -180,7 +178,7 @@ class Controller extends Object
var $beforeFilter = null;
/**
* Constructor.
* Constructor.
*
*/
function __construct ($params=null)
@ -205,9 +203,9 @@ class Controller extends Object
else
{
// Run a single before filter
}
}
}
parent::__construct();
}
@ -329,7 +327,8 @@ class Controller extends Object
}
/**
* Enter description here...
* Gets an instance of the view object & prepares it for rendering the output, then
* asks the view to actualy do the job.
*
* @param unknown_type $action
* @param unknown_type $layout
@ -416,7 +415,7 @@ class Controller extends Object
/**
* Sets data for this view. Will set title if the key "title" is in given $data array.
*
* @param array $data Array of
* @param array $data Array of
* @access private
*/
function _setArray($data)
@ -442,11 +441,12 @@ class Controller extends Object
}
/**
* Enter description here...
* Shows a message to the user $time seconds, then redirects to $url
* Uses flash.thtml as a layout for the messages
*
* @param unknown_type $message
* @param unknown_type $url
* @param unknown_type $time
* @param string $message Message to display to the user
* @param string $url Relative URL to redirect to after the time expires
* @param int $time Time to show the message
*/
function flash($message, $url, $time=1)
{
@ -459,9 +459,14 @@ class Controller extends Object
$this->render(null,false,VIEWS.'layouts'.DS.'flash.thtml');
}
/**
* Enter description here...
* Shows a message to the user $time seconds, then redirects to $url
* Uses flash.thtml as a layout for the messages
*
* @param string $message Message to display to the user
* @param string $url URL to redirect to after the time expires
* @param int $time Time to show the message
*
* @param unknown_type $message
* @param unknown_type $url
@ -478,18 +483,18 @@ class Controller extends Object
$this->render(null,false,VIEWS.'layouts'.DS.'flash.thtml');
}
/**
* This function creates a $fieldNames array for the view to use.
* @todo Map more database field types to html form fields.
* @todo View the database field types from all the supported databases.
*
*/
function generateFieldNames( $data = null, $doCreateOptions = true )
function generateFieldNames( $data = null, $doCreateOptions = true )
{
// Initialize the list array
$fieldNames = array();
// figure out what model and table we are working with
$model = Inflector::pluralize($this->name);
$table = Inflector::singularize($this->name);
@ -497,7 +502,7 @@ class Controller extends Object
// get all of the column names.
$classRegistry =& ClassRegistry::getInstance();
$objRegistryModel = $classRegistry->getObject($table);
foreach ($objRegistryModel->_table_info as $tables)
{
foreach ($tables as $tabl)
@ -524,7 +529,7 @@ class Controller extends Object
{
$fieldNames[$tabl['name']]['prompt'] = 'Modified';
}
// Now, set up some other attributes that will be useful for auto generating a form.
//tagName is in the format table/field "post/title"
$fieldNames[ $tabl['name']]['tagName'] = $table.'/'.$tabl['name'];
@ -536,14 +541,14 @@ class Controller extends Object
{
// Now, we know that this field has some validation set.
// find out if it is a required field.
if( VALID_NOT_EMPTY == $validationFields[ $tabl['name'] ] )
if( VALID_NOT_EMPTY == $validationFields[ $tabl['name'] ] )
{
// this is a required field.
$fieldNames[$tabl['name']]['required'] = true;
$fieldNames[$tabl['name']]['errorMsg'] = "Required Field";
}
}
// now, determine what the input type should be for this database field.
$lParenPos = strpos( $tabl['type'], '(');
$rParenPos = strpos( $tabl['type'], ')');
@ -559,7 +564,7 @@ class Controller extends Object
switch( $type )
{
case "text":
{
{
$fieldNames[ $tabl['name']]['type'] = 'area';
//$fieldNames[ $tabl['name']]['size'] = $fieldLength;
}
@ -571,21 +576,21 @@ class Controller extends Object
$fieldNames[ $tabl['name']]['type'] = 'select';
// This is a foreign key select dropdown box. now, we have to add the options.
$fieldNames[ $tabl['name']]['options'] = array();
// get the list of options from the other model.
$registry =& ClassRegistry::getInstance();
$otherModel = $registry->getObject($fieldNames[ $tabl['name']]['model']);
if( is_object($otherModel) )
if( is_object($otherModel) )
{
if( $doCreateOptions )
{
$otherDisplayField = $otherModel->getDisplayField();
foreach( $otherModel->findAll() as $pass )
{
foreach( $pass as $key=>$value )
foreach( $pass as $key=>$value )
{
if( $key == $fieldNames[ $tabl['name']]['model'] && isset( $value['id'] ) && isset( $value[$otherDisplayField] ) )
if( $key == $fieldNames[ $tabl['name']]['model'] && isset( $value['id'] ) && isset( $value[$otherDisplayField] ) )
{
$fieldNames[ $tabl['name']]['options'][$value['id']] = $value[$otherDisplayField];
}
@ -595,12 +600,24 @@ class Controller extends Object
$fieldNames[ $tabl['name']]['selected'] = $data[$table][$tabl['name']];
}
}
else
else
{
$fieldNames[ $tabl['name']]['type'] = 'input';
}
}
break;
case "tinyint":
{
if( $fieldLength > 1 )
{
$fieldNames[ $tabl['name']]['type'] = 'input';
}
else
{
$fieldNames[ $tabl['name']]['type'] = 'checkbox';
}
}
break;
case "int":
case "decimal":
case "float":
@ -618,21 +635,21 @@ class Controller extends Object
$fieldNames[ $tabl['name']]['type'] = 'select';
// This is a foreign key select dropdown box. now, we have to add the options.
$fieldNames[ $tabl['name']]['options'] = array();
// get the list of options from the other model.
$registry =& ClassRegistry::getInstance();
$otherModel = $registry->getObject($fieldNames[ $tabl['name']]['model']);
if( is_object($otherModel) )
if( is_object($otherModel) )
{
if( $doCreateOptions )
if( $doCreateOptions )
{
$otherDisplayField = $otherModel->getDisplayField();
foreach( $otherModel->findAll() as $pass )
{
foreach( $pass as $key=>$value )
foreach( $pass as $key=>$value )
{
if( $key == $fieldNames[ $tabl['name']]['model'] && isset( $value['id'] ) && isset( $value[$otherDisplayField] ) )
if( $key == $fieldNames[ $tabl['name']]['model'] && isset( $value['id'] ) && isset( $value[$otherDisplayField] ) )
{
$fieldNames[ $tabl['name']]['options'][$value['id']] = $value[$otherDisplayField];
}
@ -642,7 +659,7 @@ class Controller extends Object
$fieldNames[ $tabl['name']]['selected'] = $data[$table][$tabl['name']];
}
}
else
else
{
$fieldNames[ $tabl['name']]['type'] = 'input';
}
@ -654,10 +671,10 @@ class Controller extends Object
$fieldNames[ $tabl['name']]['type'] = 'select';
// This is a foreign key select dropdown box. now, we have to add the options.
$fieldNames[ $tabl['name']]['options'] = array();
$enumValues = split(',', $fieldLength );
$iCount = 1;
foreach ($enumValues as $enum )
foreach ($enumValues as $enum )
{
$enum = trim( $enum, "'" );
$fieldNames[$tabl['name']]['options'][$enum] = $enum;
@ -671,37 +688,37 @@ class Controller extends Object
{
if( 0 != strncmp( "created", $tabl['name'], 6 ) && 0 != strncmp("modified",$tabl['name'], 8) )
$fieldNames[ $tabl['name']]['type'] = $type;
}
}
break;
default:
//sorry, this database field type is not yet set up.
break;
break;
} // end switch
}
// now, add any necessary hasAndBelongsToMany list boxes
// loop through the many to many relations to make a list box.
foreach( $objRegistryModel->_manyToMany as $relation )
foreach( $objRegistryModel->_manyToMany as $relation )
{
list($tableName, $field, $value, $joinTable, $key1, $key2) = $relation;
$otherModelName = Inflector::singularize($tableName);
$otherModel = new $otherModelName();
if( $doCreateOptions )
if( $doCreateOptions )
{
$otherDisplayField = $otherModel->getDisplayField();
$fieldNames[$tableName]['model'] = $tableName;
$fieldNames[$tableName]['prompt'] = "Related ".Inflector::humanize($tableName);
$fieldNames[$tableName]['type'] = "selectMultiple";
$fieldNames[$tableName]['tagName'] = $otherModelName.'/'.$tableName;
foreach( $otherModel->findAll() as $pass )
{
foreach( $pass as $key=>$value )
foreach( $pass as $key=>$value )
{
if( $key == $otherModelName && isset( $value['id'] ) && isset( $value[$otherDisplayField] ) )
if( $key == $otherModelName && isset( $value['id'] ) && isset( $value[$otherDisplayField] ) )
{
$fieldNames[$tableName]['options'][$value['id']] = $value[$otherDisplayField];
}
@ -717,11 +734,11 @@ class Controller extends Object
}
} // end loop through manytomany relations.
}
return $fieldNames;
}
}
}
?>

View file

@ -170,6 +170,43 @@ class FormHelper
}
/**
* Returns a formatted INPUT tag for HTML FORMs.
*
* @param HtmlHelper $html The HtmlHelper object which is creating this form.
* @param string $tagName If field is to be used for CRUD, this should be modelName/fieldName
* @param string $prompt Text that will appear in the label field.
* @param bool $required True if this field is required.
* @param string $errorMsg Text that will appear if an error has occurred.
* @param int $size Size attribute for INPUT element
* @param array $htmlOptions
* @return string The formatted INPUT element
*/
function generateCheckboxDiv($html, $tagName, $prompt, $required=false, $errorMsg=null, $htmlOptions=null )
{
$htmlOptions['class'] = "inputCheckbox";
$str = $html->checkbox( $tagName, null, $htmlOptions );
$strLabel = $this->labelTag( $tagName, $prompt );
$divClass = "optional";
if( $required )
$divClass = "required";
$strError = ""; // initialize the error to empty.
if( $this->isFieldError( $html, $tagName ) )
{
// if it was an error that occured, then add the error message, and append " error" to the div tag.
$strError = $this->pTag( 'error', $errorMsg );
$divClass = sprintf( "%s error", $divClass );
}
$divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
return $this->divTag( $divClass, $divTagInside );
}
function generateDate($html, $tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null )
{
$str = $html->dateTimeOptionTag( $tagName, 'MDY' , 'NONE' );
@ -337,7 +374,10 @@ class FormHelper
{
$field['size'] = 40;
}
$strFormFields = $strFormFields.$this->generateInputDiv( $html, $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['size'], $field['htmlOptions'] );
$strFormFields = $strFormFields.$this->generateInputDiv( $html, $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['size'], $field['htmlOptions'] );
break;
case "checkbox" :
$strFormFields = $strFormFields.$this->generateCheckboxDiv( $html, $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['htmlOptions'] );
break;
case "select";
case "selectMultiple";

View file

@ -191,22 +191,32 @@ class HtmlHelper extends Helper
function link($title, $url = null, $htmlAttributes = null, $confirmMessage = false,
$return = false)
{
// prepare title for html display
$title = htmlspecialchars($title, ENT_QUOTES);
$url = $url? $url: $title;
if ($confirmMessage)
{
// prepare for html display (fix everything except quotes)
$confirmMessage = htmlspecialchars($confirmMessage, ENT_NOQUOTES);
// fix single quotes
$confirmMessage = str_replace("'", "\'", $confirmMessage);
// fix double quotes
$confirmMessage = str_replace('"', '&quot;', $confirmMessage);
$htmlAttributes['onclick'] = "return confirm('{$confirmMessage}');";
}
if (strpos($url, '://'))
{
$output = sprintf($this->tags['link'], $url,
$this->_parseAttributes($htmlAttributes), $title);
$this->_parseAttributes($htmlAttributes), $title);
}
else
{
$output = sprintf($this->tags['link'], $this->url($url, true),
$this->_parseAttributes($htmlAttributes), $title);
$this->_parseAttributes($htmlAttributes), $title);
}
return $this->output($output, $return);
@ -393,9 +403,11 @@ class HtmlHelper extends Helper
function hidden($fieldName, $htmlAttributes = null, $return = false)
{
$this->setFormTag($fieldName);
$htmlAttributes['value'] = $value? $value: $this->tagValue($fieldName);
if(!isset($htmlAttributes['value'])) {
$htmlAttributes['value'] = $this->tagValue($fieldName);
}
return $this->output(sprintf($this->tags['hidden'], $this->model, $this->field,
$this->_parseAttributes($htmlAttributes, null, '', ' ')), $return);
$this->_parseAttributes($htmlAttributes, null, ' ', ' ')), $return);
}
@ -976,30 +988,39 @@ class HtmlHelper extends Helper
*
* @param string $fieldName Name attribute of the SELECT
* @param array $option_elements Array of the OPTION elements (as 'value'=>'Text' pairs) to be used in the SELECT element
* @param boolean $show_empty Show/hide the empty select option
* @param array $select_attr Array of HTML options for the opening SELECT element
* @param array $optionAttr Array of HTML options for the enclosed OPTION elements
* @return string Formatted SELECT element
*/
function selectTag($fieldName, $option_elements, $selected=null, $select_attr=null, $optionAttr=null)
function selectTag($fieldName, $option_elements, $selected=null, $select_attr=null, $optionAttr=null, $show_empty=false)
{
$this->setFormTag($fieldName);
if (!is_array($option_elements) || !count($option_elements))
return null;
// do not display the select tag if no option elements are avaible
if (!is_array($option_elements) || count($option_elements) == 0)
{
return null;
}
if( isset($select_attr) && array_key_exists( "multiple", $select_attr) )
{
$select[] = sprintf($this->tags['selectmultiplestart'], $this->model, $this->field, $this->parseHtmlOptions($select_attr));
}
else
else
{
$select[] = sprintf($this->tags['selectstart'], $this->model, $this->field, $this->parseHtmlOptions($select_attr));
}
$select[] = sprintf($this->tags['selectempty'], $this->parseHtmlOptions($optionAttr));
if($show_empty == true)
{
$select[] = sprintf($this->tags['selectempty'], $this->parseHtmlOptions($optionAttr));
}
foreach ($option_elements as $name=>$title)
{
$options_here = $optionAttr;
if ($selected == $name)
if (!empty($selected) && ($selected == $name))
{
$options_here['selected'] = 'selected';
} else if ( is_array($selected) && array_key_exists($name, $selected) )
@ -1370,4 +1391,4 @@ class HtmlHelper extends Helper
}
}
?>
?>

View file

@ -967,7 +967,7 @@ class Model extends Object
foreach ($this->data as $n=>$v)
{
if(isset($weHaveMulti) && $count > 0)
if(isset($weHaveMulti) && $count > 0 && !empty($this->_manyToMany))
{
$joined = array($v);
}
@ -1333,29 +1333,34 @@ class Model extends Object
{
foreach ($value1 as $key2 => $value2)
{
if(!empty ($value2['id']))
{
$select[$table] = $this->db->all("SELECT * FROM {$table}
JOIN {$joineTable} ON {$joineTable}.{$joinKey1} = '$value2[id]'
AND {$joineTable}.{$JoinKey2} = {$table} .id");
}
if( is_array($select[$table]) && ($select[$table] != null))
{
$newKey = Inflector::singularize($table);
foreach ($select[$table] as $key => $value)
{
if( 0 == strncmp($key2, $joinKey1, strlen($key2)) )
{
if(!empty ($value2['id']))
{
$tmpSQL = "SELECT * FROM {$table}
JOIN {$joineTable} ON {$joineTable}.{$joinKey1} = '$value2[id]'
AND {$joineTable}.{$JoinKey2} = {$table} .id";
$select[$table] = $this->db->all($tmpSQL);
}
if( is_array($select[$table]) && ($select[$table] != null))
{
$newKey = Inflector::singularize($table);
foreach ($select[$table] as $key => $value)
{
$select1[$table][$key] = $value[$newKey];
}
$merged = array_merge_recursive($data[$count],$select1);
$newdata[$count] = $merged;
unset ($select1);
}
if(!empty($newdata[$count]))
{
$original[$count] = $newdata[$count];
}
}
$merged = array_merge_recursive($data[$count],$select1);
$newdata[$count] = $merged;
unset ($select1);
unset( $select[$table] );
}
if(!empty($newdata[$count]))
{
$original[$count] = $newdata[$count];
}
}
}
$count++;
}

View file

@ -162,8 +162,9 @@ class Scaffold extends Object {
*/
function scaffoldList($params)
{
$model = $this->model;
$this->controllerClass->set('fieldNames', $this->controllerClass->generateFieldNames(null,false) );
$this->controllerClass->set('data', $this->controllerClass->models[$this->model]->findAll());
$this->controllerClass->set('data', $this->controllerClass->models[$model]->findAll());
$this->controllerClass->render($this->actionView, '', LIBS.'controllers'.DS.'templates'.DS.'scaffolds'.DS.'list.thtml');
}
@ -201,7 +202,7 @@ class Scaffold extends Object {
function scaffoldCreate($params)
{
$this->controllerClass->set('fieldNames', $this->controllerClass->generateFieldNames() );
$this->cleanUpDateFields();
$this->cleanUpFields();
if ($this->controllerClass->models[$this->model]->save($this->controllerClass->params['data']))
{
@ -223,7 +224,7 @@ class Scaffold extends Object {
function scaffoldUpdate($params=array())
{
// clean up the date fields
$this->cleanUpDateFields();
$this->cleanUpFields();
$this->controllerClass->models[$this->model]->set($this->controllerClass->params['data']);
if ( $this->controllerClass->models[$this->model]->save())
@ -257,7 +258,7 @@ class Scaffold extends Object {
}
}
function cleanUpDateFields()
function cleanUpFields()
{
// clean up the date fields
$objModel = $this->controllerClass->models[$this->model];
@ -290,6 +291,18 @@ class Scaffold extends Object {
$newDate = date( 'Y-m-d', $newDate );
$this->controllerClass->params['data'][$this->model][$field['name']] = $newDate;
}
else if( 'tinyint(1)' == $field['type'] )
{
if( isset( $this->controllerClass->params['data'][$this->model][$field['name']]) &&
"on" == $this->controllerClass->params['data'][$this->model][$field['name']] )
{
$this->controllerClass->params['data'][$this->model][$field['name']] = true;
}
else
{
$this->controllerClass->params['data'][$this->model][$field['name']] = false;
}
}
}
}
}

View file

@ -197,12 +197,14 @@ form div input.inputCheckbox, form div input.inputRadio, input.inputCheckbox, in
background-color: transparent;
border-width: 0px;
padding: 0px;
margin: 0px 0px 0px 140px;
margin: 0px 0px 0px 0px;
}
form div.submit {
width: 214px;
padding: 0px 0px 0px 140px;
clear:both;
display:block;
}
div.submit input {
@ -327,6 +329,10 @@ div.date select {
width:auto;
}
select.autoWidth {
width:auto;
}
option {
padding-left:1em;
}

View file

@ -16,6 +16,7 @@ font-size:1.7em;
color: #383;
clear: both;
}
h3 {
font-size:1.4em;
color: #553;

View file

@ -71,6 +71,9 @@ echo $header;
function CakePHPTestSuiteHeader()
{
$groups = class_exists('Object') ? 'groups' : $_SERVER['PHP_SELF'].'?show=groups';
$cases = class_exists('Object') ? 'cases' : $_SERVER['PHP_SELF'].'?show=cases';
$suiteHeader = <<<EOD
<div id="main">
<div id="header">
@ -79,11 +82,10 @@ echo $header;
<h2>Test Suite v 1.0.0.0</h2>
</div>
</div>
<p><a href='$_SERVER[PHP_SELF]?show=groups'>Test Groups</a> || <a href='$_SERVER[PHP_SELF]?show=cases'>Test Cases</a></p>
<p><a href='$groups'>Test Groups</a> || <a href='$cases'>Test Cases</a></p>
EOD;
echo $suiteHeader;
}
function CakePHPTestSuiteFooter()
{
$footer = <<<EOD
@ -96,11 +98,11 @@ echo $footer;
CakePHPTestHeader();
CakePHPTestSuiteHeader();
if (isset($_GET['show']) && $_GET['show'] == 'cases')
if (isset($_GET['cases']))
{
CakePHPTestCaseList();
}
elseif (isset($_GET['show']) && $_GET['show'] == 'groups')
elseif (isset($_GET['groups']))
{
CakePHPTestGroupTestList();
}