form.php

来自「Cake Framwork , Excellent」· PHP 代码 · 共 1,711 行 · 第 1/4 页

PHP
1,711
字号
<?php/* SVN FILE: $Id: form.php 7118 2008-06-04 20:49:29Z gwoo $ *//** * Automatic generation of HTML FORMs from given data. * * Used for scaffolding. * * PHP versions 4 and 5 * * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/> * Copyright 2005-2008, Cake Software Foundation, Inc. *								1785 E. Sahara Avenue, Suite 490-204 *								Las Vegas, Nevada 89104 * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * * @filesource * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc. * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project * @package			cake * @subpackage		cake.cake.libs.view.helpers * @since			CakePHP(tm) v 0.10.0.1076 * @version			$Revision: 7118 $ * @modifiedby		$LastChangedBy: gwoo $ * @lastmodified	$Date: 2008-06-04 13:49:29 -0700 (Wed, 04 Jun 2008) $ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License *//** * Form helper library. * * Automatic generation of HTML FORMs from given data. * * @package		cake * @subpackage	cake.cake.libs.view.helpers */class FormHelper extends AppHelper {/** * Other helpers used by FormHelper * * @var array * @access public */	var $helpers = array('Html');/** * Holds the fields array('field_name' => array('type'=> 'string', 'length'=> 100), * primaryKey and validates array('field_name') * * @access public */	var $fieldset = array('fields' => array(), 'key' => 'id', 'validates' => array());/** * Enter description here... * * @var array */	var $__options = array(		'day' => array(), 'minute' => array(), 'hour' => array(),		'month' => array(), 'year' => array(), 'meridian' => array()	);/** * Enter description here... * * @var array * @access public */	var $fields = array();/** * Defines the type of form being created.  Set by FormHelper::create(). * * @var string * @access public */	var $requestType = null;/** * Returns an HTML FORM element. * * @access public * @param string $model The model object which the form is being defined for * @param array	 $options *			'type' Form method defaults to POST * 			'action'  The Action the form submits to. Can be a string or array, *			'url'  The url the form submits to. Can be a string or a url array, *			'default'  Allows for the creation of Ajax forms.   *			'onsubmit' Used with 'default' to create ajax forms. * * @return string An formatted opening FORM tag. */	function create($model = null, $options = array()) {		$defaultModel = null;		$view =& ClassRegistry::getObject('view');		if (is_array($model) && empty($options)) {			$options = $model;			$model = null;		}		if (empty($model) && $model !== false && !empty($this->params['models'])) {			$model = $this->params['models'][0];			$defaultModel = $this->params['models'][0];		} elseif (empty($model) && empty($this->params['models'])) {			$model = false;		} elseif (is_string($model) && (strpos($model, '/') !== false || strpos($model, '.') !== false)) {			$path = preg_split('/\/|\./', $model);			$model = $path[count($path) - 1];		}		if (ClassRegistry::isKeySet($model)) {			$object =& ClassRegistry::getObject($model);		}		$models = ClassRegistry::keys();		foreach ($models as $currentModel) {			if (ClassRegistry::isKeySet($currentModel)) {				$currentObject =& ClassRegistry::getObject($currentModel);				if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) {					$this->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors;				}			}		}		$this->setEntity($model . '.', true);		$append = '';		$created = $id = false;		if (isset($object)) {			$fields = $object->schema();			if (!empty($object->hasAndBelongsToMany)) {				foreach ($object->hasAndBelongsToMany as $alias => $assocData) {					$fields[$alias] = array('type' => 'multiple');				}			}			$validates = array();			if (!empty($object->validate)) {				foreach ($object->validate as $validateField => $validateProperties) {					if (!isset($validateProperties['required']) || (isset($validateProperties['required']) && $validateProperties['required'] !== false)) {						$validates[] = $validateField;					}				}			}			$this->fieldset = array('fields' => $fields, 'key' => $object->primaryKey, 'validates' => $validates);		}		$data = $this->fieldset;		if (isset($this->data[$model]) && isset($this->data[$model][$data['key']]) && !empty($this->data[$model][$data['key']])) {			$created = true;			$id = $this->data[$model][$data['key']];		}		$options = array_merge(array(			'type' => ($created && empty($options['action'])) ? 'put' : 'post',			'action' => null,			'url' => null,			'default' => true),		$options);		if (empty($options['url']) || is_array($options['url'])) {			if (empty($options['url']['controller'])) {				if (!empty($model) && $model != $defaultModel) {					$options['url']['controller'] = Inflector::underscore(Inflector::pluralize($model));				} elseif (!empty($this->params['controller'])) {					$options['url']['controller'] = Inflector::underscore($this->params['controller']);				}			}			if (empty($options['action'])) {				$options['action'] = ife($created, 'edit', 'add');			}			$actionDefaults = array(				'plugin' => $this->plugin,				'controller' => $view->viewPath,				'action' => $options['action'],				'id' => $id			);			if (!empty($options['action']) && !isset($options['id'])) {				$options['id'] = $model . Inflector::camelize($options['action']) . 'Form';			}			$options['action'] = array_merge($actionDefaults, (array)$options['url']);		} elseif (is_string($options['url'])) {			$options['action'] = $options['url'];		}		unset($options['url']);		switch (strtolower($options['type'])) {			case 'get':				$htmlAttributes['method'] = 'get';			break;			case 'file':				$htmlAttributes['enctype'] = 'multipart/form-data';				$options['type'] = ife($created, 'put', 'post');			case 'post':			case 'put':			case 'delete':				$append .= $this->hidden('_method', array('name' => '_method', 'value' => strtoupper($options['type']), 'id' => null));			default:				$htmlAttributes['method'] = 'post';			break;		}		$this->requestType = strtolower($options['type']);		$htmlAttributes['action'] = $this->url($options['action']);		unset($options['type'], $options['action']);		if ($options['default'] == false) {			if (isset($htmlAttributes['onSubmit']) || isset($htmlAttributes['onsubmit'])) {				$htmlAttributes['onsubmit'] .= ' event.returnValue = false; return false;';			} else {				$htmlAttributes['onsubmit'] = 'event.returnValue = false; return false;';			}		}		unset($options['default']);		$htmlAttributes = array_merge($options, $htmlAttributes);		if (isset($this->params['_Token']) && !empty($this->params['_Token'])) {			$append .= $this->hidden('_Token.key', array('value' => $this->params['_Token']['key'], 'id' => 'Token' . mt_rand()));		}		if (!empty($append)) {			$append = sprintf($this->Html->tags['fieldset'], ' style="display:none;"', $append);		}		$this->setEntity($model . '.', true);		return $this->output(sprintf($this->Html->tags['form'], $this->Html->_parseAttributes($htmlAttributes, null, ''))) . $append;	}/** * Closes an HTML form, cleans up values set by FormHelper::create(), and writes hidden * input fields where appropriate. * * If $options is set a form submit button will be created. * * @param mixed $options as a string will use $options as the value of button, * 	array usage: * 		array('label' => 'save'); value="save" * 		array('label' => 'save', 'name' => 'Whatever'); value="save" name="Whatever" * 		array('name' => 'Whatever'); value="Submit" name="Whatever" * 		array('label' => 'save', 'name' => 'Whatever', 'div' => 'good') <div class="good"> value="save" name="Whatever" * 		array('label' => 'save', 'name' => 'Whatever', 'div' => array('class' => 'good')); <div class="good"> value="save" name="Whatever" * * @return string a closing FORM tag optional submit button. * @access public */	function end($options = null) {		if (!empty($this->params['models'])) {			$models = $this->params['models'][0];		}		$out = null;		$submit = null;		if ($options !== null) {			$submitOptions = array();			if (is_string($options)) {				$submit = $options;			} else {				if (isset($options['label'])) {					$submit = $options['label'];					unset($options['label']);				}				$submitOptions = $options;				if (!$submit) {					$submit = __('Submit', true);				}			}			$out .= $this->submit($submit, $submitOptions);		} elseif (isset($this->params['_Token']) && !empty($this->params['_Token'])) {			$out .= $this->secure($this->fields);			$this->fields = array();		}		$this->setEntity(null);		$out .= $this->Html->tags['formend'];		$view =& ClassRegistry::getObject('view');		$view->modelScope = false;		return $this->output($out);	}/** * Generates a hidden field with a security hash based on the fields used in the form. * * @param array $fields The list of fields to use when generating the hash * @return string A hidden input field with a security hash * @access public */	function secure($fields) {		if (!empty($fields)) {			$append = '<fieldset style="display:none;">';			foreach ($fields as $key => $value) {				if ($key[0] != '_' && is_array($fields[$key])) {					sort($fields[$key]);				} else {					$model = substr($key, 1);					if ($key !== '__Token' && !isset($fields[$model])) {						$fields[$model] = array();					}				}			}			ksort($fields, SORT_STRING);			$append .= $this->hidden('_Token.fields', array('value' => urlencode(Security::hash(serialize($fields) . Configure::read('Security.salt'))), 'id' => 'TokenFields' . mt_rand()));			$append .= '</fieldset>';			return $append;		}		return null;	}/** * Determine which fields of a form should be used for hash * * @param string $model Model name * @param mixed $options Options * @access private */	function __secure($model = null, $options = null) {		if (!$model) {			$model = $this->model();		}		$view =& ClassRegistry::getObject('view');		$field = $view->field;		$fieldSuffix = $view->fieldSuffix;		if (isset($this->params['_Token']) && !empty($this->params['_Token'])) {			if (!empty($this->params['_Token']['disabledFields'])) {				foreach ($this->params['_Token']['disabledFields'] as $value) {					$parts = preg_split('/\/|\./', $value);					if (count($parts) == 1) {						if ($parts[0] === $field || $parts[0] === $fieldSuffix) {							return;						}					} elseif (count($parts) == 2) {						if ($parts[0] === $model && ($parts[1] === $field || $parts[1] === $fieldSuffix)) {							return;						}					}				}			}			$this->__fields($model, $field, $fieldSuffix, $options);			return;		}	}/** * Generates a field list used to secure forms * * @param string $model * @param string $field * @param string $fieldSuffix * @param mixed $options * @access private */	function __fields($model, $field, $fieldSuffix, $options) {		if (!is_null($options)) {			if (is_numeric($field)) {				$this->fields[$model][$field][$fieldSuffix] = $options;			} else {				$this->fields[$model][$field] = $options;			}			return;		}		if ((isset($this->fields[$model]) && !in_array($field, $this->fields[$model], true)) || !isset($this->fields[$model])) {			if (is_numeric($field)) {				$this->fields[$model][$field][] = $fieldSuffix;			} else if (is_null($field)) {				$this->fields[] = $model;			} else {				$this->fields[$model][] = $field;			}		}		return;	}/** * Returns true if there is an error for the given field, otherwise false * * @param string $field This should be "Modelname.fieldname", "Modelname/fieldname" is deprecated * @return boolean If there are errors this method returns true, else false. * @access public */	function isFieldError($field) {		$this->setEntity($field);		return (bool)$this->tagIsInvalid();	}/** * Returns a formatted error message for given FORM field, NULL if no errors. * * @param string $field A field name, like "Modelname.fieldname", "Modelname/fieldname" is deprecated * @param mixed $text		Error message or array of $options * @param array $options	Rendering options for <div /> wrapper tag *			'escape'  bool  Whether or not to html escape the contents of the error. *			'wrap'  mixed  Whether or not the error message should be wrapped in a div. If a string, will be used as the HTML tag to use. *			'class'  string  The classname for the error message  * @return string If there are errors this method returns an error message, otherwise null. * @access public */	function error($field, $text = null, $options = array()) {		$this->setEntity($field);		$options = array_merge(array('wrap' => true, 'class' => 'error-message', 'escape' => true), $options);		if ($error = $this->tagIsInvalid()) {			if (is_array($error)) {				list(,,$field) = explode('.', $field);				if (isset($error[$field])) {					$error = $error[$field];				} else {					return null;				}			}			if (is_array($text) && is_numeric($error) && $error > 0) {				$error--;			}			if (is_array($text) && isset($text[$error])) {				$text = $text[$error];			} elseif (is_array($text)) {			    $options = array_merge($options, $text);				$text = null;			}			if ($text != null) {				$error = $text;			} elseif (is_numeric($error)) {				$error = sprintf(__('Error in field %s', true), Inflector::humanize($this->field()));			}			if ($options['escape']) {				$error = h($error);				unset($options['escape']);			}			if ($options['wrap']) {			    $tag = is_string($options['wrap']) ? $options['wrap'] : 'div';				unset($options['wrap']);				return $this->Html->tag($tag, $error, $options);			} else {				return $error;			}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?