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

1,015 lines 32.2 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 trigger_error('Use getSubmittedID() instead', (defined('E_USER_DEPRECATED')?E_USER_DEPRECATED:E_USER_NOTICE));
482 return self::getSubmittedID();
483 }
484
485 public static function getSubmittedID() {
486 if (self::isSubmit()) {
487 return self::$submittedID;
488 } else {
489 return null;
490 }
491 }
492
493 public static function getSubmittedForm() {
494 if (self::isSubmit()) {
495 return self::$submittedForm;
496 } else {
497 return null;
498 }
499 }
500
501 /*This method restores the serialized form instance.*/
502 protected static function wp_recover($hash,$iv,$data) {
503 /*
504 if(!empty($_SESSION["pfbc"][$id]["form"]))
505 return unserialize($_SESSION["pfbc"][$id]["form"]);
506 */
507 /*
508 $storename = 'accua_form_' . md5($id);
509 if ($stored = get_transient($storename)) {
510 return unserialize($stored);
511 }
512 */
513
514 $keys = get_option('accua_form_api_keys', array());
515 @ $hash = base64_decode($hash);
516 @ $iv = base64_decode($iv);
517 @ $data = base64_decode($data);
518
519 if (!($hash && $iv && $data)) {
520 return;
521 }
522
523 if (!class_exists('Crypt_Hash')) {
524 require_once('phpseclib-crypt/Hash.php');
525 }
526 $hasher = new Crypt_Hash('sha1');
527 $hasher->setKey($keys['hash']);
528 @ $hash2 = $hasher->hash($iv.$data);
529
530 if ($hash !== $hash2) {
531 return;
532 }
533
534 if (!class_exists('Crypt_AES')) {
535 require_once('phpseclib-crypt/AES.php');
536 }
537
538 $cipher = new Crypt_AES();
539 $cipher->setPassword($keys['aes']);
540 @ $cipher->setIV($iv);
541 @ $data = $cipher->decrypt($data);
542
543 if ($data) {
544 @ $form = unserialize($data);
545 if ($form) {
546 return $form;
547 }
548 }
549 }
550
551 protected function wp_save() {
552 /*
553 $storename = 'accua_form_' . md5($this->buildID);
554 //$serialized = isset($_SESSION["pfbc"][$this->buildID]["form"]) ? $_SESSION["pfbc"][$this->buildID]["form"] : serialize($this);
555 $serialized = serialize($this);
556 set_transient($storename, $serialized, 2764800); // 32 days
557 */
558
559 if (!class_exists('Crypt_Hash')) {
560 require_once('phpseclib-crypt/Hash.php');
561 }
562 if (!class_exists('Crypt_AES')) {
563 require_once('phpseclib-crypt/AES.php');
564 }
565
566 $keys = get_option('accua_form_api_keys', array());
567 if (!(isset($keys['aes']) && isset($keys['hash']))) {
568 accua_form_api_install();
569 $keys = get_option('accua_form_api_keys', array());
570 }
571
572 $data = serialize($this);
573 $iv = wp_generate_password(64,true,true);
574
575 $cipher = new Crypt_AES();
576 $cipher->setPassword($keys['aes']);
577 $cipher->setIV($iv);
578 $data = $cipher->encrypt($data);
579
580 $hasher = new Crypt_Hash('sha1');
581 $hasher->setKey($keys['hash']);
582 $hash = $hasher->hash($iv.$data);
583
584 $ret = array(
585 '_AccuaForm_hash' => base64_encode($hash),
586 '_AccuaForm_iv' => base64_encode($iv),
587 '_AccuaForm_data' => base64_encode($data),
588 );
589 if (isset($_SESSION["pfbc"][$this->buildID]["values"])) {
590 $_SESSION["pfbc"][$this->buildID]["values"] = $ret + $_SESSION["pfbc"][$this->buildID]["values"];
591 }
592 $this->setValues($ret);
593 return $ret;
594 }
595
596 public function getLocale() {
597 return $this->locale;
598 }
599
600 public function getLanguage() {
601 return $this->language;
602 }
603
604 public function addValidateFunction($function_name, $priority = 0) {
605 $this->validate_functions[$function_name] = $priority;
606 }
607
608 public function addSubmitFunction($function_name, $priority = 0) {
609 $this->submit_functions[$function_name] = $priority;
610 }
611
612 public function getSubmittedMessages(){
613 return self::$submittedMessages;
614 }
615
616 public function setSubmittedMessages($msg){
617 return self::$submittedMessages = $msg;
618 }
619
620 public function appendSubmittedmessages($msg){
621 return self::$submittedMessages .= $msg;
622 }
623
624 public function render($returnHTML = false) {
625 $this->wp_save();
626 if($returnHTML) {
627 ob_start();
628 }
629 parent::render(false);
630 if (!empty($this->accua_ajax)) {
631 $ajax_url = json_encode(admin_url('admin-ajax.php?action=accua_form_submit'));
632 $submit_fail_message = json_encode(__('Unable to submit the form, please retry', 'accua-form-api'));
633 $required_message = json_encode(__('Please fill in all required fields', 'accua-form-api'));
634 $valid_mail_message = json_encode(__('You have to enter a valid email address where required', 'accua-form-api'));
635 $js_buildid = preg_replace('/[^a-zA-Z0-9_]/m','_',$this->buildID);
636 $formid = $this->getId();
637 $hostname = json_encode($_SERVER['SERVER_NAME']);
638
639 $post_url = json_encode($this->stats['url']);
640
641
642 echo <<<JS
643 <script type="text/javascript">
644 //<![CDATA[
645 var _handle_ajax_submit_{$js_buildid} = function() {return true;}
646 var _handle_ajax_submit_complete_{$js_buildid} = function() {return false;}
647 var _handle_ajax_submit_timeout_{$js_buildid} = function() {return false;}
648 var _handle_ajax_submit_message_{$js_buildid} = function() {}
649 var _handle_ajax_submit_response_{$js_buildid} = function() {}
650
651 jQuery(function($) {
652 var thisform = $("#{$this->buildID}");
653 var ajax_enabled = {$hostname} == location.hostname ;
654
655 var response_messages = $("#_response_messages_{$this->buildID}");
656 if (! response_messages.length) {
657 response_messages = $("<div id='_response_messages_{$this->buildID}' class='accua-form-messages'></div>");
658 $("#{$this->buildID}").before(response_messages);
659 }
660 var throbbler = $("<span class='accua_form_api_throbbler'></span>");
661
662 var _ajax_submitting_{$js_buildid} = false;
663 var timeout_handler = false;
664 var timeout_count = 0;
665 var fail_count = 0;
666 var disabled_fields = false;
667
668 var jsuuid_field = $('input[name="_AccuaForm_jsuuid"]', thisform);
669 var jsuuid = jsuuid_field.val();
670 if (jsuuid == '') {
671 var chars = '0123456789abcdefghijklmnopqrstuvwxyz'.split('');
672 var radix = chars.length
673 for (i = 0; i < 25; i++) {
674 jsuuid += chars[0 | Math.random()*radix];
675 }
676 jsuuid_field.val(jsuuid);
677 }
678
679 _handle_ajax_submit_{$js_buildid} = function() {
680 if (_ajax_submitting_{$js_buildid}) {
681 return false;
682 }
683
684 JS;
685 $this->error->clear();
686 echo <<<JS
687
688 var valid_empty = true;
689 var valid_mail = true;
690
691 $("#{$this->buildID} .pfbc-element").removeClass('pfbc-invalid');
692
693 $('.accuaforms-field-required', thisform).each(function(){
694 var field = $(this);
695
696 if (field.attr('type') === 'checkbox') {
697 if (field.is(':checked')) {
698 return true;
699 }
700 } else {
701 if (! field.val().match(/^\s*$/)) {
702 return true;
703 }
704 }
705
706 valid_empty = false;
707 field.parents("#{$this->buildID} .pfbc-element").addClass('pfbc-invalid');
708 });
709
710 $('.pfbc-textbox[type="email"]', thisform).each(function(){
711 var field = $(this);
712
713 if (field.val().match(/^\s*$/)) {
714 return true;
715 }
716
717 if (field.val().match( /^([a-zA-Z0-9_.+%-])+@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9])+$/ )) {
718 return true;
719 }
720
721 valid_mail = false;
722 field.parents("#{$this->buildID} .pfbc-element").addClass('pfbc-invalid');
723
724 });
725
726 if (valid_empty && valid_mail) {
727 thisform.append(throbbler);
728 _ajax_submitting_{$js_buildid} = true;
729 $('input[name="_AccuaForm_tentatives"]', thisform).val(fail_count);
730 disabled_fields = $("input, textarea, button, select").not('[type="submit"]').not(':disabled');
731 disabled_fields.attr('readonly','readonly');
732 timeout_count = 0;
733 if (ajax_enabled) {
734 $("#submit_target_{$js_buildid}").attr('src','').removeAttr('src');
735 timeout_handler = setTimeout(_handle_ajax_submit_timeout_{$js_buildid}, 5000);
736 }
737 return true;
738 } else {
739 var message = '';
740 if (!valid_empty) {
741 message += $required_message + '<br />';
742 }
743 if (!valid_mail) {
744 message += $valid_mail_message + '<br />';
745 }
746 thisform.append('<div class="pfbc-error ui-state-error ui-corner-all">' + message + '</div>');
747 return false;
748 }
749 }
750
751
752 _handle_ajax_submit_timeout_{$js_buildid} = function() {
753 if (_ajax_submitting_{$js_buildid}) {
754 if (timeout_count < 60) {
755 timeout_count++;
756 timeout_handler = setTimeout(_handle_ajax_submit_timeout_{$js_buildid}, 500);
757 _handle_ajax_submit_complete_{$js_buildid}();
758 } else {
759 timeout_handler = false;
760 _handle_ajax_submit_complete_{$js_buildid}();
761 if (_ajax_submitting_{$js_buildid}) {
762 _handle_ajax_submit_response_{$js_buildid}(false);
763 }
764 }
765 }
766 }
767
768 _handle_ajax_submit_complete_{$js_buildid} = function() {
769 if (_ajax_submitting_{$js_buildid}) {
770 var response = false;
771 try {
772 var responsedoc = frames['submit_target_{$js_buildid}'].document;
773 if (responsedoc.getElementById("accua-form-ajax-response-loaded")) {
774 response = $.parseJSON(responsedoc.getElementById("accua-form-ajax-response").innerHTML);
775 }
776 } catch (err) {
777 response = false;
778 }
779 if (response) {
780 return _handle_ajax_submit_response_{$js_buildid} (response);
781 }
782 }
783 }
784
785 _handle_ajax_submit_message_{$js_buildid} = function(message) {
786 if (_ajax_submitting_{$js_buildid}) {
787 var response = false;
788 try {
789 response = $.parseJSON(message.data);
790 if (response.jsuuid != jsuuid || response.buildID != "{$this->buildID}") {
791 response = false;
792 }
793 } catch (err) {
794 response = false;
795 }
796 if (response) {
797 return _handle_ajax_submit_response_{$js_buildid} (response);
798 }
799 }
800 }
801
802 _handle_ajax_submit_response_{$js_buildid} = function(response) {
803 if (_ajax_submitting_{$js_buildid}) {
804 if(response && typeof(response) == "object" && typeof(response.submitted) == "boolean") {
805 response_messages.html(response.messages);
806 if (response.submitted) {
807 if (response.valid) {
808 JS;
809 /*A callback function can be specified to handle any post submission events.*/
810 if(!empty($this->ajaxCallback)) {
811 echo $this->ajaxCallback, "(response);";
812 } else {
813 echo "$('#{$this->buildID}').hide();";
814 }
815 echo <<<JS
816 } else {
817 JS;
818 $this->error->applyAjaxErrorResponse();
819 echo <<<JS
820
821 for (var name in response.files) {
822 $(".pfbc-fieldwrap:has(input[type='file'][name='"+name+"'])", thisform).html(response.files[name]);
823 }
824
825 $("input[name='_AccuaForm_hash']",thisform).val(response._AccuaForm_hash);
826 $("input[name='_AccuaForm_iv']", thisform).val(response._AccuaForm_iv);
827 $("input[name='_AccuaForm_data']",thisform).val(response._AccuaForm_data);
828
829 disabled_fields.removeAttr('readonly');
830 }
831 }
832 } else {
833 fail_count++;
834 if (fail_count > 2) {
835 ajax_enabled = false;
836 thisform.attr("action", {$post_url} );
837 thisform.removeAttr("target");
838 $('input[name="_AccuaForm_submit_method"]', thisform).val('fallback');
839 }
840 thisform.append('<div class="pfbc-error ui-state-error ui-corner-all">' + $submit_fail_message + '</div>');
841 }
842 throbbler.remove();
843 _ajax_submitting_{$js_buildid} = false;
844 if (timeout_handler) {
845 clearTimeout(timeout_handler);
846 timeout_handler = false;
847 }
848 }
849 }
850
851 if (ajax_enabled) {
852 thisform.attr("action", {$ajax_url} );
853 thisform.attr("target","submit_target_{$js_buildid}");
854 try {
855 window.addEventListener('message', _handle_ajax_submit_message_{$js_buildid}, false);
856 } catch (e) { }
857 $('input[name="_AccuaForm_submit_method"]', thisform).val('iframe');
858 } else {
859 thisform.attr("action", {$post_url} );
860 }
861 thisform.attr("onsubmit","return _handle_ajax_submit_{$js_buildid}()");
862 });
863 //]]>
864 </script>
865 <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>
866 JS;
867 }
868
869 echo <<<JSREFERRER
870 <script type="text/javascript">
871 jQuery(function($){
872 var referrerfield = $("#{$this->buildID} input[name='_AccuaForm_referrer']");
873 if (referrerfield.val() == '') {
874 referrerfield.val(document.referrer);
875 }
876 $("#{$this->buildID} input[name='_AccuaForm_user_agent']").val(navigator.userAgent);
877 $("#{$this->buildID} input[name='_AccuaForm_platform']").val(navigator.platform);
878 });
879 </script>
880 JSREFERRER;
881
882 if($returnHTML) {
883 $html = ob_get_contents();
884 ob_end_clean();
885 return $html;
886 }
887 }
888
889 protected function renderJS() {
890 $this->renderJSFiles();
891
892 echo '<script type="text/javascript">';
893 $this->view->renderJS();
894 foreach($this->elements as $element)
895 $element->renderJS();
896
897 $id = $this->attributes["id"];
898
899 echo 'jQuery(document).ready(function() {';
900 /*jQuery is used to set the focus of the form's initial element.*/
901 if(!in_array("focus", $this->prevent))
902 echo 'jQuery("#', $id, ' :input:visible:enabled:first").focus();';
903
904 $this->view->jQueryDocumentReady();
905 foreach($this->elements as $element)
906 $element->jQueryDocumentReady();
907
908 /*For ajax, an anonymous onsubmit javascript function is bound to the form using jQuery. jQuery's
909 serialize function is used to grab each element's name/value pair.* /
910 if(!empty($this->ajax)) {
911 echo 'jQuery("#', $id, '").bind("submit", function() {';
912 $this->error->clear();
913 echo <<<JS
914 jQuery.ajax({
915 url: "{$this->attributes["action"]}",
916 type: "{$this->attributes["method"]}",
917 data: jQuery("#$id").serialize(),
918 success: function(response) {
919 if(response != undefined && typeof response == "object" && response.errors) {
920 JS;
921 $this->error->applyAjaxErrorResponse();
922 echo <<<JS
923 jQuery("html, body").animate({ scrollTop: jQuery("#$id").offset().top }, 500 );
924 }
925 else {
926 JS;
927 /*A callback function can be specified to handle any post submission events.* /
928 if(!empty($this->ajaxCallback))
929 echo $this->ajaxCallback, "(response);";
930 echo <<<JS
931 }
932 }
933 });
934 return false;
935 });
936
937 JS;
938 }
939 */
940 echo <<<JS
941 });
942 </script>
943 JS;
944 }
945
946 protected function renderCSS() {
947
948 }
949
950 public function getAjax() {
951 return $this->accua_ajax;
952 }
953
954 public function getFile($fieldname) {
955 if (isset($this->files[$fieldname])) {
956 return $this->files[$fieldname];
957 }
958 }
959
960 public function renameFile($fieldname, $newname) {
961 if (isset($this->files[$fieldname])) {
962 $file = $this->files[$fieldname];
963 @ $renamed = rename($file['dest_path'].$file['tmp_name'], $file['dest_path'].$newname);
964 if ($renamed) {
965 $this->files[$fieldname]['new_name'] = $newname;
966 return true;
967 }
968 }
969 return false;
970 }
971
972 public static function renderAjaxErrorResponse($return = false) {
973 if ($form = self::$submittedForm) {
974 $form->error->setForm($form);
975 return $form->error->renderAjaxErrorResponse($return);
976 }
977 }
978
979 public function setFormError($errors, $element = '') {
980 return self::setError($this->buildID, $errors, $element);
981 }
982
983 public function setClass($class) {
984 if(!empty($this->attributes["class"]))
985 $this->attributes["class"] .= " " . $class;
986 else
987 $this->attributes["class"] = $class;
988 }
989
990 public static function ajaxSubmit() {
991 $ret = array(
992 'valid' => false,
993 'messages' => self::getSubmittedMessages(),
994 'jsuuid' => self::$rawData['_AccuaForm_jsuuid'],
995 'buildID' => self::$submittedBuildID,
996 'files' => array(),
997 );
998 if ($ret['submitted'] = self::isSubmit()){
999 if ($ret['valid'] = self::isValid()) {
1000
1001 } else {
1002 $ret['errors'] = self::renderAjaxErrorResponse(true);
1003 }
1004 $form = self::$submittedForm;
1005 foreach ($form->files as $fieldname => $file) {
1006 if (!empty($file['name'])) {
1007 $ret['files'][$fieldname] = $form->getElementByName($fieldname)->getAlreadySubmittedText();
1008 }
1009 }
1010 $ret += $form->wp_save();
1011 }
1012 return $ret;
1013 }
1014 }
1015