CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 1.2 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 1.2
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Classes

  • AclBase
  • AclBehavior
  • AclComponent
  • AclNode
  • AclShell
  • Aco
  • AcoAction
  • AjaxHelper
  • ApcEngine
  • ApiShell
  • App
  • AppController
  • AppHelper
  • AppModel
  • Aro
  • AuthComponent
  • BakeShell
  • BehaviorCollection
  • Cache
  • CacheEngine
  • CacheHelper
  • CakeErrorController
  • CakeLog
  • CakeSchema
  • CakeSession
  • CakeSocket
  • ClassRegistry
  • Component
  • Configure
  • ConnectionManager
  • ConsoleShell
  • ContainableBehavior
  • Controller
  • ControllerTask
  • CookieComponent
  • DataSource
  • DbAcl
  • DbAclSchema
  • DbConfigTask
  • DboAdodb
  • DboDb2
  • DboFirebird
  • DboMssql
  • DboMysql
  • DboMysqlBase
  • DboMysqli
  • DboOdbc
  • DboOracle
  • DboPostgres
  • DboSource
  • DboSqlite
  • DboSybase
  • Debugger
  • EmailComponent
  • ErrorHandler
  • ExtractTask
  • File
  • FileEngine
  • Flay
  • Folder
  • FormHelper
  • Helper
  • HtmlHelper
  • HttpSocket
  • I18n
  • I18nModel
  • i18nSchema
  • I18nShell
  • Inflector
  • IniAcl
  • JavascriptHelper
  • JsHelper
  • JsHelperObject
  • L10n
  • MagicDb
  • MagicFileResource
  • MediaView
  • MemcacheEngine
  • Model
  • ModelBehavior
  • ModelTask
  • Multibyte
  • NumberHelper
  • Object
  • Overloadable
  • Overloadable2
  • PagesController
  • PaginatorHelper
  • Permission
  • PluginTask
  • ProjectTask
  • RequestHandlerComponent
  • Router
  • RssHelper
  • Sanitize
  • Scaffold
  • ScaffoldView
  • SchemaShell
  • Security
  • SecurityComponent
  • SessionComponent
  • SessionHelper
  • SessionsSchema
  • Set
  • Shell
  • String
  • TestSuiteShell
  • TestTask
  • TextHelper
  • ThemeView
  • TimeHelper
  • TranslateBehavior
  • TreeBehavior
  • Validation
  • View
  • ViewTask
  • XcacheEngine
  • Xml
  • XmlElement
  • XmlHelper
  • XmlManager
  • XmlNode
  • XmlTextNode

