Completed
Push — master ( 9a4d14...00691e )
by Alexander
04:43 queued 51s
created

AbstractForm::init()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 9
nc 2
nop 0
1
<?php
2
/**
3
 * Base class for forms
4
 *
5
 * @file      AbstractForm.php
6
 *
7
 * PHP version 5.6+
8
 *
9
 * @author    Alexander Yancharuk <alex at itvault dot info>
10
 * @copyright © 2012-2016 Alexander Yancharuk <alex at itvault at info>
11
 * @date      Вск Авг 12 10:30:52 2012
12
 * @license   The BSD 3-Clause License
13
 *            <https://tldrlegal.com/license/bsd-3-clause-license-(revised)>
14
 */
15
16
namespace Veles\Form;
17
18
use Form\Elements\ResetElement;
19
use Veles\Cache\Cache;
20
use Veles\Form\Elements\ButtonElement;
21
use Veles\Form\Elements\HiddenElement;
22
use Veles\Form\Elements\ElementInterface;
23
use Veles\Form\Elements\SubmitElement;
24
use Veles\Validators\RegExValidator;
25
26
/**
27
 * Class AbstractForm
28
 * @author  Alexander Yancharuk <alex at itvault dot info>
29
 */
30
abstract class AbstractForm implements FormInterface
31
{
32
	protected $method   = 'post';
33
	protected $template = null;
34
	protected $data     = null;
35
	protected $sid      = null;
36
	protected $name     = null;
37
	protected $action   = null;
38
	protected $elements = [];
39
40
	/**
41
	 * Constructor
42
	 * @param mixed $data Optional data for form generation
43
	 */
44
	abstract public function __construct($data = false);
45
46
	/**
47
	 * Form save
48
	 */
49
	abstract public function save();
50
51
	/**
52
	 * Default values initialization
53
	 */
54
	protected function init()
55
	{
56
		$input      = ('get' === $this->method) ? INPUT_GET : INPUT_POST;
57
		$this->data = filter_input_array($input, FILTER_UNSAFE_RAW);
58
		$this->sid  = md5(uniqid('', true));
59
60
		$params = [
61
			'validator'  => new RegExValidator('/^[a-f\d]{32}$/'),
62
			'required'   => true,
63
			'attributes' => ['name' => 'sid', 'value' => $this->sid]
64
		];
65
		$this->addElement(new HiddenElement($params));
66
	}
67
68
	/**
69
	 * Add form element
70
	 * @param ElementInterface $element Form element
71
	 * @return void
72
	 */
73
	public function addElement(ElementInterface $element)
74
	{
75
		$this->elements[] = $element;
76
	}
77
78
	/**
79
	 * Form validation
80
	 * @return bool
81
	 */
82
	public function valid()
83
	{
84
		/** @var ElementInterface $element*/
85
		foreach ($this->elements as $element) {
86
			switch (true) {
87
				case $element instanceof ButtonElement:
88
				case $element instanceof ResetElement:
89
				case $element instanceof SubmitElement:
90
					break;
91
				default:
92
					if (!$element->validate($this)) {
93
						return false;
94
					}
95
					break;
96
			}
97
		}
98
99
		return true;
100
	}
101
102
	/**
103
	 * Check is form submitted by security key presence
104
	 * @return bool
105
	 */
106
	public function submitted()
107
	{
108
		if (!isset($this->data['sid'])) {
109
			return false;
110
		}
111
112
		$key = $this->name . $this->data['sid'];
113
114
		if (!Cache::get($key)) {
115
			return false;
116
		}
117
118
		return true;
119
	}
120
121
	/**
122
	 * Security key cleanup
123
	 */
124
	public function cleanup()
125
	{
126
		$key = $this->name . $this->data['sid'];
127
		Cache::del($key);
128
	}
129
130
	/**
131
	 * Form output
132
	 * @return string
133
	 */
134
	public function __toString()
135
	{
136
		$elements = $tpl = [];
137
		$output   = file_get_contents($this->template);
138
139
		/** @var ElementInterface $element */
140
		foreach ($this->elements as $number => $element) {
141
			$elements[] = $element->render();
142
			$tpl[]      = "#$number#";
143
		}
144
145
		$tpl      = array_merge($tpl, ["#method#", "#action#", "#name#"]);
146
		$elements = array_merge(
147
			$elements,
148
			[
149
				$this->method,
150
				$this->action,
151
				$this->name
152
			]
153
		);
154
155
		$this->saveSid();
156
157
		return str_replace($tpl, $elements, $output);
158
	}
159
160
	/**
161
	 * Return form security id
162
	 *
163
	 * Can be used for refresh sid after ajax-request
164
	 *
165
	 * @return string
166
	 */
167
	public function getSid()
168
	{
169
		return $this->sid;
170
	}
171
172
	/**
173
	 * Save form security id to cache
174
	 * @return bool
175
	 */
176
	public function saveSid()
177
	{
178
		return Cache::set($this->name . $this->sid, true, 7200);
179
	}
180
181
	/**
182
	 * Get data by element name
183
	 *
184
	 * @param string $name Element name
185
	 *
186
	 * @return null|string
187
	 */
188
	public function getData($name)
189
	{
190
		return (isset($this->data[$name])) ? $this->data[$name] : null;
191
	}
192
}
193