1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: namespace Cake\View\Widget;
16:
17: use Cake\View\Form\ContextInterface;
18: use Cake\View\Helper\IdGeneratorTrait;
19: use Traversable;
20:
21: 22: 23: 24: 25: 26:
27: class RadioWidget implements WidgetInterface
28: {
29: use IdGeneratorTrait;
30:
31: 32: 33: 34: 35:
36: protected $_templates;
37:
38: 39: 40: 41: 42:
43: protected $_label;
44:
45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58:
59: public function __construct($templates, $label)
60: {
61: $this->_templates = $templates;
62: $this->_label = $label;
63: }
64:
65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84:
85: public function render(array $data, ContextInterface $context)
86: {
87: $data += [
88: 'name' => '',
89: 'options' => [],
90: 'disabled' => null,
91: 'val' => null,
92: 'escape' => true,
93: 'label' => true,
94: 'empty' => false,
95: 'idPrefix' => null,
96: 'templateVars' => [],
97: ];
98: if ($data['options'] instanceof Traversable) {
99: $options = iterator_to_array($data['options']);
100: } else {
101: $options = (array)$data['options'];
102: }
103:
104: if (!empty($data['empty'])) {
105: $empty = $data['empty'] === true ? 'empty' : $data['empty'];
106: $options = ['' => $empty] + $options;
107: }
108: unset($data['empty']);
109:
110: $this->_idPrefix = $data['idPrefix'];
111: $this->_clearIds();
112: $opts = [];
113: foreach ($options as $val => $text) {
114: $opts[] = $this->_renderInput($val, $text, $data, $context);
115: }
116:
117: return implode('', $opts);
118: }
119:
120: 121: 122: 123: 124: 125: 126:
127: protected function _isDisabled($radio, $disabled)
128: {
129: if (!$disabled) {
130: return false;
131: }
132: if ($disabled === true) {
133: return true;
134: }
135: $isNumeric = is_numeric($radio['value']);
136:
137: return (!is_array($disabled) || in_array((string)$radio['value'], $disabled, !$isNumeric));
138: }
139:
140: 141: 142: 143: 144: 145: 146: 147: 148:
149: protected function _renderInput($val, $text, $data, $context)
150: {
151: $escape = $data['escape'];
152: if (is_int($val) && isset($text['text'], $text['value'])) {
153: $radio = $text;
154: } else {
155: $radio = ['value' => $val, 'text' => $text];
156: }
157: $radio['name'] = $data['name'];
158:
159: if (!isset($radio['templateVars'])) {
160: $radio['templateVars'] = [];
161: }
162: if (!empty($data['templateVars'])) {
163: $radio['templateVars'] = array_merge($data['templateVars'], $radio['templateVars']);
164: }
165:
166: if (empty($radio['id'])) {
167: if (isset($data['id'])) {
168: $radio['id'] = $data['id'] . '-' . trim(
169: $this->_idSuffix($radio['value']),
170: '-'
171: );
172: } else {
173: $radio['id'] = $this->_id($radio['name'], $radio['value']);
174: }
175: }
176: if (isset($data['val']) && is_bool($data['val'])) {
177: $data['val'] = $data['val'] ? 1 : 0;
178: }
179: if (isset($data['val']) && (string)$data['val'] === (string)$radio['value']) {
180: $radio['checked'] = true;
181: $radio['templateVars']['activeClass'] = 'active';
182: }
183:
184: if (!is_bool($data['label']) && isset($radio['checked']) && $radio['checked']) {
185: $data['label'] = $this->_templates->addClass($data['label'], 'selected');
186: }
187:
188: $radio['disabled'] = $this->_isDisabled($radio, $data['disabled']);
189: if (!empty($data['required'])) {
190: $radio['required'] = true;
191: }
192: if (!empty($data['form'])) {
193: $radio['form'] = $data['form'];
194: }
195:
196: $input = $this->_templates->format('radio', [
197: 'name' => $radio['name'],
198: 'value' => $escape ? h($radio['value']) : $radio['value'],
199: 'templateVars' => $radio['templateVars'],
200: 'attrs' => $this->_templates->formatAttributes($radio + $data, ['name', 'value', 'text', 'options', 'label', 'val', 'type']),
201: ]);
202:
203: $label = $this->_renderLabel(
204: $radio,
205: $data['label'],
206: $input,
207: $context,
208: $escape
209: );
210:
211: if ($label === false &&
212: strpos($this->_templates->get('radioWrapper'), '{{input}}') === false
213: ) {
214: $label = $input;
215: }
216:
217: return $this->_templates->format('radioWrapper', [
218: 'input' => $input,
219: 'label' => $label,
220: 'templateVars' => $data['templateVars'],
221: ]);
222: }
223:
224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236:
237: protected function _renderLabel($radio, $label, $input, $context, $escape)
238: {
239: if (isset($radio['label'])) {
240: $label = $radio['label'];
241: } elseif ($label === false) {
242: return false;
243: }
244: $labelAttrs = is_array($label) ? $label : [];
245: $labelAttrs += [
246: 'for' => $radio['id'],
247: 'escape' => $escape,
248: 'text' => $radio['text'],
249: 'templateVars' => $radio['templateVars'],
250: 'input' => $input,
251: ];
252:
253: return $this->_label->render($labelAttrs, $context);
254: }
255:
256: 257: 258:
259: public function secureFields(array $data)
260: {
261: return [$data['name']];
262: }
263: }
264: