PluginProbe
Packeta / 2.0.9
Packeta v2.0.9
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
packeta / deps / nette / forms / src / Forms / Helpers.php

Helpers.php in Packeta 2.0.9, at deps/nette/forms/src/Forms/Helpers.php

196 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 declare (strict_types=1);
8 namespace Packetery\Nette\Forms;
9
10 use Packetery\Nette;
11 use Packetery\Nette\Utils\Html;
12 use Packetery\Nette\Utils\Strings;
13 /**
14 * Forms helpers.
15 */
16 class Helpers
17 {
18 use \Packetery\Nette\StaticClass;
19 private const UNSAFE_NAMES = ['attributes', 'children', 'elements', 'focus', 'length', 'reset', 'style', 'submit', 'onsubmit', 'form', 'presenter', 'action'];
20 /**
21 * Extracts and sanitizes submitted form data for single control.
22 * @param int $type type Form::DATA_TEXT, DATA_LINE, DATA_FILE, DATA_KEYS
23 * @return string|string[]
24 * @internal
25 */
26 public static function extractHttpData(array $data, string $htmlName, int $type)
27 {
28 $name = \explode('[', \str_replace(['[]', ']', '.'], ['', '', '_'], $htmlName));
29 $data = \Packetery\Nette\Utils\Arrays::get($data, $name, null);
30 $itype = $type & ~Form::DATA_KEYS;
31 if (\substr($htmlName, -2) === '[]') {
32 if (!\is_array($data)) {
33 return [];
34 }
35 foreach ($data as $k => $v) {
36 $data[$k] = $v = static::sanitize($itype, $v);
37 if ($v === null) {
38 unset($data[$k]);
39 }
40 }
41 if ($type & Form::DATA_KEYS) {
42 return $data;
43 }
44 return \array_values($data);
45 } else {
46 return static::sanitize($itype, $data);
47 }
48 }
49 private static function sanitize(int $type, $value)
50 {
51 if ($type === Form::DATA_TEXT) {
52 return \is_scalar($value) ? Strings::normalizeNewLines($value) : null;
53 } elseif ($type === Form::DATA_LINE) {
54 return \is_scalar($value) ? Strings::trim(\strtr((string) $value, "\r\n", ' ')) : null;
55 } elseif ($type === Form::DATA_FILE) {
56 return $value instanceof \Packetery\Nette\Http\FileUpload ? $value : null;
57 } else {
58 throw new \Packetery\Nette\InvalidArgumentException('Unknown data type');
59 }
60 }
61 /**
62 * Converts control name to HTML name.
63 */
64 public static function generateHtmlName(string $id) : string
65 {
66 $name = \str_replace(\Packetery\Nette\ComponentModel\IComponent::NAME_SEPARATOR, '][', $id, $count);
67 if ($count) {
68 $name = \substr_replace($name, '', \strpos($name, ']'), 1) . ']';
69 }
70 if (\is_numeric($name) || \in_array($name, self::UNSAFE_NAMES, \true)) {
71 $name = '_' . $name;
72 }
73 return $name;
74 }
75 public static function exportRules(Rules $rules) : array
76 {
77 $payload = [];
78 foreach ($rules as $rule) {
79 if (!$rule->canExport()) {
80 if ($rule->branch) {
81 continue;
82 }
83 break;
84 }
85 $op = $rule->validator;
86 if (!\is_string($op)) {
87 $op = \Packetery\Nette\Utils\Callback::toString($op);
88 }
89 if ($rule->branch) {
90 $item = ['op' => ($rule->isNegative ? '~' : '') . $op, 'rules' => static::exportRules($rule->branch), 'control' => $rule->control->getHtmlName()];
91 if ($rule->branch->getToggles()) {
92 $item['toggle'] = $rule->branch->getToggles();
93 } elseif (!$item['rules']) {
94 continue;
95 }
96 } else {
97 $msg = Validator::formatMessage($rule, \false);
98 if ($msg instanceof \Packetery\Nette\HtmlStringable) {
99 $msg = \html_entity_decode(\strip_tags((string) $msg), \ENT_QUOTES | \ENT_HTML5, 'UTF-8');
100 }
101 $item = ['op' => ($rule->isNegative ? '~' : '') . $op, 'msg' => $msg];
102 }
103 if (\is_array($rule->arg)) {
104 $item['arg'] = [];
105 foreach ($rule->arg as $key => $value) {
106 $item['arg'][$key] = $value instanceof Control ? ['control' => $value->getHtmlName()] : $value;
107 }
108 } elseif ($rule->arg !== null) {
109 $item['arg'] = $rule->arg instanceof Control ? ['control' => $rule->arg->getHtmlName()] : $rule->arg;
110 }
111 $payload[] = $item;
112 }
113 return $payload;
114 }
115 public static function createInputList(array $items, array $inputAttrs = null, array $labelAttrs = null, $wrapper = null) : string
116 {
117 [$inputAttrs, $inputTag] = self::prepareAttrs($inputAttrs, 'input');
118 [$labelAttrs, $labelTag] = self::prepareAttrs($labelAttrs, 'label');
119 $res = '';
120 $input = Html::el();
121 $label = Html::el();
122 [$wrapper, $wrapperEnd] = $wrapper instanceof Html ? [$wrapper->startTag(), $wrapper->endTag()] : [(string) $wrapper, ''];
123 foreach ($items as $value => $caption) {
124 foreach ($inputAttrs as $k => $v) {
125 $input->attrs[$k] = $v[$value] ?? null;
126 }
127 foreach ($labelAttrs as $k => $v) {
128 $label->attrs[$k] = $v[$value] ?? null;
129 }
130 $input->value = $value;
131 $res .= ($res === '' && $wrapperEnd === '' ? '' : $wrapper) . $labelTag . $label->attributes() . '>' . $inputTag . $input->attributes() . (Html::$xhtml ? ' />' : '>') . ($caption instanceof \Packetery\Nette\HtmlStringable ? $caption : \htmlspecialchars((string) $caption, \ENT_NOQUOTES, 'UTF-8')) . '</label>' . $wrapperEnd;
132 }
133 return $res;
134 }
135 public static function createSelectBox(array $items, array $optionAttrs = null, $selected = null) : Html
136 {
137 if ($selected !== null) {
138 $optionAttrs['selected?'] = $selected;
139 }
140 [$optionAttrs, $optionTag] = self::prepareAttrs($optionAttrs, 'option');
141 $option = Html::el();
142 $res = $tmp = '';
143 foreach ($items as $group => $subitems) {
144 if (\is_array($subitems)) {
145 $res .= Html::el('optgroup')->label($group)->startTag();
146 $tmp = '</optgroup>';
147 } else {
148 $subitems = [$group => $subitems];
149 }
150 foreach ($subitems as $value => $caption) {
151 $option->value = $value;
152 foreach ($optionAttrs as $k => $v) {
153 $option->attrs[$k] = $v[$value] ?? null;
154 }
155 if ($caption instanceof Html) {
156 $caption = clone $caption;
157 $res .= $caption->setName('option')->addAttributes($option->attrs);
158 } else {
159 $res .= $optionTag . $option->attributes() . '>' . \htmlspecialchars((string) $caption, \ENT_NOQUOTES, 'UTF-8') . '</option>';
160 }
161 if ($selected === $value) {
162 unset($optionAttrs['selected'], $option->attrs['selected']);
163 }
164 }
165 $res .= $tmp;
166 $tmp = '';
167 }
168 return Html::el('select')->setHtml($res);
169 }
170 private static function prepareAttrs(?array $attrs, string $name) : array
171 {
172 $dynamic = [];
173 foreach ((array) $attrs as $k => $v) {
174 if ($k[-1] === '?' || $k[-1] === ':') {
175 $p = \substr($k, 0, -1);
176 unset($attrs[$k], $attrs[$p]);
177 if ($k[-1] === '?') {
178 $dynamic[$p] = \array_fill_keys((array) $v, \true);
179 } elseif (\is_array($v) && $v) {
180 $dynamic[$p] = $v;
181 } else {
182 $attrs[$p] = $v;
183 }
184 }
185 }
186 return [$dynamic, '<' . $name . Html::el(null, $attrs)->attributes()];
187 }
188 /** @internal */
189 public static function iniGetSize(string $name) : int
190 {
191 $value = \ini_get($name);
192 $units = ['k' => 10, 'm' => 20, 'g' => 30];
193 return isset($units[$ch = \strtolower(\substr($value, -1))]) ? (int) $value << $units[$ch] : (int) $value;
194 }
195 }
196