PluginProbe
Contact Forms by Cimatti / 1.4.1
Contact Forms by Cimatti v1.4.1
2.3.6 2.3.5 2.3.0 2.2.32 2.2.4 2.2.0 2.1.2 2.1.1 trunk 1.0 1.1 1.2 1.2.1 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 All 62 releases
contact-forms / AccuaForm.php

AccuaForm.php in Contact Forms by Cimatti 1.4.1, at AccuaForm.php

1,050 lines 33.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 class AccuaForm extends Form {
3 protected static $submitted = null;
4 protected static $valid = null;
5 protected static $submittedID = null;
6 protected static $submittedBuildID = null;
7 protected static $submittedForm = null;
8 protected static $submittedFormUsed = false;
9 protected static $submittedData = null;
10 protected static $rawData = null;
11 protected static $submittedMessages = '';
12
13 protected $formID = null;
14 protected $buildID = null;
15 protected $validate_functions = array();
16 protected $submit_functions = array();
17 protected $elements_sleep;
18 public $stats = array();
19 protected $accua_ajax;
20 protected $locale = null;
21 protected $language = null;
22 protected $files = array();
23
24 protected $original_locale = null;
25 protected $original_language = null;
26 protected $original_l10n = null;
27 protected $forced_language = false;
28 protected $elementsByName = array();
29 protected $elementCounter = 0;
30
31 public function force_language() {
32 if ((!$this->forced_language) && $this->language && function_exists('qtrans_getLanguage')) {
33 global $q_config;
34 $this->original_language = $q_config['language'];
35
36 if ($this->language != $this->original_language) {
37 $this->original_locale =& $GLOBALS['wp_locale'];
38 $this->original_l10n =& $GLOBALS['l10n'];
39
40 unset($GLOBALS['wp_locale']);
41 unset($GLOBALS['l10n']);
42 $GLOBALS['l10n'] = array();
43
44 $GLOBALS['q_config']['language'] = $this->language;
45 load_default_textdomain();
46 load_plugin_textdomain( 'accua-form-api', false, ACCUA_FORM_API_PLUGIN_TEXTDOMAIN_PATH);
47 require_once( ABSPATH . WPINC . '/locale.php' );
48 $GLOBALS['wp_locale'] = new WP_Locale();
49 $GLOBALS['wp_locale']->register_globals();
50
51 $this->forced_language = true;
52 }
53 }
54 }
55
56 public function restore_language() {
57 if ($this->forced_language) {
58 unset($GLOBALS['wp_locale']);
59 unset($GLOBALS['l10n']);
60
61 $GLOBALS['q_config']['language'] = $this->original_language;
62 $GLOBALS['l10n'] =& $this->original_l10n;
63 $GLOBALS['wp_locale'] =& $this->original_locale;
64 if ($GLOBALS['wp_locale']) {
65 $GLOBALS['wp_locale']->register_globals();
66 }
67
68 $this->forced_language = false;
69 }
70 }
71
72 public function __sleep() {
73 $this->elements_sleep = $this->getElements();
74 return array('attributes', 'elements_sleep', 'error', 'view', 'prefix', 'widthSuffix', 'ajax', 'ajaxCallback', 'attributes', 'jQueryUITheme', 'resourcesPath', 'prevent', 'width', 'formID', 'buildID', 'validate_functions', 'submit_functions', 'stats', 'accua_ajax', 'locale', 'language', 'files');
75 }
76
77 public function __wakeup() {
78 foreach ($this->elements_sleep as $element) {
79 $this->addElement($element);
80 }
81 unset($this->elements_sleep);
82 if ($this->view) {
83 $this->view->setForm($this);
84 }
85 if ($this->error) {
86 $this->error->setForm($this);
87 }
88 }
89
90 public function addElement($element) {
91 $name = $element->getName();
92 if ($name) {
93 $this->elementsByName[$name] = $element;
94 }
95 $id = $element->getID();
96 if(empty($id)) {
97 $element->setID($this->attributes["id"] . "-element-" . $this->elementCounter);
98 }
99 $this->elementCounter++;
100 return parent::addElement($element);
101 }
102
103 public function getElementByName($name) {
104 if (isset($this->elementsByName[$name])) {
105 return $this->elementsByName[$name];
106 } else {
107 return null;
108 }
109 }
110
111 public function removeElement($element) {
112 foreach ($this->elements as $k => $e) {
113 if ($e === $element) {
114 $name = $element->getName();
115 if ($name) {
116 unset ($this->elementsByName[$name]);
117 }
118 unset($this->elements[$k]);
119 return true;
120 }
121 }
122 return false;
123 }
124
125 public static function sessionID() {
126 $sessionid = session_id();
127 if ($sessionid === '') {
128 session_start();
129 $sessionid = session_id();
130 }
131 return $sessionid;
132 }
133
134 public static function getBaseURL() {
135 static $ret = null;
136 if ($ret === null) {
137 $s = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";
138 $sp = strtolower($_SERVER["SERVER_PROTOCOL"]);
139 $protocol = substr($sp, 0, strpos($sp, "/")) . $s;
140 $port = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
141 $ret = $protocol . "://" . $_SERVER['SERVER_NAME'] . $port;
142 }
143 return $ret;
144 }
145
146 public static function create($baseid = 'pfbc', $params = array()) {
147 if (self::isSubmit() && (!self::isValid()) && ($baseid === self::$submittedID) && (!self::$submittedFormUsed)) {
148 self::$submittedFormUsed = true;
149 if (!(self::isValid() || empty(self::$submittedForm))) {
150 $form = self::$submittedForm;
151 $form->setValues(self::$submittedData);
152 return $form;
153 }
154 $form = new AccuaForm ($baseid, $params, self::$submittedBuildID);
155 $form->setValues(self::$submittedData);
156 } else {
157 $form = new AccuaForm($baseid, $params);
158 }
159 if (function_exists($baseid)) {
160 call_user_func($baseid, $form);
161 }
162 do_action('accua_form_alter', $baseid, $form);
163 return $form;
164 }
165
166 function __construct($id = 'pfbc', $params = array(), $buildid = '') {
167 if ($buildid === '') {
168 $buildid = 'accua-form_' . $id . '_' . uniqid();
169 }
170
171 if (is_array($params)) {
172 $params += array(
173 'width' => '',
174 'layout' => 'sidebyside',
175 );
176 //$width = $params['width'];
177 } else {
178 //$width = $params;
179 $params = array(
180 //'width' => $width,
181 'layout' => 'sidebyside',
182 );
183 }
184 $class = 'accua-form ' . $id;
185 switch ($params['layout']) {
186 case 'toplabel':
187 $this->view = new AccuaForm_View_Standard();
188 $class .= ' accua-form-view-standard';
189 break;
190 case 'sidebyside':
191 default:
192 $this->view = new AccuaForm_View_SideBySide(
193 '19',
194 array('labelPaddingRight' => '1')
195 );
196 $class .= ' accua-form-view-sidebyside';
197 }
198 $this->error = new AccuaForm_Error_Standard(array(
199 'errorfound' => '',
200 'errorsfound' => '',
201 ));
202 if ($width === ""){
203 $width = "100%";
204 }
205 $this->attributes = array(
206 'class' => $class,
207 'novalidate' => 'novalidate',
208 );
209
210 parent::__construct($buildid, $width);
211
212
213 $this->formID = $id;
214 $this->buildID = $buildid;
215 $this->addElement(new Element_Hidden('_AccuaForm_ID', $id));
216 $this->addElement(new Element_Hidden('_AccuaForm_buildID', $buildid));
217 $this->addElement(new Element_Hidden('_AccuaForm_wpnonce', wp_create_nonce( $buildid )));
218 $this->addElement(new Element_Hidden('_AccuaForm_jsuuid', ''));
219 $this->addElement(new Element_Hidden('_AccuaForm_referrer', ''));
220 $this->addElement(new Element_Hidden('_AccuaForm_user_agent', ''));
221 $this->addElement(new Element_Hidden('_AccuaForm_platform', ''));
222 $this->addElement(new Element_Hidden('_AccuaForm_tentatives', '0'));
223 $this->addElement(new Element_Hidden('_AccuaForm_submit_method', 'normal'));
224 $this->addElement(new Element_Hidden('_AccuaForm_hash', ''));
225 $this->addElement(new Element_Hidden('_AccuaForm_iv', ''));
226 $this->addElement(new Element_Hidden('_AccuaForm_data', ''));
227 /*
228 * - Prima di generare l'html del form, salva una copia serializzata compreso di codice SHA2, criptato, in _AccuaForm_serialized
229 * - Quando ricevi il form, decripta _AccuaForm_serialized e controlla che sia valido
230 *
231 * */
232
233 //$this->addElement(new Element_Hidden('PHPSESSID', self::sessionID()));
234 $this->prevent = array('jQuery', 'jQueryUI', 'jQueryUIButtons', 'focus', 'style');
235 $this->configure(array('action' => ''));
236
237 if (function_exists('qtrans_getLanguage')) {
238 $this->language = qtrans_getLanguage();
239 $this->locale = $GLOBALS['q_config']['locale'][$this->language];
240 } else {
241 $this->locale = get_locale();
242 $this->language = explode('_', $this->locale);
243 $this->language = $this->language[0];
244 }
245
246 global $post;
247 $pid = empty($post->ID) ? 0 : $post->ID;
248
249 $uri = isset($GLOBALS['q_config']['url_info']['original_url']) ? $GLOBALS['q_config']['url_info']['original_url'] : $_SERVER['REQUEST_URI'];
250
251 $url = self::getBaseURL() . $uri ;
252
253 $this->stats = array(
254 'pid' => $pid,
255 'ip' => $_SERVER['REMOTE_ADDR'], //updated after submit
256 'original_ip' => $_SERVER['REMOTE_ADDR'], //unreliable if using a static page caching system
257 'uri' => $uri,
258 'url' => $url,
259 'referrer' => $_SERVER['HTTP_REFERER'], //updated after submit using javascript
260 'original_referrer' => $_SERVER['HTTP_REFERER'], //unreliable if using a static page caching system
261 'lang' => $this->language,
262 'locale' => $this->locale,
263 'created' => time(),
264 'submitted' => null,
265 'user_agent' => '',
266 'platform' => '',
267 'tentatives' => '',
268 'submit_method' => '',
269 );
270
271 $this->view->setForm($this);
272 $this->error->setForm($this);
273 }
274
275 public static function isSubmit() {
276 if (self::$submitted !== null) {
277 return self::$submitted;
278 }
279 self::$submitted = false;
280 $sessid = self::sessionID();
281
282 if($_SERVER['REQUEST_METHOD'] == 'POST') {
283 self::$rawData = stripslashes_deep($_POST);
284 } else {
285 self::$rawData = stripslashes_deep($_GET);
286 }
287
288 if (empty(self::$rawData['_AccuaForm_ID']) || empty(self::$rawData['_AccuaForm_buildID']) || empty(self::$rawData['_AccuaForm_wpnonce']) /* || empty(self::$rawData['PHPSESSID']) */
289 || empty(self::$rawData['_AccuaForm_hash']) || empty(self::$rawData['_AccuaForm_iv']) || empty(self::$rawData['_AccuaForm_data'])) {
290 return false;
291 }
292
293 /*
294 if (self::$rawData['PHPSESSID'] !== $sessid) {
295 return false;
296 }
297 */
298
299 $id = self::$rawData['_AccuaForm_buildID'];
300 $form = self::wp_recover(self::$rawData['_AccuaForm_hash'], self::$rawData['_AccuaForm_iv'], self::$rawData['_AccuaForm_data']);
301
302 if (empty($form)) {
303 return false;
304 }
305
306 if ($form->formID !== self::$rawData['_AccuaForm_ID'] || $form->buildID !== $id ) {
307 return false;
308 }
309
310 /*
311 if (!wp_verify_nonce(self::$rawData['_AccuaForm_wpnonce'], $id)) {
312 return false;
313 }
314 */
315
316 /* check if already submitted from uuid and other parameters */
317 $already_submitted = false;
318 if (!empty(self::$rawData['_AccuaForm_jsuuid'])) {
319 if (preg_match("/^[a-z0-9]{25}$/", self::$rawData['_AccuaForm_jsuuid'])) {
320 $already_submitted_data = get_transient('accuaformsub_'.self::$rawData['_AccuaForm_jsuuid']);
321 if ($already_submitted_data && $already_submitted_data['buildID'] == $form->buildID) {
322 $form = $already_submitted_data['form'];
323 self::$submittedMessages = $already_submitted_data['submittedMessages'];
324 self::$valid = true;
325 $already_submitted = true;
326 }
327 } else {
328 return false;
329 }
330 }
331
332 if (!$already_submitted) {
333 $form->stats['submitted'] = time();
334 $form->stats['ip'] = $_SERVER['REMOTE_ADDR'];
335 $form->stats['referrer'] = self::$rawData['_AccuaForm_referrer'];
336 $form->stats['jsuuid'] = self::$rawData['_AccuaForm_jsuuid'];
337 $form->stats['user_agent'] = self::$rawData['_AccuaForm_user_agent'];
338 $form->stats['platform'] = self::$rawData['_AccuaForm_platform'];
339 $form->stats['tentatives'] = self::$rawData['_AccuaForm_tentatives'];
340 $form->stats['submit_method'] = self::$rawData['_AccuaForm_submit_method'];
341 }
342 self::$submitted = true;
343 self::$submittedID = $form->formID;
344 self::$submittedBuildID = $form->buildID;
345 self::$submittedForm = $form;
346 return true;
347 }
348
349 public static function isValid() {
350 if (!self::isSubmit()){
351 return null;
352 }
353 if (self::$valid !== null) {
354 return self::$valid;
355 }
356
357 //$subdata = array();
358 $id = self::$submittedBuildID;
359 //$form = self::wp_recover($id);
360 $form = self::$submittedForm;
361 $valid = true;
362
363 $form->force_language();
364
365 /*Any values/errors stored in the session for this form are cleared.*/
366 self::clearValues($id);
367 self::clearErrors($id);
368
369 self::$submittedData = array();
370 /*Each element's value is saved in the session and checked against any validation rules applied
371 to the element.*/
372 $elements = $form->getElements();
373 if(!empty($elements)) {
374 foreach($elements as $element) {
375 $invalidFile = false;
376 $name = $element->getName();
377 if(substr($name, -2) == "[]") {
378 $name = substr($name, 0, -2);
379 }
380
381 /*The File element must be handled differently b/c it uses the $_FILES superglobal and
382 not $_GET or $_POST.*/
383 if($element instanceof AccuaForm_Element_File) {
384 if (!empty($form->files[$name]['name'])) {
385 $value = $form->files[$name]['name'];
386 } else if ((!empty($_FILES[$name])) && ($_FILES[$name]['error'] != UPLOAD_ERR_NO_FILE)) {
387 //$file = $_FILES[$name];
388 //include_once( ABSPATH . '/wp-admin/includes/file.php' );
389 //$overrides = array( 'test_form' => false );
390 //$file = wp_handle_upload( $file, $overrides );
391
392 $file = $element->handle_upload($_FILES[$name]);
393 $value = $file['name'];
394
395 if (empty($file['errors'])) {
396 $form->files[$name] = $file;
397 } else {
398 self::setError($id, $file['errors'] , $name);
399 $valid = false;
400 $invalidFile = true;
401 }
402 } else {
403 $value = null;
404 }
405 } else if ($element instanceof Element_File){
406 $value = $_FILES[$name]["name"];
407 } else if (isset(self::$rawData[$name])) {
408 $value = self::$rawData[$name];
409 if(is_array($value)) {
410 foreach($value as $key => $value_i) {
411 $value[$key] = (string) $value_i;
412 }
413 } else {
414 $value = (string) $value;
415 }
416 } else {
417 $value = null;
418 }
419
420 //self::setSessionValue($id, $name, $value);
421
422 /*If a validation error is found, the error message is saved in the session along with
423 the element's name.*/
424 if(!$element->isValid($value)) {
425 self::setError($id, $element->getErrors(), $name);
426 $valid = false;
427 if ($element instanceof AccuaForm_Element_File) {
428 $invalidFile = true;
429 }
430 }
431
432 if($invalidFile) {
433 if (isset($file['tmp_name'])) {
434 unlink($element->getDestPath . $file['tmp_name']);
435 unset($form->files[$name]);
436 }
437 } else if($name !== '') {
438 self::$submittedData[$name] = $value;
439 }
440 }
441 }
442 $_SESSION["pfbc"][$id]["values"] = self::$submittedData;
443
444
445 if (function_exists(self::$submittedID.'_validate')) {
446 $valid = call_user_func(self::$submittedID.'_validate', $valid, self::$submittedID, self::$submittedData, $form);
447 }
448 $valid = apply_filters('accua_form_validate', $valid, self::$submittedID, self::$submittedData, $form);
449
450 asort($form->validate_functions);
451 foreach($form->validate_functions as $func => $priority){
452 if (function_exists($func)) {
453 $valid = call_user_func($func, $valid, self::$submittedID, self::$submittedData, $form);
454 }
455 }
456
457 if ($valid) {
458 if (function_exists(self::$submittedID.'_submit')) {
459 call_user_func(self::$submittedID.'_submit', self::$submittedID, self::$submittedData, $form);
460 }
461 do_action('accua_form_submit', self::$submittedID, self::$submittedData, $form);
462 asort($form->submit_functions);
463 foreach($form->submit_functions as $func => $priority){
464 if (function_exists($func)) {
465 call_user_func($func, self::$submittedID, self::$submittedData, $form);
466 }
467 }
468 }
469
470 /*If no validation errors were found, the form's session values are cleared.*/
471 /*
472 if($valid) {
473 if($clearValues)
474 self::clearValues($id);
475 self::clearErrors($id);
476 }
477 */
478
479 //TODO: Should i save here?
480 //$form->save();
481 //$_SESSION["pfbc"][$id]["form"] = serialize($form);
482
483 $form->restore_language();
484
485 if ($valid && self::$rawData['_AccuaForm_jsuuid'] ) {
486 set_transient('accuaformsub_'.self::$rawData['_AccuaForm_jsuuid'], array(
487 'buildID' => self::$submittedBuildID,
488 'form' => self::$submittedForm,
489 'submittedMessages' => self::$submittedMessages,
490 ), 86400);
491 }
492
493 return self::$valid = (bool)$valid;
494 }
495
496 public static function getSubmittedData() {
497 self::isValid();
498 return self::$submittedData;
499 }
500
501 public static function getSumbittedID() {
502 trigger_error('Use getSubmittedID() instead', (defined('E_USER_DEPRECATED')?E_USER_DEPRECATED:E_USER_NOTICE));
503 return self::getSubmittedID();
504 }
505
506 public static function getSubmittedID() {
507 if (self::isSubmit()) {
508 return self::$submittedID;
509 } else {
510 return null;
511 }
512 }
513
514 public static function getSubmittedForm() {
515 if (self::isSubmit()) {
516 return self::$submittedForm;
517 } else {
518 return null;
519 }
520 }
521
522 /*This method restores the serialized form instance.*/
523 protected static function wp_recover($hash,$iv,$data) {
524 /*
525 if(!empty($_SESSION["pfbc"][$id]["form"]))
526 return unserialize($_SESSION["pfbc"][$id]["form"]);
527 */
528 /*
529 $storename = 'accua_form_' . md5($id);
530 if ($stored = get_transient($storename)) {
531 return unserialize($stored);
532 }
533 */
534
535 $keys = get_option('accua_form_api_keys', array());
536 @ $hash = base64_decode($hash);
537 @ $iv = base64_decode($iv);
538 @ $data = base64_decode($data);
539
540 if (!($hash && $iv && $data)) {
541 return;
542 }
543
544 if (!class_exists('Crypt_Hash')) {
545 require_once('phpseclib-crypt/Hash.php');
546 }
547 $hasher = new Crypt_Hash('sha1');
548 $hasher->setKey($keys['hash']);
549 @ $hash2 = $hasher->hash($iv.$data);
550
551 if ($hash !== $hash2) {
552 return;
553 }
554
555 if (!class_exists('Crypt_AES')) {
556 require_once('phpseclib-crypt/AES.php');
557 }
558
559 $cipher = new Crypt_AES();
560 $cipher->setPassword($keys['aes']);
561 @ $cipher->setIV($iv);
562 @ $data = $cipher->decrypt($data);
563
564 if ($data) {
565 @ $form = unserialize($data);
566 if ($form) {
567 return $form;
568 }
569 }
570 }
571
572 protected function wp_save() {
573 /*
574 $storename = 'accua_form_' . md5($this->buildID);
575 //$serialized = isset($_SESSION["pfbc"][$this->buildID]["form"]) ? $_SESSION["pfbc"][$this->buildID]["form"] : serialize($this);
576 $serialized = serialize($this);
577 set_transient($storename, $serialized, 2764800); // 32 days
578 */
579
580 if (!class_exists('Crypt_Hash')) {
581 require_once('phpseclib-crypt/Hash.php');
582 }
583 if (!class_exists('Crypt_AES')) {
584 require_once('phpseclib-crypt/AES.php');
585 }
586
587 $keys = get_option('accua_form_api_keys', array());
588 if (!(isset($keys['aes']) && isset($keys['hash']))) {
589 accua_form_api_install();
590 $keys = get_option('accua_form_api_keys', array());
591 }
592
593 $data = serialize($this);
594 $iv = wp_generate_password(64,true,true);
595
596 $cipher = new Crypt_AES();
597 $cipher->setPassword($keys['aes']);
598 $cipher->setIV($iv);
599 $data = $cipher->encrypt($data);
600
601 $hasher = new Crypt_Hash('sha1');
602 $hasher->setKey($keys['hash']);
603 $hash = $hasher->hash($iv.$data);
604
605 $ret = array(
606 '_AccuaForm_hash' => base64_encode($hash),
607 '_AccuaForm_iv' => base64_encode($iv),
608 '_AccuaForm_data' => base64_encode($data),
609 );
610 if (isset($_SESSION["pfbc"][$this->buildID]["values"])) {
611 $_SESSION["pfbc"][$this->buildID]["values"] = $ret + $_SESSION["pfbc"][$this->buildID]["values"];
612 }
613 $this->setValues($ret);
614 return $ret;
615 }
616
617 public function getLocale() {
618 return $this->locale;
619 }
620
621 public function getLanguage() {
622 return $this->language;
623 }
624
625 public function addValidateFunction($function_name, $priority = 0) {
626 $this->validate_functions[$function_name] = $priority;
627 }
628
629 public function addSubmitFunction($function_name, $priority = 0) {
630 $this->submit_functions[$function_name] = $priority;
631 }
632
633 public function getSubmittedMessages(){
634 return self::$submittedMessages;
635 }
636
637 public function setSubmittedMessages($msg){
638 return self::$submittedMessages = $msg;
639 }
640
641 public function appendSubmittedmessages($msg){
642 return self::$submittedMessages .= $msg;
643 }
644
645 public function render($returnHTML = false) {
646 $this->wp_save();
647 if($returnHTML) {
648 ob_start();
649 }
650 parent::render(false);
651 if (!empty($this->accua_ajax)) {
652 $ajax_url = json_encode(admin_url('admin-ajax.php?action=accua_form_submit'), JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
653 $submit_fail_message = json_encode(__('Unable to submit the form, please retry', 'accua-form-api'), JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
654 $required_message = json_encode(__('Please fill in all required fields', 'accua-form-api'), JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
655 $valid_mail_message = json_encode(__('You have to enter a valid email address where required', 'accua-form-api'), JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
656 $js_buildid = preg_replace('/[^a-zA-Z0-9_]/m','_',$this->buildID);
657 $formid = $this->getId();
658 $hostname = json_encode($_SERVER['SERVER_NAME'], JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
659
660 $post_url = json_encode($this->stats['url'], JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
661
662
663 echo <<<JS
664 <script type="text/javascript">
665 //<![CDATA[
666 var _handle_ajax_submit_{$js_buildid} = function() {return true;}
667 var _handle_ajax_submit_complete_{$js_buildid} = function() {return false;}
668 var _handle_ajax_submit_timeout_{$js_buildid} = function() {return false;}
669 var _handle_ajax_submit_message_{$js_buildid} = function() {}
670 var _handle_ajax_submit_response_{$js_buildid} = function() {}
671
672 jQuery(function($) {
673 var thisform = $("#{$this->buildID}");
674 var ajax_enabled = {$hostname} == location.hostname ;
675
676 var response_messages = $("#_response_messages_{$this->buildID}");
677 if (! response_messages.length) {
678 response_messages = $("<div id='_response_messages_{$this->buildID}' class='accua-form-messages'></div>");
679 $("#{$this->buildID}").before(response_messages);
680 }
681 var throbbler = $("<span class='accua_form_api_throbbler'></span>");
682
683 var _ajax_submitting_{$js_buildid} = false;
684 var timeout_handler = false;
685 var timeout_count = 0;
686 var fail_count = 0;
687 var disabled_fields = false;
688
689 var jsuuid_field = $('input[name="_AccuaForm_jsuuid"]', thisform);
690 var jsuuid = jsuuid_field.val();
691 if (jsuuid == '') {
692 var chars = '0123456789abcdefghijklmnopqrstuvwxyz'.split('');
693 var radix = chars.length
694 for (i = 0; i < 25; i++) {
695 jsuuid += chars[0 | Math.random()*radix];
696 }
697 jsuuid_field.val(jsuuid);
698 }
699
700 _handle_ajax_submit_{$js_buildid} = function() {
701 if (_ajax_submitting_{$js_buildid}) {
702 return false;
703 }
704
705 JS;
706 $this->error->clear();
707 echo <<<JS
708
709 var valid_empty = true;
710 var valid_mail = true;
711
712 $("#{$this->buildID} .pfbc-element").removeClass('pfbc-invalid');
713
714 $('.accuaforms-field-required', thisform).each(function(){
715 var field = $(this);
716 var type = field.attr('type');
717
718 if (type === 'checkbox' || type === 'radio') {
719 if ($("[name='"+field.attr("name")+"']:checked", "#{$this->buildID}").length > 0) {
720 return true;
721 }
722 } else {
723 var val = field.val();
724 if (typeof(val) == "string") {
725 if (! val.match(/^\s*$/)) {
726 return true;
727 }
728 } else if ((typeof(val) == "object") && val && (val.length > 0)) {
729 return true;
730 } else if (val) {
731 return true;
732 }
733 }
734
735 valid_empty = false;
736 field.parents("#{$this->buildID} .pfbc-element").addClass('pfbc-invalid');
737 });
738
739 $('.pfbc-textbox[type="email"]', thisform).each(function(){
740 var field = $(this);
741
742 if (field.val().match(/^\s*$/)) {
743 return true;
744 }
745
746 if (field.val().match( /^([a-zA-Z0-9_.+%-])+@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9])+$/ )) {
747 return true;
748 }
749
750 valid_mail = false;
751 field.parents("#{$this->buildID} .pfbc-element").addClass('pfbc-invalid');
752
753 });
754
755 if (valid_empty && valid_mail) {
756 thisform.append(throbbler);
757 _ajax_submitting_{$js_buildid} = true;
758 $('input[name="_AccuaForm_tentatives"]', thisform).val(fail_count);
759 disabled_fields = $("input, textarea, button, select", thisform).not('[type="submit"]').not(':disabled');
760 disabled_fields.attr('readonly','readonly');
761 timeout_count = 0;
762 if (ajax_enabled) {
763 $("#submit_target_{$js_buildid}").attr('src','').removeAttr('src');
764 timeout_handler = setTimeout(_handle_ajax_submit_timeout_{$js_buildid}, 5000);
765 }
766 return true;
767 } else {
768 var message = '';
769 if (!valid_empty) {
770 message += '<li>' + $required_message + '</li>';
771 }
772 if (!valid_mail) {
773 message += '<li>' + $valid_mail_message + '</li>';
774 }
775 thisform.append('<div class="pfbc-error ui-state-error ui-corner-all"><ul>' + message + '</ul></div>');
776 return false;
777 }
778 }
779
780
781 _handle_ajax_submit_timeout_{$js_buildid} = function() {
782 if (_ajax_submitting_{$js_buildid}) {
783 if (timeout_count < 60) {
784 timeout_count++;
785 timeout_handler = setTimeout(_handle_ajax_submit_timeout_{$js_buildid}, 500);
786 _handle_ajax_submit_complete_{$js_buildid}();
787 } else {
788 timeout_handler = false;
789 _handle_ajax_submit_complete_{$js_buildid}();
790 if (_ajax_submitting_{$js_buildid}) {
791 _handle_ajax_submit_response_{$js_buildid}(false);
792 }
793 }
794 }
795 }
796
797 _handle_ajax_submit_complete_{$js_buildid} = function() {
798 if (_ajax_submitting_{$js_buildid}) {
799 var response = false;
800 try {
801 var responsedoc = frames['submit_target_{$js_buildid}'].document;
802 if (responsedoc.getElementById("accua-form-ajax-response-loaded")) {
803 response = $.parseJSON(responsedoc.getElementById("accua-form-ajax-response").innerHTML);
804 }
805 } catch (err) {
806 response = false;
807 }
808 if (response) {
809 return _handle_ajax_submit_response_{$js_buildid} (response);
810 }
811 }
812 }
813
814 _handle_ajax_submit_message_{$js_buildid} = function(message) {
815 if (_ajax_submitting_{$js_buildid}) {
816 var response = false;
817 try {
818 response = $.parseJSON(message.data);
819 if (response.jsuuid != jsuuid || response.buildID != "{$this->buildID}") {
820 response = false;
821 }
822 } catch (err) {
823 response = false;
824 }
825 if (response) {
826 return _handle_ajax_submit_response_{$js_buildid} (response);
827 }
828 }
829 }
830
831 _handle_ajax_submit_response_{$js_buildid} = function(response) {
832 if (_ajax_submitting_{$js_buildid}) {
833 if(response && typeof(response) == "object" && typeof(response.submitted) == "boolean") {
834 response_messages.html(response.messages);
835 if (response.submitted) {
836 if (response.valid) {
837 JS;
838 /*A callback function can be specified to handle any post submission events.*/
839 if(!empty($this->ajaxCallback)) {
840 echo $this->ajaxCallback, "(response);";
841 } else {
842 echo "$('#{$this->buildID}').hide();";
843 }
844 echo <<<JS
845 } else {
846 JS;
847 $this->error->applyAjaxErrorResponse();
848 echo <<<JS
849
850 for (var name in response.files) {
851 $(".pfbc-fieldwrap:has(input[type='file'][name='"+name+"'])", thisform).html(response.files[name]);
852 }
853
854 $("input[name='_AccuaForm_hash']",thisform).val(response._AccuaForm_hash);
855 $("input[name='_AccuaForm_iv']", thisform).val(response._AccuaForm_iv);
856 $("input[name='_AccuaForm_data']",thisform).val(response._AccuaForm_data);
857
858 disabled_fields.removeAttr('readonly');
859 }
860 }
861 } else {
862 fail_count++;
863 if (fail_count > 2) {
864 ajax_enabled = false;
865 thisform.attr("action", {$post_url} );
866 thisform.removeAttr("target");
867 $('input[name="_AccuaForm_submit_method"]', thisform).val('fallback');
868 }
869 thisform.append('<div class="pfbc-error ui-state-error ui-corner-all">' + $submit_fail_message + '</div>');
870 }
871 $('.accua_forms_show_recaptcha_button', thisform).click();
872 if (((typeof accuaform_recaptcha2_initialized) != 'undefined') && accuaform_recaptcha2_initialized) {
873 $('.accua_forms_recaptcha2_container', thisform).each(function(){
874 accua_forms_reload_recaptcha2($(this).attr('id'));
875 });
876 }
877 throbbler.remove();
878 _ajax_submitting_{$js_buildid} = false;
879 if (timeout_handler) {
880 clearTimeout(timeout_handler);
881 timeout_handler = false;
882 }
883 }
884 }
885
886 if (ajax_enabled) {
887 thisform.attr("action", {$ajax_url} );
888 thisform.attr("target","submit_target_{$js_buildid}");
889 try {
890 window.addEventListener('message', _handle_ajax_submit_message_{$js_buildid}, false);
891 } catch (e) { }
892 $('input[name="_AccuaForm_submit_method"]', thisform).val('iframe');
893 } else {
894 thisform.attr("action", {$post_url} );
895 }
896 thisform.attr("onsubmit","return _handle_ajax_submit_{$js_buildid}()");
897 });
898 //]]>
899 </script>
900 <iframe id="submit_target_{$js_buildid}" name="submit_target_{$js_buildid}" onload="_handle_ajax_submit_complete_{$js_buildid}()" onerror="_handle_ajax_submit_complete_{$js_buildid}()" style="width:0;height:0;border:0px solid #fff"></iframe>
901 JS;
902 }
903
904 echo <<<JSREFERRER
905 <script type="text/javascript">
906 jQuery(function($){
907 var referrerfield = $("#{$this->buildID} input[name='_AccuaForm_referrer']");
908 if (referrerfield.val() == '') {
909 referrerfield.val(document.referrer);
910 }
911 $("#{$this->buildID} input[name='_AccuaForm_user_agent']").val(navigator.userAgent);
912 $("#{$this->buildID} input[name='_AccuaForm_platform']").val(navigator.platform);
913 });
914 </script>
915 JSREFERRER;
916
917 if($returnHTML) {
918 $html = ob_get_contents();
919 ob_end_clean();
920 return $html;
921 }
922 }
923
924 protected function renderJS() {
925 $this->renderJSFiles();
926
927 echo '<script type="text/javascript">';
928 $this->view->renderJS();
929 foreach($this->elements as $element)
930 $element->renderJS();
931
932 $id = $this->attributes["id"];
933
934 echo 'jQuery(document).ready(function() {';
935 /*jQuery is used to set the focus of the form's initial element.*/
936 if(!in_array("focus", $this->prevent))
937 echo 'jQuery("#', $id, ' :input:visible:enabled:first").focus();';
938
939 $this->view->jQueryDocumentReady();
940 foreach($this->elements as $element)
941 $element->jQueryDocumentReady();
942
943 /*For ajax, an anonymous onsubmit javascript function is bound to the form using jQuery. jQuery's
944 serialize function is used to grab each element's name/value pair.* /
945 if(!empty($this->ajax)) {
946 echo 'jQuery("#', $id, '").bind("submit", function() {';
947 $this->error->clear();
948 echo <<<JS
949 jQuery.ajax({
950 url: "{$this->attributes["action"]}",
951 type: "{$this->attributes["method"]}",
952 data: jQuery("#$id").serialize(),
953 success: function(response) {
954 if(response != undefined && typeof response == "object" && response.errors) {
955 JS;
956 $this->error->applyAjaxErrorResponse();
957 echo <<<JS
958 jQuery("html, body").animate({ scrollTop: jQuery("#$id").offset().top }, 500 );
959 }
960 else {
961 JS;
962 /*A callback function can be specified to handle any post submission events.* /
963 if(!empty($this->ajaxCallback))
964 echo $this->ajaxCallback, "(response);";
965 echo <<<JS
966 }
967 }
968 });
969 return false;
970 });
971
972 JS;
973 }
974 */
975 echo <<<JS
976 });
977 </script>
978 JS;
979 }
980
981 protected function renderCSS() {
982
983 }
984
985 public function getAjax() {
986 return $this->accua_ajax;
987 }
988
989 public function getFile($fieldname) {
990 if (isset($this->files[$fieldname])) {
991 return $this->files[$fieldname];
992 }
993 }
994
995 public function renameFile($fieldname, $newname) {
996 if (isset($this->files[$fieldname])) {
997 $file = $this->files[$fieldname];
998 @ $renamed = rename($file['dest_path'].$file['tmp_name'], $file['dest_path'].$newname);
999 if ($renamed) {
1000 $this->files[$fieldname]['new_name'] = $newname;
1001 return true;
1002 }
1003 }
1004 return false;
1005 }
1006
1007 public static function renderAjaxErrorResponse($return = false) {
1008 if ($form = self::$submittedForm) {
1009 $form->error->setForm($form);
1010 return $form->error->renderAjaxErrorResponse($return);
1011 }
1012 }
1013
1014 public function setFormError($errors, $element = '') {
1015 return self::setError($this->buildID, $errors, $element);
1016 }
1017
1018 public function setClass($class) {
1019 if(!empty($this->attributes["class"]))
1020 $this->attributes["class"] .= " " . $class;
1021 else
1022 $this->attributes["class"] = $class;
1023 }
1024
1025 public static function ajaxSubmit() {
1026 $ret = array(
1027 'valid' => false,
1028 'messages' => self::getSubmittedMessages(),
1029 'jsuuid' => self::$rawData['_AccuaForm_jsuuid'],
1030 'buildID' => self::$submittedBuildID,
1031 'files' => array(),
1032 );
1033 if ($ret['submitted'] = self::isSubmit()){
1034 if ($ret['valid'] = self::isValid()) {
1035
1036 } else {
1037 $ret['errors'] = self::renderAjaxErrorResponse(true);
1038 }
1039 $form = self::$submittedForm;
1040 foreach ($form->files as $fieldname => $file) {
1041 if (!empty($file['name'])) {
1042 $ret['files'][$fieldname] = $form->getElementByName($fieldname)->getAlreadySubmittedText();
1043 }
1044 }
1045 $ret += $form->wp_save();
1046 }
1047 return $ret;
1048 }
1049 }
1050