1: <?php
2: /**
3: * This file is part of the PHPLucidFrame library.
4: * Core utility for AJAX form handling and form validation
5: *
6: * @package PHPLucidFrame\Core
7: * @since PHPLucidFrame v 1.0.0
8: * @copyright Copyright (c), PHPLucidFrame.
9: * @link http://phplucidframe.com
10: * @license http://www.opensource.org/licenses/mit-license.php MIT License
11: *
12: * This source file is subject to the MIT license that is bundled
13: * with this source code in the file LICENSE
14: */
15:
16: namespace LucidFrame\Core;
17:
18: /**
19: * Core utility for AJAX form handling and form validation
20: */
21: class Form
22: {
23: /** @var string The HTML form ID */
24: private static $id;
25: /** @var array The error messages and their associated HTML ID */
26: private static $error = array();
27: /** @var boolean TRUE/FALSE for form validation success */
28: private static $success = false;
29: /** @var string The form message */
30: private static $message = '';
31: /** @var string URL to be redirect upon form submission completed */
32: private static $redirect = '';
33: /** @var string The Javascript callback function to be invoked upon form submission completed */
34: private static $callback = '';
35:
36: /**
37: * Constructor
38: */
39: public static function init()
40: {
41: self::$id = '';
42: self::$error = array();
43: self::$success = false;
44: self::$message = '';
45: self::$redirect = '';
46: self::$callback = '';
47: }
48:
49: /**
50: * Setter for the class properties
51: * @param string $key The property name
52: * @param mixed $value The value to be set
53: * @return void
54: */
55: public static function set($key, $value = '')
56: {
57: self::$$key = $value;
58: }
59:
60: /**
61: * Getter for the class properties
62: * @param string $key The property name
63: * @param mixed $value The default value for the property
64: * @return mixed
65: */
66: public static function get($key, $value = null)
67: {
68: if (isset(self::$$key)) {
69: return self::$$key;
70: }
71:
72: return $value;
73: }
74:
75: /**
76: * Form token generation
77: * @return void
78: */
79: public static function token()
80: {
81: $token = _encrypt(time());
82: session_set(_cfg('formTokenName'), $token);
83: echo '<input type="hidden" name="lc_formToken_' . _cfg('formTokenName') . '" value="' . $token . '" />';
84: }
85:
86: /**
87: * Form token validation
88: * @param array $validations The array of validation rules
89: * @param array $data The optional data array (if no `value` in $validation, it will be looked up in $data)
90: * @return boolean
91: */
92: public static function validate($validations = null, $data = [])
93: {
94: if (!isset($_POST['lc_formToken_' . _cfg('formTokenName')])) {
95: Validation::addError('', _t('Invalid form token.'));
96: return false;
97: }
98:
99: $token = _decrypt(session_get(_cfg('formTokenName')));
100: $postedToken = _decrypt(_post('lc_formToken_'._cfg('formTokenName')));
101: $result = false;
102: # check token first
103: if ($token == $postedToken) {
104: # check referer if it is requesting in the same site
105: if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] && _cfg('siteDomain')) {
106: $siteDomain = _cfg('siteDomain');
107: $siteDomain = preg_replace('/^www\./', '', $siteDomain);
108: $parsedURL = parse_url($_SERVER['HTTP_REFERER']);
109: $parsedURL['host'] = preg_replace('/^www\./', '', $parsedURL['host']);
110: if (strcasecmp($siteDomain, $parsedURL['host']) == 0) {
111: $result = true;
112: }
113: }
114: }
115:
116: if (!$result) {
117: Validation::addError('', _t('Error occurred during form submission. Please refresh the page to try again.'));
118: return false;
119: }
120:
121: if ($validations && Validation::check($validations, $data) === false) {
122: return false;
123: }
124:
125: return true;
126: }
127:
128: /**
129: * AJAX form responder
130: * @param string $formId The HTML form ID
131: * @param array $errors The array of the errors (it is used only for generic form processing)
132: * @param bool $forceJson Send json header
133: * @return void
134: */
135: public static function respond($formId, $errors = null, $forceJson = false)
136: {
137: self::$id = $formId;
138: self::$error = validation_get('errors');
139: $ajaxResponse = $errors === null;
140:
141: if (is_array($errors) && count($errors)) {
142: self::$error = $errors;
143: $ajaxResponse = false;
144: # if no error message and no other message, no need to respond
145: if (count(self::$error) == 0 && empty(self::$message)) {
146: return;
147: }
148: }
149:
150: $response = array(
151: 'formId' => self::$id,
152: 'success' => self::$success ? true : false,
153: 'error' => self::$error,
154: 'msg' => self::$message,
155: 'redirect' => self::$redirect,
156: 'callback' => self::$callback
157: );
158:
159: if ($ajaxResponse) {
160: if ($forceJson) {
161: _json($response);
162: } else {
163: echo json_encode($response);
164: }
165: } else {
166: echo '<script type="text/javascript">';
167: echo 'LC.Form.submitHandler(' . json_encode($response) . ')';
168: echo '</script>';
169: }
170: }
171:
172: /**
173: * Permits you to set the value of an input or textarea.
174: * Allows you to safely use HTML and characters such as quotes within form elements without breaking out of the form
175: *
176: * @param string $name The input element field name
177: * @param mixed $defaultValue The default value of the input element (optional)
178: *
179: * @return mixed The value of the input element
180: */
181: public static function value($name, $defaultValue = null)
182: {
183: $value = _post($name);
184:
185: return $value ? _h($value) : _h($defaultValue);
186: }
187:
188: /**
189: * Permits you to set the value to a rich text editor or any input where HTML source is required to be rendered.
190: * Allows you to safely use HTML and characters such as quotes within form elements without breaking out of the form
191: *
192: * @param string $name The input element field name
193: * @param mixed $defaultValue The default value of the input element (optional)
194: *
195: * @return mixed The value of the input element
196: */
197: public static function htmlValue($name, $defaultValue = null)
198: {
199: if (count($_POST)) {
200: if (!isset($_POST[$name])) {
201: return '';
202: }
203: $value = _xss($_POST[$name]);
204:
205: return _h($value);
206: }
207:
208: return _h($defaultValue);
209: }
210:
211: /**
212: * Allow you to select the option of a drop-down list.
213: *
214: * @param string $name The field name of the drop-down list
215: * @param mixed $value The option value to check against
216: * @param mixed $defaultValue The default selected value (optional)
217: *
218: * @return string `'selected="selected"'` if the option is found, otherwise the empty string returned
219: */
220: public static function selected($name, $value, $defaultValue = null)
221: {
222: return self::inputSelection($name, $value, $defaultValue) ? 'selected="selected"' : '';
223: }
224:
225: /**
226: * Allow you to select a checkbox or a radio button
227: *
228: * @param string $name The field name of the checkbox or radio button
229: * @param mixed $value The value to check against
230: * @param mixed $defaultValue The default selected value (optional)
231: *
232: * @return string `'checked="checked"'` if the option is found, otherwise the empty string returned
233: */
234: public static function checked($name, $value, $defaultValue = null)
235: {
236: return self::inputSelection($name, $value, $defaultValue) ? 'checked="checked"' : '';
237: }
238:
239: /**
240: * @param string $name The field name of the checkbox or radio button or drop-down list
241: * @param mixed $value The value to check against
242: * @param mixed $defaultValue The default selected value (optional)
243: *
244: * @return bool TRUE if the option is found, otherwise FALSE
245: * @internal
246: * @ignore
247: *
248: * Allow you to select a checkbox or a radio button or an option of a drop-down list
249: *
250: */
251: public static function inputSelection($name, $value, $defaultValue = null)
252: {
253: if (count($_POST)) {
254: $name = preg_replace('/(\[\])$/', '', $name); // group[] will be replaced as group
255: if (!isset($_POST[$name])) {
256: return '';
257: }
258: $postedValue = _post($name);
259: if (is_array($postedValue) && in_array($value, $postedValue)) {
260: return true;
261: } elseif ($value == $postedValue) {
262: return true;
263: } else {
264: return false;
265: }
266: } else {
267: if (is_array($defaultValue) && in_array($value, $defaultValue)) {
268: return true;
269: } elseif ($value == $defaultValue) {
270: return true;
271: } else {
272: return false;
273: }
274: }
275: }
276: }
277: