1<?php
2/**
3 * Zend Framework (http://framework.zend.com/)
4 *
5 * @link      http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license   http://framework.zend.com/license/new-bsd New BSD License
8 */
9
10namespace Zend\Form\View\Helper;
11
12use Zend\Form\ElementInterface;
13use Zend\Form\Exception;
14
15class FormInput extends AbstractHelper
16{
17    /**
18     * Attributes valid for the input tag
19     *
20     * @var array
21     */
22    protected $validTagAttributes = array(
23        'name'           => true,
24        'accept'         => true,
25        'alt'            => true,
26        'autocomplete'   => true,
27        'autofocus'      => true,
28        'checked'        => true,
29        'dirname'        => true,
30        'disabled'       => true,
31        'form'           => true,
32        'formaction'     => true,
33        'formenctype'    => true,
34        'formmethod'     => true,
35        'formnovalidate' => true,
36        'formtarget'     => true,
37        'height'         => true,
38        'list'           => true,
39        'max'            => true,
40        'maxlength'      => true,
41        'min'            => true,
42        'multiple'       => true,
43        'pattern'        => true,
44        'placeholder'    => true,
45        'readonly'       => true,
46        'required'       => true,
47        'size'           => true,
48        'src'            => true,
49        'step'           => true,
50        'type'           => true,
51        'value'          => true,
52        'width'          => true,
53    );
54
55    /**
56     * Valid values for the input type
57     *
58     * @var array
59     */
60    protected $validTypes = array(
61        'text'           => true,
62        'button'         => true,
63        'checkbox'       => true,
64        'file'           => true,
65        'hidden'         => true,
66        'image'          => true,
67        'password'       => true,
68        'radio'          => true,
69        'reset'          => true,
70        'select'         => true,
71        'submit'         => true,
72        'color'          => true,
73        'date'           => true,
74        'datetime'       => true,
75        'datetime-local' => true,
76        'email'          => true,
77        'month'          => true,
78        'number'         => true,
79        'range'          => true,
80        'search'         => true,
81        'tel'            => true,
82        'time'           => true,
83        'url'            => true,
84        'week'           => true,
85    );
86
87    /**
88     * Invoke helper as functor
89     *
90     * Proxies to {@link render()}.
91     *
92     * @param  ElementInterface|null $element
93     * @return string|FormInput
94     */
95    public function __invoke(ElementInterface $element = null)
96    {
97        if (!$element) {
98            return $this;
99        }
100
101        return $this->render($element);
102    }
103
104    /**
105     * Render a form <input> element from the provided $element
106     *
107     * @param  ElementInterface $element
108     * @throws Exception\DomainException
109     * @return string
110     */
111    public function render(ElementInterface $element)
112    {
113        $name = $element->getName();
114        if ($name === null || $name === '') {
115            throw new Exception\DomainException(sprintf(
116                '%s requires that the element has an assigned name; none discovered',
117                __METHOD__
118            ));
119        }
120
121        $attributes          = $element->getAttributes();
122        $attributes['name']  = $name;
123        $type                = $this->getType($element);
124        $attributes['type']  = $type;
125        $attributes['value'] = $element->getValue();
126        if ('password' == $type) {
127            $attributes['value'] = '';
128        }
129
130        return sprintf(
131            '<input %s%s',
132            $this->createAttributesString($attributes),
133            $this->getInlineClosingBracket()
134        );
135    }
136
137    /**
138     * Determine input type to use
139     *
140     * @param  ElementInterface $element
141     * @return string
142     */
143    protected function getType(ElementInterface $element)
144    {
145        $type = $element->getAttribute('type');
146        if (empty($type)) {
147            return 'text';
148        }
149
150        $type = strtolower($type);
151        if (!isset($this->validTypes[$type])) {
152            return 'text';
153        }
154
155        return $type;
156    }
157}
158