Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Utils
  • none
  • Tracy
    • Bridges
      • Nette

Classes

  • Container
  • ControlGroup
  • Form
  • Helpers
  • Rule
  • Rules
  • Validator

Interfaces

  • IControl
  • IFormRenderer
  • ISubmitterControl
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Other releases
  • Nette homepage
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\Forms;
  9: 
 10: use Nette;
 11: use Nette\Utils\Strings;
 12: use Nette\Utils\Html;
 13: 
 14: 
 15: /**
 16:  * Forms helpers.
 17:  */
 18: class Helpers extends Nette\Object
 19: {
 20:     private static $unsafeNames = array(
 21:         'attributes', 'children', 'elements', 'focus', 'length', 'reset', 'style', 'submit', 'onsubmit', 'form',
 22:         'presenter', 'action',
 23:     );
 24: 
 25: 
 26:     /**
 27:      * Extracts and sanitizes submitted form data for single control.
 28:      * @param  array   submitted data
 29:      * @param  string  control HTML name
 30:      * @param  string  type Form::DATA_TEXT, DATA_LINE, DATA_FILE, DATA_KEYS
 31:      * @return string|string[]
 32:      * @internal
 33:      */
 34:     public static function extractHttpData(array $data, $htmlName, $type)
 35:     {
 36:         $name = explode('[', str_replace(array('[]', ']', '.'), array('', '', '_'), $htmlName));
 37:         $data = Nette\Utils\Arrays::get($data, $name, NULL);
 38:         $itype = $type & ~Form::DATA_KEYS;
 39: 
 40:         if (substr($htmlName, -2) === '[]') {
 41:             if (!is_array($data)) {
 42:                 return array();
 43:             }
 44:             foreach ($data as $k => $v) {
 45:                 $data[$k] = $v = static::sanitize($itype, $v);
 46:                 if ($v === NULL) {
 47:                     unset($data[$k]);
 48:                 }
 49:             }
 50:             if ($type & Form::DATA_KEYS) {
 51:                 return $data;
 52:             }
 53:             return array_values($data);
 54:         } else {
 55:             return static::sanitize($itype, $data);
 56:         }
 57:     }
 58: 
 59: 
 60:     private static function sanitize($type, $value)
 61:     {
 62:         if ($type === Form::DATA_TEXT) {
 63:             return is_scalar($value) ? Strings::normalizeNewLines($value) : NULL;
 64: 
 65:         } elseif ($type === Form::DATA_LINE) {
 66:             return is_scalar($value) ? Strings::trim(strtr($value, "\r\n", '  ')) : NULL;
 67: 
 68:         } elseif ($type === Form::DATA_FILE) {
 69:             return $value instanceof Nette\Http\FileUpload ? $value : NULL;
 70: 
 71:         } else {
 72:             throw new Nette\InvalidArgumentException('Unknown data type');
 73:         }
 74:     }
 75: 
 76: 
 77:     /**
 78:      * Converts control name to HTML name.
 79:      * @return string
 80:      */
 81:     public static function generateHtmlName($id)
 82:     {
 83:         $name = str_replace(Nette\ComponentModel\IComponent::NAME_SEPARATOR, '][', $id, $count);
 84:         if ($count) {
 85:             $name = substr_replace($name, '', strpos($name, ']'), 1) . ']';
 86:         }
 87:         if (is_numeric($name) || in_array($name, self::$unsafeNames, TRUE)) {
 88:             $name = '_' . $name;
 89:         }
 90:         return $name;
 91:     }
 92: 
 93: 
 94:     /**
 95:      * @return array
 96:      */
 97:     public static function exportRules(Rules $rules)
 98:     {
 99:         $payload = array();
100:         foreach ($rules as $rule) {
101:             if (!is_string($op = $rule->validator)) {
102:                 if (!Nette\Utils\Callback::isStatic($op)) {
103:                     continue;
104:                 }
105:                 $op = Nette\Utils\Callback::toString($op);
106:             }
107:             if ($rule->branch) {
108:                 $item = array(
109:                     'op' => ($rule->isNegative ? '~' : '') . $op,
110:                     'rules' => static::exportRules($rule->branch),
111:                     'control' => $rule->control->getHtmlName(),
112:                 );
113:                 if ($rule->branch->getToggles()) {
114:                     $item['toggle'] = $rule->branch->getToggles();
115:                 } elseif (!$item['rules']) {
116:                     continue;
117:                 }
118:             } else {
119:                 $item = array('op' => ($rule->isNegative ? '~' : '') . $op, 'msg' => Validator::formatMessage($rule, FALSE));
120:             }
121: 
122:             if (is_array($rule->arg)) {
123:                 $item['arg'] = array();
124:                 foreach ($rule->arg as $key => $value) {
125:                     $item['arg'][$key] = $value instanceof IControl ? array('control' => $value->getHtmlName()) : $value;
126:                 }
127:             } elseif ($rule->arg !== NULL) {
128:                 $item['arg'] = $rule->arg instanceof IControl ? array('control' => $rule->arg->getHtmlName()) : $rule->arg;
129:             }
130: 
131:             $payload[] = $item;
132:         }
133:         return $payload;
134:     }
135: 
136: 
137:     /**
138:      * @return string
139:      */
140:     public static function createInputList(array $items, array $inputAttrs = NULL, array $labelAttrs = NULL, $wrapper = NULL)
141:     {
142:         list($inputAttrs, $inputTag) = self::prepareAttrs($inputAttrs, 'input');
143:         list($labelAttrs, $labelTag) = self::prepareAttrs($labelAttrs, 'label');
144:         $res = '';
145:         $input = Html::el();
146:         $label = Html::el();
147:         list($wrapper, $wrapperEnd) = $wrapper instanceof Html ? array($wrapper->startTag(), $wrapper->endTag()) : array((string) $wrapper, '');
148: 
149:         foreach ($items as $value => $caption) {
150:             foreach ($inputAttrs as $k => $v) {
151:                 $input->attrs[$k] = isset($v[$value]) ? $v[$value] : NULL;
152:             }
153:             foreach ($labelAttrs as $k => $v) {
154:                 $label->attrs[$k] = isset($v[$value]) ? $v[$value] : NULL;
155:             }
156:             $input->value = $value;
157:             $res .= ($res === '' && $wrapperEnd === '' ? '' : $wrapper)
158:                 . $labelTag . $label->attributes() . '>'
159:                 . $inputTag . $input->attributes() . (Html::$xhtml ? ' />' : '>')
160:                 . ($caption instanceof Html ? $caption : htmlspecialchars($caption, ENT_NOQUOTES, 'UTF-8'))
161:                 . '</label>'
162:                 . $wrapperEnd;
163:         }
164:         return $res;
165:     }
166: 
167: 
168:     /**
169:      * @return Html
170:      */
171:     public static function createSelectBox(array $items, array $optionAttrs = NULL, $selected = NULL)
172:     {
173:         if ($selected !== NULL) {
174:             $optionAttrs['selected?'] = $selected;
175:         }
176:         list($optionAttrs, $optionTag) = self::prepareAttrs($optionAttrs, 'option');
177:         $option = Html::el();
178:         $res = $tmp = '';
179:         foreach ($items as $group => $subitems) {
180:             if (is_array($subitems)) {
181:                 $res .= Html::el('optgroup')->label($group)->startTag();
182:                 $tmp = '</optgroup>';
183:             } else {
184:                 $subitems = array($group => $subitems);
185:             }
186:             foreach ($subitems as $value => $caption) {
187:                 $option->value = $value;
188:                 foreach ($optionAttrs as $k => $v) {
189:                     $option->attrs[$k] = isset($v[$value]) ? $v[$value] : NULL;
190:                 }
191:                 if ($caption instanceof Html) {
192:                     $caption = clone $caption;
193:                     $res .= $caption->setName('option')->addAttributes($option->attrs);
194:                 } else {
195:                     $res .= $optionTag . $option->attributes() . '>'
196:                         . htmlspecialchars($caption, ENT_NOQUOTES, 'UTF-8')
197:                         . '</option>';
198:                 }
199:             }
200:             $res .= $tmp;
201:             $tmp = '';
202:         }
203:         return Html::el('select')->setHtml($res);
204:     }
205: 
206: 
207:     private static function prepareAttrs($attrs, $name)
208:     {
209:         $dynamic = array();
210:         foreach ((array) $attrs as $k => $v) {
211:             $p = str_split($k, strlen($k) - 1);
212:             if ($p[1] === '?' || $p[1] === ':') {
213:                 unset($attrs[$k], $attrs[$p[0]]);
214:                 if ($p[1] === '?') {
215:                     $dynamic[$p[0]] = array_fill_keys((array) $v, TRUE);
216:                 } elseif (is_array($v) && $v) {
217:                     $dynamic[$p[0]] = $v;
218:                 } else {
219:                     $attrs[$p[0]] = $v;
220:                 }
221:             }
222:         }
223:         return array($dynamic, '<' . $name . Html::el(NULL, $attrs)->attributes());
224:     }
225: 
226: }
227: 
Nette 2.3-20161221 API API documentation generated by ApiGen 2.8.0