PluginProbe
Contact Forms by Cimatti / 1.0
Contact Forms by Cimatti v1.0
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.0, at AccuaForm.php

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