|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
/** |
|
3
|
|
|
* This file has been modified by pH7 developers team (Pierre-Henry SORIA). |
|
4
|
|
|
*/ |
|
5
|
|
|
|
|
6
|
|
|
namespace PFBC; |
|
7
|
|
|
|
|
8
|
|
|
use PH7\Framework\Layout\Html\Design; |
|
9
|
|
|
use PH7\Framework\Mvc\Request\Http as HttpRequest; |
|
10
|
|
|
|
|
11
|
|
|
/*This project's namespace structure is leveraged to autoload requested classes at runtime.*/ |
|
12
|
|
|
function load($class) |
|
13
|
|
|
{ |
|
14
|
|
|
$file = __DIR__ . '/../' . str_replace('\\', PH7_DS, $class) . '.php'; |
|
15
|
|
|
if (is_file($file)) { |
|
16
|
|
|
include $file; |
|
17
|
|
|
} |
|
18
|
|
|
} |
|
19
|
|
|
|
|
20
|
|
|
spl_autoload_register('PFBC\load'); |
|
21
|
|
|
if (in_array('__autoload', spl_autoload_functions(), true)) { |
|
22
|
|
|
spl_autoload_register('__autoload'); |
|
23
|
|
|
} |
|
24
|
|
|
|
|
25
|
|
|
class Form extends Base |
|
26
|
|
|
{ |
|
27
|
|
|
private static $sFormId; |
|
28
|
|
|
protected $ajax; |
|
29
|
|
|
protected $attributes; |
|
30
|
|
|
protected $error; |
|
31
|
|
|
protected $jQueryUITheme = 'smoothness'; |
|
32
|
|
|
protected $resourcesPath; |
|
33
|
|
|
protected $prevent = []; |
|
34
|
|
|
protected $view; |
|
35
|
|
|
/*jQueryUI themes can be previewed at http://jqueryui.com/themeroller/.*/ |
|
36
|
|
|
protected $width; |
|
37
|
|
|
private $elements = []; |
|
38
|
|
|
/*Prevents various automated from being automatically applied. Current options for this array |
|
39
|
|
|
included jQuery, jQueryUI, jQueryUIButtons, focus, and style.*/ |
|
40
|
|
|
private $prefix = 'http'; |
|
41
|
|
|
private $values = []; |
|
42
|
|
|
private $ajaxCallback; |
|
43
|
|
|
private $widthSuffix = 'px'; |
|
44
|
|
|
|
|
45
|
|
|
public function __construct($id = 'pfbc', $width = '') |
|
|
|
|
|
|
46
|
|
|
{ |
|
47
|
|
|
self::$sFormId = $id; |
|
48
|
|
|
$this->configure([ |
|
49
|
|
|
'width' => $width, |
|
50
|
|
|
'action' => basename($_SERVER['SCRIPT_NAME']), |
|
51
|
|
|
'id' => preg_replace("/\W/", '-', $id), |
|
52
|
|
|
'method' => 'post' |
|
53
|
|
|
]); |
|
54
|
|
|
|
|
55
|
|
|
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') { |
|
56
|
|
|
$this->prefix = 'https'; |
|
57
|
|
|
} |
|
58
|
|
|
|
|
59
|
|
|
/*The Standard view class is applied by default and will be used unless a different view is |
|
60
|
|
|
specified in the form's configure method*/ |
|
61
|
|
|
if (empty($this->view)) { |
|
62
|
|
|
$this->view = new View\CStandard; |
|
63
|
|
|
} |
|
64
|
|
|
|
|
65
|
|
|
if (empty($this->error)) { |
|
66
|
|
|
$this->error = new Error\Standard; |
|
67
|
|
|
} |
|
68
|
|
|
|
|
69
|
|
|
$this->resourcesPath = PH7_URL_STATIC . 'PFBC'; |
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
|
|
public static function isValid($id = 'pfbc', $clearValues = true) |
|
|
|
|
|
|
73
|
|
|
{ |
|
74
|
|
|
$valid = true; |
|
75
|
|
|
/*The form's instance is recovered (unserialized) from the session.*/ |
|
76
|
|
|
$form = self::recover($id); |
|
77
|
|
|
if (!empty($form)) { |
|
78
|
|
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') |
|
79
|
|
|
$data = $_POST; |
|
80
|
|
|
else |
|
81
|
|
|
$data = $_GET; |
|
82
|
|
|
|
|
83
|
|
|
/*Any values/errors stored in the session for this form are cleared.*/ |
|
84
|
|
|
self::clearValues($id); |
|
85
|
|
|
self::clearErrors($id); |
|
86
|
|
|
|
|
87
|
|
|
/*Each element's value is saved in the session and checked against any validation rules applied |
|
88
|
|
|
to the element.*/ |
|
89
|
|
|
if (!empty($form->elements)) { |
|
90
|
|
|
foreach ($form->elements as $element) { |
|
91
|
|
|
$name = $element->getName(); |
|
92
|
|
|
if (substr($name, -2) == '[]') { |
|
93
|
|
|
$name = substr($name, 0, -2); |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
/*The File element must be handled differently b/c it uses the $_FILES superglobal and |
|
97
|
|
|
not $_GET or $_POST.*/ |
|
98
|
|
|
if ($element instanceof Element\File) { |
|
99
|
|
|
$data[$name] = $_FILES[$name]['name']; |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
if (isset($data[$name])) { |
|
103
|
|
|
$value = $data[$name]; |
|
104
|
|
|
if (is_array($value)) { |
|
105
|
|
|
$valueSize = sizeof($value); |
|
106
|
|
|
for ($v = 0; $v < $valueSize; ++$v) { |
|
107
|
|
|
$value[$v] = stripslashes($value[$v]); |
|
108
|
|
|
} |
|
109
|
|
|
} else { |
|
110
|
|
|
$value = stripslashes($value); |
|
111
|
|
|
} |
|
112
|
|
|
self::setSessionValue($id, $name, $value); |
|
113
|
|
|
} else { |
|
114
|
|
|
$value = null; |
|
115
|
|
|
} |
|
116
|
|
|
|
|
117
|
|
|
/*If a validation error is found, the error message is saved in the session along with |
|
118
|
|
|
the element's name.*/ |
|
119
|
|
|
if (!$element->isValid($value)) { |
|
120
|
|
|
self::setError($id, $element->getErrors(), $name); |
|
121
|
|
|
$valid = false; |
|
122
|
|
|
} |
|
123
|
|
|
} |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
/*If no validation errors were found, the form's session values are cleared.*/ |
|
127
|
|
|
if ($valid) { |
|
128
|
|
|
if ($clearValues) { |
|
129
|
|
|
self::clearValues($id); |
|
130
|
|
|
} |
|
131
|
|
|
self::clearErrors($id); |
|
132
|
|
|
} |
|
133
|
|
|
} else { |
|
134
|
|
|
$valid = false; |
|
135
|
|
|
} |
|
136
|
|
|
|
|
137
|
|
|
return $valid; |
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
private static function recover($id) |
|
|
|
|
|
|
141
|
|
|
{ |
|
142
|
|
|
if (!empty($_SESSION['pfbc'][$id]['form'])) { |
|
143
|
|
|
return unserialize($_SESSION['pfbc'][$id]['form']); |
|
144
|
|
|
} |
|
145
|
|
|
|
|
146
|
|
|
return ''; |
|
147
|
|
|
} |
|
148
|
|
|
|
|
149
|
|
|
public static function clearValues($id = 'pfbc') |
|
|
|
|
|
|
150
|
|
|
{ |
|
151
|
|
|
if (!empty($_SESSION['pfbc'][$id]['values'])) { |
|
152
|
|
|
unset($_SESSION['pfbc'][$id]['values']); |
|
153
|
|
|
} |
|
154
|
|
|
} |
|
155
|
|
|
|
|
156
|
|
|
public static function clearErrors($id = 'pfbc') |
|
|
|
|
|
|
157
|
|
|
{ |
|
158
|
|
|
if (!empty($_SESSION['pfbc'][$id]['errors'])) { |
|
159
|
|
|
unset($_SESSION['pfbc'][$id]['errors']); |
|
160
|
|
|
} |
|
161
|
|
|
} |
|
162
|
|
|
|
|
163
|
|
|
public static function setSessionValue($id, $element, $value) |
|
|
|
|
|
|
164
|
|
|
{ |
|
165
|
|
|
$_SESSION['pfbc'][$id]['values'][$element] = $value; |
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
/** |
|
169
|
|
|
* Validation errors are saved in the session after the form submission, and will be displayed to the user |
|
170
|
|
|
* when redirected back to the form. |
|
171
|
|
|
*/ |
|
172
|
|
|
public static function setError($id, $messages, $element = '') |
|
|
|
|
|
|
173
|
|
|
{ |
|
174
|
|
|
if (!is_array($messages)) { |
|
175
|
|
|
$messages = [$messages]; |
|
176
|
|
|
} |
|
177
|
|
|
|
|
178
|
|
|
if (empty($_SESSION['pfbc'][$id]['errors'][$element])) { |
|
179
|
|
|
$_SESSION['pfbc'][$id]['errors'][$element] = []; |
|
180
|
|
|
} |
|
181
|
|
|
|
|
182
|
|
|
foreach ($messages as $message) { |
|
183
|
|
|
$_SESSION['pfbc'][$id]['errors'][$element][] = $message; |
|
184
|
|
|
} |
|
185
|
|
|
} |
|
186
|
|
|
|
|
187
|
|
|
/** |
|
188
|
|
|
* @return string The ID of the form. |
|
189
|
|
|
*/ |
|
190
|
|
|
public static function getFormId() |
|
191
|
|
|
{ |
|
192
|
|
|
return self::$sFormId; |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
/** |
|
196
|
|
|
* When ajax is used to submit the form's data, validation errors need to be manually sent back to the |
|
197
|
|
|
* form using json. |
|
198
|
|
|
* |
|
199
|
|
|
* @param string $id |
|
200
|
|
|
*/ |
|
201
|
|
|
public static function renderAjaxErrorResponse($id = 'pfbc') |
|
202
|
|
|
{ |
|
203
|
|
|
$form = self::recover($id); |
|
204
|
|
|
if (!empty($form)) { |
|
205
|
|
|
$form->error->renderAjaxErrorResponse(); |
|
206
|
|
|
} |
|
207
|
|
|
} |
|
208
|
|
|
|
|
209
|
|
|
public static function setSuccess($id, $message, $element = '') |
|
|
|
|
|
|
210
|
|
|
{ |
|
211
|
|
|
return (new Design)->setFlashMsg($message, Design::SUCCESS_TYPE); |
|
212
|
|
|
} |
|
213
|
|
|
|
|
214
|
|
|
/** |
|
215
|
|
|
* When a form is serialized and stored in the session, this function prevents any |
|
216
|
|
|
* non-essential information from being included. |
|
217
|
|
|
*/ |
|
218
|
|
|
public function __sleep() |
|
219
|
|
|
{ |
|
220
|
|
|
return ['attributes', 'elements', 'error']; |
|
221
|
|
|
} |
|
222
|
|
|
|
|
223
|
|
|
public function addElement(Element $element) |
|
224
|
|
|
{ |
|
225
|
|
|
$element->setForm($this); |
|
226
|
|
|
//If the element doesn't have a specified id, a generic identifier is applied. |
|
227
|
|
|
$id = $element->getID(); |
|
228
|
|
|
if (empty($id)) |
|
229
|
|
|
$element->setID($this->attributes['id'] . '-element-' . sizeof($this->elements)); |
|
230
|
|
|
$this->elements[] = $element; |
|
231
|
|
|
|
|
232
|
|
|
/*For ease-of-use, the form tag's encytype attribute is automatically set if the File element |
|
233
|
|
|
class is added.*/ |
|
234
|
|
|
if ($element instanceof Element\File) |
|
235
|
|
|
$this->attributes['enctype'] = 'multipart/form-data'; |
|
236
|
|
|
} |
|
237
|
|
|
|
|
238
|
|
|
public function getAjax() |
|
239
|
|
|
{ |
|
240
|
|
|
return $this->ajax; |
|
241
|
|
|
} |
|
242
|
|
|
|
|
243
|
|
|
public function getElements() |
|
244
|
|
|
{ |
|
245
|
|
|
return $this->elements; |
|
246
|
|
|
} |
|
247
|
|
|
|
|
248
|
|
|
public function getError() |
|
249
|
|
|
{ |
|
250
|
|
|
return $this->error; |
|
251
|
|
|
} |
|
252
|
|
|
|
|
253
|
|
|
public function getId() |
|
254
|
|
|
{ |
|
255
|
|
|
return $this->attributes['id']; |
|
256
|
|
|
} |
|
257
|
|
|
|
|
258
|
|
|
public function getJQueryUIButtons() |
|
259
|
|
|
{ |
|
260
|
|
|
return $this->jQueryUIButtons; |
|
261
|
|
|
} |
|
262
|
|
|
|
|
263
|
|
|
public function getPrevent() |
|
264
|
|
|
{ |
|
265
|
|
|
return $this->prevent; |
|
266
|
|
|
} |
|
267
|
|
|
|
|
268
|
|
|
public function getResourcesPath() |
|
269
|
|
|
{ |
|
270
|
|
|
return $this->resourcesPath; |
|
271
|
|
|
} |
|
272
|
|
|
|
|
273
|
|
|
public function getErrors() |
|
|
|
|
|
|
274
|
|
|
{ |
|
275
|
|
|
$errors = []; |
|
276
|
|
|
if (session_status() !== PHP_SESSION_ACTIVE) { |
|
277
|
|
|
$errors[''] = ['Error: pH7CMS requires an active session to work properly. Simply add session_start() to your script before any output has been sent to the browser.']; |
|
278
|
|
|
} else { |
|
279
|
|
|
$errors = []; |
|
280
|
|
|
$id = $this->attributes['id']; |
|
281
|
|
|
if (!empty($_SESSION['pfbc'][$id]['errors'])) { |
|
282
|
|
|
$errors = $_SESSION['pfbc'][$id]['errors']; |
|
283
|
|
|
} |
|
284
|
|
|
} |
|
285
|
|
|
|
|
286
|
|
|
return $errors; |
|
287
|
|
|
} |
|
288
|
|
|
|
|
289
|
|
|
public function getWidth() |
|
290
|
|
|
{ |
|
291
|
|
|
return $this->width; |
|
292
|
|
|
} |
|
293
|
|
|
|
|
294
|
|
|
public function getWidthSuffix() |
|
295
|
|
|
{ |
|
296
|
|
|
return $this->widthSuffix; |
|
297
|
|
|
} |
|
298
|
|
|
|
|
299
|
|
|
public function render($returnHTML = false) |
|
300
|
|
|
{ |
|
301
|
|
|
$this->view->setForm($this); |
|
302
|
|
|
$this->error->setForm($this); |
|
303
|
|
|
|
|
304
|
|
|
/*When validation errors occur, the form's submitted values are saved in a session |
|
305
|
|
|
array, which allows them to be pre-populated when the user is redirected to the form.*/ |
|
306
|
|
|
$values = self::getSessionValues($this->attributes['id']); |
|
307
|
|
|
if (!empty($values)) |
|
308
|
|
|
$this->setValues($values); |
|
309
|
|
|
$this->applyValues(); |
|
310
|
|
|
|
|
311
|
|
|
$this->formatWidthProperties(); |
|
312
|
|
|
|
|
313
|
|
|
if ($returnHTML) { |
|
314
|
|
|
ob_start(); |
|
315
|
|
|
} |
|
316
|
|
|
|
|
317
|
|
|
$this->renderCSS(); |
|
318
|
|
|
$this->view->render(); |
|
319
|
|
|
$this->renderJS(); |
|
320
|
|
|
|
|
321
|
|
|
/*The form's instance is serialized and saved in a session variable for use during validation.*/ |
|
322
|
|
|
$this->save(); |
|
323
|
|
|
|
|
324
|
|
|
if ($returnHTML) { |
|
325
|
|
|
$html = ob_get_contents(); |
|
326
|
|
|
ob_end_clean(); |
|
327
|
|
|
return $html; |
|
328
|
|
|
} |
|
329
|
|
|
} |
|
330
|
|
|
|
|
331
|
|
|
public static function getSessionValues($id = 'pfbc') |
|
|
|
|
|
|
332
|
|
|
{ |
|
333
|
|
|
$values = []; |
|
334
|
|
|
if (!empty($_SESSION['pfbc'][$id]['values'])) |
|
335
|
|
|
$values = $_SESSION['pfbc'][$id]['values']; |
|
336
|
|
|
return $values; |
|
337
|
|
|
} |
|
338
|
|
|
|
|
339
|
|
|
/** |
|
340
|
|
|
* An associative array is used to pre-populate form elements. The keys of this array correspond with |
|
341
|
|
|
* the element names. |
|
342
|
|
|
* |
|
343
|
|
|
* @param array $values |
|
344
|
|
|
*/ |
|
345
|
|
|
public function setValues(array $values) |
|
346
|
|
|
{ |
|
347
|
|
|
$this->values = array_merge($this->values, $values); |
|
348
|
|
|
} |
|
349
|
|
|
|
|
350
|
|
|
/** |
|
351
|
|
|
* Values that have been set through the setValues method, either manually by the developer |
|
352
|
|
|
* or after validation errors, are applied to elements within this method. |
|
353
|
|
|
*/ |
|
354
|
|
|
private function applyValues() |
|
355
|
|
|
{ |
|
356
|
|
|
foreach ($this->elements as $element) { |
|
357
|
|
|
$name = $element->getName(); |
|
358
|
|
|
if (isset($this->values[$name])) { |
|
359
|
|
|
$element->setValue($this->values[$name]); |
|
360
|
|
|
} elseif (substr($name, -2) == '[]' && |
|
361
|
|
|
isset($this->values[substr($name, 0, -2)]) |
|
362
|
|
|
) { |
|
363
|
|
|
$element->setValue($this->values[substr($name, 0, -2)]); |
|
364
|
|
|
} |
|
365
|
|
|
} |
|
366
|
|
|
} |
|
367
|
|
|
|
|
368
|
|
|
/** |
|
369
|
|
|
* This method parses the form's width property into a numeric width value and a width suffix - either px or %. |
|
370
|
|
|
* These values are used by the form's concrete view class. |
|
371
|
|
|
*/ |
|
372
|
|
|
public function formatWidthProperties() |
|
373
|
|
|
{ |
|
374
|
|
|
if (!empty($this->width)) { |
|
375
|
|
|
if (substr($this->width, -1) == '%') { |
|
376
|
|
|
$this->width = substr($this->width, 0, -1); |
|
377
|
|
|
$this->widthSuffix = '%'; |
|
378
|
|
|
} elseif (substr($this->width, -2) == 'px') { |
|
379
|
|
|
$this->width = substr($this->width, 0, -2); |
|
380
|
|
|
} |
|
381
|
|
|
} else { |
|
382
|
|
|
/*If the form's width property is empty, 100% will be assumed.*/ |
|
383
|
|
|
$this->width = 100; |
|
384
|
|
|
$this->widthSuffix = '%'; |
|
385
|
|
|
} |
|
386
|
|
|
} |
|
387
|
|
|
|
|
388
|
|
|
private function renderCSS() |
|
389
|
|
|
{ |
|
390
|
|
|
echo '<style scoped="scoped">'; |
|
391
|
|
|
$this->view->renderCSS(); |
|
392
|
|
|
$this->error->renderCSS(); |
|
393
|
|
|
foreach ($this->elements as $element) { |
|
394
|
|
|
$element->renderCSS(); |
|
395
|
|
|
} |
|
396
|
|
|
echo '</style>'; |
|
397
|
|
|
} |
|
398
|
|
|
|
|
399
|
|
|
private function renderJS() |
|
400
|
|
|
{ |
|
401
|
|
|
$this->renderJSFiles(); |
|
402
|
|
|
echo '<script>'; |
|
403
|
|
|
$this->view->renderJS(); |
|
404
|
|
|
foreach ($this->elements as $element) { |
|
405
|
|
|
$element->renderJS(); |
|
406
|
|
|
} |
|
407
|
|
|
|
|
408
|
|
|
$id = $this->attributes['id']; |
|
409
|
|
|
|
|
410
|
|
|
echo 'jQuery(document).ready(function() {'; |
|
411
|
|
|
|
|
412
|
|
|
/*When the form is submitted, disable all submit buttons to prevent duplicate submissions.*/ |
|
413
|
|
|
echo 'jQuery("#', $id, '").bind("submit", function() {'; |
|
414
|
|
|
if ($this->isNotJQueryUiButtons()) { |
|
415
|
|
|
echo 'jQuery(this).find("button[type=submit]").button("disable");'; |
|
416
|
|
|
echo 'jQuery(this).find("button[type=submit] span.ui-button-text").css("padding-right", "2.1em").append(\'<img class="pfbc-loading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAIiIiAAAAGdnZyMjIwAAADQ0NEVFRU5OTiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" alt="Loading..."/>\');'; |
|
417
|
|
|
} else { |
|
418
|
|
|
echo 'jQuery(this).find("button[type=submit]").attr("disabled", "disabled");'; |
|
419
|
|
|
} |
|
420
|
|
|
echo '});'; |
|
421
|
|
|
|
|
422
|
|
|
// Don't want to focus the first form field on the homepage |
|
423
|
|
|
if ($this->isFormFocusNotOnHomepage()) { |
|
424
|
|
|
// Use jQuery to set the focus of the form's initial element |
|
425
|
|
|
echo 'jQuery("#', $id, ' :input:visible:enabled:first").focus();'; |
|
426
|
|
|
} |
|
427
|
|
|
|
|
428
|
|
|
$this->view->jQueryDocumentReady(); |
|
429
|
|
|
foreach ($this->elements as $element) { |
|
430
|
|
|
$element->jQueryDocumentReady(); |
|
431
|
|
|
} |
|
432
|
|
|
|
|
433
|
|
|
/*For ajax, an anonymous onsubmit javascript function is bound to the form using jQuery. jQuery's |
|
434
|
|
|
serialize function is used to grab each element's name/value pair.*/ |
|
435
|
|
|
if (!empty($this->ajax)) { |
|
436
|
|
|
echo 'jQuery("#', $id, '").bind("submit", {'; |
|
437
|
|
|
$this->error->clear(); |
|
438
|
|
|
echo <<<JS |
|
439
|
|
|
jQuery.ajax({ |
|
440
|
|
|
url: "{$this->attributes["action"]}", |
|
441
|
|
|
type: "{$this->attributes["method"]}", |
|
442
|
|
|
data: jQuery("#$id").serialize(), |
|
443
|
|
|
success: function(response) { |
|
444
|
|
|
if(typeof response != "undefined" && typeof response == "object" && response.errors) { |
|
445
|
|
|
JS; |
|
446
|
|
|
$this->error->applyAjaxErrorResponse(); |
|
447
|
|
|
echo <<<JS |
|
448
|
|
|
jQuery("html, body").animate({ scrollTop: jQuery("#$id").offset().top }, 500 ); |
|
449
|
|
|
} |
|
450
|
|
|
else { |
|
451
|
|
|
JS; |
|
452
|
|
|
/*A callback function can be specified to handle any post submission events.*/ |
|
453
|
|
|
if (!empty($this->ajaxCallback)) { |
|
454
|
|
|
echo $this->ajaxCallback, '(response);'; |
|
455
|
|
|
} |
|
456
|
|
|
|
|
457
|
|
|
echo '}'; |
|
458
|
|
|
|
|
459
|
|
|
if ($this->isNotJQueryUiButtons()) { |
|
460
|
|
|
echo 'jQuery("#', $id, ' button[type=submit] span.ui-button-text").css("padding-right", "1em").find("img").remove();'; |
|
461
|
|
|
echo 'jQuery("#', $id, ' button[type=submit]").button("enable");'; |
|
462
|
|
|
} else { |
|
463
|
|
|
echo 'jQuery("#', $id, '").find("button[type=submit]").removeAttr("disabled");'; |
|
464
|
|
|
} |
|
465
|
|
|
|
|
466
|
|
|
echo <<<JS |
|
467
|
|
|
} |
|
468
|
|
|
}); |
|
469
|
|
|
return false; |
|
470
|
|
|
}); |
|
471
|
|
|
|
|
472
|
|
|
JS; |
|
473
|
|
|
} |
|
474
|
|
|
|
|
475
|
|
|
echo <<<JS |
|
476
|
|
|
}); |
|
477
|
|
|
</script> |
|
478
|
|
|
JS; |
|
479
|
|
|
} |
|
480
|
|
|
|
|
481
|
|
|
private function renderJSFiles() |
|
482
|
|
|
{ |
|
483
|
|
|
$urls = []; |
|
484
|
|
|
|
|
485
|
|
|
/** |
|
486
|
|
|
* These files are already included by default in layout.tpl, therefore it is unnecessary to include them again. |
|
487
|
|
|
* |
|
488
|
|
|
* if(!in_array("jQuery", $this->prevent)) |
|
489
|
|
|
* $urls[] = $this->_prefix . "://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"; |
|
490
|
|
|
* if(!in_array("jQueryUI", $this->prevent)) |
|
491
|
|
|
* $urls[] = $this->_prefix . "://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"; |
|
492
|
|
|
*/ |
|
493
|
|
|
foreach ($this->elements as $element) { |
|
494
|
|
|
$elementUrls = $element->getJSFiles(); |
|
495
|
|
|
if (is_array($elementUrls)) { |
|
496
|
|
|
$urls = array_merge($urls, $elementUrls); |
|
497
|
|
|
} |
|
498
|
|
|
} |
|
499
|
|
|
|
|
500
|
|
|
/*This section prevents duplicate css files from being loaded.*/ |
|
501
|
|
|
if (!empty($urls)) { |
|
502
|
|
|
$urls = array_values(array_unique($urls)); |
|
503
|
|
|
foreach ($urls as $url) { |
|
504
|
|
|
echo '<script src="', $url, '"></script>'; |
|
505
|
|
|
} |
|
506
|
|
|
} |
|
507
|
|
|
} |
|
508
|
|
|
|
|
509
|
|
|
/** |
|
510
|
|
|
* The save method serialized the form's instance and saves it in the session. |
|
511
|
|
|
*/ |
|
512
|
|
|
private function save() |
|
|
|
|
|
|
513
|
|
|
{ |
|
514
|
|
|
$_SESSION['pfbc'][$this->attributes['id']]['form'] = serialize($this); |
|
515
|
|
|
} |
|
516
|
|
|
|
|
517
|
|
|
private function renderCSSFiles() |
|
518
|
|
|
{ |
|
519
|
|
|
$urls = []; |
|
520
|
|
|
/** |
|
521
|
|
|
* These files are already included by default in layout.tpl, therefore it is unnecessary to include them again. |
|
522
|
|
|
* |
|
523
|
|
|
* if(!in_array('jQueryUI', $this->prevent)) |
|
524
|
|
|
* $urls[] = $this->prefix . '://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/' . $this->jQueryUITheme . '/jquery-ui.css'; |
|
525
|
|
|
*/ |
|
526
|
|
|
foreach ($this->elements as $element) { |
|
527
|
|
|
$elementUrls = $element->getCSSFiles(); |
|
528
|
|
|
if (is_array($elementUrls)) { |
|
529
|
|
|
$urls = array_merge($urls, $elementUrls); |
|
530
|
|
|
} |
|
531
|
|
|
} |
|
532
|
|
|
|
|
533
|
|
|
//*This section prevents duplicate css files from being loaded.*/ |
|
534
|
|
|
if (!empty($urls)) { |
|
535
|
|
|
$urls = array_values(array_unique($urls)); |
|
536
|
|
|
foreach ($urls as $url) { |
|
537
|
|
|
echo '<link rel="stylesheet" href="', $url, '"/>'; |
|
538
|
|
|
} |
|
539
|
|
|
} |
|
540
|
|
|
} |
|
541
|
|
|
|
|
542
|
|
|
/** |
|
543
|
|
|
* @return bool |
|
544
|
|
|
*/ |
|
545
|
|
|
private function isNotJQueryUiButtons() |
|
546
|
|
|
{ |
|
547
|
|
|
return !in_array('jQueryUIButtons', $this->prevent, true); |
|
548
|
|
|
} |
|
549
|
|
|
|
|
550
|
|
|
/** |
|
551
|
|
|
* @return bool |
|
552
|
|
|
*/ |
|
553
|
|
|
private function isFormFocusNotOnHomepage() |
|
554
|
|
|
{ |
|
555
|
|
|
return ((new HttpRequest)->currentUrl() !== PH7_URL_ROOT) && |
|
556
|
|
|
!in_array('focus', $this->prevent, true); |
|
557
|
|
|
} |
|
558
|
|
|
} |
|
559
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.