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 + -
显示快捷键?