Functions

  • __enclose
  • make_clean_css
  • mb_encode_mimeheader
  • mb_stripos
  • mb_stristr
  • mb_strlen
  • mb_strpos
  • mb_strrchr
  • mb_strrichr
  • mb_strripos
  • mb_strrpos
  • mb_strstr
  • mb_strtolower
  • mb_strtoupper
  • mb_substr
  • mb_substr_count
  • write_css_cache
   1: <?php
   2: /* SVN FILE: $Id$ */
   3: /**
   4:  * Automatic generation of HTML FORMs from given data.
   5:  *
   6:  * Used for scaffolding.
   7:  *
   8:  * PHP versions 4 and 5
   9:  *
  10:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  11:  * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  12:  *
  13:  * Licensed under The MIT License
  14:  * Redistributions of files must retain the above copyright notice.
  15:  *
  16:  * @copyright     Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  17:  * @link          http://cakephp.org CakePHP(tm) Project
  18:  * @package       cake
  19:  * @subpackage    cake.cake.libs.view.helpers
  20:  * @since         CakePHP(tm) v 0.10.0.1076
  21:  * @version       $Revision$
  22:  * @modifiedby    $LastChangedBy$
  23:  * @lastmodified  $Date$
  24:  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
  25:  */
  26: /**
  27:  * Form helper library.
  28:  *
  29:  * Automatic generation of HTML FORMs from given data.
  30:  *
  31:  * @package       cake
  32:  * @subpackage    cake.cake.libs.view.helpers
  33:  */
  34: class FormHelper extends AppHelper {
  35: /**
  36:  * Other helpers used by FormHelper
  37:  *
  38:  * @var array
  39:  * @access public
  40:  */
  41:     var $helpers = array('Html');
  42: /**
  43:  * Holds the fields array('field_name' => array('type'=> 'string', 'length'=> 100),
  44:  * primaryKey and validates array('field_name')
  45:  *
  46:  * @access public
  47:  */
  48:     var $fieldset = array('fields' => array(), 'key' => 'id', 'validates' => array());
  49: /**
  50:  * Options used by DateTime fields
  51:  *
  52:  * @var array
  53:  */
  54:     var $__options = array(
  55:         'day' => array(), 'minute' => array(), 'hour' => array(),
  56:         'month' => array(), 'year' => array(), 'meridian' => array()
  57:     );
  58: /**
  59:  * List of fields created, used with secure forms.
  60:  *
  61:  * @var array
  62:  * @access public
  63:  */
  64:     var $fields = array();
  65: /**
  66:  * Defines the type of form being created.  Set by FormHelper::create().
  67:  *
  68:  * @var string
  69:  * @access public
  70:  */
  71:     var $requestType = null;
  72: /**
  73:  * Returns an HTML FORM element.
  74:  *
  75:  * Options:
  76:  *
  77:  * - 'type' Form method defaults to POST
  78:  * - 'action'  The Action the form submits to. Can be a string or array,
  79:  * - 'url'  The url the form submits to. Can be a string or a url array,
  80:  * - 'default'  Allows for the creation of Ajax forms.
  81:  * - 'onsubmit' Used in conjunction with 'default' to create ajax forms.
  82:  *
  83:  * @access public
  84:  * @param string $model The model object which the form is being defined for
  85:  * @param array $options An array of html attributes and options.
  86:  * @return string An formatted opening FORM tag.
  87:  */
  88:     function create($model = null, $options = array()) {
  89:         $defaultModel = null;
  90:         $view =& ClassRegistry::getObject('view');
  91: 
  92:         if (is_array($model) && empty($options)) {
  93:             $options = $model;
  94:             $model = null;
  95:         }
  96: 
  97:         if (empty($model) && $model !== false && !empty($this->params['models'])) {
  98:             $model = $this->params['models'][0];
  99:             $defaultModel = $this->params['models'][0];
 100:         } elseif (empty($model) && empty($this->params['models'])) {
 101:             $model = false;
 102:         } elseif (is_string($model) && strpos($model, '.') !== false) {
 103:             $path = explode('.', $model);
 104:             $model = $path[count($path) - 1];
 105:         }
 106: 
 107:         if (ClassRegistry::isKeySet($model)) {
 108:             $object =& ClassRegistry::getObject($model);
 109:         }
 110: 
 111:         $models = ClassRegistry::keys();
 112:         foreach ($models as $currentModel) {
 113:             if (ClassRegistry::isKeySet($currentModel)) {
 114:                 $currentObject =& ClassRegistry::getObject($currentModel);
 115:                 if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) {
 116:                     $this->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors;
 117:                 }
 118:             }
 119:         }
 120: 
 121:         $this->setEntity($model . '.', true);
 122:         $append = '';
 123:         $created = $id = false;
 124: 
 125:         if (isset($object)) {
 126:             $fields = $object->schema();
 127:             foreach ($fields as $key => $value) {
 128:                 unset($fields[$key]);
 129:                 $fields[$model . '.' . $key] = $value;
 130:             }
 131: 
 132:             if (!empty($object->hasAndBelongsToMany)) {
 133:                 foreach ($object->hasAndBelongsToMany as $alias => $assocData) {
 134:                     $fields[$alias] = array('type' => 'multiple');
 135:                 }
 136:             }
 137:             $validates = array();
 138:             if (!empty($object->validate)) {
 139:                 foreach ($object->validate as $validateField => $validateProperties) {
 140:                     if (is_array($validateProperties)) {
 141:                         $dims = Set::countDim($validateProperties);
 142:                         if (($dims == 1 && !isset($validateProperties['required']) || (array_key_exists('required', $validateProperties) && $validateProperties['required'] !== false))) {
 143:                             $validates[] = $validateField;
 144:                         } elseif ($dims > 1) {
 145:                             foreach ($validateProperties as $rule => $validateProp) {
 146:                                 if (is_array($validateProp) && (array_key_exists('required', $validateProp) && $validateProp['required'] !== false)) {
 147:                                     $validates[] = $validateField;
 148:                                 }
 149:                             }
 150:                         }
 151:                     }
 152:                 }
 153:             }
 154:             $key = $object->primaryKey;
 155:             $this->fieldset = compact('fields', 'key', 'validates');
 156:         }
 157: 
 158:         $data = $this->fieldset;
 159:         $recordExists = (
 160:             isset($this->data[$model]) &&
 161:             isset($this->data[$model][$data['key']]) &&
 162:             !empty($this->data[$model][$data['key']])
 163:         );
 164: 
 165:         if ($recordExists) {
 166:             $created = true;
 167:             $id = $this->data[$model][$data['key']];
 168:         }
 169:         $options = array_merge(array(
 170:             'type' => ($created && empty($options['action'])) ? 'put' : 'post',
 171:             'action' => null,
 172:             'url' => null,
 173:             'default' => true),
 174:         $options);
 175: 
 176:         if (empty($options['url']) || is_array($options['url'])) {
 177:             if (empty($options['url']['controller'])) {
 178:                 if (!empty($model) && $model != $defaultModel) {
 179:                     $options['url']['controller'] = Inflector::underscore(Inflector::pluralize($model));
 180:                 } elseif (!empty($this->params['controller'])) {
 181:                     $options['url']['controller'] = Inflector::underscore($this->params['controller']);
 182:                 }
 183:             }
 184:             if (empty($options['action'])) {
 185:                 $options['action'] = ($created) ? 'edit' : 'add';
 186:             }
 187: 
 188:             $actionDefaults = array(
 189:                 'plugin' => $this->plugin,
 190:                 'controller' => $view->viewPath,
 191:                 'action' => $options['action'],
 192:                 'id' => $id
 193:             );
 194:             if (!empty($options['action']) && !isset($options['id'])) {
 195:                 $options['id'] = $model . Inflector::camelize($options['action']) . 'Form';
 196:             }
 197:             $options['action'] = array_merge($actionDefaults, (array)$options['url']);
 198:         } elseif (is_string($options['url'])) {
 199:             $options['action'] = $options['url'];
 200:         }
 201:         unset($options['url']);
 202: 
 203:         switch (strtolower($options['type'])) {
 204:             case 'get':
 205:                 $htmlAttributes['method'] = 'get';
 206:             break;
 207:             case 'file':
 208:                 $htmlAttributes['enctype'] = 'multipart/form-data';
 209:                 $options['type'] = ($created) ? 'put' : 'post';
 210:             case 'post':
 211:             case 'put':
 212:             case 'delete':
 213:                 $append .= $this->hidden('_method', array(
 214:                     'name' => '_method', 'value' => strtoupper($options['type']), 'id' => null
 215:                 ));
 216:             default:
 217:                 $htmlAttributes['method'] = 'post';
 218:             break;
 219:         }
 220:         $this->requestType = strtolower($options['type']);
 221: 
 222:         $htmlAttributes['action'] = $this->url($options['action']);
 223:         unset($options['type'], $options['action']);
 224: 
 225:         if ($options['default'] == false) {
 226:             if (isset($htmlAttributes['onSubmit']) || isset($htmlAttributes['onsubmit'])) {
 227:                 $htmlAttributes['onsubmit'] .= ' event.returnValue = false; return false;';
 228:             } else {
 229:                 $htmlAttributes['onsubmit'] = 'event.returnValue = false; return false;';
 230:             }
 231:         }
 232:         unset($options['default']);
 233:         $htmlAttributes = array_merge($options, $htmlAttributes);
 234: 
 235:         if (isset($this->params['_Token']) && !empty($this->params['_Token'])) {
 236:             $append .= $this->hidden('_Token.key', array(
 237:                 'value' => $this->params['_Token']['key'], 'id' => 'Token' . mt_rand())
 238:             );
 239:         }
 240: 
 241:         if (!empty($append)) {
 242:             $append = sprintf($this->Html->tags['fieldset'], ' style="display:none;"', $append);
 243:         }
 244: 
 245:         $this->setEntity($model . '.', true);
 246:         $attributes = $this->_parseAttributes($htmlAttributes, null, '');
 247:         return $this->output(sprintf($this->Html->tags['form'], $attributes)) . $append;
 248:     }
 249: /**
 250:  * Closes an HTML form, cleans up values set by FormHelper::create(), and writes hidden
 251:  * input fields where appropriate.
 252:  *
 253:  * If $options is set a form submit button will be created.
 254:  *
 255:  * @param mixed $options as a string will use $options as the value of button,
 256:  *  array usage:
 257:  *      array('label' => 'save'); value="save"
 258:  *      array('label' => 'save', 'name' => 'Whatever'); value="save" name="Whatever"
 259:  *      array('name' => 'Whatever'); value="Submit" name="Whatever"
 260:  *      array('label' => 'save', 'name' => 'Whatever', 'div' => 'good') <div class="good"> value="save" name="Whatever"
 261:  *      array('label' => 'save', 'name' => 'Whatever', 'div' => array('class' => 'good')); <div class="good"> value="save" name="Whatever"
 262:  *
 263:  * @return string a closing FORM tag optional submit button.
 264:  * @access public
 265:  */
 266:     function end($options = null) {
 267:         if (!empty($this->params['models'])) {
 268:             $models = $this->params['models'][0];
 269:         }
 270:         $out = null;
 271:         $submit = null;
 272: 
 273:         if ($options !== null) {
 274:             $submitOptions = array();
 275:             if (is_string($options)) {
 276:                 $submit = $options;
 277:             } else {
 278:                 if (isset($options['label'])) {
 279:                     $submit = $options['label'];
 280:                     unset($options['label']);
 281:                 }
 282:                 $submitOptions = $options;
 283: 
 284:                 if (!$submit) {
 285:                     $submit = __('Submit', true);
 286:                 }
 287:             }
 288:             $out .= $this->submit($submit, $submitOptions);
 289:         }
 290:         if (isset($this->params['_Token']) && !empty($this->params['_Token'])) {
 291:             $out .= $this->secure($this->fields);
 292:             $this->fields = array();
 293:         }
 294:         $this->setEntity(null);
 295:         $out .= $this->Html->tags['formend'];
 296: 
 297:         $view =& ClassRegistry::getObject('view');
 298:         $view->modelScope = false;
 299:         return $this->output($out);
 300:     }
 301: /**
 302:  * Generates a hidden field with a security hash based on the fields used in the form.
 303:  *
 304:  * @param array $fields The list of fields to use when generating the hash
 305:  * @return string A hidden input field with a security hash
 306:  * @access public
 307:  */
 308:     function secure($fields = array()) {
 309:         if (!isset($this->params['_Token']) || empty($this->params['_Token'])) {
 310:             return;
 311:         }
 312:         $out = '<fieldset style="display:none;">';
 313:         $locked = array();
 314: 
 315:         foreach ($fields as $key => $value) {
 316:             if (!is_int($key)) {
 317:                 $locked[$key] = $value;
 318:                 unset($fields[$key]);
 319:             }
 320:         }
 321:         sort($fields, SORT_STRING);
 322:         ksort($locked, SORT_STRING);
 323:         $fields += $locked;
 324: 
 325:         $fields = Security::hash(serialize($fields) . Configure::read('Security.salt'));
 326:         $locked = implode(array_keys($locked), '|');
 327: 
 328:         $out .= $this->hidden('_Token.fields', array(
 329:             'value' => urlencode($fields . ':' . $locked),
 330:             'id' => 'TokenFields' . mt_rand()
 331:         ));
 332:         return $out .= '</fieldset>';
 333:     }
 334: /**
 335:  * Determine which fields of a form should be used for hash
 336:  *
 337:  * @param mixed $field Reference to field to be secured
 338:  * @param mixed $value Field value, if value should not be tampered with
 339:  * @access private
 340:  */
 341:     function __secure($field = null, $value = null) {
 342:         if (!$field) {
 343:             $view =& ClassRegistry::getObject('view');
 344:             $field = $view->entity();
 345:         } elseif (is_string($field)) {
 346:             $field = Set::filter(explode('.', $field), true);
 347:         }
 348: 
 349:         if (!empty($this->params['_Token']['disabledFields'])) {
 350:             foreach ((array)$this->params['_Token']['disabledFields'] as $disabled) {
 351:                 $disabled = explode('.', $disabled);
 352:                 if (array_values(array_intersect($field, $disabled)) === $disabled) {
 353:                     return;
 354:                 }
 355:             }
 356:         }
 357:         $field = implode('.', $field);
 358:         if (!in_array($field, $this->fields)) {
 359:             if ($value !== null) {
 360:                 return $this->fields[$field] = $value;
 361:             }
 362:             $this->fields[] = $field;
 363:         }
 364:     }
 365: /**
 366:  * Returns true if there is an error for the given field, otherwise false
 367:  *
 368:  * @param string $field This should be "Modelname.fieldname"
 369:  * @return boolean If there are errors this method returns true, else false.
 370:  * @access public
 371:  */
 372:     function isFieldError($field) {
 373:         $this->setEntity($field);
 374:         return (bool)$this->tagIsInvalid();
 375:     }
 376: /**
 377:  * Returns a formatted error message for given FORM field, NULL if no errors.
 378:  *
 379:  * Options:
 380:  *
 381:  * - 'escape'  bool  Whether or not to html escape the contents of the error.
 382:  * - 'wrap'  mixed  Whether or not the error message should be wrapped in a div. If a
 383:  *   string, will be used as the HTML tag to use.
 384:  * - 'class'  string  The classname for the error message
 385:  *
 386:  * @param string $field  A field name, like "Modelname.fieldname"
 387:  * @param mixed $text  Error message or array of $options
 388:  * @param array $options  Rendering options for <div /> wrapper tag
 389:  * @return string If there are errors this method returns an error message, otherwise null.
 390:  * @access public
 391:  */
 392:     function error($field, $text = null, $options = array()) {
 393:         $defaults = array('wrap' => true, 'class' => 'error-message', 'escape' => true);
 394:         $options = array_merge($defaults, $options);
 395:         $this->setEntity($field);
 396: 
 397:         if ($error = $this->tagIsInvalid()) {
 398:             if (is_array($error)) {
 399:                 list(,,$field) = explode('.', $field);
 400:                 if (isset($error[$field])) {
 401:                     $error = $error[$field];
 402:                 } else {
 403:                     return null;
 404:                 }
 405:             }
 406: 
 407:             if (is_array($text) && is_numeric($error) && $error > 0) {
 408:                 $error--;
 409:             }
 410:             if (is_array($text)) {
 411:                 $options = array_merge($options, $text);
 412:                 $text = isset($text[$error]) ? $text[$error] : null;
 413:                 unset($options[$error]);
 414:             }
 415: 
 416:             if ($text != null) {
 417:                 $error = $text;
 418:             } elseif (is_numeric($error)) {
 419:                 $error = sprintf(__('Error in field %s', true), Inflector::humanize($this->field()));
 420:             }
 421:             if ($options['escape']) {
 422:                 $error = h($error);
 423:                 unset($options['escape']);
 424:             }
 425:             if ($options['wrap']) {
 426:                 $tag = is_string($options['wrap']) ? $options['wrap'] : 'div';
 427:                 unset($options['wrap']);
 428:                 return $this->Html->tag($tag, $error, $options);
 429:             } else {
 430:                 return $error;
 431:             }
 432:         } else {
 433:             return null;
 434:         }
 435:     }
 436: /**
 437:  * Returns a formatted LABEL element for HTML FORMs.
 438:  *
 439:  * @param string $fieldName This should be "Modelname.fieldname"
 440:  * @param string $text Text that will appear in the label field.
 441:  * @param array $attributes Array of HTML attributes.
 442:  * @return string The formatted LABEL element
 443:  */
 444:     function label($fieldName = null, $text = null, $attributes = array()) {
 445:         if (empty($fieldName)) {
 446:             $view = ClassRegistry::getObject('view');
 447:             $fieldName = implode('.', $view->entity());
 448:         }
 449: 
 450:         if ($text === null) {
 451:             if (strpos($fieldName, '.') !== false) {
 452:                 $text = array_pop(explode('.', $fieldName));
 453:             } else {
 454:                 $text = $fieldName;
 455:             }
 456:             if (substr($text, -3) == '_id') {
 457:                 $text = substr($text, 0, strlen($text) - 3);
 458:             }
 459:             $text = __(Inflector::humanize(Inflector::underscore($text)), true);
 460:         }
 461: 
 462:         if (isset($attributes['for'])) {
 463:             $labelFor = $attributes['for'];
 464:             unset($attributes['for']);
 465:         } else {
 466:             $labelFor = $this->domId($fieldName);
 467:         }
 468: 
 469:         return $this->output(sprintf(
 470:             $this->Html->tags['label'],
 471:             $labelFor,
 472:             $this->_parseAttributes($attributes), $text
 473:         ));
 474:     }
 475: /**
 476:  * Generate a set of inputs for `$fields`.  If $fields is null the current model
 477:  * will be used.
 478:  *
 479:  * In addition to controller fields output, `$fields` can be used to control legend
 480:  * and fieldset rendering with the `fieldset` and `legend` keys. 
 481:  * `$form->inputs(array('legend' => 'My legend'));` Would generate an input set with 
 482:  * a custom legend.  You can customize individual inputs through `$fields` as well.
 483:  * 
 484:  * {{{
 485:  *  $form->inputs(array(
 486:  *      'name' => array('label' => 'custom label')
 487:  *  ));
 488:  * }}}
 489:  *
 490:  * @param mixed $fields An array of fields to generate inputs for, or null.
 491:  * @param array $blacklist a simple array of fields to skip.
 492:  * @return string Completed form inputs.
 493:  * @access public
 494:  */
 495:     function inputs($fields = null, $blacklist = null) {
 496:         $fieldset = $legend = true;
 497: 
 498:         if (is_array($fields)) {
 499:             if (array_key_exists('legend', $fields)) {
 500:                 $legend = $fields['legend'];
 501:                 unset($fields['legend']);
 502:             }
 503: 
 504:             if (isset($fields['fieldset'])) {
 505:                 $fieldset = $fields['fieldset'];
 506:                 unset($fields['fieldset']);
 507:             }
 508:         } elseif ($fields !== null) {
 509:             $fieldset = $legend = $fields;
 510:             if (!is_bool($fieldset)) {
 511:                 $fieldset = true;
 512:             }
 513:             $fields = array();
 514:         }
 515: 
 516:         if (empty($fields)) {
 517:             $fields = array_keys($this->fieldset['fields']);
 518:         }
 519: 
 520:         if ($legend === true) {
 521:             $actionName = __('New', true);
 522:             $isEdit = (
 523:                 strpos($this->action, 'update') !== false ||
 524:                 strpos($this->action, 'edit') !== false
 525:             );
 526:             if ($isEdit) {
 527:                 $actionName = __('Edit', true);
 528:             }
 529:             $modelName = Inflector::humanize(Inflector::underscore($this->model()));
 530:             $legend = $actionName .' '. __($modelName, true);
 531:         }
 532: 
 533:         $out = null;
 534:         foreach ($fields as $name => $options) {
 535:             if (is_numeric($name) && !is_array($options)) {
 536:                 $name = $options;
 537:                 $options = array();
 538:             }
 539:             $entity = explode('.', $name);
 540:             $blacklisted = (
 541:                 is_array($blacklist) &&
 542:                 (in_array($name, $blacklist) || in_array(end($entity), $blacklist))
 543:             );
 544:             if ($blacklisted) {
 545:                 continue;
 546:             }
 547:             $out .= $this->input($name, $options);
 548:         }
 549: 
 550:         if (is_string($fieldset)) {
 551:             $fieldsetClass = sprintf(' class="%s"', $fieldset);
 552:         } else {
 553:             $fieldsetClass = '';
 554:         }
 555: 
 556:         if ($fieldset && $legend) {
 557:             return sprintf(
 558:                 $this->Html->tags['fieldset'],
 559:                 $fieldsetClass,
 560:                 sprintf($this->Html->tags['legend'], $legend) . $out
 561:             );
 562:         } elseif ($fieldset) {
 563:             return sprintf($this->Html->tags['fieldset'], $fieldsetClass, $out);
 564:         } else {
 565:             return $out;
 566:         }
 567:     }
 568: /**
 569:  * Generates a form input element complete with label and wrapper div
 570:  *
 571:  * Options - See each field type method for more information. Any options that are part of 
 572:  * $attributes or $options for the different type methods can be included in $options for input().
 573:  *
 574:  * - 'type' - Force the type of widget you want. e.g. ```type => 'select'```
 575:  * - 'label' - control the label
 576:  * - 'div' - control the wrapping div element
 577:  * - 'options' - for widgets that take options e.g. radio, select
 578:  * - 'error' - control the error message that is produced
 579:  *
 580:  * @param string $fieldName This should be "Modelname.fieldname"
 581:  * @param array $options Each type of input takes different options.
 582:  * @return string Completed form widget
 583:  */
 584:     function input($fieldName, $options = array()) {
 585:         $view =& ClassRegistry::getObject('view');
 586:         $this->setEntity($fieldName);
 587:         $entity = implode('.', $view->entity());
 588: 
 589:         $defaults = array('before' => null, 'between' => null, 'after' => null);
 590:         $options = array_merge($defaults, $options);
 591: 
 592:         if (!isset($options['type'])) {
 593:             $options['type'] = 'text';
 594: 
 595:             if (isset($options['options'])) {
 596:                 $options['type'] = 'select';
 597:             } elseif (in_array($this->field(), array('psword', 'passwd', 'password'))) {
 598:                 $options['type'] = 'password';
 599:             } elseif (isset($this->fieldset['fields'][$entity])) {
 600:                 $fieldDef = $this->fieldset['fields'][$entity];
 601:                 $type = $fieldDef['type'];
 602:                 $primaryKey = $this->fieldset['key'];
 603:             } elseif (ClassRegistry::isKeySet($this->model())) {
 604:                 $model =& ClassRegistry::getObject($this->model());
 605:                 $type = $model->getColumnType($this->field());
 606:                 $fieldDef = $model->schema();
 607: 
 608:                 if (isset($fieldDef[$this->field()])) {
 609:                     $fieldDef = $fieldDef[$this->field()];
 610:                 } else {
 611:                     $fieldDef = array();
 612:                 }
 613:                 $primaryKey = $model->primaryKey;
 614:             }
 615: 
 616:             if (isset($type)) {
 617:                 $map = array(
 618:                     'string'  => 'text',     'datetime'  => 'datetime',
 619:                     'boolean' => 'checkbox', 'timestamp' => 'datetime',
 620:                     'text'    => 'textarea', 'time'      => 'time',
 621:                     'date'    => 'date',     'float'     => 'text'
 622:                 );
 623: 
 624:                 if (isset($this->map[$type])) {
 625:                     $options['type'] = $this->map[$type];
 626:                 } elseif (isset($map[$type])) {
 627:                     $options['type'] = $map[$type];
 628:                 }
 629:                 if ($this->field() == $primaryKey) {
 630:                     $options['type'] = 'hidden';
 631:                 }
 632:             }
 633: 
 634:             if ($this->model() === $this->field()) {
 635:                 $options['type'] = 'select';
 636:                 if (!isset($options['multiple'])) {
 637:                     $options['multiple'] = 'multiple';
 638:                 }
 639:             }
 640:         }
 641:         $types = array('text', 'checkbox', 'radio', 'select');
 642: 
 643:         if (!isset($options['options']) && in_array($options['type'], $types)) {
 644:             $view =& ClassRegistry::getObject('view');
 645:             $varName = Inflector::variable(
 646:                 Inflector::pluralize(preg_replace('/_id$/', '', $this->field()))
 647:             );
 648:             $varOptions = $view->getVar($varName);
 649:             if (is_array($varOptions)) {
 650:                 if ($options['type'] !== 'radio') {
 651:                     $options['type'] = 'select';
 652:                 }
 653:                 $options['options'] = $varOptions;
 654:             }
 655:         }
 656: 
 657:         $autoLength = (!array_key_exists('maxlength', $options) && isset($fieldDef['length']));
 658:         if ($autoLength && $options['type'] == 'text') {
 659:             $options['maxlength'] = $fieldDef['length'];
 660:         }
 661:         if ($autoLength && $fieldDef['type'] == 'float') {
 662:             $options['maxlength'] = array_sum(explode(',', $fieldDef['length']))+1;
 663:         }
 664: 
 665:         $out = '';
 666:         $div = true;
 667:         $divOptions = array();
 668: 
 669:         if (array_key_exists('div', $options)) {
 670:             $div = $options['div'];
 671:             unset($options['div']);
 672:         }
 673: 
 674:         if (!empty($div)) {
 675:             $divOptions['class'] = 'input';
 676:             $divOptions = $this->addClass($divOptions, $options['type']);
 677:             if (is_string($div)) {
 678:                 $divOptions['class'] = $div;
 679:             } elseif (is_array($div)) {
 680:                 $divOptions = array_merge($divOptions, $div);
 681:             }
 682:             if (in_array($this->field(), $this->fieldset['validates'])) {
 683:                 $divOptions = $this->addClass($divOptions, 'required');
 684:             }
 685:             if (!isset($divOptions['tag'])) {
 686:                 $divOptions['tag'] = 'div';
 687:             }
 688:         }
 689: 
 690:         $label = null;
 691:         if (isset($options['label']) && $options['type'] !== 'radio') {
 692:             $label = $options['label'];
 693:             unset($options['label']);
 694:         }
 695: 
 696:         if ($options['type'] === 'radio') {
 697:             $label = false;
 698:             if (isset($options['options'])) {
 699:                 if (is_array($options['options'])) {
 700:                     $radioOptions = $options['options'];
 701:                 } else {
 702:                     $radioOptions = array($options['options']);
 703:                 }
 704:                 unset($options['options']);
 705:             }
 706:         }
 707: 
 708:         if ($label !== false) {
 709:             $labelAttributes = $this->domId(array(), 'for');
 710:             if ($options['type'] === 'date' || $options['type'] === 'datetime') {
 711:                 if (isset($options['dateFormat']) && $options['dateFormat'] === 'NONE') {
 712:                     $labelAttributes['for'] .= 'Hour';
 713:                 } else {
 714:                     $labelAttributes['for'] .= 'Month';
 715:                 }
 716:             } elseif ($options['type'] === 'time') {
 717:                 $labelAttributes['for'] .= 'Hour';
 718:             }
 719: 
 720:             if (is_array($label)) {
 721:                 $labelText = null;
 722:                 if (isset($label['text'])) {
 723:                     $labelText = $label['text'];
 724:                     unset($label['text']);
 725:                 }
 726:                 $labelAttributes = array_merge($labelAttributes, $label);
 727:             } else {
 728:                 $labelText = $label;
 729:             }
 730: 
 731:             if (isset($options['id'])) {
 732:                 $labelAttributes = array_merge($labelAttributes, array('for' => $options['id']));
 733:             }
 734:             $out = $this->label($fieldName, $labelText, $labelAttributes);
 735:         }
 736: 
 737:         $error = null;
 738:         if (isset($options['error'])) {
 739:             $error = $options['error'];
 740:             unset($options['error']);
 741:         }
 742: 
 743:         $selected = null;
 744:         if (array_key_exists('selected', $options)) {
 745:             $selected = $options['selected'];
 746:             unset($options['selected']);
 747:         }
 748:         if (isset($options['rows']) || isset($options['cols'])) {
 749:             $options['type'] = 'textarea';
 750:         }
 751: 
 752:         $empty = false;
 753:         if (isset($options['empty'])) {
 754:             $empty = $options['empty'];
 755:             unset($options['empty']);
 756:         }
 757: 
 758:         $timeFormat = 12;
 759:         if (isset($options['timeFormat'])) {
 760:             $timeFormat = $options['timeFormat'];
 761:             unset($options['timeFormat']);
 762:         }
 763: 
 764:         $dateFormat = 'MDY';
 765:         if (isset($options['dateFormat'])) {
 766:             $dateFormat = $options['dateFormat'];
 767:             unset($options['dateFormat']);
 768:         }
 769: 
 770:         $type = $options['type'];
 771:         $before = $options['before'];
 772:         $between = $options['between'];
 773:         $after = $options['after'];
 774:         unset($options['type'], $options['before'], $options['between'], $options['after']);
 775: 
 776:         switch ($type) {
 777:             case 'hidden':
 778:                 $out = $this->hidden($fieldName, $options);
 779:                 unset($divOptions);
 780:             break;
 781:             case 'checkbox':
 782:                 $out = $before . $this->checkbox($fieldName, $options) . $between . $out;
 783:             break;
 784:             case 'radio':
 785:                 $out = $before . $out . $this->radio($fieldName, $radioOptions, $options) . $between;
 786:             break;
 787:             case 'text':
 788:             case 'password':
 789:                 $out = $before . $out . $between . $this->{$type}($fieldName, $options);
 790:             break;
 791:             case 'file':
 792:                 $out = $before . $out . $between . $this->file($fieldName, $options);
 793:             break;
 794:             case 'select':
 795:                 $options = array_merge(array('options' => array()), $options);
 796:                 $list = $options['options'];
 797:                 unset($options['options']);
 798:                 $out = $before . $out . $between . $this->select(
 799:                     $fieldName, $list, $selected, $options, $empty
 800:                 );
 801:             break;
 802:             case 'time':
 803:                 $out = $before . $out . $between . $this->dateTime(
 804:                     $fieldName, null, $timeFormat, $selected, $options, $empty
 805:                 );
 806:             break;
 807:             case 'date':
 808:                 $out = $before . $out . $between . $this->dateTime(
 809:                     $fieldName, $dateFormat, null, $selected, $options, $empty
 810:                 );
 811:             break;
 812:             case 'datetime':
 813:                 $out = $before . $out . $between . $this->dateTime(
 814:                     $fieldName, $dateFormat, $timeFormat, $selected, $options, $empty
 815:                 );
 816:             break;
 817:             case 'textarea':
 818:             default:
 819:                 $out = $before . $out . $between . $this->textarea($fieldName, array_merge(
 820:                     array('cols' => '30', 'rows' => '6'), $options
 821:                 ));
 822:             break;
 823:         }
 824: 
 825:         if ($type != 'hidden') {
 826:             $out .= $after;
 827:             if ($error !== false) {
 828:                 $errMsg = $this->error($fieldName, $error);
 829:                 if ($errMsg) {
 830:                     $out .= $errMsg;
 831:                     $divOptions = $this->addClass($divOptions, 'error');
 832:                 }
 833:             }
 834:         }
 835:         if (isset($divOptions) && isset($divOptions['tag'])) {
 836:             $tag = $divOptions['tag'];
 837:             unset($divOptions['tag']);
 838:             $out = $this->Html->tag($tag, $out, $divOptions);
 839:         }
 840:         return $out;
 841:     }
 842: /**
 843:  * Creates a checkbox input widget.
 844:  *
 845:  * Options:
 846:  *
 847:  * - 'value' - the value of the checkbox
 848:  * - checked' - boolean indicate that this checkbox is checked.
 849:  *
 850:  * @param string $fieldName Name of a field, like this "Modelname.fieldname"
 851:  * @param array $options Array of HTML attributes.
 852:  * @todo Right now, automatically setting the 'checked' value is dependent on whether or not the
 853:  *    checkbox is bound to a model.  This should probably be re-evaluated in future versions.
 854:  * @return string An HTML text input element
 855:  */
 856:     function checkbox($fieldName, $options = array()) {
 857:         $options = $this->_initInputField($fieldName, $options);
 858:         $value = current($this->value());
 859: 
 860:         if (!isset($options['value']) || empty($options['value'])) {
 861:             $options['value'] = 1;
 862:         } elseif (
 863:             (!isset($options['checked']) && !empty($value) && $value === $options['value']) ||
 864:             !empty($options['checked'])
 865:         ) {
 866:             $options['checked'] = 'checked';
 867:         }
 868:         $hiddenOptions = array(
 869:             'id' => $options['id'] . '_', 'name' => $options['name'],
 870:             'value' => '0', 'secure' => false
 871:         );
 872:         if (isset($options['disabled']) && $options['disabled'] == true) {
 873:             $hiddenOptions['disabled'] = 'disabled';
 874:         }
 875:         $output = $this->hidden($fieldName, $hiddenOptions);
 876: 
 877:         return $this->output($output . sprintf(
 878:             $this->Html->tags['checkbox'],
 879:             $options['name'],
 880:             $this->_parseAttributes($options, array('name'), null, ' ')
 881:         ));
 882:     }
 883: /**
 884:  * Creates a set of radio widgets.
 885:  *
 886:  * Attributes:
 887:  *
 888:  * - 'separator' - define the string in between the radio buttons
 889:  * - 'legend' - control whether or not the widget set has a fieldset & legend
 890:  * - 'value' - indicate a value that is should be checked
 891:  * - 'label' - boolean to indicate whether or not labels for widgets show be displayed
 892:  *
 893:  * @param string $fieldName Name of a field, like this "Modelname.fieldname"
 894:  * @param array $options Radio button options array.
 895:  * @param array $attributes Array of HTML attributes.
 896:  * @return string
 897:  */
 898:     function radio($fieldName, $options = array(), $attributes = array()) {
 899:         $attributes = $this->_initInputField($fieldName, $attributes);
 900:         $legend = false;
 901: 
 902:         if (isset($attributes['legend'])) {
 903:             $legend = $attributes['legend'];
 904:             unset($attributes['legend']);
 905:         } elseif (count($options) > 1) {
 906:             $legend = __(Inflector::humanize($this->field()), true);
 907:         }
 908:         $label = true;
 909: 
 910:         if (isset($attributes['label'])) {
 911:             $label = $attributes['label'];
 912:             unset($attributes['label']);
 913:         }
 914:         $inbetween = null;
 915: 
 916:         if (isset($attributes['separator'])) {
 917:             $inbetween = $attributes['separator'];
 918:             unset($attributes['separator']);
 919:         }
 920: 
 921:         if (isset($attributes['value'])) {
 922:             $value = $attributes['value'];
 923:         } else {
 924:             $value =  $this->value($fieldName);
 925:         }
 926:         $out = array();
 927: 
 928:         foreach ($options as $optValue => $optTitle) {
 929:             $optionsHere = array('value' => $optValue);
 930: 
 931:             if (isset($value) && $optValue == $value) {
 932:                 $optionsHere['checked'] = 'checked';
 933:             }
 934:             $parsedOptions = $this->_parseAttributes(
 935:                 array_merge($attributes, $optionsHere),
 936:                 array('name', 'type', 'id'), '', ' '
 937:             );
 938:             $tagName = Inflector::camelize(
 939:                 $attributes['id'] . '_' . Inflector::underscore($optValue)
 940:             );
 941: 
 942:             if ($label) {
 943:                 $optTitle =  sprintf($this->Html->tags['label'], $tagName, null, $optTitle);
 944:             }
 945:             $out[] =  sprintf(
 946:                 $this->Html->tags['radio'], $attributes['name'],
 947:                 $tagName, $parsedOptions, $optTitle
 948:             );
 949:         }
 950:         $hidden = null;
 951: 
 952:         if (!isset($value) || $value === '') {
 953:             $hidden = $this->hidden($fieldName, array(
 954:                 'id' => $attributes['id'] . '_', 'value' => '', 'name' => $attributes['name']
 955:             ));
 956:         }
 957:         $out = $hidden . implode($inbetween, $out);
 958: 
 959:         if ($legend) {
 960:             $out = sprintf(
 961:                 $this->Html->tags['fieldset'], '',
 962:                 sprintf($this->Html->tags['legend'], $legend) . $out
 963:             );
 964:         }
 965:         return $this->output($out);
 966:     }
 967: /**
 968:  * Creates a text input widget.
 969:  *
 970:  * @param string $fieldName Name of a field, in the form "Modelname.fieldname"
 971:  * @param array  $options Array of HTML attributes.
 972:  * @return string An HTML text input element
 973:  */
 974:     function text($fieldName, $options = array()) {
 975:         $options = $this->_initInputField($fieldName, array_merge(
 976:             array('type' => 'text'), $options
 977:         ));
 978:         return $this->output(sprintf(
 979:             $this->Html->tags['input'],
 980:             $options['name'],
 981:             $this->_parseAttributes($options, array('name'), null, ' ')
 982:         ));
 983:     }
 984: /**
 985:  * Creates a password input widget.
 986:  *
 987:  * @param  string  $fieldName Name of a field, like in the form "Modelname.fieldname"
 988:  * @param  array    $options Array of HTML attributes.
 989:  * @return string
 990:  */
 991:     function password($fieldName, $options = array()) {
 992:         $options = $this->_initInputField($fieldName, $options);
 993:         return $this->output(sprintf(
 994:             $this->Html->tags['password'],
 995:             $options['name'],
 996:             $this->_parseAttributes($options, array('name'), null, ' ')
 997:         ));
 998:     }
 999: /**
1000:  * Creates a textarea widget.
1001:  *
1002:  * @param string $fieldName Name of a field, in the form "Modelname.fieldname"
1003:  * @param array $options Array of HTML attributes.
1004:  * @return string An HTML text input element
1005:  */
1006:     function textarea($fieldName, $options = array()) {
1007:         $options = $this->_initInputField($fieldName, $options);
1008:         $value = null;
1009: 
1010:         if (array_key_exists('value', $options)) {
1011:             $value = $options['value'];
1012:             if (!array_key_exists('escape', $options) || $options['escape'] !== false) {
1013:                 $value = h($value);
1014:             }
1015:             unset($options['value']);
1016:         }
1017:         return $this->output(sprintf(
1018:             $this->Html->tags['textarea'],
1019:             $options['name'],
1020:             $this->_parseAttributes($options, array('type', 'name'), null, ' '),
1021:             $value
1022:         ));
1023:     }
1024: /**
1025:  * Creates a hidden input field.
1026:  *
1027:  * @param string $fieldName Name of a field, in the form"Modelname.fieldname"
1028:  * @param array $options Array of HTML attributes.
1029:  * @return string
1030:  * @access public
1031:  */
1032:     function hidden($fieldName, $options = array()) {
1033:         $secure = true;
1034: 
1035:         if (isset($options['secure'])) {
1036:             $secure = $options['secure'];
1037:             unset($options['secure']);
1038:         }
1039:         $options = $this->_initInputField($fieldName, array_merge(
1040:             $options, array('secure' => false)
1041:         ));
1042:         $model = $this->model();
1043: 
1044:         if ($fieldName !== '_method' && $model !== '_Token' && $secure) {
1045:             $this->__secure(null, '' . $options['value']);
1046:         }
1047: 
1048:         return $this->output(sprintf(
1049:             $this->Html->tags['hidden'],
1050:             $options['name'],
1051:             $this->_parseAttributes($options, array('name', 'class'), '', ' ')
1052:         ));
1053:     }
1054: /**
1055:  * Creates file input widget.
1056:  *
1057:  * @param string $fieldName Name of a field, in the form "Modelname.fieldname"
1058:  * @param array $options Array of HTML attributes.
1059:  * @return string
1060:  * @access public
1061:  */
1062:     function file($fieldName, $options = array()) {
1063:         $options = array_merge($options, array('secure' => false));
1064:         $options = $this->_initInputField($fieldName, $options);
1065:         $view =& ClassRegistry::getObject('view');
1066:         $field = $view->entity();
1067: 
1068:         foreach (array('name', 'type', 'tmp_name', 'error', 'size') as $suffix) {
1069:             $this->__secure(array_merge($field, array($suffix)));
1070:         }
1071: 
1072:         $attributes = $this->_parseAttributes($options, array('name'), '', ' ');
1073:         return $this->output(sprintf($this->Html->tags['file'], $options['name'], $attributes));
1074:     }
1075: /**
1076:  * Creates a button tag.
1077:  *
1078:  * @param string $title  The button's caption
1079:  * @param array $options Array of options.
1080:  * @return string A HTML button tag.
1081:  * @access public
1082:  */
1083:     function button($title, $options = array()) {
1084:         $options = array_merge(array('type' => 'button', 'value' => $title), $options);
1085: 
1086:         if (isset($options['name']) && strpos($options['name'], '.') !== false) {
1087:             if ($this->value($options['name'])) {
1088:                 $options['checked'] = 'checked';
1089:             }
1090:             $name = $options['name'];
1091:             unset($options['name']);
1092:             $options = $this->_initInputField($name, $options);
1093:         }
1094:         return $this->output(sprintf(
1095:             $this->Html->tags['button'],
1096:             $options['type'],
1097:             $this->_parseAttributes($options, array('type'), '', ' ')
1098:         ));
1099:     }
1100: /**
1101:  * Creates a submit button element.
1102:  *
1103:  * ### Options
1104:  *
1105:  * - `div` - Include a wrapping div?  Defaults to true.  Accepts sub options similar to 
1106:  *   FormHelper::input().
1107:  * - Other attributes will be assigned to the input element.
1108:  *
1109:  * @param string $caption The label appearing on the button OR if string contains :// or the
1110:  *  extension .jpg, .jpe, .jpeg, .gif, .png use an image if the extension
1111:  *  exists, AND the first character is /, image is relative to webroot,
1112:  *  OR if the first character is not /, image is relative to webroot/img.
1113:  * @param array $options Array of options.  See above.
1114:  * @return string A HTML submit button
1115:  */
1116:     function submit($caption = null, $options = array()) {
1117:         if (!$caption) {
1118:             $caption = __('Submit', true);
1119:         }
1120:         $out = null;
1121:         $div = true;
1122: 
1123:         if (isset($options['div'])) {
1124:             $div = $options['div'];
1125:             unset($options['div']);
1126:         }
1127:         $divOptions = array('tag' => 'div');
1128: 
1129:         if ($div === true) {
1130:             $divOptions['class'] = 'submit';
1131:         } elseif ($div === false) {
1132:             unset($divOptions);
1133:         } elseif (is_string($div)) {
1134:             $divOptions['class'] = $div;
1135:         } elseif (is_array($div)) {
1136:             $divOptions = array_merge(array('class' => 'submit', 'tag' => 'div'), $div);
1137:         }
1138: 
1139:         if (strpos($caption, '://') !== false) {
1140:             $out .= $this->output(sprintf(
1141:                 $this->Html->tags['submitimage'],
1142:                 $caption,
1143:                 $this->_parseAttributes($options, null, '', ' ')
1144:             ));
1145:         } elseif (preg_match('/\.(jpg|jpe|jpeg|gif|png|ico)$/', $caption)) {
1146:             if ($caption{0} !== '/') {
1147:                 $url = $this->webroot(IMAGES_URL . $caption);
1148:             } else {
1149:                 $caption = trim($caption, '/');
1150:                 $url = $this->webroot($caption);
1151:             }
1152:             $out .= $this->output(sprintf(
1153:                 $this->Html->tags['submitimage'],
1154:                 $url,
1155:                 $this->_parseAttributes($options, null, '', ' ')
1156:             ));
1157:         } else {
1158:             $options['value'] = $caption;
1159:             $out .= $this->output(sprintf(
1160:                 $this->Html->tags['submit'],
1161:                 $this->_parseAttributes($options, null, '', ' ')
1162:             ));
1163:         }
1164: 
1165:         if (isset($divOptions)) {
1166:             $tag = $divOptions['tag'];
1167:             unset($divOptions['tag']);
1168:             $out = $this->Html->tag($tag, $out, $divOptions);
1169:         }
1170:         return $out;
1171:     }
1172: /**
1173:  * Returns a formatted SELECT element.
1174:  *
1175:  * Attributes:
1176:  *
1177:  * - 'showParents' - If included in the array and set to true, an additional option element
1178:  *   will be added for the parent of each option group.
1179:  * - 'multiple' - show a multiple select box.  If set to 'checkbox' multiple checkboxes will be
1180:  *   created instead.
1181:  *
1182:  * @param string $fieldName Name attribute of the SELECT
1183:  * @param array $options Array of the OPTION elements (as 'value'=>'Text' pairs) to be used in the
1184:  *    SELECT element
1185:  * @param mixed $selected The option selected by default.  If null, the default value
1186:  *   from POST data will be used when available.
1187:  * @param array $attributes The HTML attributes of the select element.
1188:  * @param mixed $showEmpty If true, the empty select option is shown.  If a string,
1189:  *   that string is displayed as the empty element.
1190:  * @return string Formatted SELECT element
1191:  */
1192:     function select($fieldName, $options = array(), $selected = null, $attributes = array(), $showEmpty = '') {
1193:         $select = array();
1194:         $showParents = false;
1195:         $escapeOptions = true;
1196:         $style = null;
1197:         $tag = null;
1198: 
1199:         if (isset($attributes['escape'])) {
1200:             $escapeOptions = $attributes['escape'];
1201:             unset($attributes['escape']);
1202:         }
1203:         $attributes = $this->_initInputField($fieldName, array_merge(
1204:             (array)$attributes, array('secure' => false)
1205:         ));
1206: 
1207:         if (is_string($options) && isset($this->__options[$options])) {
1208:             $options = $this->__generateOptions($options);
1209:         } elseif (!is_array($options)) {
1210:             $options = array();
1211:         }
1212:         if (isset($attributes['type'])) {
1213:             unset($attributes['type']);
1214:         }
1215:         if (in_array('showParents', $attributes)) {
1216:             $showParents = true;
1217:             unset($attributes['showParents']);
1218:         }
1219: 
1220:         if (!isset($selected)) {
1221:             $selected = $attributes['value'];
1222:         }
1223: 
1224:         if (isset($attributes) && array_key_exists('multiple', $attributes)) {
1225:             $style = ($attributes['multiple'] === 'checkbox') ? 'checkbox' : null;
1226:             $template = ($style) ? 'checkboxmultiplestart' : 'selectmultiplestart';
1227:             $tag = $this->Html->tags[$template];
1228:             $select[] = $this->hidden(null, array('value' => '', 'id' => null, 'secure' => false));
1229:         } else {
1230:             $tag = $this->Html->tags['selectstart'];
1231:         }
1232: 
1233:         if (!empty($tag) || isset($template)) {
1234:             $this->__secure();
1235:             $select[] = sprintf($tag, $attributes['name'], $this->_parseAttributes(
1236:                 $attributes, array('name', 'value'))
1237:             );
1238:         }
1239:         $emptyMulti = (
1240:             $showEmpty !== null && $showEmpty !== false && !(
1241:                 empty($showEmpty) && (isset($attributes) &&
1242:                 array_key_exists('multiple', $attributes))
1243:             )
1244:         );
1245: 
1246:         if ($emptyMulti) {
1247:             $showEmpty = ($showEmpty === true) ? '' : $showEmpty;
1248:             $options = array_reverse($options, true);
1249:             $options[''] = $showEmpty;
1250:             $options = array_reverse($options, true);
1251:         }
1252: 
1253:         $select = array_merge($select, $this->__selectOptions(
1254:             array_reverse($options, true),
1255:             $selected,
1256:             array(),
1257:             $showParents,
1258:             array('escape' => $escapeOptions, 'style' => $style)
1259:         ));
1260: 
1261:         $template = ($style == 'checkbox') ? 'checkboxmultipleend' : 'selectend';
1262:         $select[] = $this->Html->tags[$template];
1263:         return $this->output(implode("\n", $select));
1264:     }
1265: /**
1266:  * Returns a SELECT element for days.
1267:  *
1268:  * @param string $fieldName Prefix name for the SELECT element
1269:  * @param string $selected Option which is selected.
1270:  * @param array  $attributes HTML attributes for the select element
1271:  * @param mixed $showEmpty Show/hide the empty select option
1272:  * @return string
1273:  */
1274:     function day($fieldName, $selected = null, $attributes = array(), $showEmpty = true) {
1275:         if ((empty($selected) || $selected === true) && $value = $this->value($fieldName)) {
1276:             if (is_array($value)) {
1277:                 extract($value);
1278:                 $selected = $day;
1279:             } else {
1280:                 if (empty($value)) {
1281:                     if (!$showEmpty) {
1282:                         $selected = 'now';
1283:                     }
1284:                 } else {
1285:                     $selected = $value;
1286:                 }
1287:             }
1288:         }
1289: 
1290:         if (strlen($selected) > 2) {
1291:             $selected = date('d', strtotime($selected));
1292:         } elseif ($selected === false) {
1293:             $selected = null;
1294:         }
1295:         return $this->select(
1296:             $fieldName . ".day", $this->__generateOptions('day'), $selected, $attributes, $showEmpty
1297:         );
1298:     }
1299: /**
1300:  * Returns a SELECT element for years
1301:  *
1302:  * @param string $fieldName Prefix name for the SELECT element
1303:  * @param integer $minYear First year in sequence
1304:  * @param integer $maxYear Last year in sequence
1305:  * @param string $selected Option which is selected.
1306:  * @param array $attributes Attribute array for the select elements.
1307:  * @param boolean $showEmpty Show/hide the empty select option
1308:  * @return string
1309:  */
1310:     function year($fieldName, $minYear = null, $maxYear = null, $selected = null, $attributes = array(), $showEmpty = true) {
1311:         if ((empty($selected) || $selected === true) && $value = $this->value($fieldName)) {
1312:             if (is_array($value)) {
1313:                 extract($value);
1314:                 $selected = $year;
1315:             } else {
1316:                 if (empty($value)) {
1317:                     if (!$showEmpty && !$maxYear) {
1318:                         $selected = 'now';
1319: 
1320:                     } elseif (!$showEmpty && $maxYear && !$selected) {
1321:                         $selected = $maxYear;
1322:                     }
1323:                 } else {
1324:                     $selected = $value;
1325:                 }
1326:             }
1327:         }
1328: 
1329:         if (strlen($selected) > 4 || $selected === 'now') {
1330:             $selected = date('Y', strtotime($selected));
1331:         } elseif ($selected === false) {
1332:             $selected = null;
1333:         }
1334:         $yearOptions = array('min' => $minYear, 'max' => $maxYear);
1335:         return $this->select(
1336:             $fieldName . ".year", $this->__generateOptions('year', $yearOptions),
1337:             $selected, $attributes, $showEmpty
1338:         );
1339:     }
1340: /**
1341:  * Returns a SELECT element for months.
1342:  *
1343:  * Attributes:
1344:  *
1345:  * - 'monthNames' is set and false 2 digit numbers will be used instead of text.
1346:  *
1347:  * @param string $fieldName Prefix name for the SELECT element
1348:  * @param string $selected Option which is selected.
1349:  * @param array $attributes Attributes for the select element
1350:  * @param boolean $showEmpty Show/hide the empty select option
1351:  * @return string
1352:  */
1353:     function month($fieldName, $selected = null, $attributes = array(), $showEmpty = true) {
1354:         if ((empty($selected) || $selected === true) && $value = $this->value($fieldName)) {
1355:             if (is_array($value)) {
1356:                 extract($value);
1357:                 $selected = $month;
1358:             } else {
1359:                 if (empty($value)) {
1360:                     if (!$showEmpty) {
1361:                         $selected = 'now';
1362:                     }
1363:                 } else {
1364:                     $selected = $value;
1365:                 }
1366:             }
1367:         }
1368: 
1369:         if (strlen($selected) > 2) {
1370:             $selected = date('m', strtotime($selected));
1371:         } elseif ($selected === false) {
1372:             $selected = null;
1373:         }
1374:         $defaults = array('monthNames' => true);
1375:         $attributes = array_merge($defaults, (array) $attributes);
1376:         $monthNames = $attributes['monthNames'];
1377:         unset($attributes['monthNames']);
1378: 
1379:         return $this->select(
1380:             $fieldName . ".month",
1381:             $this->__generateOptions('month', array('monthNames' => $monthNames)),
1382:             $selected, $attributes, $showEmpty
1383:         );
1384:     }
1385: /**
1386:  * Returns a SELECT element for hours.
1387:  *
1388:  * @param string $fieldName Prefix name for the SELECT element
1389:  * @param boolean $format24Hours True for 24 hours format
1390:  * @param string $selected Option which is selected.
1391:  * @param array $attributes List of HTML attributes
1392:  * @param mixed $showEmpty True to show an empty element, or a string to provide default empty element text
1393:  * @return string
1394:  */
1395:     function hour($fieldName, $format24Hours = false, $selected = null, $attributes = array(), $showEmpty = true) {
1396:         if ((empty($selected) || $selected === true) && $value = $this->value($fieldName)) {
1397:             if (is_array($value)) {
1398:                 extract($value);
1399:                 $selected = $hour;
1400:             } else {
1401:                 if (empty($value)) {
1402:                     if (!$showEmpty) {
1403:                         $selected = 'now';
1404:                     }
1405:                 } else {
1406:                     $selected = $value;
1407:                 }
1408:             }
1409:         } else {
1410:             $value = $selected;
1411:         }
1412: 
1413:         if (strlen($selected) > 2) {
1414:             if ($format24Hours) {
1415:                 $selected = date('H', strtotime($value));
1416:             } else {
1417:                 $selected = date('g', strtotime($value));
1418:             }
1419:         } elseif ($selected === false) {
1420:             $selected = null;
1421:         }
1422:         return $this->select(
1423:             $fieldName . ".hour",
1424:             $this->__generateOptions($format24Hours ? 'hour24' : 'hour'),
1425:             $selected, $attributes, $showEmpty
1426:         );
1427:     }
1428: /**
1429:  * Returns a SELECT element for minutes.
1430:  *
1431:  * @param string $fieldName Prefix name for the SELECT element
1432:  * @param string $selected Option which is selected.
1433:  * @param string $attributes Array of Attributes
1434:  * @param bool $showEmpty True to show an empty element, or a string to provide default empty element text
1435:  * @return string
1436:  */
1437:     function minute($fieldName, $selected = null, $attributes = array(), $showEmpty = true) {
1438:         if ((empty($selected) || $selected === true) && $value = $this->value($fieldName)) {
1439:             if (is_array($value)) {
1440:                 extract($value);
1441:                 $selected = $min;
1442:             } else {
1443:                 if (empty($value)) {
1444:                     if (!$showEmpty) {
1445:                         $selected = 'now';
1446:                     }
1447:                 } else {
1448:                     $selected = $value;
1449:                 }
1450:             }
1451:         }
1452: 
1453:         if (strlen($selected) > 2) {
1454:             $selected = date('i', strtotime($selected));
1455:         } elseif ($selected === false) {
1456:             $selected = null;
1457:         }
1458:         $minuteOptions = array();
1459: 
1460:         if (isset($attributes['interval'])) {
1461:             $minuteOptions['interval'] = $attributes['interval'];
1462:             unset($attributes['interval']);
1463:         }
1464:         return $this->select(
1465:             $fieldName . ".min", $this->__generateOptions('minute', $minuteOptions),
1466:             $selected, $attributes, $showEmpty
1467:         );
1468:     }
1469: /**
1470:  * Returns a SELECT element for AM or PM.
1471:  *
1472:  * @param string $fieldName Prefix name for the SELECT element
1473:  * @param string $selected Option which is selected.
1474:  * @param string $attributes Array of Attributes
1475:  * @param bool $showEmpty Show/Hide an empty option
1476:  * @return string
1477:  */
1478:     function meridian($fieldName, $selected = null, $attributes = array(), $showEmpty = true) {
1479:         if ((empty($selected) || $selected === true) && $value = $this->value($fieldName)) {
1480:             if (is_array($value)) {
1481:                 extract($value);
1482:                 $selected = $meridian;
1483:             } else {
1484:                 if (empty($value)) {
1485:                     if (!$showEmpty) {
1486:                         $selected = date('a');
1487:                     }
1488:                 } else {
1489:                     $selected = date('a', strtotime($value));
1490:                 }
1491:             }
1492:         }
1493: 
1494:         if ($selected === false) {
1495:             $selected = null;
1496:         }
1497:         return $this->select(
1498:             $fieldName . ".meridian", $this->__generateOptions('meridian'),
1499:             $selected, $attributes, $showEmpty
1500:         );
1501:     }
1502: /**
1503:  * Returns a set of SELECT elements for a full datetime setup: day, month and year, and then time.
1504:  *
1505:  * Attributes:
1506:  *
1507:  * - 'monthNames' If set and false numbers will be used for month select instead of text.
1508:  * - 'minYear' The lowest year to use in the year select
1509:  * - 'maxYear' The maximum year to use in the year select
1510:  * - 'interval' The interval for the minutes select. Defaults to 1
1511:  * - 'separator' The contents of the string between select elements. Defaults to '-'
1512:  *
1513:  * @param string $fieldName Prefix name for the SELECT element
1514:  * @param string $dateFormat DMY, MDY, YMD or NONE.
1515:  * @param string $timeFormat 12, 24, NONE
1516:  * @param string $selected Option which is selected.
1517:  * @param string $attributes array of Attributes
1518:  * @param bool $showEmpty Whether or not to show an empty default value.
1519:  * @return string The HTML formatted OPTION element
1520:  */
1521:     function dateTime($fieldName, $dateFormat = 'DMY', $timeFormat = '12', $selected = null, $attributes = array(), $showEmpty = true) {
1522:         $year = $month = $day = $hour = $min = $meridian = null;
1523: 
1524:         if (empty($selected)) {
1525:             $selected = $this->value($fieldName);
1526:         }
1527: 
1528:         if ($selected === null && $showEmpty != true) {
1529:             $selected = time();
1530:         }
1531: 
1532:         if (!empty($selected)) {
1533:             if (is_array($selected)) {
1534:                 extract($selected);
1535:             } else {
1536:                 if (is_numeric($selected)) {
1537:                     $selected = strftime('%Y-%m-%d %H:%M:%S', $selected);
1538:                 }
1539:                 $meridian = 'am';
1540:                 $pos = strpos($selected, '-');
1541:                 if ($pos !== false) {
1542:                     $date = explode('-', $selected);
1543:                     $days = explode(' ', $date[2]);
1544:                     $day = $days[0];
1545:                     $month = $date[1];
1546:                     $year = $date[0];
1547:                 } else {
1548:                     $days[1] = $selected;
1549:                 }
1550: 
1551:                 if ($timeFormat != 'NONE' && !empty($timeFormat)) {
1552:                     $time = explode(':', $days[1]);
1553:                     $check = str_replace(':', '', $days[1]);
1554: 
1555:                     if (($check > 115959) && $timeFormat == '12') {
1556:                         $time[0] = $time[0] - 12;
1557:                         $meridian = 'pm';
1558:                     } elseif ($time[0] == '12' && $timeFormat == '12') {
1559:                         $meridian = 'pm';
1560:                     } elseif ($time[0] == '00' && $timeFormat == '12') {
1561:                         $time[0] = 12;
1562:                     } elseif ($time[0] > 12) {
1563:                         $meridian = 'pm';
1564:                     }
1565:                     if ($time[0] == 0 && $timeFormat == '12') {
1566:                         $time[0] = 12;
1567:                     }
1568:                     $hour = $time[0];
1569:                     $min = $time[1];
1570:                 }
1571:             }
1572:         }
1573: 
1574:         $elements = array('Day','Month','Year','Hour','Minute','Meridian');
1575:         $defaults = array(
1576:             'minYear' => null, 'maxYear' => null, 'separator' => '-',
1577:             'interval' => 1, 'monthNames' => true
1578:         );
1579:         $attributes = array_merge($defaults, (array) $attributes);
1580:         if (isset($attributes['minuteInterval'])) {
1581:             $attributes['interval'] = $attributes['minuteInterval'];
1582:             unset($attributes['minuteInterval']);
1583:         }
1584:         $minYear = $attributes['minYear'];
1585:         $maxYear = $attributes['maxYear'];
1586:         $separator = $attributes['separator'];
1587:         $interval = $attributes['interval'];
1588:         $monthNames = $attributes['monthNames'];
1589:         $attributes = array_diff_key($attributes, $defaults);
1590: 
1591:         if (isset($attributes['id'])) {
1592:             if (is_string($attributes['id'])) {
1593:                 // build out an array version
1594:                 foreach ($elements as $element) {
1595:                     $selectAttrName = 'select' . $element . 'Attr';
1596:                     ${$selectAttrName} = $attributes;
1597:                     ${$selectAttrName}['id'] = $attributes['id'] . $element;
1598:                 }
1599:             } elseif (is_array($attributes['id'])) {
1600:                 // check for missing ones and build selectAttr for each element
1601:                 foreach ($elements as $element) {
1602:                     $selectAttrName = 'select' . $element . 'Attr';
1603:                     ${$selectAttrName} = $attributes;
1604:                     ${$selectAttrName}['id'] = $attributes['id'][strtolower($element)];
1605:                 }
1606:             }
1607:         } else {
1608:             // build the selectAttrName with empty id's to pass
1609:             foreach ($elements as $element) {
1610:                 $selectAttrName = 'select' . $element . 'Attr';
1611:                 ${$selectAttrName} = $attributes;
1612:             }
1613:         }
1614: 
1615:         $opt = '';
1616: 
1617:         if ($dateFormat != 'NONE') {
1618:             $selects = array();
1619:             foreach (preg_split('//', $dateFormat, -1, PREG_SPLIT_NO_EMPTY) as $char) {
1620:                 switch ($char) {
1621:                     case 'Y':
1622:                         $selects[] = $this->year(
1623:                             $fieldName, $minYear, $maxYear, $year, $selectYearAttr, $showEmpty
1624:                         );
1625:                     break;
1626:                     case 'M':
1627:                         $selectMonthAttr['monthNames'] = $monthNames;
1628:                         $selects[] = $this->month($fieldName, $month, $selectMonthAttr, $showEmpty);
1629:                     break;
1630:                     case 'D':
1631:                         $selects[] = $this->day($fieldName, $day, $selectDayAttr, $showEmpty);
1632:                     break;
1633:                 }
1634:             }
1635:             $opt = implode($separator, $selects);
1636:         }
1637:         if (!empty($interval) && $interval > 1 && !empty($min)) {
1638:             $min = round($min * (1 / $interval)) * $interval;
1639:         }
1640:         $selectMinuteAttr['interval'] = $interval;
1641:         switch ($timeFormat) {
1642:             case '24':
1643:                 $opt .= $this->hour($fieldName, true, $hour, $selectHourAttr, $showEmpty) . ':' .
1644:                 $this->minute($fieldName, $min, $selectMinuteAttr, $showEmpty);
1645:             break;
1646:             case '12':
1647:                 $opt .= $this->hour($fieldName, false, $hour, $selectHourAttr, $showEmpty) . ':' .
1648:                 $this->minute($fieldName, $min, $selectMinuteAttr, $showEmpty) . ' ' .
1649:                 $this->meridian($fieldName, $meridian, $selectMeridianAttr, $showEmpty);
1650:             break;
1651:             case 'NONE':
1652:             default:
1653:                 $opt .= '';
1654:             break;
1655:         }
1656:         return $opt;
1657:     }
1658: /**
1659:  * Gets the input field name for the current tag
1660:  *
1661:  * @param array $options
1662:  * @param string $key
1663:  * @return array
1664:  */
1665:     function __name($options = array(), $field = null, $key = 'name') {
1666:         if ($this->requestType == 'get') {
1667:             if ($options === null) {
1668:                 $options = array();
1669:             } elseif (is_string($options)) {
1670:                 $field = $options;
1671:                 $options = 0;
1672:             }
1673: 
1674:             if (!empty($field)) {
1675:                 $this->setEntity($field);
1676:             }
1677: 
1678:             if (is_array($options) && isset($options[$key])) {
1679:                 return $options;
1680:             }
1681: 
1682:             $view = ClassRegistry::getObject('view');
1683:             $name = $view->field;
1684:             if (!empty($view->fieldSuffix)) {
1685:                 $name .= '[' . $view->fieldSuffix . ']';
1686:             }
1687: 
1688:             if (is_array($options)) {
1689:                 $options[$key] = $name;
1690:                 return $options;
1691:             } else {
1692:                 return $name;
1693:             }
1694:         }
1695:         return parent::__name($options, $field, $key);
1696:     }
1697: /**
1698:  * Returns an array of formatted OPTION/OPTGROUP elements
1699:  * @access private
1700:  * @return array
1701:  */
1702:     function __selectOptions($elements = array(), $selected = null, $parents = array(), $showParents = null, $attributes = array()) {
1703:         $select = array();
1704:         $attributes = array_merge(array('escape' => true, 'style' => null), $attributes);
1705:         $selectedIsEmpty = ($selected === '' || $selected === null);
1706:         $selectedIsArray = is_array($selected);
1707: 
1708:         foreach ($elements as $name => $title) {
1709:             $htmlOptions = array();
1710:             if (is_array($title) && (!isset($title['name']) || !isset($title['value']))) {
1711:                 if (!empty($name)) {
1712:                     if ($attributes['style'] === 'checkbox') {
1713:                         $select[] = $this->Html->tags['fieldsetend'];
1714:                     } else {
1715:                         $select[] = $this->Html->tags['optiongroupend'];
1716:                     }
1717:                     $parents[] = $name;
1718:                 }
1719:                 $select = array_merge($select, $this->__selectOptions(
1720:                     $title, $selected, $parents, $showParents, $attributes
1721:                 ));
1722: 
1723:                 if (!empty($name)) {
1724:                     if ($attributes['style'] === 'checkbox') {
1725:                         $select[] = sprintf($this->Html->tags['fieldsetstart'], $name);
1726:                     } else {
1727:                         $select[] = sprintf($this->Html->tags['optiongroup'], $name, '');
1728:                     }
1729:                 }
1730:                 $name = null;
1731:             } elseif (is_array($title)) {
1732:                 $htmlOptions = $title;
1733:                 $name = $title['value'];
1734:                 $title = $title['name'];
1735:                 unset($htmlOptions['name'], $htmlOptions['value']);
1736:             }
1737: 
1738:             if ($name !== null) {
1739:                 if (
1740:                     (!$selectedIsArray && !$selectedIsEmpty && (string)$selected == (string)$name) || 
1741:                     ($selectedIsArray && in_array($name, $selected))
1742:                 ) {
1743:                     if ($attributes['style'] === 'checkbox') {
1744:                         $htmlOptions['checked'] = true;
1745:                     } else {
1746:                         $htmlOptions['selected'] = 'selected';
1747:                     }
1748:                 }
1749: 
1750:                 if ($showParents || (!in_array($title, $parents))) {
1751:                     $title = ($attributes['escape']) ? h($title) : $title;
1752: 
1753:                     if ($attributes['style'] === 'checkbox') {
1754:                         $htmlOptions['value'] = $name;
1755: 
1756:                         $tagName = Inflector::camelize(
1757:                             $this->model() . '_' . $this->field().'_'.Inflector::underscore($name)
1758:                         );
1759:                         $htmlOptions['id'] = $tagName;
1760:                         $label = array('for' => $tagName);
1761: 
1762:                         if (isset($htmlOptions['checked']) && $htmlOptions['checked'] === true) {
1763:                             $label['class'] = 'selected';
1764:                         }
1765: 
1766:                         list($name) = array_values($this->__name());
1767: 
1768:                         if (empty($attributes['class'])) {
1769:                             $attributes['class'] = 'checkbox';
1770:                         }
1771:                         $label = $this->label(null, $title, $label);
1772:                         $item = sprintf(
1773:                             $this->Html->tags['checkboxmultiple'], $name,
1774:                             $this->_parseAttributes($htmlOptions)
1775:                         );
1776:                         $select[] = $this->Html->div($attributes['class'], $item . $label);
1777:                     } else {
1778:                         $select[] = sprintf(
1779:                             $this->Html->tags['selectoption'],
1780:                             $name, $this->_parseAttributes($htmlOptions), $title
1781:                         );
1782:                     }
1783:                 }
1784:             }
1785:         }
1786: 
1787:         return array_reverse($select, true);
1788:     }
1789: /**
1790:  * Generates option lists for common <select /> menus
1791:  * @access private
1792:  */
1793:     function __generateOptions($name, $options = array()) {
1794:         if (!empty($this->options[$name])) {
1795:             return $this->options[$name];
1796:         }
1797:         $data = array();
1798: 
1799:         switch ($name) {
1800:             case 'minute':
1801:                 if (isset($options['interval'])) {
1802:                     $interval = $options['interval'];
1803:                 } else {
1804:                     $interval = 1;
1805:                 }
1806:                 $i = 0;
1807:                 while ($i < 60) {
1808:                     $data[$i] = sprintf('%02d', $i);
1809:                     $i += $interval;
1810:                 }
1811:             break;
1812:             case 'hour':
1813:                 for ($i = 1; $i <= 12; $i++) {
1814:                     $data[sprintf('%02d', $i)] = $i;
1815:                 }
1816:             break;
1817:             case 'hour24':
1818:                 for ($i = 0; $i <= 23; $i++) {
1819:                     $data[sprintf('%02d', $i)] = $i;
1820:                 }
1821:             break;
1822:             case 'meridian':
1823:                 $data = array('am' => 'am', 'pm' => 'pm');
1824:             break;
1825:             case 'day':
1826:                 $min = 1;
1827:                 $max = 31;
1828: 
1829:                 if (isset($options['min'])) {
1830:                     $min = $options['min'];
1831:                 }
1832:                 if (isset($options['max'])) {
1833:                     $max = $options['max'];
1834:                 }
1835: 
1836:                 for ($i = $min; $i <= $max; $i++) {
1837:                     $data[sprintf('%02d', $i)] = $i;
1838:                 }
1839:             break;
1840:             case 'month':
1841:                 if ($options['monthNames']) {
1842:                     $data['01'] = __('January', true);
1843:                     $data['02'] = __('February', true);
1844:                     $data['03'] = __('March', true);
1845:                     $data['04'] = __('April', true);
1846:                     $data['05'] = __('May', true);
1847:                     $data['06'] = __('June', true);
1848:                     $data['07'] = __('July', true);
1849:                     $data['08'] = __('August', true);
1850:                     $data['09'] = __('September', true);
1851:                     $data['10'] = __('October', true);
1852:                     $data['11'] = __('November', true);
1853:                     $data['12'] = __('December', true);
1854:                 } else {
1855:                     for ($m = 1; $m <= 12; $m++) {
1856:                         $data[sprintf("%02s", $m)] = strftime("%m", mktime(1, 1, 1, $m, 1, 1999));
1857:                     }
1858:                 }
1859:             break;
1860:             case 'year':
1861:                 $current = intval(date('Y'));
1862: 
1863:                 if (!isset($options['min'])) {
1864:                     $min = $current - 20;
1865:                 } else {
1866:                     $min = $options['min'];
1867:                 }
1868: 
1869:                 if (!isset($options['max'])) {
1870:                     $max = $current + 20;
1871:                 } else {
1872:                     $max = $options['max'];
1873:                 }
1874:                 if ($min > $max) {
1875:                     list($min, $max) = array($max, $min);
1876:                 }
1877:                 for ($i = $min; $i <= $max; $i++) {
1878:                     $data[$i] = $i;
1879:                 }
1880:                 $data = array_reverse($data, true);
1881:             break;
1882:         }
1883:         $this->__options[$name] = $data;
1884:         return $this->__options[$name];
1885:     }
1886: /**
1887:  * Sets field defaults and adds field to form security input hash
1888:  * 
1889:  * Options
1890:  *  - secure - boolean whether or not the the field should be added to the security fields.
1891:  * 
1892:  * @param string $field
1893:  * @param array $options
1894:  * @return array
1895:  * @access protected
1896:  */
1897:     function _initInputField($field, $options = array()) {
1898:         if (isset($options['secure'])) {
1899:             $secure = $options['secure'];
1900:             unset($options['secure']);
1901:         } else {
1902:             $secure = (isset($this->params['_Token']) && !empty($this->params['_Token']));
1903:         }
1904:         $result = parent::_initInputField($field, $options);
1905: 
1906:         if ($secure) {
1907:             $this->__secure();
1908:         }
1909:         return $result;
1910:     }
1911: }
1912: 
1913: ?>
1914: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs