Contact Form 7 - Version 3.3

Version Description

  • New: Introduce a new special mail tag [_user_agent] for user agent information.
  • New: Make WordPress Comment Blacklist applicable for inputs through contact forms.
  • New: Introduce new form of mail tag [_raw_{field name}]. This allows to output raw user input those have not been modified with pipes.
  • New: Make mail tags available in response messages.
  • New: Introduce new additional setting on_submit. It works like on_sent_ok and has one-line JavaScript code, but on_submit code is fired regardless of whether or not the mail has been sent successfully.
  • New: Introduce 5 new jQuery custom event triggers (invalid.wpcf7, spam.wpcf7, mailsent.wpcf7, mailfailed.wpcf7, submit.wpcf7).
  • Fix: Nonce used in a form have been changed to have no time limit.
  • Fix: Make every post metas key have underscore prefix.
  • The jQuery Form Plugin (jquery.form.js) has been updated to 3.15 and compressed with YUI compressor.
  • The required WordPress version has been changed and now requires WordPress 3.3 or higher. If you use WordPress 3.2, you will need to upgrade WordPress.
  • Translations for Arabic and German have been updated.

=

Download this release

Release Info

Developer takayukister
Plugin Icon 128x128 Contact Form 7
Version 3.3
Comparing to
See all releases

Code changes from version 3.2.1 to 3.3

admin/admin.php CHANGED
@@ -235,34 +235,6 @@ function wpcf7_admin_enqueue_scripts( $hook_suffix ) {
235
  'tagGenerators' => wpcf7_tag_generators() ) );
236
  }
237
 
238
- add_action( 'admin_print_footer_scripts', 'wpcf7_print_taggenerators_json', 20 );
239
-
240
- function wpcf7_print_taggenerators_json() { // for backward compatibility
241
- global $plugin_page, $wpcf7_tag_generators;
242
-
243
- if ( ! version_compare( get_bloginfo( 'version' ), '3.3-dev', '<' ) )
244
- return;
245
-
246
- if ( ! isset( $plugin_page ) || 'wpcf7' != $plugin_page )
247
- return;
248
-
249
- $taggenerators = array();
250
-
251
- foreach ( (array) $wpcf7_tag_generators as $name => $tg ) {
252
- $taggenerators[$name] = array_merge(
253
- (array) $tg['options'],
254
- array( 'title' => $tg['title'], 'content' => $tg['content'] ) );
255
- }
256
-
257
- ?>
258
- <script type="text/javascript">
259
- /* <![CDATA[ */
260
- _wpcf7.tagGenerators = <?php echo json_encode( $taggenerators ) ?>;
261
- /* ]]> */
262
- </script>
263
- <?php
264
- }
265
-
266
  function wpcf7_admin_management_page() {
267
  global $wpcf7_contact_form;
268
 
235
  'tagGenerators' => wpcf7_tag_generators() ) );
236
  }
237
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  function wpcf7_admin_management_page() {
239
  global $wpcf7_contact_form;
240
 
includes/classes.php CHANGED
@@ -65,11 +65,14 @@ class WPCF7_ContactForm {
65
  $this->id = $post->ID;
66
  $this->title = $post->post_title;
67
 
68
- $this->form = get_post_meta( $post->ID, 'form', true );
69
- $this->mail = get_post_meta( $post->ID, 'mail', true );
70
- $this->mail_2 = get_post_meta( $post->ID, 'mail_2', true );
71
- $this->messages = get_post_meta( $post->ID, 'messages', true );
72
- $this->additional_settings = get_post_meta( $post->ID, 'additional_settings', true );
 
 
 
73
 
74
  $this->upgrade();
75
  }
@@ -77,6 +80,17 @@ class WPCF7_ContactForm {
77
  do_action_ref_array( 'wpcf7_contact_form', array( &$this ) );
78
  }
79
 
 
 
 
 
 
 
 
 
 
 
 
80
  // Return true if this form is the same one as currently POSTed.
81
  function is_posted() {
82
  if ( ! isset( $_POST['_wpcf7_unit_tag'] ) || empty( $_POST['_wpcf7_unit_tag'] ) )
@@ -119,16 +133,14 @@ class WPCF7_ContactForm {
119
  $class = 'wpcf7-form';
120
 
121
  if ( $this->is_posted() ) {
122
- if ( ! empty( $_POST['_wpcf7_validation_errors'] ) ) {
123
  $class .= ' invalid';
124
- } elseif ( ! empty( $_POST['_wpcf7_mail_sent'] ) ) {
125
- if ( ! empty( $_POST['_wpcf7_mail_sent']['spam'] ) )
126
- $class .= ' spam';
127
- elseif ( ! empty( $_POST['_wpcf7_mail_sent']['ok'] ) )
128
- $class .= ' sent';
129
- else
130
- $class .= ' failed';
131
- }
132
  }
133
 
134
  $class = apply_filters( 'wpcf7_form_class_attr', $class );
@@ -159,7 +171,7 @@ class WPCF7_ContactForm {
159
  '_wpcf7_unit_tag' => $this->unit_tag );
160
 
161
  if ( WPCF7_VERIFY_NONCE )
162
- $hidden_fields['_wpnonce'] = wpcf7_create_nonce( $this->unit_tag );
163
 
164
  $content = '';
165
 
@@ -177,20 +189,18 @@ class WPCF7_ContactForm {
177
  $content = '';
178
 
179
  if ( $this->is_posted() ) { // Post response output for non-AJAX
180
- if ( isset( $_POST['_wpcf7_mail_sent'] ) && $_POST['_wpcf7_mail_sent']['id'] == $this->id ) {
181
- if ( $_POST['_wpcf7_mail_sent']['ok'] ) {
182
- $class .= ' wpcf7-mail-sent-ok';
183
- $content = $_POST['_wpcf7_mail_sent']['message'];
184
- } else {
185
- $class .= ' wpcf7-mail-sent-ng';
186
- if ( $_POST['_wpcf7_mail_sent']['spam'] )
187
- $class .= ' wpcf7-spam-blocked';
188
- $content = $_POST['_wpcf7_mail_sent']['message'];
189
- }
190
- } elseif ( isset( $_POST['_wpcf7_validation_errors'] ) && $_POST['_wpcf7_validation_errors']['id'] == $this->id ) {
191
  $class .= ' wpcf7-validation-errors';
192
- $content = $this->message( 'validation_error' );
193
- }
 
 
 
 
 
 
 
194
  } else {
195
  $class .= ' wpcf7-display-none';
196
  }
@@ -204,17 +214,16 @@ class WPCF7_ContactForm {
204
  if ( ! $this->is_posted() )
205
  return '';
206
 
207
- if ( ! isset( $_POST['_wpcf7_validation_errors']['messages'][$name] ) )
208
  return '';
209
 
210
- $ve = trim( $_POST['_wpcf7_validation_errors']['messages'][$name] );
211
 
212
- if ( ! empty( $ve ) ) {
213
- $ve = '<span class="wpcf7-not-valid-tip-no-ajax">' . esc_html( $ve ) . '</span>';
214
- return apply_filters( 'wpcf7_validation_error', $ve, $name, $this );
215
- }
216
 
217
- return '';
 
218
  }
219
 
220
  /* Form Elements */
@@ -334,7 +343,8 @@ class WPCF7_ContactForm {
334
  'spam' => false,
335
  'message' => '',
336
  'mail_sent' => false,
337
- 'scripts_on_sent_ok' => null );
 
338
 
339
  $this->setup_posted_data();
340
 
@@ -371,6 +381,13 @@ class WPCF7_ContactForm {
371
  $result['message'] = $this->message( 'mail_sent_ng' );
372
  }
373
 
 
 
 
 
 
 
 
374
  // remove upload files
375
  foreach ( (array) $this->uploaded_files as $name => $path ) {
376
  @unlink( $path );
@@ -407,11 +424,24 @@ class WPCF7_ContactForm {
407
  if ( WPCF7_VERIFY_NONCE && ! $this->verify_nonce() )
408
  $spam = true;
409
 
 
 
 
410
  return apply_filters( 'wpcf7_spam', $spam );
411
  }
412
 
413
  function verify_nonce() {
414
- return wpcf7_verify_nonce( $_POST['_wpnonce'], $_POST['_wpcf7_unit_tag'] );
 
 
 
 
 
 
 
 
 
 
415
  }
416
 
417
  /* Mail */
@@ -464,24 +494,18 @@ class WPCF7_ContactForm {
464
  function compose_mail( $mail_template, $send = true ) {
465
  $this->mail_template_in_process = $mail_template;
466
 
467
- $regex = '/(\[?)\[\s*([a-zA-Z_][0-9a-zA-Z:._-]*)\s*\](\]?)/';
468
-
469
  $use_html = (bool) $mail_template['use_html'];
470
 
471
- $callback = array( &$this, 'mail_callback' );
472
- $callback_html = array( &$this, 'mail_callback_html' );
473
-
474
- $subject = preg_replace_callback( $regex, $callback, $mail_template['subject'] );
475
- $sender = preg_replace_callback( $regex, $callback, $mail_template['sender'] );
476
- $recipient = preg_replace_callback( $regex, $callback, $mail_template['recipient'] );
477
- $additional_headers =
478
- preg_replace_callback( $regex, $callback, $mail_template['additional_headers'] );
479
 
480
  if ( $use_html ) {
481
- $body = preg_replace_callback( $regex, $callback_html, $mail_template['body'] );
482
  $body = wpautop( $body );
483
  } else {
484
- $body = preg_replace_callback( $regex, $callback, $mail_template['body'] );
485
  }
486
 
487
  $attachments = array();
@@ -514,6 +538,17 @@ class WPCF7_ContactForm {
514
  return compact( 'subject', 'sender', 'body', 'recipient', 'headers', 'attachments' );
515
  }
516
 
 
 
 
 
 
 
 
 
 
 
 
517
  function mail_callback_html( $matches ) {
518
  return $this->mail_callback( $matches, true );
519
  }
@@ -536,12 +571,12 @@ class WPCF7_ContactForm {
536
  $replaced = wptexturize( $replaced );
537
  }
538
 
539
- $replaced = apply_filters( 'wpcf7_mail_tag_replaced', $replaced, $submitted );
540
 
541
  return stripslashes( $replaced );
542
  }
543
 
544
- if ( $special = apply_filters( 'wpcf7_special_mail_tags', '', $matches[2] ) )
545
  return $special;
546
 
547
  return $matches[0];
@@ -553,6 +588,8 @@ class WPCF7_ContactForm {
553
  $messages = $this->messages;
554
  $message = isset( $messages[$status] ) ? $messages[$status] : '';
555
 
 
 
556
  return apply_filters( 'wpcf7_display_message', $message, $status );
557
  }
558
 
@@ -610,16 +647,9 @@ class WPCF7_ContactForm {
610
  /* Save */
611
 
612
  function save() {
613
- $metas = array( 'form', 'mail', 'mail_2', 'messages', 'additional_settings' );
614
 
615
- $post_content = '';
616
-
617
- foreach ( $metas as $meta ) {
618
- $props = (array) $this->{$meta};
619
-
620
- foreach ( $props as $prop )
621
- $post_content .= "\n" . trim( $prop );
622
- }
623
 
624
  if ( $this->initial ) {
625
  $post_id = wp_insert_post( array(
@@ -636,8 +666,8 @@ class WPCF7_ContactForm {
636
  }
637
 
638
  if ( $post_id ) {
639
- foreach ( $metas as $meta )
640
- update_post_meta( $post_id, $meta, wpcf7_normalize_newline_deep( $this->{$meta} ) );
641
 
642
  if ( $this->initial ) {
643
  $this->initial = false;
@@ -658,11 +688,10 @@ class WPCF7_ContactForm {
658
  $new->initial = true;
659
  $new->title = $this->title . '_copy';
660
 
661
- $new->form = $this->form;
662
- $new->mail = $this->mail;
663
- $new->mail_2 = $this->mail_2;
664
- $new->messages = $this->messages;
665
- $new->additional_settings = $this->additional_settings;
666
 
667
  $new = apply_filters_ref_array( 'wpcf7_copy', array( &$new, &$this ) );
668
 
@@ -738,11 +767,10 @@ function wpcf7_get_contact_form_default_pack( $args = '' ) {
738
 
739
  $contact_form->title = ( $title ? $title : __( 'Untitled', 'wpcf7' ) );
740
 
741
- $contact_form->form = wpcf7_get_default_template( 'form' );
742
- $contact_form->mail = wpcf7_get_default_template( 'mail' );
743
- $contact_form->mail_2 = wpcf7_get_default_template( 'mail_2' );
744
- $contact_form->messages = wpcf7_get_default_template( 'messages' );
745
- $contact_form->additional_settings = wpcf7_get_default_template( 'additional_settings' );
746
 
747
  if ( isset( $mo_orig ) )
748
  $l10n['wpcf7'] = $mo_orig;
65
  $this->id = $post->ID;
66
  $this->title = $post->post_title;
67
 
68
+ $props = $this->get_properties();
69
+
70
+ foreach ( $props as $prop => $value ) {
71
+ if ( metadata_exists( 'post', $post->ID, '_' . $prop ) )
72
+ $this->{$prop} = get_post_meta( $post->ID, '_' . $prop, true );
73
+ else
74
+ $this->{$prop} = get_post_meta( $post->ID, $prop, true );
75
+ }
76
 
77
  $this->upgrade();
78
  }
80
  do_action_ref_array( 'wpcf7_contact_form', array( &$this ) );
81
  }
82
 
83
+ function get_properties() {
84
+ $prop_names = array( 'form', 'mail', 'mail_2', 'messages', 'additional_settings' );
85
+
86
+ $properties = array();
87
+
88
+ foreach ( $prop_names as $prop_name )
89
+ $properties[$prop_name] = isset( $this->{$prop_name} ) ? $this->{$prop_name} : '';
90
+
91
+ return apply_filters( 'wpcf7_contact_form_properties', $properties, $this );
92
+ }
93
+
94
  // Return true if this form is the same one as currently POSTed.
95
  function is_posted() {
96
  if ( ! isset( $_POST['_wpcf7_unit_tag'] ) || empty( $_POST['_wpcf7_unit_tag'] ) )
133
  $class = 'wpcf7-form';
134
 
135
  if ( $this->is_posted() ) {
136
+ if ( empty( $_POST['_wpcf7_result']['valid'] ) )
137
  $class .= ' invalid';
138
+ elseif ( ! empty( $_POST['_wpcf7_result']['spam'] ) )
139
+ $class .= ' spam';
140
+ elseif ( ! empty( $_POST['_wpcf7_result']['mail_sent'] ) )
141
+ $class .= ' sent';
142
+ else
143
+ $class .= ' failed';
 
 
144
  }
145
 
146
  $class = apply_filters( 'wpcf7_form_class_attr', $class );
171
  '_wpcf7_unit_tag' => $this->unit_tag );
172
 
173
  if ( WPCF7_VERIFY_NONCE )
174
+ $hidden_fields['_wpnonce'] = wpcf7_create_nonce( $this->id );
175
 
176
  $content = '';
177
 
189
  $content = '';
190
 
191
  if ( $this->is_posted() ) { // Post response output for non-AJAX
192
+
193
+ if ( empty( $_POST['_wpcf7_result']['valid'] ) )
 
 
 
 
 
 
 
 
 
194
  $class .= ' wpcf7-validation-errors';
195
+ elseif ( ! empty( $_POST['_wpcf7_result']['spam'] ) )
196
+ $class .= ' wpcf7-spam-blocked';
197
+ elseif ( ! empty( $_POST['_wpcf7_result']['mail_sent'] ) )
198
+ $class .= ' wpcf7-mail-sent-ok';
199
+ else
200
+ $class .= ' wpcf7-mail-sent-ng';
201
+
202
+ $content = $_POST['_wpcf7_result']['message'];
203
+
204
  } else {
205
  $class .= ' wpcf7-display-none';
206
  }
214
  if ( ! $this->is_posted() )
215
  return '';
216
 
217
+ if ( ! isset( $_POST['_wpcf7_result']['invalid_reasons'][$name] ) )
218
  return '';
219
 
220
+ $ve = trim( $_POST['_wpcf7_result']['invalid_reasons'][$name] );
221
 
222
+ if ( empty( $ve ) )
223
+ return '';
 
 
224
 
225
+ $ve = '<span class="wpcf7-not-valid-tip-no-ajax">' . esc_html( $ve ) . '</span>';
226
+ return apply_filters( 'wpcf7_validation_error', $ve, $name, $this );
227
  }
228
 
229
  /* Form Elements */
343
  'spam' => false,
344
  'message' => '',
345
  'mail_sent' => false,
346
+ 'scripts_on_sent_ok' => null,
347
+ 'scripts_on_submit' => null );
348
 
349
  $this->setup_posted_data();
350
 
381
  $result['message'] = $this->message( 'mail_sent_ng' );
382
  }
383
 
384
+ if ( $ajax ) {
385
+ $on_submit = $this->additional_setting( 'on_submit', false );
386
+
387
+ if ( ! empty( $on_submit ) )
388
+ $result['scripts_on_submit'] = array_map( 'wpcf7_strip_quote', $on_submit );
389
+ }
390
+
391
  // remove upload files
392
  foreach ( (array) $this->uploaded_files as $name => $path ) {
393
  @unlink( $path );
424
  if ( WPCF7_VERIFY_NONCE && ! $this->verify_nonce() )
425
  $spam = true;
426
 
427
+ if ( $this->blacklist_check() )
428
+ $spam = true;
429
+
430
  return apply_filters( 'wpcf7_spam', $spam );
431
  }
432
 
433
  function verify_nonce() {
434
+ return wpcf7_verify_nonce( $_POST['_wpnonce'], $this->id );
435
+ }
436
+
437
+ function blacklist_check() {
438
+ $target = wpcf7_array_flatten( $this->posted_data );
439
+ $target[] = $_SERVER['REMOTE_ADDR'];
440
+ $target[] = $_SERVER['HTTP_USER_AGENT'];
441
+
442
+ $target = implode( "\n", $target );
443
+
444
+ return wpcf7_blacklist_check( $target );
445
  }
446
 
447
  /* Mail */
494
  function compose_mail( $mail_template, $send = true ) {
495
  $this->mail_template_in_process = $mail_template;
496
 
 
 
497
  $use_html = (bool) $mail_template['use_html'];
498
 
499
+ $subject = $this->replace_mail_tags( $mail_template['subject'] );
500
+ $sender = $this->replace_mail_tags( $mail_template['sender'] );
501
+ $recipient = $this->replace_mail_tags( $mail_template['recipient'] );
502
+ $additional_headers = $this->replace_mail_tags( $mail_template['additional_headers'] );
 
 
 
 
503
 
504
  if ( $use_html ) {
505
+ $body = $this->replace_mail_tags( $mail_template['body'], true );
506
  $body = wpautop( $body );
507
  } else {
508
+ $body = $this->replace_mail_tags( $mail_template['body'] );
509
  }
510
 
511
  $attachments = array();
538
  return compact( 'subject', 'sender', 'body', 'recipient', 'headers', 'attachments' );
539
  }
540
 
541
+ function replace_mail_tags( $content, $html = false ) {
542
+ $regex = '/(\[?)\[\s*([a-zA-Z_][0-9a-zA-Z:._-]*)\s*\](\]?)/';
543
+
544
+ if ( $html )
545
+ $callback = array( &$this, 'mail_callback_html' );
546
+ else
547
+ $callback = array( &$this, 'mail_callback' );
548
+
549
+ return preg_replace_callback( $regex, $callback, $content );
550
+ }
551
+
552
  function mail_callback_html( $matches ) {
553
  return $this->mail_callback( $matches, true );
554
  }
571
  $replaced = wptexturize( $replaced );
572
  }
573
 
574
+ $replaced = apply_filters( 'wpcf7_mail_tag_replaced', $replaced, $submitted, $html );
575
 
576
  return stripslashes( $replaced );
577
  }
578
 
579
+ if ( $special = apply_filters( 'wpcf7_special_mail_tags', '', $matches[2], $html ) )
580
  return $special;
581
 
582
  return $matches[0];
588
  $messages = $this->messages;
589
  $message = isset( $messages[$status] ) ? $messages[$status] : '';
590
 
591
+ $message = $this->replace_mail_tags( $message, true );
592
+
593
  return apply_filters( 'wpcf7_display_message', $message, $status );
594
  }
595
 
647
  /* Save */
648
 
649
  function save() {
650
+ $props = $this->get_properties();
651
 
652
+ $post_content = implode( "\n", wpcf7_array_flatten( $props ) );
 
 
 
 
 
 
 
653
 
654
  if ( $this->initial ) {
655
  $post_id = wp_insert_post( array(
666
  }
667
 
668
  if ( $post_id ) {
669
+ foreach ( $props as $prop => $value )
670
+ update_post_meta( $post_id, '_' . $prop, wpcf7_normalize_newline_deep( $value ) );
671
 
672
  if ( $this->initial ) {
673
  $this->initial = false;
688
  $new->initial = true;
689
  $new->title = $this->title . '_copy';
690
 
691
+ $props = $this->get_properties();
692
+
693
+ foreach ( $props as $prop => $value )
694
+ $new->{$prop} = $value;
 
695
 
696
  $new = apply_filters_ref_array( 'wpcf7_copy', array( &$new, &$this ) );
697
 
767
 
768
  $contact_form->title = ( $title ? $title : __( 'Untitled', 'wpcf7' ) );
769
 
770
+ $props = $contact_form->get_properties();
771
+
772
+ foreach ( $props as $prop => $value )
773
+ $contact_form->{$prop} = wpcf7_get_default_template( $prop );
 
774
 
775
  if ( isset( $mo_orig ) )
776
  $l10n['wpcf7'] = $mo_orig;
includes/controller.php CHANGED
@@ -80,6 +80,9 @@ function wpcf7_ajax_json_echo() {
80
  if ( ! empty( $result['scripts_on_sent_ok'] ) )
81
  $items['onSentOk'] = $result['scripts_on_sent_ok'];
82
 
 
 
 
83
  $items = apply_filters( 'wpcf7_ajax_json_echo', $items, $result );
84
 
85
  $wpcf7_contact_form = null;
@@ -114,23 +117,10 @@ function wpcf7_submit_nonajax() {
114
 
115
  $id = (int) $_POST['_wpcf7'];
116
 
117
- if ( $wpcf7_contact_form = wpcf7_contact_form( $id ) ) {
118
- $result = $wpcf7_contact_form->submit();
119
-
120
- if ( ! $result['valid'] ) {
121
- $_POST['_wpcf7_validation_errors'] = array(
122
- 'id' => $id,
123
- 'messages' => $result['invalid_reasons'] );
124
- } else {
125
- $_POST['_wpcf7_mail_sent'] = array(
126
- 'id' => $id,
127
- 'ok' => $result['mail_sent'],
128
- 'message' => $result['message'],
129
- 'spam' => $result['spam'] );
130
- }
131
 
132
- $wpcf7_contact_form = null;
133
- }
134
  }
135
 
136
  add_action( 'the_post', 'wpcf7_the_post' );
@@ -237,8 +227,8 @@ function wpcf7_enqueue_scripts() {
237
  // so we need to deregister it and re-register the latest one
238
  wp_deregister_script( 'jquery-form' );
239
  wp_register_script( 'jquery-form',
240
- wpcf7_plugin_url( 'includes/js/jquery.form.js' ),
241
- array( 'jquery' ), '3.14', true );
242
 
243
  $in_footer = true;
244
  if ( 'header' === WPCF7_LOAD_JS )
80
  if ( ! empty( $result['scripts_on_sent_ok'] ) )
81
  $items['onSentOk'] = $result['scripts_on_sent_ok'];
82
 
83
+ if ( ! empty( $result['scripts_on_submit'] ) )
84
+ $items['onSubmit'] = $result['scripts_on_submit'];
85
+
86
  $items = apply_filters( 'wpcf7_ajax_json_echo', $items, $result );
87
 
88
  $wpcf7_contact_form = null;
117
 
118
  $id = (int) $_POST['_wpcf7'];
119
 
120
+ if ( $wpcf7_contact_form = wpcf7_contact_form( $id ) )
121
+ $_POST['_wpcf7_result'] = $wpcf7_contact_form->submit();
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
+ $wpcf7_contact_form = null;
 
124
  }
125
 
126
  add_action( 'the_post', 'wpcf7_the_post' );
227
  // so we need to deregister it and re-register the latest one
228
  wp_deregister_script( 'jquery-form' );
229
  wp_register_script( 'jquery-form',
230
+ wpcf7_plugin_url( 'includes/js/jquery.form.min.js' ),
231
+ array( 'jquery' ), '3.15', true );
232
 
233
  $in_footer = true;
234
  if ( 'header' === WPCF7_LOAD_JS )
includes/functions.php CHANGED
@@ -262,32 +262,48 @@ function wpcf7_ajax_loader() {
262
  return apply_filters( 'wpcf7_ajax_loader', $url );
263
  }
264
 
265
- /* Nonce functions: wpcf7_verify_nonce() and wpcf7_create_nonce()
266
- * For front-end use only.
267
- * Almost the same as wp_verify_nonce() and wp_create_nonce() except that $uid is always 0.
268
- */
269
-
270
  function wpcf7_verify_nonce( $nonce, $action = -1 ) {
271
- $i = wp_nonce_tick();
272
- $uid = 0;
 
 
 
 
 
 
 
 
 
 
273
 
274
- // Nonce generated 0-12 hours ago
275
- if ( substr( wp_hash( $i . $action . $uid, 'nonce' ), -12, 10 ) == $nonce )
276
- return 1;
277
 
278
- // Nonce generated 12-24 hours ago
279
- if ( substr( wp_hash( ( $i - 1 ) . $action . $uid, 'nonce' ), -12, 10 ) == $nonce )
280
- return 2;
 
 
 
 
 
 
 
 
281
 
282
- // Invalid nonce
283
  return false;
284
  }
285
 
286
- function wpcf7_create_nonce( $action = -1 ) {
287
- $i = wp_nonce_tick();
288
- $uid = 0;
 
 
 
 
 
289
 
290
- return substr( wp_hash( $i . $action . $uid, 'nonce' ), -12, 10 );
291
  }
292
 
293
  ?>
262
  return apply_filters( 'wpcf7_ajax_loader', $url );
263
  }
264
 
 
 
 
 
 
265
  function wpcf7_verify_nonce( $nonce, $action = -1 ) {
266
+ if ( substr( wp_hash( $action, 'nonce' ), -12, 10 ) == $nonce )
267
+ return true;
268
+
269
+ return false;
270
+ }
271
+
272
+ function wpcf7_create_nonce( $action = -1 ) {
273
+ return substr( wp_hash( $action, 'nonce' ), -12, 10 );
274
+ }
275
+
276
+ function wpcf7_blacklist_check( $target ) {
277
+ $mod_keys = trim( get_option( 'blacklist_keys' ) );
278
 
279
+ if ( empty( $mod_keys ) )
280
+ return false;
 
281
 
282
+ $words = explode( "\n", $mod_keys );
283
+
284
+ foreach ( (array) $words as $word ) {
285
+ $word = trim( $word );
286
+
287
+ if ( empty( $word ) )
288
+ continue;
289
+
290
+ if ( preg_match( '#' . preg_quote( $word, '#' ) . '#', $target ) )
291
+ return true;
292
+ }
293
 
 
294
  return false;
295
  }
296
 
297
+ function wpcf7_array_flatten( $input ) {
298
+ if ( ! is_array( $input ) )
299
+ return array( $input );
300
+
301
+ $output = array();
302
+
303
+ foreach ( $input as $value )
304
+ $output = array_merge( $output, wpcf7_array_flatten( $value ) );
305
 
306
+ return $output;
307
  }
308
 
309
  ?>
includes/js/jquery.form.dev.js DELETED
@@ -1,1089 +0,0 @@
1
- /*!
2
- * jQuery Form Plugin
3
- * version: 3.14 (30-JUL-2012)
4
- * @requires jQuery v1.3.2 or later
5
- *
6
- * Examples and documentation at: http://malsup.com/jquery/form/
7
- * Project repository: https://github.com/malsup/form
8
- * Dual licensed under the MIT and GPL licenses:
9
- * http://malsup.github.com/mit-license.txt
10
- * http://malsup.github.com/gpl-license-v2.txt
11
- */
12
- /*global ActiveXObject alert */
13
- ;(function($) {
14
- "use strict";
15
-
16
- /*
17
- Usage Note:
18
- -----------
19
- Do not use both ajaxSubmit and ajaxForm on the same form. These
20
- functions are mutually exclusive. Use ajaxSubmit if you want
21
- to bind your own submit handler to the form. For example,
22
-
23
- $(document).ready(function() {
24
- $('#myForm').on('submit', function(e) {
25
- e.preventDefault(); // <-- important
26
- $(this).ajaxSubmit({
27
- target: '#output'
28
- });
29
- });
30
- });
31
-
32
- Use ajaxForm when you want the plugin to manage all the event binding
33
- for you. For example,
34
-
35
- $(document).ready(function() {
36
- $('#myForm').ajaxForm({
37
- target: '#output'
38
- });
39
- });
40
-
41
- You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
42
- form does not have to exist when you invoke ajaxForm:
43
-
44
- $('#myForm').ajaxForm({
45
- delegation: true,
46
- target: '#output'
47
- });
48
-
49
- When using ajaxForm, the ajaxSubmit function will be invoked for you
50
- at the appropriate time.
51
- */
52
-
53
- /**
54
- * Feature detection
55
- */
56
- var feature = {};
57
- feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
58
- feature.formdata = window.FormData !== undefined;
59
-
60
- /**
61
- * ajaxSubmit() provides a mechanism for immediately submitting
62
- * an HTML form using AJAX.
63
- */
64
- $.fn.ajaxSubmit = function(options) {
65
- /*jshint scripturl:true */
66
-
67
- // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
68
- if (!this.length) {
69
- log('ajaxSubmit: skipping submit process - no element selected');
70
- return this;
71
- }
72
-
73
- var method, action, url, $form = this;
74
-
75
- if (typeof options == 'function') {
76
- options = { success: options };
77
- }
78
-
79
- method = this.attr('method');
80
- action = this.attr('action');
81
- url = (typeof action === 'string') ? $.trim(action) : '';
82
- url = url || window.location.href || '';
83
- if (url) {
84
- // clean url (don't include hash vaue)
85
- url = (url.match(/^([^#]+)/)||[])[1];
86
- }
87
-
88
- options = $.extend(true, {
89
- url: url,
90
- success: $.ajaxSettings.success,
91
- type: method || 'GET',
92
- iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
93
- }, options);
94
-
95
- // hook for manipulating the form data before it is extracted;
96
- // convenient for use with rich editors like tinyMCE or FCKEditor
97
- var veto = {};
98
- this.trigger('form-pre-serialize', [this, options, veto]);
99
- if (veto.veto) {
100
- log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
101
- return this;
102
- }
103
-
104
- // provide opportunity to alter form data before it is serialized
105
- if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
106
- log('ajaxSubmit: submit aborted via beforeSerialize callback');
107
- return this;
108
- }
109
-
110
- var traditional = options.traditional;
111
- if ( traditional === undefined ) {
112
- traditional = $.ajaxSettings.traditional;
113
- }
114
-
115
- var elements = [];
116
- var qx, a = this.formToArray(options.semantic, elements);
117
- if (options.data) {
118
- options.extraData = options.data;
119
- qx = $.param(options.data, traditional);
120
- }
121
-
122
- // give pre-submit callback an opportunity to abort the submit
123
- if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
124
- log('ajaxSubmit: submit aborted via beforeSubmit callback');
125
- return this;
126
- }
127
-
128
- // fire vetoable 'validate' event
129
- this.trigger('form-submit-validate', [a, this, options, veto]);
130
- if (veto.veto) {
131
- log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
132
- return this;
133
- }
134
-
135
- var q = $.param(a, traditional);
136
- if (qx) {
137
- q = ( q ? (q + '&' + qx) : qx );
138
- }
139
- if (options.type.toUpperCase() == 'GET') {
140
- options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
141
- options.data = null; // data is null for 'get'
142
- }
143
- else {
144
- options.data = q; // data is the query string for 'post'
145
- }
146
-
147
- var callbacks = [];
148
- if (options.resetForm) {
149
- callbacks.push(function() { $form.resetForm(); });
150
- }
151
- if (options.clearForm) {
152
- callbacks.push(function() { $form.clearForm(options.includeHidden); });
153
- }
154
-
155
- // perform a load on the target only if dataType is not provided
156
- if (!options.dataType && options.target) {
157
- var oldSuccess = options.success || function(){};
158
- callbacks.push(function(data) {
159
- var fn = options.replaceTarget ? 'replaceWith' : 'html';
160
- $(options.target)[fn](data).each(oldSuccess, arguments);
161
- });
162
- }
163
- else if (options.success) {
164
- callbacks.push(options.success);
165
- }
166
-
167
- options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
168
- var context = options.context || this ; // jQuery 1.4+ supports scope context
169
- for (var i=0, max=callbacks.length; i < max; i++) {
170
- callbacks[i].apply(context, [data, status, xhr || $form, $form]);
171
- }
172
- };
173
-
174
- // are there files to upload?
175
- var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)
176
- var hasFileInputs = fileInputs.length > 0;
177
- var mp = 'multipart/form-data';
178
- var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
179
-
180
- var fileAPI = feature.fileapi && feature.formdata;
181
- log("fileAPI :" + fileAPI);
182
- var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
183
-
184
- // options.iframe allows user to force iframe mode
185
- // 06-NOV-09: now defaulting to iframe mode if file input is detected
186
- if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
187
- // hack to fix Safari hang (thanks to Tim Molendijk for this)
188
- // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
189
- if (options.closeKeepAlive) {
190
- $.get(options.closeKeepAlive, function() {
191
- fileUploadIframe(a);
192
- });
193
- }
194
- else {
195
- fileUploadIframe(a);
196
- }
197
- }
198
- else if ((hasFileInputs || multipart) && fileAPI) {
199
- fileUploadXhr(a);
200
- }
201
- else {
202
- $.ajax(options);
203
- }
204
-
205
- // clear element array
206
- for (var k=0; k < elements.length; k++)
207
- elements[k] = null;
208
-
209
- // fire 'notify' event
210
- this.trigger('form-submit-notify', [this, options]);
211
- return this;
212
-
213
- // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
214
- function fileUploadXhr(a) {
215
- var formdata = new FormData();
216
-
217
- for (var i=0; i < a.length; i++) {
218
- formdata.append(a[i].name, a[i].value);
219
- }
220
-
221
- if (options.extraData) {
222
- for (var p in options.extraData)
223
- if (options.extraData.hasOwnProperty(p))
224
- formdata.append(p, options.extraData[p]);
225
- }
226
-
227
- options.data = null;
228
-
229
- var s = $.extend(true, {}, $.ajaxSettings, options, {
230
- contentType: false,
231
- processData: false,
232
- cache: false,
233
- type: 'POST'
234
- });
235
-
236
- if (options.uploadProgress) {
237
- // workaround because jqXHR does not expose upload property
238
- s.xhr = function() {
239
- var xhr = jQuery.ajaxSettings.xhr();
240
- if (xhr.upload) {
241
- xhr.upload.onprogress = function(event) {
242
- var percent = 0;
243
- var position = event.loaded || event.position; /*event.position is deprecated*/
244
- var total = event.total;
245
- if (event.lengthComputable) {
246
- percent = Math.ceil(position / total * 100);
247
- }
248
- options.uploadProgress(event, position, total, percent);
249
- };
250
- }
251
- return xhr;
252
- };
253
- }
254
-
255
- s.data = null;
256
- var beforeSend = s.beforeSend;
257
- s.beforeSend = function(xhr, o) {
258
- o.data = formdata;
259
- if(beforeSend)
260
- beforeSend.call(this, xhr, o);
261
- };
262
- $.ajax(s);
263
- }
264
-
265
- // private function for handling file uploads (hat tip to YAHOO!)
266
- function fileUploadIframe(a) {
267
- var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
268
- var useProp = !!$.fn.prop;
269
-
270
- if ($(':input[name=submit],:input[id=submit]', form).length) {
271
- // if there is an input with a name or id of 'submit' then we won't be
272
- // able to invoke the submit fn on the form (at least not x-browser)
273
- alert('Error: Form elements must not have name or id of "submit".');
274
- return;
275
- }
276
-
277
- if (a) {
278
- // ensure that every serialized input is still enabled
279
- for (i=0; i < elements.length; i++) {
280
- el = $(elements[i]);
281
- if ( useProp )
282
- el.prop('disabled', false);
283
- else
284
- el.removeAttr('disabled');
285
- }
286
- }
287
-
288
- s = $.extend(true, {}, $.ajaxSettings, options);
289
- s.context = s.context || s;
290
- id = 'jqFormIO' + (new Date().getTime());
291
- if (s.iframeTarget) {
292
- $io = $(s.iframeTarget);
293
- n = $io.attr('name');
294
- if (!n)
295
- $io.attr('name', id);
296
- else
297
- id = n;
298
- }
299
- else {
300
- $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
301
- $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
302
- }
303
- io = $io[0];
304
-
305
-
306
- xhr = { // mock object
307
- aborted: 0,
308
- responseText: null,
309
- responseXML: null,
310
- status: 0,
311
- statusText: 'n/a',
312
- getAllResponseHeaders: function() {},
313
- getResponseHeader: function() {},
314
- setRequestHeader: function() {},
315
- abort: function(status) {
316
- var e = (status === 'timeout' ? 'timeout' : 'aborted');
317
- log('aborting upload... ' + e);
318
- this.aborted = 1;
319
- // #214
320
- if (io.contentWindow.document.execCommand) {
321
- try { // #214
322
- io.contentWindow.document.execCommand('Stop');
323
- } catch(ignore) {}
324
- }
325
- $io.attr('src', s.iframeSrc); // abort op in progress
326
- xhr.error = e;
327
- if (s.error)
328
- s.error.call(s.context, xhr, e, status);
329
- if (g)
330
- $.event.trigger("ajaxError", [xhr, s, e]);
331
- if (s.complete)
332
- s.complete.call(s.context, xhr, e);
333
- }
334
- };
335
-
336
- g = s.global;
337
- // trigger ajax global events so that activity/block indicators work like normal
338
- if (g && 0 === $.active++) {
339
- $.event.trigger("ajaxStart");
340
- }
341
- if (g) {
342
- $.event.trigger("ajaxSend", [xhr, s]);
343
- }
344
-
345
- if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
346
- if (s.global) {
347
- $.active--;
348
- }
349
- return;
350
- }
351
- if (xhr.aborted) {
352
- return;
353
- }
354
-
355
- // add submitting element to data if we know it
356
- sub = form.clk;
357
- if (sub) {
358
- n = sub.name;
359
- if (n && !sub.disabled) {
360
- s.extraData = s.extraData || {};
361
- s.extraData[n] = sub.value;
362
- if (sub.type == "image") {
363
- s.extraData[n+'.x'] = form.clk_x;
364
- s.extraData[n+'.y'] = form.clk_y;
365
- }
366
- }
367
- }
368
-
369
- var CLIENT_TIMEOUT_ABORT = 1;
370
- var SERVER_ABORT = 2;
371
-
372
- function getDoc(frame) {
373
- var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document;
374
- return doc;
375
- }
376
-
377
- // Rails CSRF hack (thanks to Yvan Barthelemy)
378
- var csrf_token = $('meta[name=csrf-token]').attr('content');
379
- var csrf_param = $('meta[name=csrf-param]').attr('content');
380
- if (csrf_param && csrf_token) {
381
- s.extraData = s.extraData || {};
382
- s.extraData[csrf_param] = csrf_token;
383
- }
384
-
385
- // take a breath so that pending repaints get some cpu time before the upload starts
386
- function doSubmit() {
387
- // make sure form attrs are set
388
- var t = $form.attr('target'), a = $form.attr('action');
389
-
390
- // update form attrs in IE friendly way
391
- form.setAttribute('target',id);
392
- if (!method) {
393
- form.setAttribute('method', 'POST');
394
- }
395
- if (a != s.url) {
396
- form.setAttribute('action', s.url);
397
- }
398
-
399
- // ie borks in some cases when setting encoding
400
- if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
401
- $form.attr({
402
- encoding: 'multipart/form-data',
403
- enctype: 'multipart/form-data'
404
- });
405
- }
406
-
407
- // support timout
408
- if (s.timeout) {
409
- timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
410
- }
411
-
412
- // look for server aborts
413
- function checkState() {
414
- try {
415
- var state = getDoc(io).readyState;
416
- log('state = ' + state);
417
- if (state && state.toLowerCase() == 'uninitialized')
418
- setTimeout(checkState,50);
419
- }
420
- catch(e) {
421
- log('Server abort: ' , e, ' (', e.name, ')');
422
- cb(SERVER_ABORT);
423
- if (timeoutHandle)
424
- clearTimeout(timeoutHandle);
425
- timeoutHandle = undefined;
426
- }
427
- }
428
-
429
- // add "extra" data to form if provided in options
430
- var extraInputs = [];
431
- try {
432
- if (s.extraData) {
433
- for (var n in s.extraData) {
434
- if (s.extraData.hasOwnProperty(n)) {
435
- // if using the $.param format that allows for multiple values with the same name
436
- if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
437
- extraInputs.push(
438
- $('<input type="hidden" name="'+s.extraData[n].name+'">').attr('value',s.extraData[n].value)
439
- .appendTo(form)[0]);
440
- } else {
441
- extraInputs.push(
442
- $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
443
- .appendTo(form)[0]);
444
- }
445
- }
446
- }
447
- }
448
-
449
- if (!s.iframeTarget) {
450
- // add iframe to doc and submit the form
451
- $io.appendTo('body');
452
- if (io.attachEvent)
453
- io.attachEvent('onload', cb);
454
- else
455
- io.addEventListener('load', cb, false);
456
- }
457
- setTimeout(checkState,15);
458
- form.submit();
459
- }
460
- finally {
461
- // reset attrs and remove "extra" input elements
462
- form.setAttribute('action',a);
463
- if(t) {
464
- form.setAttribute('target', t);
465
- } else {
466
- $form.removeAttr('target');
467
- }
468
- $(extraInputs).remove();
469
- }
470
- }
471
-
472
- if (s.forceSync) {
473
- doSubmit();
474
- }
475
- else {
476
- setTimeout(doSubmit, 10); // this lets dom updates render
477
- }
478
-
479
- var data, doc, domCheckCount = 50, callbackProcessed;
480
-
481
- function cb(e) {
482
- if (xhr.aborted || callbackProcessed) {
483
- return;
484
- }
485
- try {
486
- doc = getDoc(io);
487
- }
488
- catch(ex) {
489
- log('cannot access response document: ', ex);
490
- e = SERVER_ABORT;
491
- }
492
- if (e === CLIENT_TIMEOUT_ABORT && xhr) {
493
- xhr.abort('timeout');
494
- return;
495
- }
496
- else if (e == SERVER_ABORT && xhr) {
497
- xhr.abort('server abort');
498
- return;
499
- }
500
-
501
- if (!doc || doc.location.href == s.iframeSrc) {
502
- // response not received yet
503
- if (!timedOut)
504
- return;
505
- }
506
- if (io.detachEvent)
507
- io.detachEvent('onload', cb);
508
- else
509
- io.removeEventListener('load', cb, false);
510
-
511
- var status = 'success', errMsg;
512
- try {
513
- if (timedOut) {
514
- throw 'timeout';
515
- }
516
-
517
- var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
518
- log('isXml='+isXml);
519
- if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
520
- if (--domCheckCount) {
521
- // in some browsers (Opera) the iframe DOM is not always traversable when
522
- // the onload callback fires, so we loop a bit to accommodate
523
- log('requeing onLoad callback, DOM not available');
524
- setTimeout(cb, 250);
525
- return;
526
- }
527
- // let this fall through because server response could be an empty document
528
- //log('Could not access iframe DOM after mutiple tries.');
529
- //throw 'DOMException: not available';
530
- }
531
-
532
- //log('response detected');
533
- var docRoot = doc.body ? doc.body : doc.documentElement;
534
- xhr.responseText = docRoot ? docRoot.innerHTML : null;
535
- xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
536
- if (isXml)
537
- s.dataType = 'xml';
538
- xhr.getResponseHeader = function(header){
539
- var headers = {'content-type': s.dataType};
540
- return headers[header];
541
- };
542
- // support for XHR 'status' & 'statusText' emulation :
543
- if (docRoot) {
544
- xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
545
- xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
546
- }
547
-
548
- var dt = (s.dataType || '').toLowerCase();
549
- var scr = /(json|script|text)/.test(dt);
550
- if (scr || s.textarea) {
551
- // see if user embedded response in textarea
552
- var ta = doc.getElementsByTagName('textarea')[0];
553
- if (ta) {
554
- xhr.responseText = ta.value;
555
- // support for XHR 'status' & 'statusText' emulation :
556
- xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
557
- xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
558
- }
559
- else if (scr) {
560
- // account for browsers injecting pre around json response
561
- var pre = doc.getElementsByTagName('pre')[0];
562
- var b = doc.getElementsByTagName('body')[0];
563
- if (pre) {
564
- xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
565
- }
566
- else if (b) {
567
- xhr.responseText = b.textContent ? b.textContent : b.innerText;
568
- }
569
- }
570
- }
571
- else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
572
- xhr.responseXML = toXml(xhr.responseText);
573
- }
574
-
575
- try {
576
- data = httpData(xhr, dt, s);
577
- }
578
- catch (e) {
579
- status = 'parsererror';
580
- xhr.error = errMsg = (e || status);
581
- }
582
- }
583
- catch (e) {
584
- log('error caught: ',e);
585
- status = 'error';
586
- xhr.error = errMsg = (e || status);
587
- }
588
-
589
- if (xhr.aborted) {
590
- log('upload aborted');
591
- status = null;
592
- }
593
-
594
- if (xhr.status) { // we've set xhr.status
595
- status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
596
- }
597
-
598
- // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
599
- if (status === 'success') {
600
- if (s.success)
601
- s.success.call(s.context, data, 'success', xhr);
602
- if (g)
603
- $.event.trigger("ajaxSuccess", [xhr, s]);
604
- }
605
- else if (status) {
606
- if (errMsg === undefined)
607
- errMsg = xhr.statusText;
608
- if (s.error)
609
- s.error.call(s.context, xhr, status, errMsg);
610
- if (g)
611
- $.event.trigger("ajaxError", [xhr, s, errMsg]);
612
- }
613
-
614
- if (g)
615
- $.event.trigger("ajaxComplete", [xhr, s]);
616
-
617
- if (g && ! --$.active) {
618
- $.event.trigger("ajaxStop");
619
- }
620
-
621
- if (s.complete)
622
- s.complete.call(s.context, xhr, status);
623
-
624
- callbackProcessed = true;
625
- if (s.timeout)
626
- clearTimeout(timeoutHandle);
627
-
628
- // clean up
629
- setTimeout(function() {
630
- if (!s.iframeTarget)
631
- $io.remove();
632
- xhr.responseXML = null;
633
- }, 100);
634
- }
635
-
636
- var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
637
- if (window.ActiveXObject) {
638
- doc = new ActiveXObject('Microsoft.XMLDOM');
639
- doc.async = 'false';
640
- doc.loadXML(s);
641
- }
642
- else {
643
- doc = (new DOMParser()).parseFromString(s, 'text/xml');
644
- }
645
- return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
646
- };
647
- var parseJSON = $.parseJSON || function(s) {
648
- /*jslint evil:true */
649
- return window['eval']('(' + s + ')');
650
- };
651
-
652
- var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
653
-
654
- var ct = xhr.getResponseHeader('content-type') || '',
655
- xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
656
- data = xml ? xhr.responseXML : xhr.responseText;
657
-
658
- if (xml && data.documentElement.nodeName === 'parsererror') {
659
- if ($.error)
660
- $.error('parsererror');
661
- }
662
- if (s && s.dataFilter) {
663
- data = s.dataFilter(data, type);
664
- }
665
- if (typeof data === 'string') {
666
- if (type === 'json' || !type && ct.indexOf('json') >= 0) {
667
- data = parseJSON(data);
668
- } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
669
- $.globalEval(data);
670
- }
671
- }
672
- return data;
673
- };
674
- }
675
- };
676
-
677
- /**
678
- * ajaxForm() provides a mechanism for fully automating form submission.
679
- *
680
- * The advantages of using this method instead of ajaxSubmit() are:
681
- *
682
- * 1: This method will include coordinates for <input type="image" /> elements (if the element
683
- * is used to submit the form).
684
- * 2. This method will include the submit element's name/value data (for the element that was
685
- * used to submit the form).
686
- * 3. This method binds the submit() method to the form for you.
687
- *
688
- * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
689
- * passes the options argument along after properly binding events for submit elements and
690
- * the form itself.
691
- */
692
- $.fn.ajaxForm = function(options) {
693
- options = options || {};
694
- options.delegation = options.delegation && $.isFunction($.fn.on);
695
-
696
- // in jQuery 1.3+ we can fix mistakes with the ready state
697
- if (!options.delegation && this.length === 0) {
698
- var o = { s: this.selector, c: this.context };
699
- if (!$.isReady && o.s) {
700
- log('DOM not ready, queuing ajaxForm');
701
- $(function() {
702
- $(o.s,o.c).ajaxForm(options);
703
- });
704
- return this;
705
- }
706
- // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
707
- log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
708
- return this;
709
- }
710
-
711
- if ( options.delegation ) {
712
- $(document)
713
- .off('submit.form-plugin', this.selector, doAjaxSubmit)
714
- .off('click.form-plugin', this.selector, captureSubmittingElement)
715
- .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
716
- .on('click.form-plugin', this.selector, options, captureSubmittingElement);
717
- return this;
718
- }
719
-
720
- return this.ajaxFormUnbind()
721
- .bind('submit.form-plugin', options, doAjaxSubmit)
722
- .bind('click.form-plugin', options, captureSubmittingElement);
723
- };
724
-
725
- // private event handlers
726
- function doAjaxSubmit(e) {
727
- /*jshint validthis:true */
728
- var options = e.data;
729
- if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
730
- e.preventDefault();
731
- $(this).ajaxSubmit(options);
732
- }
733
- }
734
-
735
- function captureSubmittingElement(e) {
736
- /*jshint validthis:true */
737
- var target = e.target;
738
- var $el = $(target);
739
- if (!($el.is(":submit,input:image"))) {
740
- // is this a child element of the submit el? (ex: a span within a button)
741
- var t = $el.closest(':submit');
742
- if (t.length === 0) {
743
- return;
744
- }
745
- target = t[0];
746
- }
747
- var form = this;
748
- form.clk = target;
749
- if (target.type == 'image') {
750
- if (e.offsetX !== undefined) {
751
- form.clk_x = e.offsetX;
752
- form.clk_y = e.offsetY;
753
- } else if (typeof $.fn.offset == 'function') {
754
- var offset = $el.offset();
755
- form.clk_x = e.pageX - offset.left;
756
- form.clk_y = e.pageY - offset.top;
757
- } else {
758
- form.clk_x = e.pageX - target.offsetLeft;
759
- form.clk_y = e.pageY - target.offsetTop;
760
- }
761
- }
762
- // clear form vars
763
- setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
764
- }
765
-
766
-
767
- // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
768
- $.fn.ajaxFormUnbind = function() {
769
- return this.unbind('submit.form-plugin click.form-plugin');
770
- };
771
-
772
- /**
773
- * formToArray() gathers form element data into an array of objects that can
774
- * be passed to any of the following ajax functions: $.get, $.post, or load.
775
- * Each object in the array has both a 'name' and 'value' property. An example of
776
- * an array for a simple login form might be:
777
- *
778
- * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
779
- *
780
- * It is this array that is passed to pre-submit callback functions provided to the
781
- * ajaxSubmit() and ajaxForm() methods.
782
- */
783
- $.fn.formToArray = function(semantic, elements) {
784
- var a = [];
785
- if (this.length === 0) {
786
- return a;
787
- }
788
-
789
- var form = this[0];
790
- var els = semantic ? form.getElementsByTagName('*') : form.elements;
791
- if (!els) {
792
- return a;
793
- }
794
-
795
- var i,j,n,v,el,max,jmax;
796
- for(i=0, max=els.length; i < max; i++) {
797
- el = els[i];
798
- n = el.name;
799
- if (!n) {
800
- continue;
801
- }
802
-
803
- if (semantic && form.clk && el.type == "image") {
804
- // handle image inputs on the fly when semantic == true
805
- if(!el.disabled && form.clk == el) {
806
- a.push({name: n, value: $(el).val(), type: el.type });
807
- a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
808
- }
809
- continue;
810
- }
811
-
812
- v = $.fieldValue(el, true);
813
- if (v && v.constructor == Array) {
814
- if (elements)
815
- elements.push(el);
816
- for(j=0, jmax=v.length; j < jmax; j++) {
817
- a.push({name: n, value: v[j]});
818
- }
819
- }
820
- else if (feature.fileapi && el.type == 'file' && !el.disabled) {
821
- if (elements)
822
- elements.push(el);
823
- var files = el.files;
824
- if (files.length) {
825
- for (j=0; j < files.length; j++) {
826
- a.push({name: n, value: files[j], type: el.type});
827
- }
828
- }
829
- else {
830
- // #180
831
- a.push({ name: n, value: '', type: el.type });
832
- }
833
- }
834
- else if (v !== null && typeof v != 'undefined') {
835
- if (elements)
836
- elements.push(el);
837
- a.push({name: n, value: v, type: el.type, required: el.required});
838
- }
839
- }
840
-
841
- if (!semantic && form.clk) {
842
- // input type=='image' are not found in elements array! handle it here
843
- var $input = $(form.clk), input = $input[0];
844
- n = input.name;
845
- if (n && !input.disabled && input.type == 'image') {
846
- a.push({name: n, value: $input.val()});
847
- a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
848
- }
849
- }
850
- return a;
851
- };
852
-
853
- /**
854
- * Serializes form data into a 'submittable' string. This method will return a string
855
- * in the format: name1=value1&amp;name2=value2
856
- */
857
- $.fn.formSerialize = function(semantic) {
858
- //hand off to jQuery.param for proper encoding
859
- return $.param(this.formToArray(semantic));
860
- };
861
-
862
- /**
863
- * Serializes all field elements in the jQuery object into a query string.
864
- * This method will return a string in the format: name1=value1&amp;name2=value2
865
- */
866
- $.fn.fieldSerialize = function(successful) {
867
- var a = [];
868
- this.each(function() {
869
- var n = this.name;
870
- if (!n) {
871
- return;
872
- }
873
- var v = $.fieldValue(this, successful);
874
- if (v && v.constructor == Array) {
875
- for (var i=0,max=v.length; i < max; i++) {
876
- a.push({name: n, value: v[i]});
877
- }
878
- }
879
- else if (v !== null && typeof v != 'undefined') {
880
- a.push({name: this.name, value: v});
881
- }
882
- });
883
- //hand off to jQuery.param for proper encoding
884
- return $.param(a);
885
- };
886
-
887
- /**
888
- * Returns the value(s) of the element in the matched set. For example, consider the following form:
889
- *
890
- * <form><fieldset>
891
- * <input name="A" type="text" />
892
- * <input name="A" type="text" />
893
- * <input name="B" type="checkbox" value="B1" />
894
- * <input name="B" type="checkbox" value="B2"/>
895
- * <input name="C" type="radio" value="C1" />
896
- * <input name="C" type="radio" value="C2" />
897
- * </fieldset></form>
898
- *
899
- * var v = $(':text').fieldValue();
900
- * // if no values are entered into the text inputs
901
- * v == ['','']
902
- * // if values entered into the text inputs are 'foo' and 'bar'
903
- * v == ['foo','bar']
904
- *
905
- * var v = $(':checkbox').fieldValue();
906
- * // if neither checkbox is checked
907
- * v === undefined
908
- * // if both checkboxes are checked
909
- * v == ['B1', 'B2']
910
- *
911
- * var v = $(':radio').fieldValue();
912
- * // if neither radio is checked
913
- * v === undefined
914
- * // if first radio is checked
915
- * v == ['C1']
916
- *
917
- * The successful argument controls whether or not the field element must be 'successful'
918
- * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
919
- * The default value of the successful argument is true. If this value is false the value(s)
920
- * for each element is returned.
921
- *
922
- * Note: This method *always* returns an array. If no valid value can be determined the
923
- * array will be empty, otherwise it will contain one or more values.
924
- */
925
- $.fn.fieldValue = function(successful) {
926
- for (var val=[], i=0, max=this.length; i < max; i++) {
927
- var el = this[i];
928
- var v = $.fieldValue(el, successful);
929
- if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
930
- continue;
931
- }
932
- if (v.constructor == Array)
933
- $.merge(val, v);
934
- else
935
- val.push(v);
936
- }
937
- return val;
938
- };
939
-
940
- /**
941
- * Returns the value of the field element.
942
- */
943
- $.fieldValue = function(el, successful) {
944
- var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
945
- if (successful === undefined) {
946
- successful = true;
947
- }
948
-
949
- if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
950
- (t == 'checkbox' || t == 'radio') && !el.checked ||
951
- (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
952
- tag == 'select' && el.selectedIndex == -1)) {
953
- return null;
954
- }
955
-
956
- if (tag == 'select') {
957
- var index = el.selectedIndex;
958
- if (index < 0) {
959
- return null;
960
- }
961
- var a = [], ops = el.options;
962
- var one = (t == 'select-one');
963
- var max = (one ? index+1 : ops.length);
964
- for(var i=(one ? index : 0); i < max; i++) {
965
- var op = ops[i];
966
- if (op.selected) {
967
- var v = op.value;
968
- if (!v) { // extra pain for IE...
969
- v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
970
- }
971
- if (one) {
972
- return v;
973
- }
974
- a.push(v);
975
- }
976
- }
977
- return a;
978
- }
979
- return $(el).val();
980
- };
981
-
982
- /**
983
- * Clears the form data. Takes the following actions on the form's input fields:
984
- * - input text fields will have their 'value' property set to the empty string
985
- * - select elements will have their 'selectedIndex' property set to -1
986
- * - checkbox and radio inputs will have their 'checked' property set to false
987
- * - inputs of type submit, button, reset, and hidden will *not* be effected
988
- * - button elements will *not* be effected
989
- */
990
- $.fn.clearForm = function(includeHidden) {
991
- return this.each(function() {
992
- $('input,select,textarea', this).clearFields(includeHidden);
993
- });
994
- };
995
-
996
- /**
997
- * Clears the selected form elements.
998
- */
999
- $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
1000
- var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
1001
- return this.each(function() {
1002
- var t = this.type, tag = this.tagName.toLowerCase();
1003
- if (re.test(t) || tag == 'textarea') {
1004
- this.value = '';
1005
- }
1006
- else if (t == 'checkbox' || t == 'radio') {
1007
- this.checked = false;
1008
- }
1009
- else if (tag == 'select') {
1010
- this.selectedIndex = -1;
1011
- }
1012
- else if (includeHidden) {
1013
- // includeHidden can be the value true, or it can be a selector string
1014
- // indicating a special test; for example:
1015
- // $('#myForm').clearForm('.special:hidden')
1016
- // the above would clean hidden inputs that have the class of 'special'
1017
- if ( (includeHidden === true && /hidden/.test(t)) ||
1018
- (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
1019
- this.value = '';
1020
- }
1021
- });
1022
- };
1023
-
1024
- /**
1025
- * Resets the form data. Causes all form elements to be reset to their original value.
1026
- */
1027
- $.fn.resetForm = function() {
1028
- return this.each(function() {
1029
- // guard against an input with the name of 'reset'
1030
- // note that IE reports the reset function as an 'object'
1031
- if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
1032
- this.reset();
1033
- }
1034
- });
1035
- };
1036
-
1037
- /**
1038
- * Enables or disables any matching elements.
1039
- */
1040
- $.fn.enable = function(b) {
1041
- if (b === undefined) {
1042
- b = true;
1043
- }
1044
- return this.each(function() {
1045
- this.disabled = !b;
1046
- });
1047
- };
1048
-
1049
- /**
1050
- * Checks/unchecks any matching checkboxes or radio buttons and
1051
- * selects/deselects and matching option elements.
1052
- */
1053
- $.fn.selected = function(select) {
1054
- if (select === undefined) {
1055
- select = true;
1056
- }
1057
- return this.each(function() {
1058
- var t = this.type;
1059
- if (t == 'checkbox' || t == 'radio') {
1060
- this.checked = select;
1061
- }
1062
- else if (this.tagName.toLowerCase() == 'option') {
1063
- var $sel = $(this).parent('select');
1064
- if (select && $sel[0] && $sel[0].type == 'select-one') {
1065
- // deselect all other options
1066
- $sel.find('option').selected(false);
1067
- }
1068
- this.selected = select;
1069
- }
1070
- });
1071
- };
1072
-
1073
- // expose debug var
1074
- $.fn.ajaxSubmit.debug = false;
1075
-
1076
- // helper fn for console logging
1077
- function log() {
1078
- if (!$.fn.ajaxSubmit.debug)
1079
- return;
1080
- var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
1081
- if (window.console && window.console.log) {
1082
- window.console.log(msg);
1083
- }
1084
- else if (window.opera && window.opera.postError) {
1085
- window.opera.postError(msg);
1086
- }
1087
- }
1088
-
1089
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/js/jquery.form.js CHANGED
@@ -1,6 +1,6 @@
1
  /*!
2
  * jQuery Form Plugin
3
- * version: 3.14 (30-JUL-2012)
4
  * @requires jQuery v1.3.2 or later
5
  *
6
  * Examples and documentation at: http://malsup.com/jquery/form/
@@ -9,4 +9,1095 @@
9
  * http://malsup.github.com/mit-license.txt
10
  * http://malsup.github.com/gpl-license-v2.txt
11
  */
12
- (function(e){var c={};c.fileapi=e("<input type='file'/>").get(0).files!==undefined;c.formdata=window.FormData!==undefined;e.fn.ajaxSubmit=function(g){if(!this.length){d("ajaxSubmit: skipping submit process - no element selected");return this}var f,w,i,l=this;if(typeof g=="function"){g={success:g}}f=this.attr("method");w=this.attr("action");i=(typeof w==="string")?e.trim(w):"";i=i||window.location.href||"";if(i){i=(i.match(/^([^#]+)/)||[])[1]}g=e.extend(true,{url:i,success:e.ajaxSettings.success,type:f||"GET",iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},g);var r={};this.trigger("form-pre-serialize",[this,g,r]);if(r.veto){d("ajaxSubmit: submit vetoed via form-pre-serialize trigger");return this}if(g.beforeSerialize&&g.beforeSerialize(this,g)===false){d("ajaxSubmit: submit aborted via beforeSerialize callback");return this}var j=g.traditional;if(j===undefined){j=e.ajaxSettings.traditional}var o=[];var z,A=this.formToArray(g.semantic,o);if(g.data){g.extraData=g.data;z=e.param(g.data,j)}if(g.beforeSubmit&&g.beforeSubmit(A,this,g)===false){d("ajaxSubmit: submit aborted via beforeSubmit callback");return this}this.trigger("form-submit-validate",[A,this,g,r]);if(r.veto){d("ajaxSubmit: submit vetoed via form-submit-validate trigger");return this}var u=e.param(A,j);if(z){u=(u?(u+"&"+z):z)}if(g.type.toUpperCase()=="GET"){g.url+=(g.url.indexOf("?")>=0?"&":"?")+u;g.data=null}else{g.data=u}var C=[];if(g.resetForm){C.push(function(){l.resetForm()})}if(g.clearForm){C.push(function(){l.clearForm(g.includeHidden)})}if(!g.dataType&&g.target){var h=g.success||function(){};C.push(function(q){var k=g.replaceTarget?"replaceWith":"html";e(g.target)[k](q).each(h,arguments)})}else{if(g.success){C.push(g.success)}}g.success=function(F,q,G){var E=g.context||this;for(var D=0,k=C.length;D<k;D++){C[D].apply(E,[F,q,G||l,l])}};var y=e("input:file:enabled[value]",this);var m=y.length>0;var x="multipart/form-data";var t=(l.attr("enctype")==x||l.attr("encoding")==x);var s=c.fileapi&&c.formdata;d("fileAPI :"+s);var n=(m||t)&&!s;if(g.iframe!==false&&(g.iframe||n)){if(g.closeKeepAlive){e.get(g.closeKeepAlive,function(){B(A)})}else{B(A)}}else{if((m||t)&&s){p(A)}else{e.ajax(g)}}for(var v=0;v<o.length;v++){o[v]=null}this.trigger("form-submit-notify",[this,g]);return this;function p(q){var k=new FormData();for(var D=0;D<q.length;D++){k.append(q[D].name,q[D].value)}if(g.extraData){for(var G in g.extraData){if(g.extraData.hasOwnProperty(G)){k.append(G,g.extraData[G])}}}g.data=null;var F=e.extend(true,{},e.ajaxSettings,g,{contentType:false,processData:false,cache:false,type:"POST"});if(g.uploadProgress){F.xhr=function(){var H=jQuery.ajaxSettings.xhr();if(H.upload){H.upload.onprogress=function(L){var K=0;var I=L.loaded||L.position;var J=L.total;if(L.lengthComputable){K=Math.ceil(I/J*100)}g.uploadProgress(L,I,J,K)}}return H}}F.data=null;var E=F.beforeSend;F.beforeSend=function(I,H){H.data=k;if(E){E.call(this,I,H)}};e.ajax(F)}function B(ab){var G=l[0],F,X,R,Z,U,I,M,K,L,V,Y,P;var J=!!e.fn.prop;if(e(":input[name=submit],:input[id=submit]",G).length){alert('Error: Form elements must not have name or id of "submit".');return}if(ab){for(X=0;X<o.length;X++){F=e(o[X]);if(J){F.prop("disabled",false)}else{F.removeAttr("disabled")}}}R=e.extend(true,{},e.ajaxSettings,g);R.context=R.context||R;U="jqFormIO"+(new Date().getTime());if(R.iframeTarget){I=e(R.iframeTarget);V=I.attr("name");if(!V){I.attr("name",U)}else{U=V}}else{I=e('<iframe name="'+U+'" src="'+R.iframeSrc+'" />');I.css({position:"absolute",top:"-1000px",left:"-1000px"})}M=I[0];K={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(ae){var af=(ae==="timeout"?"timeout":"aborted");d("aborting upload... "+af);this.aborted=1;if(M.contentWindow.document.execCommand){try{M.contentWindow.document.execCommand("Stop")}catch(ag){}}I.attr("src",R.iframeSrc);K.error=af;if(R.error){R.error.call(R.context,K,af,ae)}if(Z){e.event.trigger("ajaxError",[K,R,af])}if(R.complete){R.complete.call(R.context,K,af)}}};Z=R.global;if(Z&&0===e.active++){e.event.trigger("ajaxStart")}if(Z){e.event.trigger("ajaxSend",[K,R])}if(R.beforeSend&&R.beforeSend.call(R.context,K,R)===false){if(R.global){e.active--}return}if(K.aborted){return}L=G.clk;if(L){V=L.name;if(V&&!L.disabled){R.extraData=R.extraData||{};R.extraData[V]=L.value;if(L.type=="image"){R.extraData[V+".x"]=G.clk_x;R.extraData[V+".y"]=G.clk_y}}}var Q=1;var N=2;function O(af){var ae=af.contentWindow?af.contentWindow.document:af.contentDocument?af.contentDocument:af.document;return ae}var E=e("meta[name=csrf-token]").attr("content");var D=e("meta[name=csrf-param]").attr("content");if(D&&E){R.extraData=R.extraData||{};R.extraData[D]=E}function W(){var ag=l.attr("target"),ae=l.attr("action");G.setAttribute("target",U);if(!f){G.setAttribute("method","POST")}if(ae!=R.url){G.setAttribute("action",R.url)}if(!R.skipEncodingOverride&&(!f||/post/i.test(f))){l.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"})}if(R.timeout){P=setTimeout(function(){Y=true;T(Q)},R.timeout)}function ah(){try{var aj=O(M).readyState;d("state = "+aj);if(aj&&aj.toLowerCase()=="uninitialized"){setTimeout(ah,50)}}catch(ak){d("Server abort: ",ak," (",ak.name,")");T(N);if(P){clearTimeout(P)}P=undefined}}var af=[];try{if(R.extraData){for(var ai in R.extraData){if(R.extraData.hasOwnProperty(ai)){if(e.isPlainObject(R.extraData[ai])&&R.extraData[ai].hasOwnProperty("name")&&R.extraData[ai].hasOwnProperty("value")){af.push(e('<input type="hidden" name="'+R.extraData[ai].name+'">').attr("value",R.extraData[ai].value).appendTo(G)[0])}else{af.push(e('<input type="hidden" name="'+ai+'">').attr("value",R.extraData[ai]).appendTo(G)[0])}}}}if(!R.iframeTarget){I.appendTo("body");if(M.attachEvent){M.attachEvent("onload",T)}else{M.addEventListener("load",T,false)}}setTimeout(ah,15);G.submit()}finally{G.setAttribute("action",ae);if(ag){G.setAttribute("target",ag)}else{l.removeAttr("target")}e(af).remove()}}if(R.forceSync){W()}else{setTimeout(W,10)}var ac,ad,aa=50,H;function T(aj){if(K.aborted||H){return}try{ad=O(M)}catch(am){d("cannot access response document: ",am);aj=N}if(aj===Q&&K){K.abort("timeout");return}else{if(aj==N&&K){K.abort("server abort");return}}if(!ad||ad.location.href==R.iframeSrc){if(!Y){return}}if(M.detachEvent){M.detachEvent("onload",T)}else{M.removeEventListener("load",T,false)}var ah="success",al;try{if(Y){throw"timeout"}var ag=R.dataType=="xml"||ad.XMLDocument||e.isXMLDoc(ad);d("isXml="+ag);if(!ag&&window.opera&&(ad.body===null||!ad.body.innerHTML)){if(--aa){d("requeing onLoad callback, DOM not available");setTimeout(T,250);return}}var an=ad.body?ad.body:ad.documentElement;K.responseText=an?an.innerHTML:null;K.responseXML=ad.XMLDocument?ad.XMLDocument:ad;if(ag){R.dataType="xml"}K.getResponseHeader=function(aq){var ap={"content-type":R.dataType};return ap[aq]};if(an){K.status=Number(an.getAttribute("status"))||K.status;K.statusText=an.getAttribute("statusText")||K.statusText}var ae=(R.dataType||"").toLowerCase();var ak=/(json|script|text)/.test(ae);if(ak||R.textarea){var ai=ad.getElementsByTagName("textarea")[0];if(ai){K.responseText=ai.value;K.status=Number(ai.getAttribute("status"))||K.status;K.statusText=ai.getAttribute("statusText")||K.statusText}else{if(ak){var af=ad.getElementsByTagName("pre")[0];var ao=ad.getElementsByTagName("body")[0];if(af){K.responseText=af.textContent?af.textContent:af.innerText}else{if(ao){K.responseText=ao.textContent?ao.textContent:ao.innerText}}}}}else{if(ae=="xml"&&!K.responseXML&&K.responseText){K.responseXML=S(K.responseText)}}try{ac=k(K,ae,R)}catch(aj){ah="parsererror";K.error=al=(aj||ah)}}catch(aj){d("error caught: ",aj);ah="error";K.error=al=(aj||ah)}if(K.aborted){d("upload aborted");ah=null}if(K.status){ah=(K.status>=200&&K.status<300||K.status===304)?"success":"error"}if(ah==="success"){if(R.success){R.success.call(R.context,ac,"success",K)}if(Z){e.event.trigger("ajaxSuccess",[K,R])}}else{if(ah){if(al===undefined){al=K.statusText}if(R.error){R.error.call(R.context,K,ah,al)}if(Z){e.event.trigger("ajaxError",[K,R,al])}}}if(Z){e.event.trigger("ajaxComplete",[K,R])}if(Z&&!--e.active){e.event.trigger("ajaxStop")}if(R.complete){R.complete.call(R.context,K,ah)}H=true;if(R.timeout){clearTimeout(P)}setTimeout(function(){if(!R.iframeTarget){I.remove()}K.responseXML=null},100)}var S=e.parseXML||function(ae,af){if(window.ActiveXObject){af=new ActiveXObject("Microsoft.XMLDOM");af.async="false";af.loadXML(ae)}else{af=(new DOMParser()).parseFromString(ae,"text/xml")}return(af&&af.documentElement&&af.documentElement.nodeName!="parsererror")?af:null};var q=e.parseJSON||function(ae){return window["eval"]("("+ae+")")};var k=function(aj,ah,ag){var af=aj.getResponseHeader("content-type")||"",ae=ah==="xml"||!ah&&af.indexOf("xml")>=0,ai=ae?aj.responseXML:aj.responseText;if(ae&&ai.documentElement.nodeName==="parsererror"){if(e.error){e.error("parsererror")}}if(ag&&ag.dataFilter){ai=ag.dataFilter(ai,ah)}if(typeof ai==="string"){if(ah==="json"||!ah&&af.indexOf("json")>=0){ai=q(ai)}else{if(ah==="script"||!ah&&af.indexOf("javascript")>=0){e.globalEval(ai)}}}return ai}}};e.fn.ajaxForm=function(f){f=f||{};f.delegation=f.delegation&&e.isFunction(e.fn.on);if(!f.delegation&&this.length===0){var g={s:this.selector,c:this.context};if(!e.isReady&&g.s){d("DOM not ready, queuing ajaxForm");e(function(){e(g.s,g.c).ajaxForm(f)});return this}d("terminating; zero elements found by selector"+(e.isReady?"":" (DOM not ready)"));return this}if(f.delegation){e(document).off("submit.form-plugin",this.selector,b).off("click.form-plugin",this.selector,a).on("submit.form-plugin",this.selector,f,b).on("click.form-plugin",this.selector,f,a);return this}return this.ajaxFormUnbind().bind("submit.form-plugin",f,b).bind("click.form-plugin",f,a)};function b(g){var f=g.data;if(!g.isDefaultPrevented()){g.preventDefault();e(this).ajaxSubmit(f)}}function a(j){var i=j.target;var g=e(i);if(!(g.is(":submit,input:image"))){var f=g.closest(":submit");if(f.length===0){return}i=f[0]}var h=this;h.clk=i;if(i.type=="image"){if(j.offsetX!==undefined){h.clk_x=j.offsetX;h.clk_y=j.offsetY}else{if(typeof e.fn.offset=="function"){var k=g.offset();h.clk_x=j.pageX-k.left;h.clk_y=j.pageY-k.top}else{h.clk_x=j.pageX-i.offsetLeft;h.clk_y=j.pageY-i.offsetTop}}}setTimeout(function(){h.clk=h.clk_x=h.clk_y=null},100)}e.fn.ajaxFormUnbind=function(){return this.unbind("submit.form-plugin click.form-plugin")};e.fn.formToArray=function(w,f){var u=[];if(this.length===0){return u}var k=this[0];var o=w?k.getElementsByTagName("*"):k.elements;if(!o){return u}var q,p,m,x,l,s,h;for(q=0,s=o.length;q<s;q++){l=o[q];m=l.name;if(!m){continue}if(w&&k.clk&&l.type=="image"){if(!l.disabled&&k.clk==l){u.push({name:m,value:e(l).val(),type:l.type});u.push({name:m+".x",value:k.clk_x},{name:m+".y",value:k.clk_y})}continue}x=e.fieldValue(l,true);if(x&&x.constructor==Array){if(f){f.push(l)}for(p=0,h=x.length;p<h;p++){u.push({name:m,value:x[p]})}}else{if(c.fileapi&&l.type=="file"&&!l.disabled){if(f){f.push(l)}var g=l.files;if(g.length){for(p=0;p<g.length;p++){u.push({name:m,value:g[p],type:l.type})}}else{u.push({name:m,value:"",type:l.type})}}else{if(x!==null&&typeof x!="undefined"){if(f){f.push(l)}u.push({name:m,value:x,type:l.type,required:l.required})}}}}if(!w&&k.clk){var r=e(k.clk),t=r[0];m=t.name;if(m&&!t.disabled&&t.type=="image"){u.push({name:m,value:r.val()});u.push({name:m+".x",value:k.clk_x},{name:m+".y",value:k.clk_y})}}return u};e.fn.formSerialize=function(f){return e.param(this.formToArray(f))};e.fn.fieldSerialize=function(g){var f=[];this.each(function(){var l=this.name;if(!l){return}var j=e.fieldValue(this,g);if(j&&j.constructor==Array){for(var k=0,h=j.length;k<h;k++){f.push({name:l,value:j[k]})}}else{if(j!==null&&typeof j!="undefined"){f.push({name:this.name,value:j})}}});return e.param(f)};e.fn.fieldValue=function(l){for(var k=[],h=0,f=this.length;h<f;h++){var j=this[h];var g=e.fieldValue(j,l);if(g===null||typeof g=="undefined"||(g.constructor==Array&&!g.length)){continue}if(g.constructor==Array){e.merge(k,g)}else{k.push(g)}}return k};e.fieldValue=function(f,m){var h=f.name,s=f.type,u=f.tagName.toLowerCase();if(m===undefined){m=true}if(m&&(!h||f.disabled||s=="reset"||s=="button"||(s=="checkbox"||s=="radio")&&!f.checked||(s=="submit"||s=="image")&&f.form&&f.form.clk!=f||u=="select"&&f.selectedIndex==-1)){return null}if(u=="select"){var o=f.selectedIndex;if(o<0){return null}var q=[],g=f.options;var k=(s=="select-one");var p=(k?o+1:g.length);for(var j=(k?o:0);j<p;j++){var l=g[j];if(l.selected){var r=l.value;if(!r){r=(l.attributes&&l.attributes.value&&!(l.attributes.value.specified))?l.text:l.value}if(k){return r}q.push(r)}}return q}return e(f).val()};e.fn.clearForm=function(f){return this.each(function(){e("input,select,textarea",this).clearFields(f)})};e.fn.clearFields=e.fn.clearInputs=function(f){var g=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i;return this.each(function(){var i=this.type,h=this.tagName.toLowerCase();if(g.test(i)||h=="textarea"){this.value=""}else{if(i=="checkbox"||i=="radio"){this.checked=false}else{if(h=="select"){this.selectedIndex=-1}else{if(f){if((f===true&&/hidden/.test(i))||(typeof f=="string"&&e(this).is(f))){this.value=""}}}}}})};e.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset()}})};e.fn.enable=function(f){if(f===undefined){f=true}return this.each(function(){this.disabled=!f})};e.fn.selected=function(f){if(f===undefined){f=true}return this.each(function(){var g=this.type;if(g=="checkbox"||g=="radio"){this.checked=f}else{if(this.tagName.toLowerCase()=="option"){var h=e(this).parent("select");if(f&&h[0]&&h[0].type=="select-one"){h.find("option").selected(false)}this.selected=f}}})};e.fn.ajaxSubmit.debug=false;function d(){if(!e.fn.ajaxSubmit.debug){return}var f="[jquery.form] "+Array.prototype.join.call(arguments,"");if(window.console&&window.console.log){window.console.log(f)}else{if(window.opera&&window.opera.postError){window.opera.postError(f)}}}})(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  /*!
2
  * jQuery Form Plugin
3
+ * version: 3.15 (09-SEP-2012)
4
  * @requires jQuery v1.3.2 or later
5
  *
6
  * Examples and documentation at: http://malsup.com/jquery/form/
9
  * http://malsup.github.com/mit-license.txt
10
  * http://malsup.github.com/gpl-license-v2.txt
11
  */
12
+ /*global ActiveXObject alert */
13
+ ;(function($) {
14
+ "use strict";
15
+
16
+ /*
17
+ Usage Note:
18
+ -----------
19
+ Do not use both ajaxSubmit and ajaxForm on the same form. These
20
+ functions are mutually exclusive. Use ajaxSubmit if you want
21
+ to bind your own submit handler to the form. For example,
22
+
23
+ $(document).ready(function() {
24
+ $('#myForm').on('submit', function(e) {
25
+ e.preventDefault(); // <-- important
26
+ $(this).ajaxSubmit({
27
+ target: '#output'
28
+ });
29
+ });
30
+ });
31
+
32
+ Use ajaxForm when you want the plugin to manage all the event binding
33
+ for you. For example,
34
+
35
+ $(document).ready(function() {
36
+ $('#myForm').ajaxForm({
37
+ target: '#output'
38
+ });
39
+ });
40
+
41
+ You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
42
+ form does not have to exist when you invoke ajaxForm:
43
+
44
+ $('#myForm').ajaxForm({
45
+ delegation: true,
46
+ target: '#output'
47
+ });
48
+
49
+ When using ajaxForm, the ajaxSubmit function will be invoked for you
50
+ at the appropriate time.
51
+ */
52
+
53
+ /**
54
+ * Feature detection
55
+ */
56
+ var feature = {};
57
+ feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
58
+ feature.formdata = window.FormData !== undefined;
59
+
60
+ /**
61
+ * ajaxSubmit() provides a mechanism for immediately submitting
62
+ * an HTML form using AJAX.
63
+ */
64
+ $.fn.ajaxSubmit = function(options) {
65
+ /*jshint scripturl:true */
66
+
67
+ // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
68
+ if (!this.length) {
69
+ log('ajaxSubmit: skipping submit process - no element selected');
70
+ return this;
71
+ }
72
+
73
+ var method, action, url, $form = this;
74
+
75
+ if (typeof options == 'function') {
76
+ options = { success: options };
77
+ }
78
+
79
+ method = this.attr('method');
80
+ action = this.attr('action');
81
+ url = (typeof action === 'string') ? $.trim(action) : '';
82
+ url = url || window.location.href || '';
83
+ if (url) {
84
+ // clean url (don't include hash vaue)
85
+ url = (url.match(/^([^#]+)/)||[])[1];
86
+ }
87
+
88
+ options = $.extend(true, {
89
+ url: url,
90
+ success: $.ajaxSettings.success,
91
+ type: method || 'GET',
92
+ iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
93
+ }, options);
94
+
95
+ // hook for manipulating the form data before it is extracted;
96
+ // convenient for use with rich editors like tinyMCE or FCKEditor
97
+ var veto = {};
98
+ this.trigger('form-pre-serialize', [this, options, veto]);
99
+ if (veto.veto) {
100
+ log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
101
+ return this;
102
+ }
103
+
104
+ // provide opportunity to alter form data before it is serialized
105
+ if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
106
+ log('ajaxSubmit: submit aborted via beforeSerialize callback');
107
+ return this;
108
+ }
109
+
110
+ var traditional = options.traditional;
111
+ if ( traditional === undefined ) {
112
+ traditional = $.ajaxSettings.traditional;
113
+ }
114
+
115
+ var elements = [];
116
+ var qx, a = this.formToArray(options.semantic, elements);
117
+ if (options.data) {
118
+ options.extraData = options.data;
119
+ qx = $.param(options.data, traditional);
120
+ }
121
+
122
+ // give pre-submit callback an opportunity to abort the submit
123
+ if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
124
+ log('ajaxSubmit: submit aborted via beforeSubmit callback');
125
+ return this;
126
+ }
127
+
128
+ // fire vetoable 'validate' event
129
+ this.trigger('form-submit-validate', [a, this, options, veto]);
130
+ if (veto.veto) {
131
+ log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
132
+ return this;
133
+ }
134
+
135
+ var q = $.param(a, traditional);
136
+ if (qx) {
137
+ q = ( q ? (q + '&' + qx) : qx );
138
+ }
139
+ if (options.type.toUpperCase() == 'GET') {
140
+ options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
141
+ options.data = null; // data is null for 'get'
142
+ }
143
+ else {
144
+ options.data = q; // data is the query string for 'post'
145
+ }
146
+
147
+ var callbacks = [];
148
+ if (options.resetForm) {
149
+ callbacks.push(function() { $form.resetForm(); });
150
+ }
151
+ if (options.clearForm) {
152
+ callbacks.push(function() { $form.clearForm(options.includeHidden); });
153
+ }
154
+
155
+ // perform a load on the target only if dataType is not provided
156
+ if (!options.dataType && options.target) {
157
+ var oldSuccess = options.success || function(){};
158
+ callbacks.push(function(data) {
159
+ var fn = options.replaceTarget ? 'replaceWith' : 'html';
160
+ $(options.target)[fn](data).each(oldSuccess, arguments);
161
+ });
162
+ }
163
+ else if (options.success) {
164
+ callbacks.push(options.success);
165
+ }
166
+
167
+ options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
168
+ var context = options.context || this ; // jQuery 1.4+ supports scope context
169
+ for (var i=0, max=callbacks.length; i < max; i++) {
170
+ callbacks[i].apply(context, [data, status, xhr || $form, $form]);
171
+ }
172
+ };
173
+
174
+ // are there files to upload?
175
+ var fileInputs = $('input:file:enabled[value]', this); // [value] (issue #113)
176
+ var hasFileInputs = fileInputs.length > 0;
177
+ var mp = 'multipart/form-data';
178
+ var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
179
+
180
+ var fileAPI = feature.fileapi && feature.formdata;
181
+ log("fileAPI :" + fileAPI);
182
+ var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
183
+
184
+ // options.iframe allows user to force iframe mode
185
+ // 06-NOV-09: now defaulting to iframe mode if file input is detected
186
+ if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
187
+ // hack to fix Safari hang (thanks to Tim Molendijk for this)
188
+ // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
189
+ if (options.closeKeepAlive) {
190
+ $.get(options.closeKeepAlive, function() {
191
+ fileUploadIframe(a);
192
+ });
193
+ }
194
+ else {
195
+ fileUploadIframe(a);
196
+ }
197
+ }
198
+ else if ((hasFileInputs || multipart) && fileAPI) {
199
+ fileUploadXhr(a);
200
+ }
201
+ else {
202
+ $.ajax(options);
203
+ }
204
+
205
+ // clear element array
206
+ for (var k=0; k < elements.length; k++)
207
+ elements[k] = null;
208
+
209
+ // fire 'notify' event
210
+ this.trigger('form-submit-notify', [this, options]);
211
+ return this;
212
+
213
+ // utility fn for deep serialization
214
+ function deepSerialize(extraData){
215
+ var serialized = $.param(extraData).split('&');
216
+ var len = serialized.length;
217
+ var result = {};
218
+ var i, part;
219
+ for (i=0; i < len; i++) {
220
+ part = serialized[i].split('=');
221
+ result[decodeURIComponent(part[0])] = decodeURIComponent(part[1]);
222
+ }
223
+ return result;
224
+ }
225
+
226
+ // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
227
+ function fileUploadXhr(a) {
228
+ var formdata = new FormData();
229
+
230
+ for (var i=0; i < a.length; i++) {
231
+ formdata.append(a[i].name, a[i].value);
232
+ }
233
+
234
+ if (options.extraData) {
235
+ var serializedData = deepSerialize(options.extraData);
236
+ for (var p in serializedData)
237
+ if (serializedData.hasOwnProperty(p))
238
+ formdata.append(p, serializedData[p]);
239
+ }
240
+
241
+ options.data = null;
242
+
243
+ var s = $.extend(true, {}, $.ajaxSettings, options, {
244
+ contentType: false,
245
+ processData: false,
246
+ cache: false,
247
+ type: 'POST'
248
+ });
249
+
250
+ if (options.uploadProgress) {
251
+ // workaround because jqXHR does not expose upload property
252
+ s.xhr = function() {
253
+ var xhr = jQuery.ajaxSettings.xhr();
254
+ if (xhr.upload) {
255
+ xhr.upload.onprogress = function(event) {
256
+ var percent = 0;
257
+ var position = event.loaded || event.position; /*event.position is deprecated*/
258
+ var total = event.total;
259
+ if (event.lengthComputable) {
260
+ percent = Math.ceil(position / total * 100);
261
+ }
262
+ options.uploadProgress(event, position, total, percent);
263
+ };
264
+ }
265
+ return xhr;
266
+ };
267
+ }
268
+
269
+ s.data = null;
270
+ var beforeSend = s.beforeSend;
271
+ s.beforeSend = function(xhr, o) {
272
+ o.data = formdata;
273
+ if(beforeSend)
274
+ beforeSend.call(this, xhr, o);
275
+ };
276
+ $.ajax(s);
277
+ }
278
+
279
+ // private function for handling file uploads (hat tip to YAHOO!)
280
+ function fileUploadIframe(a) {
281
+ var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
282
+ var useProp = !!$.fn.prop;
283
+
284
+ if ($(':input[name=submit],:input[id=submit]', form).length) {
285
+ // if there is an input with a name or id of 'submit' then we won't be
286
+ // able to invoke the submit fn on the form (at least not x-browser)
287
+ alert('Error: Form elements must not have name or id of "submit".');
288
+ return;
289
+ }
290
+
291
+ if (a) {
292
+ // ensure that every serialized input is still enabled
293
+ for (i=0; i < elements.length; i++) {
294
+ el = $(elements[i]);
295
+ if ( useProp )
296
+ el.prop('disabled', false);
297
+ else
298
+ el.removeAttr('disabled');
299
+ }
300
+ }
301
+
302
+ s = $.extend(true, {}, $.ajaxSettings, options);
303
+ s.context = s.context || s;
304
+ id = 'jqFormIO' + (new Date().getTime());
305
+ if (s.iframeTarget) {
306
+ $io = $(s.iframeTarget);
307
+ n = $io.attr('name');
308
+ if (!n)
309
+ $io.attr('name', id);
310
+ else
311
+ id = n;
312
+ }
313
+ else {
314
+ $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
315
+ $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
316
+ }
317
+ io = $io[0];
318
+
319
+
320
+ xhr = { // mock object
321
+ aborted: 0,
322
+ responseText: null,
323
+ responseXML: null,
324
+ status: 0,
325
+ statusText: 'n/a',
326
+ getAllResponseHeaders: function() {},
327
+ getResponseHeader: function() {},
328
+ setRequestHeader: function() {},
329
+ abort: function(status) {
330
+ var e = (status === 'timeout' ? 'timeout' : 'aborted');
331
+ log('aborting upload... ' + e);
332
+ this.aborted = 1;
333
+ // #214
334
+ if (io.contentWindow.document.execCommand) {
335
+ try { // #214
336
+ io.contentWindow.document.execCommand('Stop');
337
+ } catch(ignore) {}
338
+ }
339
+ $io.attr('src', s.iframeSrc); // abort op in progress
340
+ xhr.error = e;
341
+ if (s.error)
342
+ s.error.call(s.context, xhr, e, status);
343
+ if (g)
344
+ $.event.trigger("ajaxError", [xhr, s, e]);
345
+ if (s.complete)
346
+ s.complete.call(s.context, xhr, e);
347
+ }
348
+ };
349
+
350
+ g = s.global;
351
+ // trigger ajax global events so that activity/block indicators work like normal
352
+ if (g && 0 === $.active++) {
353
+ $.event.trigger("ajaxStart");
354
+ }
355
+ if (g) {
356
+ $.event.trigger("ajaxSend", [xhr, s]);
357
+ }
358
+
359
+ if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
360
+ if (s.global) {
361
+ $.active--;
362
+ }
363
+ return;
364
+ }
365
+ if (xhr.aborted) {
366
+ return;
367
+ }
368
+
369
+ // add submitting element to data if we know it
370
+ sub = form.clk;
371
+ if (sub) {
372
+ n = sub.name;
373
+ if (n && !sub.disabled) {
374
+ s.extraData = s.extraData || {};
375
+ s.extraData[n] = sub.value;
376
+ if (sub.type == "image") {
377
+ s.extraData[n+'.x'] = form.clk_x;
378
+ s.extraData[n+'.y'] = form.clk_y;
379
+ }
380
+ }
381
+ }
382
+
383
+ var CLIENT_TIMEOUT_ABORT = 1;
384
+ var SERVER_ABORT = 2;
385
+
386
+ function getDoc(frame) {
387
+ var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document;
388
+ return doc;
389
+ }
390
+
391
+ // Rails CSRF hack (thanks to Yvan Barthelemy)
392
+ var csrf_token = $('meta[name=csrf-token]').attr('content');
393
+ var csrf_param = $('meta[name=csrf-param]').attr('content');
394
+ if (csrf_param && csrf_token) {
395
+ s.extraData = s.extraData || {};
396
+ s.extraData[csrf_param] = csrf_token;
397
+ }
398
+
399
+ // take a breath so that pending repaints get some cpu time before the upload starts
400
+ function doSubmit() {
401
+ // make sure form attrs are set
402
+ var t = $form.attr('target'), a = $form.attr('action');
403
+
404
+ // update form attrs in IE friendly way
405
+ form.setAttribute('target',id);
406
+ if (!method) {
407
+ form.setAttribute('method', 'POST');
408
+ }
409
+ if (a != s.url) {
410
+ form.setAttribute('action', s.url);
411
+ }
412
+
413
+ // ie borks in some cases when setting encoding
414
+ if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
415
+ $form.attr({
416
+ encoding: 'multipart/form-data',
417
+ enctype: 'multipart/form-data'
418
+ });
419
+ }
420
+
421
+ // support timout
422
+ if (s.timeout) {
423
+ timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
424
+ }
425
+
426
+ // look for server aborts
427
+ function checkState() {
428
+ try {
429
+ var state = getDoc(io).readyState;
430
+ log('state = ' + state);
431
+ if (state && state.toLowerCase() == 'uninitialized')
432
+ setTimeout(checkState,50);
433
+ }
434
+ catch(e) {
435
+ log('Server abort: ' , e, ' (', e.name, ')');
436
+ cb(SERVER_ABORT);
437
+ if (timeoutHandle)
438
+ clearTimeout(timeoutHandle);
439
+ timeoutHandle = undefined;
440
+ }
441
+ }
442
+
443
+ // add "extra" data to form if provided in options
444
+ var extraInputs = [];
445
+ try {
446
+ if (s.extraData) {
447
+ for (var n in s.extraData) {
448
+ if (s.extraData.hasOwnProperty(n)) {
449
+ // if using the $.param format that allows for multiple values with the same name
450
+ if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
451
+ extraInputs.push(
452
+ $('<input type="hidden" name="'+s.extraData[n].name+'">').attr('value',s.extraData[n].value)
453
+ .appendTo(form)[0]);
454
+ } else {
455
+ extraInputs.push(
456
+ $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
457
+ .appendTo(form)[0]);
458
+ }
459
+ }
460
+ }
461
+ }
462
+
463
+ if (!s.iframeTarget) {
464
+ // add iframe to doc and submit the form
465
+ $io.appendTo('body');
466
+ if (io.attachEvent)
467
+ io.attachEvent('onload', cb);
468
+ else
469
+ io.addEventListener('load', cb, false);
470
+ }
471
+ setTimeout(checkState,15);
472
+ form.submit();
473
+ }
474
+ finally {
475
+ // reset attrs and remove "extra" input elements
476
+ form.setAttribute('action',a);
477
+ if(t) {
478
+ form.setAttribute('target', t);
479
+ } else {
480
+ $form.removeAttr('target');
481
+ }
482
+ $(extraInputs).remove();
483
+ }
484
+ }
485
+
486
+ if (s.forceSync) {
487
+ doSubmit();
488
+ }
489
+ else {
490
+ setTimeout(doSubmit, 10); // this lets dom updates render
491
+ }
492
+
493
+ var data, doc, domCheckCount = 50, callbackProcessed;
494
+
495
+ function cb(e) {
496
+ if (xhr.aborted || callbackProcessed) {
497
+ return;
498
+ }
499
+ try {
500
+ doc = getDoc(io);
501
+ }
502
+ catch(ex) {
503
+ log('cannot access response document: ', ex);
504
+ e = SERVER_ABORT;
505
+ }
506
+ if (e === CLIENT_TIMEOUT_ABORT && xhr) {
507
+ xhr.abort('timeout');
508
+ return;
509
+ }
510
+ else if (e == SERVER_ABORT && xhr) {
511
+ xhr.abort('server abort');
512
+ return;
513
+ }
514
+
515
+ if (!doc || doc.location.href == s.iframeSrc) {
516
+ // response not received yet
517
+ if (!timedOut)
518
+ return;
519
+ }
520
+ if (io.detachEvent)
521
+ io.detachEvent('onload', cb);
522
+ else
523
+ io.removeEventListener('load', cb, false);
524
+
525
+ var status = 'success', errMsg;
526
+ try {
527
+ if (timedOut) {
528
+ throw 'timeout';
529
+ }
530
+
531
+ var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
532
+ log('isXml='+isXml);
533
+ if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
534
+ if (--domCheckCount) {
535
+ // in some browsers (Opera) the iframe DOM is not always traversable when
536
+ // the onload callback fires, so we loop a bit to accommodate
537
+ log('requeing onLoad callback, DOM not available');
538
+ setTimeout(cb, 250);
539
+ return;
540
+ }
541
+ // let this fall through because server response could be an empty document
542
+ //log('Could not access iframe DOM after mutiple tries.');
543
+ //throw 'DOMException: not available';
544
+ }
545
+
546
+ //log('response detected');
547
+ var docRoot = doc.body ? doc.body : doc.documentElement;
548
+ xhr.responseText = docRoot ? docRoot.innerHTML : null;
549
+ xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
550
+ if (isXml)
551
+ s.dataType = 'xml';
552
+ xhr.getResponseHeader = function(header){
553
+ var headers = {'content-type': s.dataType};
554
+ return headers[header];
555
+ };
556
+ // support for XHR 'status' & 'statusText' emulation :
557
+ if (docRoot) {
558
+ xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
559
+ xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
560
+ }
561
+
562
+ var dt = (s.dataType || '').toLowerCase();
563
+ var scr = /(json|script|text)/.test(dt);
564
+ if (scr || s.textarea) {
565
+ // see if user embedded response in textarea
566
+ var ta = doc.getElementsByTagName('textarea')[0];
567
+ if (ta) {
568
+ xhr.responseText = ta.value;
569
+ // support for XHR 'status' & 'statusText' emulation :
570
+ xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
571
+ xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
572
+ }
573
+ else if (scr) {
574
+ // account for browsers injecting pre around json response
575
+ var pre = doc.getElementsByTagName('pre')[0];
576
+ var b = doc.getElementsByTagName('body')[0];
577
+ if (pre) {
578
+ xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
579
+ }
580
+ else if (b) {
581
+ xhr.responseText = b.textContent ? b.textContent : b.innerText;
582
+ }
583
+ }
584
+ }
585
+ else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
586
+ xhr.responseXML = toXml(xhr.responseText);
587
+ }
588
+
589
+ try {
590
+ data = httpData(xhr, dt, s);
591
+ }
592
+ catch (e) {
593
+ status = 'parsererror';
594
+ xhr.error = errMsg = (e || status);
595
+ }
596
+ }
597
+ catch (e) {
598
+ log('error caught: ',e);
599
+ status = 'error';
600
+ xhr.error = errMsg = (e || status);
601
+ }
602
+
603
+ if (xhr.aborted) {
604
+ log('upload aborted');
605
+ status = null;
606
+ }
607
+
608
+ if (xhr.status) { // we've set xhr.status
609
+ status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
610
+ }
611
+
612
+ // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
613
+ if (status === 'success') {
614
+ if (s.success)
615
+ s.success.call(s.context, data, 'success', xhr);
616
+ if (g)
617
+ $.event.trigger("ajaxSuccess", [xhr, s]);
618
+ }
619
+ else if (status) {
620
+ if (errMsg === undefined)
621
+ errMsg = xhr.statusText;
622
+ if (s.error)
623
+ s.error.call(s.context, xhr, status, errMsg);
624
+ if (g)
625
+ $.event.trigger("ajaxError", [xhr, s, errMsg]);
626
+ }
627
+
628
+ if (g)
629
+ $.event.trigger("ajaxComplete", [xhr, s]);
630
+
631
+ if (g && ! --$.active) {
632
+ $.event.trigger("ajaxStop");
633
+ }
634
+
635
+ if (s.complete)
636
+ s.complete.call(s.context, xhr, status);
637
+
638
+ callbackProcessed = true;
639
+ if (s.timeout)
640
+ clearTimeout(timeoutHandle);
641
+
642
+ // clean up
643
+ setTimeout(function() {
644
+ if (!s.iframeTarget)
645
+ $io.remove();
646
+ xhr.responseXML = null;
647
+ }, 100);
648
+ }
649
+
650
+ var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
651
+ if (window.ActiveXObject) {
652
+ doc = new ActiveXObject('Microsoft.XMLDOM');
653
+ doc.async = 'false';
654
+ doc.loadXML(s);
655
+ }
656
+ else {
657
+ doc = (new DOMParser()).parseFromString(s, 'text/xml');
658
+ }
659
+ return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
660
+ };
661
+ var parseJSON = $.parseJSON || function(s) {
662
+ /*jslint evil:true */
663
+ return window['eval']('(' + s + ')');
664
+ };
665
+
666
+ var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
667
+
668
+ var ct = xhr.getResponseHeader('content-type') || '',
669
+ xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
670
+ data = xml ? xhr.responseXML : xhr.responseText;
671
+
672
+ if (xml && data.documentElement.nodeName === 'parsererror') {
673
+ if ($.error)
674
+ $.error('parsererror');
675
+ }
676
+ if (s && s.dataFilter) {
677
+ data = s.dataFilter(data, type);
678
+ }
679
+ if (typeof data === 'string') {
680
+ if (type === 'json' || !type && ct.indexOf('json') >= 0) {
681
+ data = parseJSON(data);
682
+ } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
683
+ $.globalEval(data);
684
+ }
685
+ }
686
+ return data;
687
+ };
688
+ }
689
+ };
690
+
691
+ /**
692
+ * ajaxForm() provides a mechanism for fully automating form submission.
693
+ *
694
+ * The advantages of using this method instead of ajaxSubmit() are:
695
+ *
696
+ * 1: This method will include coordinates for <input type="image" /> elements (if the element
697
+ * is used to submit the form).
698
+ * 2. This method will include the submit element's name/value data (for the element that was
699
+ * used to submit the form).
700
+ * 3. This method binds the submit() method to the form for you.
701
+ *
702
+ * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
703
+ * passes the options argument along after properly binding events for submit elements and
704
+ * the form itself.
705
+ */
706
+ $.fn.ajaxForm = function(options) {
707
+ options = options || {};
708
+ options.delegation = options.delegation && $.isFunction($.fn.on);
709
+
710
+ // in jQuery 1.3+ we can fix mistakes with the ready state
711
+ if (!options.delegation && this.length === 0) {
712
+ var o = { s: this.selector, c: this.context };
713
+ if (!$.isReady && o.s) {
714
+ log('DOM not ready, queuing ajaxForm');
715
+ $(function() {
716
+ $(o.s,o.c).ajaxForm(options);
717
+ });
718
+ return this;
719
+ }
720
+ // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
721
+ log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
722
+ return this;
723
+ }
724
+
725
+ if ( options.delegation ) {
726
+ $(document)
727
+ .off('submit.form-plugin', this.selector, doAjaxSubmit)
728
+ .off('click.form-plugin', this.selector, captureSubmittingElement)
729
+ .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
730
+ .on('click.form-plugin', this.selector, options, captureSubmittingElement);
731
+ return this;
732
+ }
733
+
734
+ return this.ajaxFormUnbind()
735
+ .bind('submit.form-plugin', options, doAjaxSubmit)
736
+ .bind('click.form-plugin', options, captureSubmittingElement);
737
+ };
738
+
739
+ // private event handlers
740
+ function doAjaxSubmit(e) {
741
+ /*jshint validthis:true */
742
+ var options = e.data;
743
+ if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
744
+ e.preventDefault();
745
+ $(this).ajaxSubmit(options);
746
+ }
747
+ }
748
+
749
+ function captureSubmittingElement(e) {
750
+ /*jshint validthis:true */
751
+ var target = e.target;
752
+ var $el = $(target);
753
+ if (!($el.is(":submit,input:image"))) {
754
+ // is this a child element of the submit el? (ex: a span within a button)
755
+ var t = $el.closest(':submit');
756
+ if (t.length === 0) {
757
+ return;
758
+ }
759
+ target = t[0];
760
+ }
761
+ var form = this;
762
+ form.clk = target;
763
+ if (target.type == 'image') {
764
+ if (e.offsetX !== undefined) {
765
+ form.clk_x = e.offsetX;
766
+ form.clk_y = e.offsetY;
767
+ } else if (typeof $.fn.offset == 'function') {
768
+ var offset = $el.offset();
769
+ form.clk_x = e.pageX - offset.left;
770
+ form.clk_y = e.pageY - offset.top;
771
+ } else {
772
+ form.clk_x = e.pageX - target.offsetLeft;
773
+ form.clk_y = e.pageY - target.offsetTop;
774
+ }
775
+ }
776
+ // clear form vars
777
+ setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
778
+ }
779
+
780
+
781
+ // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
782
+ $.fn.ajaxFormUnbind = function() {
783
+ return this.unbind('submit.form-plugin click.form-plugin');
784
+ };
785
+
786
+ /**
787
+ * formToArray() gathers form element data into an array of objects that can
788
+ * be passed to any of the following ajax functions: $.get, $.post, or load.
789
+ * Each object in the array has both a 'name' and 'value' property. An example of
790
+ * an array for a simple login form might be:
791
+ *
792
+ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
793
+ *
794
+ * It is this array that is passed to pre-submit callback functions provided to the
795
+ * ajaxSubmit() and ajaxForm() methods.
796
+ */
797
+ $.fn.formToArray = function(semantic, elements) {
798
+ var a = [];
799
+ if (this.length === 0) {
800
+ return a;
801
+ }
802
+
803
+ var form = this[0];
804
+ var els = semantic ? form.getElementsByTagName('*') : form.elements;
805
+ if (!els) {
806
+ return a;
807
+ }
808
+
809
+ var i,j,n,v,el,max,jmax;
810
+ for(i=0, max=els.length; i < max; i++) {
811
+ el = els[i];
812
+ n = el.name;
813
+ if (!n) {
814
+ continue;
815
+ }
816
+
817
+ if (semantic && form.clk && el.type == "image") {
818
+ // handle image inputs on the fly when semantic == true
819
+ if(!el.disabled && form.clk == el) {
820
+ a.push({name: n, value: $(el).val(), type: el.type });
821
+ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
822
+ }
823
+ continue;
824
+ }
825
+
826
+ v = $.fieldValue(el, true);
827
+ if (v && v.constructor == Array) {
828
+ if (elements)
829
+ elements.push(el);
830
+ for(j=0, jmax=v.length; j < jmax; j++) {
831
+ a.push({name: n, value: v[j]});
832
+ }
833
+ }
834
+ else if (feature.fileapi && el.type == 'file' && !el.disabled) {
835
+ if (elements)
836
+ elements.push(el);
837
+ var files = el.files;
838
+ if (files.length) {
839
+ for (j=0; j < files.length; j++) {
840
+ a.push({name: n, value: files[j], type: el.type});
841
+ }
842
+ }
843
+ else {
844
+ // #180
845
+ a.push({ name: n, value: '', type: el.type });
846
+ }
847
+ }
848
+ else if (v !== null && typeof v != 'undefined') {
849
+ if (elements)
850
+ elements.push(el);
851
+ a.push({name: n, value: v, type: el.type, required: el.required});
852
+ }
853
+ }
854
+
855
+ if (!semantic && form.clk) {
856
+ // input type=='image' are not found in elements array! handle it here
857
+ var $input = $(form.clk), input = $input[0];
858
+ n = input.name;
859
+ if (n && !input.disabled && input.type == 'image') {
860
+ a.push({name: n, value: $input.val()});
861
+ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
862
+ }
863
+ }
864
+ return a;
865
+ };
866
+
867
+ /**
868
+ * Serializes form data into a 'submittable' string. This method will return a string
869
+ * in the format: name1=value1&amp;name2=value2
870
+ */
871
+ $.fn.formSerialize = function(semantic) {
872
+ //hand off to jQuery.param for proper encoding
873
+ return $.param(this.formToArray(semantic));
874
+ };
875
+
876
+ /**
877
+ * Serializes all field elements in the jQuery object into a query string.
878
+ * This method will return a string in the format: name1=value1&amp;name2=value2
879
+ */
880
+ $.fn.fieldSerialize = function(successful) {
881
+ var a = [];
882
+ this.each(function() {
883
+ var n = this.name;
884
+ if (!n) {
885
+ return;
886
+ }
887
+ var v = $.fieldValue(this, successful);
888
+ if (v && v.constructor == Array) {
889
+ for (var i=0,max=v.length; i < max; i++) {
890
+ a.push({name: n, value: v[i]});
891
+ }
892
+ }
893
+ else if (v !== null && typeof v != 'undefined') {
894
+ a.push({name: this.name, value: v});
895
+ }
896
+ });
897
+ //hand off to jQuery.param for proper encoding
898
+ return $.param(a);
899
+ };
900
+
901
+ /**
902
+ * Returns the value(s) of the element in the matched set. For example, consider the following form:
903
+ *
904
+ * <form><fieldset>
905
+ * <input name="A" type="text" />
906
+ * <input name="A" type="text" />
907
+ * <input name="B" type="checkbox" value="B1" />
908
+ * <input name="B" type="checkbox" value="B2"/>
909
+ * <input name="C" type="radio" value="C1" />
910
+ * <input name="C" type="radio" value="C2" />
911
+ * </fieldset></form>
912
+ *
913
+ * var v = $(':text').fieldValue();
914
+ * // if no values are entered into the text inputs
915
+ * v == ['','']
916
+ * // if values entered into the text inputs are 'foo' and 'bar'
917
+ * v == ['foo','bar']
918
+ *
919
+ * var v = $(':checkbox').fieldValue();
920
+ * // if neither checkbox is checked
921
+ * v === undefined
922
+ * // if both checkboxes are checked
923
+ * v == ['B1', 'B2']
924
+ *
925
+ * var v = $(':radio').fieldValue();
926
+ * // if neither radio is checked
927
+ * v === undefined
928
+ * // if first radio is checked
929
+ * v == ['C1']
930
+ *
931
+ * The successful argument controls whether or not the field element must be 'successful'
932
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
933
+ * The default value of the successful argument is true. If this value is false the value(s)
934
+ * for each element is returned.
935
+ *
936
+ * Note: This method *always* returns an array. If no valid value can be determined the
937
+ * array will be empty, otherwise it will contain one or more values.
938
+ */
939
+ $.fn.fieldValue = function(successful) {
940
+ for (var val=[], i=0, max=this.length; i < max; i++) {
941
+ var el = this[i];
942
+ var v = $.fieldValue(el, successful);
943
+ if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
944
+ continue;
945
+ }
946
+ if (v.constructor == Array)
947
+ $.merge(val, v);
948
+ else
949
+ val.push(v);
950
+ }
951
+ return val;
952
+ };
953
+
954
+ /**
955
+ * Returns the value of the field element.
956
+ */
957
+ $.fieldValue = function(el, successful) {
958
+ var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
959
+ if (successful === undefined) {
960
+ successful = true;
961
+ }
962
+
963
+ if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
964
+ (t == 'checkbox' || t == 'radio') && !el.checked ||
965
+ (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
966
+ tag == 'select' && el.selectedIndex == -1)) {
967
+ return null;
968
+ }
969
+
970
+ if (tag == 'select') {
971
+ var index = el.selectedIndex;
972
+ if (index < 0) {
973
+ return null;
974
+ }
975
+ var a = [], ops = el.options;
976
+ var one = (t == 'select-one');
977
+ var max = (one ? index+1 : ops.length);
978
+ for(var i=(one ? index : 0); i < max; i++) {
979
+ var op = ops[i];
980
+ if (op.selected) {
981
+ var v = op.value;
982
+ if (!v) { // extra pain for IE...
983
+ v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
984
+ }
985
+ if (one) {
986
+ return v;
987
+ }
988
+ a.push(v);
989
+ }
990
+ }
991
+ return a;
992
+ }
993
+ return $(el).val();
994
+ };
995
+
996
+ /**
997
+ * Clears the form data. Takes the following actions on the form's input fields:
998
+ * - input text fields will have their 'value' property set to the empty string
999
+ * - select elements will have their 'selectedIndex' property set to -1
1000
+ * - checkbox and radio inputs will have their 'checked' property set to false
1001
+ * - inputs of type submit, button, reset, and hidden will *not* be effected
1002
+ * - button elements will *not* be effected
1003
+ */
1004
+ $.fn.clearForm = function(includeHidden) {
1005
+ return this.each(function() {
1006
+ $('input,select,textarea', this).clearFields(includeHidden);
1007
+ });
1008
+ };
1009
+
1010
+ /**
1011
+ * Clears the selected form elements.
1012
+ */
1013
+ $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
1014
+ var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
1015
+ return this.each(function() {
1016
+ var t = this.type, tag = this.tagName.toLowerCase();
1017
+ if (re.test(t) || tag == 'textarea') {
1018
+ this.value = '';
1019
+ }
1020
+ else if (t == 'checkbox' || t == 'radio') {
1021
+ this.checked = false;
1022
+ }
1023
+ else if (tag == 'select') {
1024
+ this.selectedIndex = -1;
1025
+ }
1026
+ else if (includeHidden) {
1027
+ // includeHidden can be the value true, or it can be a selector string
1028
+ // indicating a special test; for example:
1029
+ // $('#myForm').clearForm('.special:hidden')
1030
+ // the above would clean hidden inputs that have the class of 'special'
1031
+ if ( (includeHidden === true && /hidden/.test(t)) ||
1032
+ (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
1033
+ this.value = '';
1034
+ }
1035
+ });
1036
+ };
1037
+
1038
+ /**
1039
+ * Resets the form data. Causes all form elements to be reset to their original value.
1040
+ */
1041
+ $.fn.resetForm = function() {
1042
+ return this.each(function() {
1043
+ // guard against an input with the name of 'reset'
1044
+ // note that IE reports the reset function as an 'object'
1045
+ if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
1046
+ this.reset();
1047
+ }
1048
+ });
1049
+ };
1050
+
1051
+ /**
1052
+ * Enables or disables any matching elements.
1053
+ */
1054
+ $.fn.enable = function(b) {
1055
+ if (b === undefined) {
1056
+ b = true;
1057
+ }
1058
+ return this.each(function() {
1059
+ this.disabled = !b;
1060
+ });
1061
+ };
1062
+
1063
+ /**
1064
+ * Checks/unchecks any matching checkboxes or radio buttons and
1065
+ * selects/deselects and matching option elements.
1066
+ */
1067
+ $.fn.selected = function(select) {
1068
+ if (select === undefined) {
1069
+ select = true;
1070
+ }
1071
+ return this.each(function() {
1072
+ var t = this.type;
1073
+ if (t == 'checkbox' || t == 'radio') {
1074
+ this.checked = select;
1075
+ }
1076
+ else if (this.tagName.toLowerCase() == 'option') {
1077
+ var $sel = $(this).parent('select');
1078
+ if (select && $sel[0] && $sel[0].type == 'select-one') {
1079
+ // deselect all other options
1080
+ $sel.find('option').selected(false);
1081
+ }
1082
+ this.selected = select;
1083
+ }
1084
+ });
1085
+ };
1086
+
1087
+ // expose debug var
1088
+ $.fn.ajaxSubmit.debug = false;
1089
+
1090
+ // helper fn for console logging
1091
+ function log() {
1092
+ if (!$.fn.ajaxSubmit.debug)
1093
+ return;
1094
+ var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
1095
+ if (window.console && window.console.log) {
1096
+ window.console.log(msg);
1097
+ }
1098
+ else if (window.opera && window.opera.postError) {
1099
+ window.opera.postError(msg);
1100
+ }
1101
+ }
1102
+
1103
+ })(jQuery);
includes/js/jquery.form.min.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery Form Plugin
3
+ * version: 3.15 (09-SEP-2012)
4
+ * @requires jQuery v1.3.2 or later
5
+ *
6
+ * Examples and documentation at: http://malsup.com/jquery/form/
7
+ * Project repository: https://github.com/malsup/form
8
+ * Dual licensed under the MIT and GPL licenses:
9
+ * http://malsup.github.com/mit-license.txt
10
+ * http://malsup.github.com/gpl-license-v2.txt
11
+ */
12
+ (function(e){var c={};c.fileapi=e("<input type='file'/>").get(0).files!==undefined;c.formdata=window.FormData!==undefined;e.fn.ajaxSubmit=function(h){if(!this.length){d("ajaxSubmit: skipping submit process - no element selected");return this}var g,x,j,m=this;if(typeof h=="function"){h={success:h}}g=this.attr("method");x=this.attr("action");j=(typeof x==="string")?e.trim(x):"";j=j||window.location.href||"";if(j){j=(j.match(/^([^#]+)/)||[])[1]}h=e.extend(true,{url:j,success:e.ajaxSettings.success,type:g||"GET",iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},h);var s={};this.trigger("form-pre-serialize",[this,h,s]);if(s.veto){d("ajaxSubmit: submit vetoed via form-pre-serialize trigger");return this}if(h.beforeSerialize&&h.beforeSerialize(this,h)===false){d("ajaxSubmit: submit aborted via beforeSerialize callback");return this}var l=h.traditional;if(l===undefined){l=e.ajaxSettings.traditional}var p=[];var A,B=this.formToArray(h.semantic,p);if(h.data){h.extraData=h.data;A=e.param(h.data,l)}if(h.beforeSubmit&&h.beforeSubmit(B,this,h)===false){d("ajaxSubmit: submit aborted via beforeSubmit callback");return this}this.trigger("form-submit-validate",[B,this,h,s]);if(s.veto){d("ajaxSubmit: submit vetoed via form-submit-validate trigger");return this}var v=e.param(B,l);if(A){v=(v?(v+"&"+A):A)}if(h.type.toUpperCase()=="GET"){h.url+=(h.url.indexOf("?")>=0?"&":"?")+v;h.data=null}else{h.data=v}var D=[];if(h.resetForm){D.push(function(){m.resetForm()})}if(h.clearForm){D.push(function(){m.clearForm(h.includeHidden)})}if(!h.dataType&&h.target){var i=h.success||function(){};D.push(function(q){var k=h.replaceTarget?"replaceWith":"html";e(h.target)[k](q).each(i,arguments)})}else{if(h.success){D.push(h.success)}}h.success=function(G,q,H){var F=h.context||this;for(var E=0,k=D.length;E<k;E++){D[E].apply(F,[G,q,H||m,m])}};var z=e("input:file:enabled[value]",this);var n=z.length>0;var y="multipart/form-data";var u=(m.attr("enctype")==y||m.attr("encoding")==y);var t=c.fileapi&&c.formdata;d("fileAPI :"+t);var o=(n||u)&&!t;if(h.iframe!==false&&(h.iframe||o)){if(h.closeKeepAlive){e.get(h.closeKeepAlive,function(){C(B)})}else{C(B)}}else{if((n||u)&&t){r(B)}else{e.ajax(h)}}for(var w=0;w<p.length;w++){p[w]=null}this.trigger("form-submit-notify",[this,h]);return this;function f(G){var H=e.param(G).split("&");var q=H.length;var k={};var F,E;for(F=0;F<q;F++){E=H[F].split("=");k[decodeURIComponent(E[0])]=decodeURIComponent(E[1])}return k}function r(q){var k=new FormData();for(var E=0;E<q.length;E++){k.append(q[E].name,q[E].value)}if(h.extraData){var H=f(h.extraData);for(var I in H){if(H.hasOwnProperty(I)){k.append(I,H[I])}}}h.data=null;var G=e.extend(true,{},e.ajaxSettings,h,{contentType:false,processData:false,cache:false,type:"POST"});if(h.uploadProgress){G.xhr=function(){var J=jQuery.ajaxSettings.xhr();if(J.upload){J.upload.onprogress=function(N){var M=0;var K=N.loaded||N.position;var L=N.total;if(N.lengthComputable){M=Math.ceil(K/L*100)}h.uploadProgress(N,K,L,M)}}return J}}G.data=null;var F=G.beforeSend;G.beforeSend=function(K,J){J.data=k;if(F){F.call(this,K,J)}};e.ajax(G)}function C(ac){var H=m[0],G,Y,S,aa,V,J,N,L,M,W,Z,Q;var K=!!e.fn.prop;if(e(":input[name=submit],:input[id=submit]",H).length){alert('Error: Form elements must not have name or id of "submit".');return}if(ac){for(Y=0;Y<p.length;Y++){G=e(p[Y]);if(K){G.prop("disabled",false)}else{G.removeAttr("disabled")}}}S=e.extend(true,{},e.ajaxSettings,h);S.context=S.context||S;V="jqFormIO"+(new Date().getTime());if(S.iframeTarget){J=e(S.iframeTarget);W=J.attr("name");if(!W){J.attr("name",V)}else{V=W}}else{J=e('<iframe name="'+V+'" src="'+S.iframeSrc+'" />');J.css({position:"absolute",top:"-1000px",left:"-1000px"})}N=J[0];L={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(af){var ag=(af==="timeout"?"timeout":"aborted");d("aborting upload... "+ag);this.aborted=1;if(N.contentWindow.document.execCommand){try{N.contentWindow.document.execCommand("Stop")}catch(ah){}}J.attr("src",S.iframeSrc);L.error=ag;if(S.error){S.error.call(S.context,L,ag,af)}if(aa){e.event.trigger("ajaxError",[L,S,ag])}if(S.complete){S.complete.call(S.context,L,ag)}}};aa=S.global;if(aa&&0===e.active++){e.event.trigger("ajaxStart")}if(aa){e.event.trigger("ajaxSend",[L,S])}if(S.beforeSend&&S.beforeSend.call(S.context,L,S)===false){if(S.global){e.active--}return}if(L.aborted){return}M=H.clk;if(M){W=M.name;if(W&&!M.disabled){S.extraData=S.extraData||{};S.extraData[W]=M.value;if(M.type=="image"){S.extraData[W+".x"]=H.clk_x;S.extraData[W+".y"]=H.clk_y}}}var R=1;var O=2;function P(ag){var af=ag.contentWindow?ag.contentWindow.document:ag.contentDocument?ag.contentDocument:ag.document;return af}var F=e("meta[name=csrf-token]").attr("content");var E=e("meta[name=csrf-param]").attr("content");if(E&&F){S.extraData=S.extraData||{};S.extraData[E]=F}function X(){var ah=m.attr("target"),af=m.attr("action");H.setAttribute("target",V);if(!g){H.setAttribute("method","POST")}if(af!=S.url){H.setAttribute("action",S.url)}if(!S.skipEncodingOverride&&(!g||/post/i.test(g))){m.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"})}if(S.timeout){Q=setTimeout(function(){Z=true;U(R)},S.timeout)}function ai(){try{var ak=P(N).readyState;d("state = "+ak);if(ak&&ak.toLowerCase()=="uninitialized"){setTimeout(ai,50)}}catch(al){d("Server abort: ",al," (",al.name,")");U(O);if(Q){clearTimeout(Q)}Q=undefined}}var ag=[];try{if(S.extraData){for(var aj in S.extraData){if(S.extraData.hasOwnProperty(aj)){if(e.isPlainObject(S.extraData[aj])&&S.extraData[aj].hasOwnProperty("name")&&S.extraData[aj].hasOwnProperty("value")){ag.push(e('<input type="hidden" name="'+S.extraData[aj].name+'">').attr("value",S.extraData[aj].value).appendTo(H)[0])}else{ag.push(e('<input type="hidden" name="'+aj+'">').attr("value",S.extraData[aj]).appendTo(H)[0])}}}}if(!S.iframeTarget){J.appendTo("body");if(N.attachEvent){N.attachEvent("onload",U)}else{N.addEventListener("load",U,false)}}setTimeout(ai,15);H.submit()}finally{H.setAttribute("action",af);if(ah){H.setAttribute("target",ah)}else{m.removeAttr("target")}e(ag).remove()}}if(S.forceSync){X()}else{setTimeout(X,10)}var ad,ae,ab=50,I;function U(ak){if(L.aborted||I){return}try{ae=P(N)}catch(an){d("cannot access response document: ",an);ak=O}if(ak===R&&L){L.abort("timeout");return}else{if(ak==O&&L){L.abort("server abort");return}}if(!ae||ae.location.href==S.iframeSrc){if(!Z){return}}if(N.detachEvent){N.detachEvent("onload",U)}else{N.removeEventListener("load",U,false)}var ai="success",am;try{if(Z){throw"timeout"}var ah=S.dataType=="xml"||ae.XMLDocument||e.isXMLDoc(ae);d("isXml="+ah);if(!ah&&window.opera&&(ae.body===null||!ae.body.innerHTML)){if(--ab){d("requeing onLoad callback, DOM not available");setTimeout(U,250);return}}var ao=ae.body?ae.body:ae.documentElement;L.responseText=ao?ao.innerHTML:null;L.responseXML=ae.XMLDocument?ae.XMLDocument:ae;if(ah){S.dataType="xml"}L.getResponseHeader=function(ar){var aq={"content-type":S.dataType};return aq[ar]};if(ao){L.status=Number(ao.getAttribute("status"))||L.status;L.statusText=ao.getAttribute("statusText")||L.statusText}var af=(S.dataType||"").toLowerCase();var al=/(json|script|text)/.test(af);if(al||S.textarea){var aj=ae.getElementsByTagName("textarea")[0];if(aj){L.responseText=aj.value;L.status=Number(aj.getAttribute("status"))||L.status;L.statusText=aj.getAttribute("statusText")||L.statusText}else{if(al){var ag=ae.getElementsByTagName("pre")[0];var ap=ae.getElementsByTagName("body")[0];if(ag){L.responseText=ag.textContent?ag.textContent:ag.innerText}else{if(ap){L.responseText=ap.textContent?ap.textContent:ap.innerText}}}}}else{if(af=="xml"&&!L.responseXML&&L.responseText){L.responseXML=T(L.responseText)}}try{ad=k(L,af,S)}catch(ak){ai="parsererror";L.error=am=(ak||ai)}}catch(ak){d("error caught: ",ak);ai="error";L.error=am=(ak||ai)}if(L.aborted){d("upload aborted");ai=null}if(L.status){ai=(L.status>=200&&L.status<300||L.status===304)?"success":"error"}if(ai==="success"){if(S.success){S.success.call(S.context,ad,"success",L)}if(aa){e.event.trigger("ajaxSuccess",[L,S])}}else{if(ai){if(am===undefined){am=L.statusText}if(S.error){S.error.call(S.context,L,ai,am)}if(aa){e.event.trigger("ajaxError",[L,S,am])}}}if(aa){e.event.trigger("ajaxComplete",[L,S])}if(aa&&!--e.active){e.event.trigger("ajaxStop")}if(S.complete){S.complete.call(S.context,L,ai)}I=true;if(S.timeout){clearTimeout(Q)}setTimeout(function(){if(!S.iframeTarget){J.remove()}L.responseXML=null},100)}var T=e.parseXML||function(af,ag){if(window.ActiveXObject){ag=new ActiveXObject("Microsoft.XMLDOM");ag.async="false";ag.loadXML(af)}else{ag=(new DOMParser()).parseFromString(af,"text/xml")}return(ag&&ag.documentElement&&ag.documentElement.nodeName!="parsererror")?ag:null};var q=e.parseJSON||function(af){return window["eval"]("("+af+")")};var k=function(ak,ai,ah){var ag=ak.getResponseHeader("content-type")||"",af=ai==="xml"||!ai&&ag.indexOf("xml")>=0,aj=af?ak.responseXML:ak.responseText;if(af&&aj.documentElement.nodeName==="parsererror"){if(e.error){e.error("parsererror")}}if(ah&&ah.dataFilter){aj=ah.dataFilter(aj,ai)}if(typeof aj==="string"){if(ai==="json"||!ai&&ag.indexOf("json")>=0){aj=q(aj)}else{if(ai==="script"||!ai&&ag.indexOf("javascript")>=0){e.globalEval(aj)}}}return aj}}};e.fn.ajaxForm=function(f){f=f||{};f.delegation=f.delegation&&e.isFunction(e.fn.on);if(!f.delegation&&this.length===0){var g={s:this.selector,c:this.context};if(!e.isReady&&g.s){d("DOM not ready, queuing ajaxForm");e(function(){e(g.s,g.c).ajaxForm(f)});return this}d("terminating; zero elements found by selector"+(e.isReady?"":" (DOM not ready)"));return this}if(f.delegation){e(document).off("submit.form-plugin",this.selector,b).off("click.form-plugin",this.selector,a).on("submit.form-plugin",this.selector,f,b).on("click.form-plugin",this.selector,f,a);return this}return this.ajaxFormUnbind().bind("submit.form-plugin",f,b).bind("click.form-plugin",f,a)};function b(g){var f=g.data;if(!g.isDefaultPrevented()){g.preventDefault();e(this).ajaxSubmit(f)}}function a(j){var i=j.target;var g=e(i);if(!(g.is(":submit,input:image"))){var f=g.closest(":submit");if(f.length===0){return}i=f[0]}var h=this;h.clk=i;if(i.type=="image"){if(j.offsetX!==undefined){h.clk_x=j.offsetX;h.clk_y=j.offsetY}else{if(typeof e.fn.offset=="function"){var k=g.offset();h.clk_x=j.pageX-k.left;h.clk_y=j.pageY-k.top}else{h.clk_x=j.pageX-i.offsetLeft;h.clk_y=j.pageY-i.offsetTop}}}setTimeout(function(){h.clk=h.clk_x=h.clk_y=null},100)}e.fn.ajaxFormUnbind=function(){return this.unbind("submit.form-plugin click.form-plugin")};e.fn.formToArray=function(w,f){var u=[];if(this.length===0){return u}var k=this[0];var o=w?k.getElementsByTagName("*"):k.elements;if(!o){return u}var q,p,m,x,l,s,h;for(q=0,s=o.length;q<s;q++){l=o[q];m=l.name;if(!m){continue}if(w&&k.clk&&l.type=="image"){if(!l.disabled&&k.clk==l){u.push({name:m,value:e(l).val(),type:l.type});u.push({name:m+".x",value:k.clk_x},{name:m+".y",value:k.clk_y})}continue}x=e.fieldValue(l,true);if(x&&x.constructor==Array){if(f){f.push(l)}for(p=0,h=x.length;p<h;p++){u.push({name:m,value:x[p]})}}else{if(c.fileapi&&l.type=="file"&&!l.disabled){if(f){f.push(l)}var g=l.files;if(g.length){for(p=0;p<g.length;p++){u.push({name:m,value:g[p],type:l.type})}}else{u.push({name:m,value:"",type:l.type})}}else{if(x!==null&&typeof x!="undefined"){if(f){f.push(l)}u.push({name:m,value:x,type:l.type,required:l.required})}}}}if(!w&&k.clk){var r=e(k.clk),t=r[0];m=t.name;if(m&&!t.disabled&&t.type=="image"){u.push({name:m,value:r.val()});u.push({name:m+".x",value:k.clk_x},{name:m+".y",value:k.clk_y})}}return u};e.fn.formSerialize=function(f){return e.param(this.formToArray(f))};e.fn.fieldSerialize=function(g){var f=[];this.each(function(){var l=this.name;if(!l){return}var j=e.fieldValue(this,g);if(j&&j.constructor==Array){for(var k=0,h=j.length;k<h;k++){f.push({name:l,value:j[k]})}}else{if(j!==null&&typeof j!="undefined"){f.push({name:this.name,value:j})}}});return e.param(f)};e.fn.fieldValue=function(l){for(var k=[],h=0,f=this.length;h<f;h++){var j=this[h];var g=e.fieldValue(j,l);if(g===null||typeof g=="undefined"||(g.constructor==Array&&!g.length)){continue}if(g.constructor==Array){e.merge(k,g)}else{k.push(g)}}return k};e.fieldValue=function(f,m){var h=f.name,s=f.type,u=f.tagName.toLowerCase();if(m===undefined){m=true}if(m&&(!h||f.disabled||s=="reset"||s=="button"||(s=="checkbox"||s=="radio")&&!f.checked||(s=="submit"||s=="image")&&f.form&&f.form.clk!=f||u=="select"&&f.selectedIndex==-1)){return null}if(u=="select"){var o=f.selectedIndex;if(o<0){return null}var q=[],g=f.options;var k=(s=="select-one");var p=(k?o+1:g.length);for(var j=(k?o:0);j<p;j++){var l=g[j];if(l.selected){var r=l.value;if(!r){r=(l.attributes&&l.attributes.value&&!(l.attributes.value.specified))?l.text:l.value}if(k){return r}q.push(r)}}return q}return e(f).val()};e.fn.clearForm=function(f){return this.each(function(){e("input,select,textarea",this).clearFields(f)})};e.fn.clearFields=e.fn.clearInputs=function(f){var g=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i;return this.each(function(){var i=this.type,h=this.tagName.toLowerCase();if(g.test(i)||h=="textarea"){this.value=""}else{if(i=="checkbox"||i=="radio"){this.checked=false}else{if(h=="select"){this.selectedIndex=-1}else{if(f){if((f===true&&/hidden/.test(i))||(typeof f=="string"&&e(this).is(f))){this.value=""}}}}}})};e.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset()}})};e.fn.enable=function(f){if(f===undefined){f=true}return this.each(function(){this.disabled=!f})};e.fn.selected=function(f){if(f===undefined){f=true}return this.each(function(){var g=this.type;if(g=="checkbox"||g=="radio"){this.checked=f}else{if(this.tagName.toLowerCase()=="option"){var h=e(this).parent("select");if(f&&h[0]&&h[0].type=="select-one"){h.find("option").selected(false)}this.selected=f}}})};e.fn.ajaxSubmit.debug=false;function d(){if(!e.fn.ajaxSubmit.debug){return}var f="[jquery.form] "+Array.prototype.join.call(arguments,"");if(window.console&&window.console.log){window.console.log(f)}else{if(window.opera&&window.opera.postError){window.opera.postError(f)}}}})(jQuery);
includes/js/scripts.js CHANGED
@@ -43,10 +43,14 @@
43
  ro.addClass('wpcf7-validation-errors');
44
  $(data.into).find('form.wpcf7-form').addClass('invalid');
45
 
 
 
46
  } else if (1 == data.spam) {
47
  ro.addClass('wpcf7-spam-blocked');
48
  $(data.into).find('form.wpcf7-form').addClass('spam');
49
 
 
 
50
  } else if (1 == data.mailSent) {
51
  ro.addClass('wpcf7-mail-sent-ok');
52
  $(data.into).find('form.wpcf7-form').addClass('sent');
@@ -54,14 +58,20 @@
54
  if (data.onSentOk)
55
  $.each(data.onSentOk, function(i, n) { eval(n) });
56
 
 
 
57
  } else {
58
  ro.addClass('wpcf7-mail-sent-ng');
59
  $(data.into).find('form.wpcf7-form').addClass('failed');
 
 
60
  }
61
 
62
  if (data.onSubmit)
63
  $.each(data.onSubmit, function(i, n) { eval(n) });
64
 
 
 
65
  if (1 == data.mailSent)
66
  $(data.into).find('form').resetForm().clearForm();
67
 
43
  ro.addClass('wpcf7-validation-errors');
44
  $(data.into).find('form.wpcf7-form').addClass('invalid');
45
 
46
+ $(data.into).trigger('invalid.wpcf7');
47
+
48
  } else if (1 == data.spam) {
49
  ro.addClass('wpcf7-spam-blocked');
50
  $(data.into).find('form.wpcf7-form').addClass('spam');
51
 
52
+ $(data.into).trigger('spam.wpcf7');
53
+
54
  } else if (1 == data.mailSent) {
55
  ro.addClass('wpcf7-mail-sent-ok');
56
  $(data.into).find('form.wpcf7-form').addClass('sent');
58
  if (data.onSentOk)
59
  $.each(data.onSentOk, function(i, n) { eval(n) });
60
 
61
+ $(data.into).trigger('mailsent.wpcf7');
62
+
63
  } else {
64
  ro.addClass('wpcf7-mail-sent-ng');
65
  $(data.into).find('form.wpcf7-form').addClass('failed');
66
+
67
+ $(data.into).trigger('mailfailed.wpcf7');
68
  }
69
 
70
  if (data.onSubmit)
71
  $.each(data.onSubmit, function(i, n) { eval(n) });
72
 
73
+ $(data.into).trigger('submit.wpcf7');
74
+
75
  if (1 == data.mailSent)
76
  $(data.into).find('form').resetForm().clearForm();
77
 
languages/wpcf7-ar.mo CHANGED
Binary file
languages/wpcf7-de_DE.mo CHANGED
Binary file
languages/wpcf7-ja.mo CHANGED
Binary file
languages/wpcf7.pot CHANGED
@@ -2,8 +2,8 @@ msgid ""
2
  msgstr ""
3
  "Project-Id-Version: Contact Form 7\n"
4
  "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2012-07-30 18:56+0900\n"
6
- "PO-Revision-Date: 2012-07-30 18:56+0900\n"
7
  "Last-Translator: Takayuki Miyoshi <takayukister@gmail.com>\n"
8
  "Language-Team: \n"
9
  "MIME-Version: 1.0\n"
@@ -13,20 +13,21 @@ msgstr ""
13
  "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_c\n"
14
  "X-Poedit-Basepath: ../..\n"
15
  "Plural-Forms: nplurals=1; plural=0;\n"
 
16
  "X-Poedit-SearchPath-0: contact-form-7\n"
17
 
18
  #: contact-form-7/wp-contact-form-7.php:5
19
  msgid "Just another contact form plugin. Simple but flexible."
20
  msgstr ""
21
 
22
- #: contact-form-7/settings.php:167
23
  #, php-format
24
  msgid "Contact form %d"
25
  msgstr ""
26
 
27
- #: contact-form-7/admin/admin.php:8
28
- #: contact-form-7/admin/admin.php:286
29
  #: contact-form-7/admin/edit-contact-form.php:12
 
30
  msgid "Contact Form 7"
31
  msgstr ""
32
 
@@ -43,8 +44,7 @@ msgstr ""
43
  msgid "Edit"
44
  msgstr ""
45
 
46
- #: contact-form-7/admin/admin.php:41
47
- #: contact-form-7/admin/admin.php:113
48
  msgid "You are not allowed to edit this item."
49
  msgstr ""
50
 
@@ -56,8 +56,7 @@ msgstr ""
56
  msgid "Error in deleting."
57
  msgstr ""
58
 
59
- #: contact-form-7/admin/admin.php:196
60
- #: contact-form-7/includes/classes.php:27
61
  msgid "Contact Forms"
62
  msgstr ""
63
 
@@ -65,122 +64,124 @@ msgstr ""
65
  msgid "Generate Tag"
66
  msgstr ""
67
 
68
- #: contact-form-7/admin/admin.php:288
69
- #: contact-form-7/admin/admin.php:320
70
- #: contact-form-7/admin/admin.php:333
71
  #: contact-form-7/admin/edit-contact-form.php:15
72
  msgid "Add New"
73
  msgstr ""
74
 
75
- #: contact-form-7/admin/admin.php:292
76
  #, php-format
77
  msgid "Search results for &#8220;%s&#8221;"
78
  msgstr ""
79
 
80
- #: contact-form-7/admin/admin.php:301
81
  msgid "Search Contact Forms"
82
  msgstr ""
83
 
84
- #: contact-form-7/admin/admin.php:319
85
  #, php-format
86
  msgid "Use the default language (%s)"
87
  msgstr ""
88
 
89
- #: contact-form-7/admin/admin.php:323
90
  msgid "Or"
91
  msgstr ""
92
 
93
- #: contact-form-7/admin/admin.php:328
94
  msgid "(select language)"
95
  msgstr ""
96
 
97
- #: contact-form-7/admin/admin.php:340
98
  msgid "Form"
99
  msgstr ""
100
 
101
- #: contact-form-7/admin/admin.php:343
102
  msgid "Mail"
103
  msgstr ""
104
 
105
- #: contact-form-7/admin/admin.php:346
106
  msgid "Mail (2)"
107
  msgstr ""
108
 
109
- #: contact-form-7/admin/admin.php:351
110
  msgid "Use mail (2)"
111
  msgstr ""
112
 
113
- #: contact-form-7/admin/admin.php:353
114
  msgid "Messages"
115
  msgstr ""
116
 
117
- #: contact-form-7/admin/admin.php:356
118
  msgid "Additional Settings"
119
  msgstr ""
120
 
121
- #: contact-form-7/admin/admin.php:387
122
  msgid "Contact form created."
123
  msgstr ""
124
 
125
- #: contact-form-7/admin/admin.php:389
126
  msgid "Contact form saved."
127
  msgstr ""
128
 
129
- #: contact-form-7/admin/admin.php:391
130
  msgid "Contact form deleted."
131
  msgstr ""
132
 
133
- #: contact-form-7/admin/admin.php:408
134
  msgid "Settings"
135
  msgstr ""
136
 
137
- #: contact-form-7/admin/admin.php:419
138
  msgid "http://contactform7.com/docs/"
139
  msgstr ""
140
 
141
- #: contact-form-7/admin/admin.php:420
142
  msgid "Docs"
143
  msgstr ""
144
 
145
- #: contact-form-7/admin/admin.php:421
146
  msgid "http://contactform7.com/faq/"
147
  msgstr ""
148
 
149
- #: contact-form-7/admin/admin.php:422
150
  msgid "FAQ"
151
  msgstr ""
152
 
153
- #: contact-form-7/admin/admin.php:423
154
  msgid "http://contactform7.com/support/"
155
  msgstr ""
156
 
157
- #: contact-form-7/admin/admin.php:424
158
  msgid "Support"
159
  msgstr ""
160
 
161
- #: contact-form-7/admin/admin.php:455
162
  msgid "Contact Form 7 needs your support. Please donate today."
163
  msgstr ""
164
 
165
- #: contact-form-7/admin/admin.php:456
166
  msgid "Your contribution is needed for making this plugin better."
167
  msgstr ""
168
 
169
- #: contact-form-7/admin/admin.php:462
170
  msgid "http://contactform7.com/donate/"
171
  msgstr ""
172
 
173
- #: contact-form-7/admin/admin.php:462
174
  msgid "Donate"
175
  msgstr ""
176
 
177
- #: contact-form-7/admin/admin.php:482
178
  #, php-format
179
- msgid "<strong>Contact Form 7 %1$s requires WordPress %2$s or higher.</strong> Please <a href=\"%3$s\">update WordPress</a> first."
 
 
180
  msgstr ""
181
 
182
  #: contact-form-7/admin/edit-contact-form.php:46
183
- msgid "Copy this code and paste it into your post, page or text widget content."
 
184
  msgstr ""
185
 
186
  #: contact-form-7/admin/edit-contact-form.php:52
@@ -274,22 +275,26 @@ msgstr ""
274
  msgid "Contact Form"
275
  msgstr ""
276
 
277
- #: contact-form-7/includes/classes.php:739
278
  msgid "Untitled"
279
  msgstr ""
280
 
281
- #: contact-form-7/includes/controller.php:253
282
  msgid "Sending ..."
283
  msgstr ""
284
 
285
  #: contact-form-7/includes/functions.php:21
286
  #, php-format
287
- msgid "%1$s is <strong>deprecated</strong> since Contact Form 7 version %2$s! Use %3$s instead."
 
 
288
  msgstr ""
289
 
290
  #: contact-form-7/includes/functions.php:23
291
  #, php-format
292
- msgid "%1$s is <strong>deprecated</strong> since Contact Form 7 version %2$s with no alternative available."
 
 
293
  msgstr ""
294
 
295
  #: contact-form-7/includes/functions.php:30
@@ -305,7 +310,10 @@ msgid "Sender's message was failed to send"
305
  msgstr ""
306
 
307
  #: contact-form-7/includes/functions.php:36
308
- msgid "Failed to send your message. Please try later or contact the administrator by another method."
 
 
 
309
  msgstr ""
310
 
311
  #: contact-form-7/includes/functions.php:40
@@ -313,7 +321,8 @@ msgid "Validation errors occurred"
313
  msgstr ""
314
 
315
  #: contact-form-7/includes/functions.php:41
316
- msgid "Validation errors occurred. Please confirm the fields and submit it again."
 
317
  msgstr ""
318
 
319
  #: contact-form-7/includes/functions.php:45
@@ -362,6 +371,7 @@ msgid "Your Message"
362
  msgstr ""
363
 
364
  #: contact-form-7/includes/functions.php:88
 
365
  msgid "Send"
366
  msgstr ""
367
 
@@ -623,12 +633,9 @@ msgstr ""
623
 
624
  #: contact-form-7/modules/acceptance.php:165
625
  #: contact-form-7/modules/captcha.php:215
626
- #: contact-form-7/modules/checkbox.php:191
627
- #: contact-form-7/modules/file.php:241
628
- #: contact-form-7/modules/quiz.php:182
629
- #: contact-form-7/modules/select.php:152
630
- #: contact-form-7/modules/text.php:179
631
- #: contact-form-7/modules/textarea.php:140
632
  msgid "Name"
633
  msgstr ""
634
 
@@ -644,26 +651,16 @@ msgstr ""
644
  #: contact-form-7/modules/captcha.php:256
645
  #: contact-form-7/modules/captcha.php:259
646
  #: contact-form-7/modules/checkbox.php:196
647
- #: contact-form-7/modules/checkbox.php:199
648
- #: contact-form-7/modules/file.php:246
649
- #: contact-form-7/modules/file.php:249
650
- #: contact-form-7/modules/file.php:254
651
- #: contact-form-7/modules/file.php:257
652
- #: contact-form-7/modules/quiz.php:187
653
- #: contact-form-7/modules/quiz.php:190
654
- #: contact-form-7/modules/quiz.php:195
655
- #: contact-form-7/modules/quiz.php:198
656
- #: contact-form-7/modules/select.php:157
657
- #: contact-form-7/modules/select.php:160
658
- #: contact-form-7/modules/submit.php:71
659
- #: contact-form-7/modules/submit.php:74
660
- #: contact-form-7/modules/submit.php:79
661
- #: contact-form-7/modules/text.php:184
662
- #: contact-form-7/modules/text.php:187
663
- #: contact-form-7/modules/text.php:192
664
- #: contact-form-7/modules/text.php:195
665
- #: contact-form-7/modules/text.php:200
666
- #: contact-form-7/modules/text.php:211
667
  #: contact-form-7/modules/textarea.php:145
668
  #: contact-form-7/modules/textarea.php:148
669
  #: contact-form-7/modules/textarea.php:153
@@ -686,22 +683,21 @@ msgstr ""
686
 
687
  #: contact-form-7/modules/acceptance.php:186
688
  #: contact-form-7/modules/captcha.php:264
689
- #: contact-form-7/modules/checkbox.php:219
690
- #: contact-form-7/modules/file.php:262
691
- #: contact-form-7/modules/quiz.php:210
692
- #: contact-form-7/modules/select.php:177
693
- #: contact-form-7/modules/submit.php:86
694
- #: contact-form-7/modules/text.php:219
695
  #: contact-form-7/modules/textarea.php:169
696
  msgid "Copy this code and paste it into the form left."
697
  msgstr ""
698
 
699
- #: contact-form-7/modules/akismet.php:110
700
  msgid "Akismet judged the sending activity as spamming"
701
  msgstr ""
702
 
703
  #: contact-form-7/modules/captcha.php:73
704
- msgid "To use CAPTCHA, you need <a href=\"http://wordpress.org/extend/plugins/really-simple-captcha/\">Really Simple CAPTCHA</a> plugin installed."
 
 
705
  msgstr ""
706
 
707
  #: contact-form-7/modules/captcha.php:187
@@ -762,11 +758,16 @@ msgstr ""
762
 
763
  #: contact-form-7/modules/captcha.php:297
764
  #, php-format
765
- msgid "This contact form contains CAPTCHA fields, but the temporary folder for the files (%s) does not exist or is not writable. You can create the folder or change its permission manually."
 
 
 
766
  msgstr ""
767
 
768
  #: contact-form-7/modules/captcha.php:303
769
- msgid "This contact form contains CAPTCHA fields, but the necessary libraries (GD and FreeType) are not available on your server."
 
 
770
  msgstr ""
771
 
772
  #: contact-form-7/modules/checkbox.php:164
@@ -777,10 +778,8 @@ msgstr ""
777
  msgid "Radio buttons"
778
  msgstr ""
779
 
780
- #: contact-form-7/modules/checkbox.php:188
781
- #: contact-form-7/modules/file.php:240
782
- #: contact-form-7/modules/select.php:151
783
- #: contact-form-7/modules/text.php:178
784
  #: contact-form-7/modules/textarea.php:139
785
  msgid "Required field?"
786
  msgstr ""
@@ -808,8 +807,7 @@ msgid "Make checkboxes exclusive?"
808
  msgstr ""
809
 
810
  #: contact-form-7/modules/checkbox.php:221
811
- #: contact-form-7/modules/select.php:179
812
- #: contact-form-7/modules/text.php:221
813
  #: contact-form-7/modules/textarea.php:171
814
  msgid "And, put this code into the Mail fields below."
815
  msgstr ""
@@ -868,12 +866,17 @@ msgstr ""
868
 
869
  #: contact-form-7/modules/file.php:289
870
  #, php-format
871
- msgid "This contact form contains file uploading fields, but the temporary folder for the files (%s) does not exist or is not writable. You can create the folder or change its permission manually."
 
 
 
872
  msgstr ""
873
 
874
  #: contact-form-7/modules/jetpack.php:14
875
  #, php-format
876
- msgid "<strong>Jetpack may cause problems for other plugins in certain cases.</strong> <a href=\"%s\" target=\"_blank\">See how to avoid it.</a>"
 
 
877
  msgstr ""
878
 
879
  #: contact-form-7/modules/quiz.php:159
@@ -940,17 +943,14 @@ msgstr ""
940
  msgid "This field requires author's email address"
941
  msgstr ""
942
 
943
- #: contact-form-7/modules/text.php:211
944
- #: contact-form-7/modules/textarea.php:161
945
  msgid "Default value"
946
  msgstr ""
947
 
948
- #: contact-form-7/modules/text.php:214
949
- #: contact-form-7/modules/textarea.php:164
950
  msgid "Use this text as watermark?"
951
  msgstr ""
952
 
953
  #: contact-form-7/modules/textarea.php:130
954
  msgid "Text area"
955
  msgstr ""
956
-
2
  msgstr ""
3
  "Project-Id-Version: Contact Form 7\n"
4
  "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2012-09-22 19:27+0900\n"
6
+ "PO-Revision-Date: 2012-09-22 19:27+0900\n"
7
  "Last-Translator: Takayuki Miyoshi <takayukister@gmail.com>\n"
8
  "Language-Team: \n"
9
  "MIME-Version: 1.0\n"
13
  "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_c\n"
14
  "X-Poedit-Basepath: ../..\n"
15
  "Plural-Forms: nplurals=1; plural=0;\n"
16
+ "X-Generator: Poedit 1.5.3\n"
17
  "X-Poedit-SearchPath-0: contact-form-7\n"
18
 
19
  #: contact-form-7/wp-contact-form-7.php:5
20
  msgid "Just another contact form plugin. Simple but flexible."
21
  msgstr ""
22
 
23
+ #: contact-form-7/settings.php:193
24
  #, php-format
25
  msgid "Contact form %d"
26
  msgstr ""
27
 
28
+ #: contact-form-7/admin/admin.php:8 contact-form-7/admin/admin.php:258
 
29
  #: contact-form-7/admin/edit-contact-form.php:12
30
+ #: contact-form-7/modules/flamingo.php:14
31
  msgid "Contact Form 7"
32
  msgstr ""
33
 
44
  msgid "Edit"
45
  msgstr ""
46
 
47
+ #: contact-form-7/admin/admin.php:41 contact-form-7/admin/admin.php:113
 
48
  msgid "You are not allowed to edit this item."
49
  msgstr ""
50
 
56
  msgid "Error in deleting."
57
  msgstr ""
58
 
59
+ #: contact-form-7/admin/admin.php:196 contact-form-7/includes/classes.php:27
 
60
  msgid "Contact Forms"
61
  msgstr ""
62
 
64
  msgid "Generate Tag"
65
  msgstr ""
66
 
67
+ #: contact-form-7/admin/admin.php:260 contact-form-7/admin/admin.php:292
68
+ #: contact-form-7/admin/admin.php:305
 
69
  #: contact-form-7/admin/edit-contact-form.php:15
70
  msgid "Add New"
71
  msgstr ""
72
 
73
+ #: contact-form-7/admin/admin.php:264
74
  #, php-format
75
  msgid "Search results for &#8220;%s&#8221;"
76
  msgstr ""
77
 
78
+ #: contact-form-7/admin/admin.php:273
79
  msgid "Search Contact Forms"
80
  msgstr ""
81
 
82
+ #: contact-form-7/admin/admin.php:291
83
  #, php-format
84
  msgid "Use the default language (%s)"
85
  msgstr ""
86
 
87
+ #: contact-form-7/admin/admin.php:295
88
  msgid "Or"
89
  msgstr ""
90
 
91
+ #: contact-form-7/admin/admin.php:300
92
  msgid "(select language)"
93
  msgstr ""
94
 
95
+ #: contact-form-7/admin/admin.php:312
96
  msgid "Form"
97
  msgstr ""
98
 
99
+ #: contact-form-7/admin/admin.php:315
100
  msgid "Mail"
101
  msgstr ""
102
 
103
+ #: contact-form-7/admin/admin.php:318
104
  msgid "Mail (2)"
105
  msgstr ""
106
 
107
+ #: contact-form-7/admin/admin.php:323
108
  msgid "Use mail (2)"
109
  msgstr ""
110
 
111
+ #: contact-form-7/admin/admin.php:325
112
  msgid "Messages"
113
  msgstr ""
114
 
115
+ #: contact-form-7/admin/admin.php:328
116
  msgid "Additional Settings"
117
  msgstr ""
118
 
119
+ #: contact-form-7/admin/admin.php:359
120
  msgid "Contact form created."
121
  msgstr ""
122
 
123
+ #: contact-form-7/admin/admin.php:361
124
  msgid "Contact form saved."
125
  msgstr ""
126
 
127
+ #: contact-form-7/admin/admin.php:363
128
  msgid "Contact form deleted."
129
  msgstr ""
130
 
131
+ #: contact-form-7/admin/admin.php:380
132
  msgid "Settings"
133
  msgstr ""
134
 
135
+ #: contact-form-7/admin/admin.php:391
136
  msgid "http://contactform7.com/docs/"
137
  msgstr ""
138
 
139
+ #: contact-form-7/admin/admin.php:392
140
  msgid "Docs"
141
  msgstr ""
142
 
143
+ #: contact-form-7/admin/admin.php:393
144
  msgid "http://contactform7.com/faq/"
145
  msgstr ""
146
 
147
+ #: contact-form-7/admin/admin.php:394
148
  msgid "FAQ"
149
  msgstr ""
150
 
151
+ #: contact-form-7/admin/admin.php:395
152
  msgid "http://contactform7.com/support/"
153
  msgstr ""
154
 
155
+ #: contact-form-7/admin/admin.php:396
156
  msgid "Support"
157
  msgstr ""
158
 
159
+ #: contact-form-7/admin/admin.php:427
160
  msgid "Contact Form 7 needs your support. Please donate today."
161
  msgstr ""
162
 
163
+ #: contact-form-7/admin/admin.php:428
164
  msgid "Your contribution is needed for making this plugin better."
165
  msgstr ""
166
 
167
+ #: contact-form-7/admin/admin.php:434
168
  msgid "http://contactform7.com/donate/"
169
  msgstr ""
170
 
171
+ #: contact-form-7/admin/admin.php:434
172
  msgid "Donate"
173
  msgstr ""
174
 
175
+ #: contact-form-7/admin/admin.php:454
176
  #, php-format
177
+ msgid ""
178
+ "<strong>Contact Form 7 %1$s requires WordPress %2$s or higher.</strong> "
179
+ "Please <a href=\"%3$s\">update WordPress</a> first."
180
  msgstr ""
181
 
182
  #: contact-form-7/admin/edit-contact-form.php:46
183
+ msgid ""
184
+ "Copy this code and paste it into your post, page or text widget content."
185
  msgstr ""
186
 
187
  #: contact-form-7/admin/edit-contact-form.php:52
275
  msgid "Contact Form"
276
  msgstr ""
277
 
278
+ #: contact-form-7/includes/classes.php:768
279
  msgid "Untitled"
280
  msgstr ""
281
 
282
+ #: contact-form-7/includes/controller.php:243
283
  msgid "Sending ..."
284
  msgstr ""
285
 
286
  #: contact-form-7/includes/functions.php:21
287
  #, php-format
288
+ msgid ""
289
+ "%1$s is <strong>deprecated</strong> since Contact Form 7 version %2$s! Use "
290
+ "%3$s instead."
291
  msgstr ""
292
 
293
  #: contact-form-7/includes/functions.php:23
294
  #, php-format
295
+ msgid ""
296
+ "%1$s is <strong>deprecated</strong> since Contact Form 7 version %2$s with "
297
+ "no alternative available."
298
  msgstr ""
299
 
300
  #: contact-form-7/includes/functions.php:30
310
  msgstr ""
311
 
312
  #: contact-form-7/includes/functions.php:36
313
+ #: contact-form-7/modules/akismet.php:127
314
+ msgid ""
315
+ "Failed to send your message. Please try later or contact the administrator "
316
+ "by another method."
317
  msgstr ""
318
 
319
  #: contact-form-7/includes/functions.php:40
321
  msgstr ""
322
 
323
  #: contact-form-7/includes/functions.php:41
324
+ msgid ""
325
+ "Validation errors occurred. Please confirm the fields and submit it again."
326
  msgstr ""
327
 
328
  #: contact-form-7/includes/functions.php:45
371
  msgstr ""
372
 
373
  #: contact-form-7/includes/functions.php:88
374
+ #: contact-form-7/modules/submit.php:45
375
  msgid "Send"
376
  msgstr ""
377
 
633
 
634
  #: contact-form-7/modules/acceptance.php:165
635
  #: contact-form-7/modules/captcha.php:215
636
+ #: contact-form-7/modules/checkbox.php:191 contact-form-7/modules/file.php:241
637
+ #: contact-form-7/modules/quiz.php:182 contact-form-7/modules/select.php:152
638
+ #: contact-form-7/modules/text.php:179 contact-form-7/modules/textarea.php:140
 
 
 
639
  msgid "Name"
640
  msgstr ""
641
 
651
  #: contact-form-7/modules/captcha.php:256
652
  #: contact-form-7/modules/captcha.php:259
653
  #: contact-form-7/modules/checkbox.php:196
654
+ #: contact-form-7/modules/checkbox.php:199 contact-form-7/modules/file.php:246
655
+ #: contact-form-7/modules/file.php:249 contact-form-7/modules/file.php:254
656
+ #: contact-form-7/modules/file.php:257 contact-form-7/modules/quiz.php:187
657
+ #: contact-form-7/modules/quiz.php:190 contact-form-7/modules/quiz.php:195
658
+ #: contact-form-7/modules/quiz.php:198 contact-form-7/modules/select.php:157
659
+ #: contact-form-7/modules/select.php:160 contact-form-7/modules/submit.php:71
660
+ #: contact-form-7/modules/submit.php:74 contact-form-7/modules/submit.php:79
661
+ #: contact-form-7/modules/text.php:184 contact-form-7/modules/text.php:187
662
+ #: contact-form-7/modules/text.php:192 contact-form-7/modules/text.php:195
663
+ #: contact-form-7/modules/text.php:200 contact-form-7/modules/text.php:211
 
 
 
 
 
 
 
 
 
 
664
  #: contact-form-7/modules/textarea.php:145
665
  #: contact-form-7/modules/textarea.php:148
666
  #: contact-form-7/modules/textarea.php:153
683
 
684
  #: contact-form-7/modules/acceptance.php:186
685
  #: contact-form-7/modules/captcha.php:264
686
+ #: contact-form-7/modules/checkbox.php:219 contact-form-7/modules/file.php:262
687
+ #: contact-form-7/modules/quiz.php:210 contact-form-7/modules/select.php:177
688
+ #: contact-form-7/modules/submit.php:86 contact-form-7/modules/text.php:219
 
 
 
689
  #: contact-form-7/modules/textarea.php:169
690
  msgid "Copy this code and paste it into the form left."
691
  msgstr ""
692
 
693
+ #: contact-form-7/modules/akismet.php:126
694
  msgid "Akismet judged the sending activity as spamming"
695
  msgstr ""
696
 
697
  #: contact-form-7/modules/captcha.php:73
698
+ msgid ""
699
+ "To use CAPTCHA, you need <a href=\"http://wordpress.org/extend/plugins/"
700
+ "really-simple-captcha/\">Really Simple CAPTCHA</a> plugin installed."
701
  msgstr ""
702
 
703
  #: contact-form-7/modules/captcha.php:187
758
 
759
  #: contact-form-7/modules/captcha.php:297
760
  #, php-format
761
+ msgid ""
762
+ "This contact form contains CAPTCHA fields, but the temporary folder for the "
763
+ "files (%s) does not exist or is not writable. You can create the folder or "
764
+ "change its permission manually."
765
  msgstr ""
766
 
767
  #: contact-form-7/modules/captcha.php:303
768
+ msgid ""
769
+ "This contact form contains CAPTCHA fields, but the necessary libraries (GD "
770
+ "and FreeType) are not available on your server."
771
  msgstr ""
772
 
773
  #: contact-form-7/modules/checkbox.php:164
778
  msgid "Radio buttons"
779
  msgstr ""
780
 
781
+ #: contact-form-7/modules/checkbox.php:188 contact-form-7/modules/file.php:240
782
+ #: contact-form-7/modules/select.php:151 contact-form-7/modules/text.php:178
 
 
783
  #: contact-form-7/modules/textarea.php:139
784
  msgid "Required field?"
785
  msgstr ""
807
  msgstr ""
808
 
809
  #: contact-form-7/modules/checkbox.php:221
810
+ #: contact-form-7/modules/select.php:179 contact-form-7/modules/text.php:221
 
811
  #: contact-form-7/modules/textarea.php:171
812
  msgid "And, put this code into the Mail fields below."
813
  msgstr ""
866
 
867
  #: contact-form-7/modules/file.php:289
868
  #, php-format
869
+ msgid ""
870
+ "This contact form contains file uploading fields, but the temporary folder "
871
+ "for the files (%s) does not exist or is not writable. You can create the "
872
+ "folder or change its permission manually."
873
  msgstr ""
874
 
875
  #: contact-form-7/modules/jetpack.php:14
876
  #, php-format
877
+ msgid ""
878
+ "<strong>Jetpack may cause problems for other plugins in certain cases.</"
879
+ "strong> <a href=\"%s\" target=\"_blank\">See how to avoid it.</a>"
880
  msgstr ""
881
 
882
  #: contact-form-7/modules/quiz.php:159
943
  msgid "This field requires author's email address"
944
  msgstr ""
945
 
946
+ #: contact-form-7/modules/text.php:211 contact-form-7/modules/textarea.php:161
 
947
  msgid "Default value"
948
  msgstr ""
949
 
950
+ #: contact-form-7/modules/text.php:214 contact-form-7/modules/textarea.php:164
 
951
  msgid "Use this text as watermark?"
952
  msgstr ""
953
 
954
  #: contact-form-7/modules/textarea.php:130
955
  msgid "Text area"
956
  msgstr ""
 
modules/akismet.php CHANGED
@@ -7,50 +7,28 @@
7
  add_filter( 'wpcf7_spam', 'wpcf7_akismet' );
8
 
9
  function wpcf7_akismet( $spam ) {
10
- global $akismet_api_host, $akismet_api_port;
11
-
12
  if ( $spam )
13
  return $spam;
14
 
15
  if ( ! function_exists( 'akismet_get_key' ) || ! akismet_get_key() )
16
  return false;
17
 
18
- $akismet_ready = false;
19
- $author = $author_email = $author_url = $content = '';
20
-
21
- $fes = wpcf7_scan_shortcode();
22
-
23
- foreach ( $fes as $fe ) {
24
- if ( ! isset( $fe['name'] ) || ! isset( $_POST[$fe['name']] ) )
25
- continue;
26
-
27
- if ( ! is_array( $fe['options'] ) )
28
- continue;
29
-
30
- if ( preg_grep( '%^akismet:author$%', $fe['options'] ) ) {
31
- $author .= ' ' . $_POST[$fe['name']];
32
- $author = trim( $author );
33
- $akismet_ready = true;
34
- }
35
 
36
- if ( preg_grep( '%^akismet:author_email$%', $fe['options'] ) && '' == $author_email ) {
37
- $author_email = trim( $_POST[$fe['name']] );
38
- $akismet_ready = true;
39
- }
40
 
41
- if ( preg_grep( '%^akismet:author_url$%', $fe['options'] ) && '' == $author_url ) {
42
- $author_url = trim( $_POST[$fe['name']] );
43
- $akismet_ready = true;
44
- }
45
 
46
- if ( '' != $content )
47
- $content .= "\n\n";
48
 
49
- $content .= $_POST[$fe['name']];
50
- }
51
 
52
- if ( ! $akismet_ready )
53
- return false;
54
 
55
  $c['blog'] = get_option( 'home' );
56
  $c['blog_lang'] = get_locale();
@@ -65,18 +43,6 @@ function wpcf7_akismet( $spam ) {
65
  if ( $permalink = get_permalink() )
66
  $c['permalink'] = $permalink;
67
 
68
- if ( '' != $author )
69
- $c['comment_author'] = $author;
70
-
71
- if ( '' != $author_email )
72
- $c['comment_author_email'] = $author_email;
73
-
74
- if ( '' != $author_url )
75
- $c['comment_author_url'] = $author_url;
76
-
77
- if ( '' != $content )
78
- $c['comment_content'] = $content;
79
-
80
  $ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' );
81
 
82
  foreach ( $_SERVER as $key => $value ) {
@@ -84,9 +50,58 @@ function wpcf7_akismet( $spam ) {
84
  $c["$key"] = $value;
85
  }
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  $query_string = '';
88
 
89
- foreach ( $c as $key => $data )
90
  $query_string .= $key . '=' . urlencode( stripslashes( (string) $data ) ) . '&';
91
 
92
  $response = akismet_http_post( $query_string,
@@ -95,9 +110,10 @@ function wpcf7_akismet( $spam ) {
95
  if ( 'true' == $response[1] )
96
  $spam = true;
97
 
98
- $spam = apply_filters( 'wpcf7_akismet_comment_check', $spam, $c );
 
99
 
100
- return $spam;
101
  }
102
 
103
 
7
  add_filter( 'wpcf7_spam', 'wpcf7_akismet' );
8
 
9
  function wpcf7_akismet( $spam ) {
 
 
10
  if ( $spam )
11
  return $spam;
12
 
13
  if ( ! function_exists( 'akismet_get_key' ) || ! akismet_get_key() )
14
  return false;
15
 
16
+ if ( ! $params = wpcf7_akismet_submitted_params() )
17
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
+ $c = array();
 
 
 
20
 
21
+ if ( ! empty( $params['author'] ) )
22
+ $c['comment_author'] = $params['author'];
 
 
23
 
24
+ if ( ! empty( $params['author_email'] ) )
25
+ $c['comment_author_email'] = $params['author_email'];
26
 
27
+ if ( ! empty( $params['author_url'] ) )
28
+ $c['comment_author_url'] = $params['author_url'];
29
 
30
+ if ( ! empty( $params['content'] ) )
31
+ $c['comment_content'] = $params['content'];
32
 
33
  $c['blog'] = get_option( 'home' );
34
  $c['blog_lang'] = get_locale();
43
  if ( $permalink = get_permalink() )
44
  $c['permalink'] = $permalink;
45
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  $ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' );
47
 
48
  foreach ( $_SERVER as $key => $value ) {
50
  $c["$key"] = $value;
51
  }
52
 
53
+ return wpcf7_akismet_comment_check( $c );
54
+ }
55
+
56
+ function wpcf7_akismet_submitted_params() {
57
+ $params = array(
58
+ 'author' => '',
59
+ 'author_email' => '',
60
+ 'author_url' => '' );
61
+
62
+ $content = '';
63
+
64
+ $fes = wpcf7_scan_shortcode();
65
+
66
+ foreach ( $fes as $fe ) {
67
+ if ( ! isset( $fe['name'] ) || ! isset( $_POST[$fe['name']] ) )
68
+ continue;
69
+
70
+ $value = trim( $_POST[$fe['name']] );
71
+ $options = (array) $fe['options'];
72
+
73
+ if ( preg_grep( '%^akismet:author$%', $options ) ) {
74
+ $params['author'] = trim( $params['author'] . ' ' . $value );
75
+
76
+ } elseif ( preg_grep( '%^akismet:author_email$%', $options ) ) {
77
+ if ( '' == $params['author_email'] )
78
+ $params['author_email'] = $value;
79
+
80
+ } elseif ( preg_grep( '%^akismet:author_url$%', $options ) ) {
81
+ if ( '' == $params['author_url'] )
82
+ $params['author_url'] = $value;
83
+ }
84
+
85
+ $content = trim( $content . "\n\n" . $value );
86
+ }
87
+
88
+ $params = array_filter( $params );
89
+
90
+ if ( ! $params )
91
+ return false;
92
+
93
+ $params['content'] = $content;
94
+
95
+ return $params;
96
+ }
97
+
98
+ function wpcf7_akismet_comment_check( $comment ) {
99
+ global $akismet_api_host, $akismet_api_port;
100
+
101
+ $spam = false;
102
  $query_string = '';
103
 
104
+ foreach ( $comment as $key => $data )
105
  $query_string .= $key . '=' . urlencode( stripslashes( (string) $data ) ) . '&';
106
 
107
  $response = akismet_http_post( $query_string,
110
  if ( 'true' == $response[1] )
111
  $spam = true;
112
 
113
+ if ( $contact_form = wpcf7_get_current_contact_form() )
114
+ $contact_form->akismet = array( 'comment' => $comment, 'spam' => $spam );
115
 
116
+ return apply_filters( 'wpcf7_akismet_comment_check', $spam, $comment );
117
  }
118
 
119
 
modules/flamingo.php CHANGED
@@ -41,40 +41,34 @@ function wpcf7_flamingo_before_send_mail( $contactform ) {
41
  unset( $posted_data[$key] );
42
  }
43
 
44
- $meta = array(
45
- 'remote_ip' => apply_filters( 'wpcf7_special_mail_tags', '', '_remote_ip' ),
46
- 'url' => apply_filters( 'wpcf7_special_mail_tags', '', '_url' ),
47
- 'date' => apply_filters( 'wpcf7_special_mail_tags', '', '_date' ),
48
- 'time' => apply_filters( 'wpcf7_special_mail_tags', '', '_time' ),
49
- 'post_id' => apply_filters( 'wpcf7_special_mail_tags', '', '_post_id' ),
50
- 'post_name' => apply_filters( 'wpcf7_special_mail_tags', '', '_post_name' ),
51
- 'post_title' => apply_filters( 'wpcf7_special_mail_tags', '', '_post_title' ),
52
- 'post_url' => apply_filters( 'wpcf7_special_mail_tags', '', '_post_url' ),
53
- 'post_author' => apply_filters( 'wpcf7_special_mail_tags', '', '_post_author' ),
54
- 'post_author_email' => apply_filters( 'wpcf7_special_mail_tags', '', '_post_author_email' ) );
55
-
56
- $args = array(
57
- 'channel' => 'contact-form-7',
58
- 'fields' => $posted_data,
59
- 'meta' => $meta,
60
- 'email' => '',
61
- 'name' => '',
62
- 'from' => '',
63
- 'subject' => '' );
64
 
65
- if ( ! empty( $posted_data['your-email'] ) )
66
- $args['from_email'] = $args['email'] = trim( $posted_data['your-email'] );
67
 
68
- if ( ! empty( $posted_data['your-name'] ) )
69
- $args['from_name'] = $args['name'] = trim( $posted_data['your-name'] );
70
 
71
- if ( ! empty( $posted_data['your-subject'] ) )
72
- $args['subject'] = trim( $posted_data['your-subject'] );
73
 
74
- $args['from'] = trim( sprintf( '%s <%s>', $args['from_name'], $args['from_email'] ) );
 
 
75
 
76
- Flamingo_Contact::add( $args );
77
- Flamingo_Inbound_Message::add( $args );
 
 
 
 
 
 
 
78
  }
79
 
80
  ?>
41
  unset( $posted_data[$key] );
42
  }
43
 
44
+ $email = isset( $posted_data['your-email'] ) ? trim( $posted_data['your-email'] ) : '';
45
+ $name = isset( $posted_data['your-name'] ) ? trim( $posted_data['your-name'] ) : '';
46
+ $subject = isset( $posted_data['your-subject'] ) ? trim( $posted_data['your-subject'] ) : '';
47
+
48
+ $meta = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ $special_mail_tags = array( 'remote_ip', 'user_agent', 'url', 'date', 'time',
51
+ 'post_id', 'post_name', 'post_title', 'post_url', 'post_author', 'post_author_email' );
52
 
53
+ foreach ( $special_mail_tags as $smt )
54
+ $meta[$smt] = apply_filters( 'wpcf7_special_mail_tags', '', '_' . $smt, false );
55
 
56
+ if ( isset( $contactform->akismet ) )
57
+ $akismet = (array) $contactform->akismet;
58
 
59
+ Flamingo_Contact::add( array(
60
+ 'email' => $email,
61
+ 'name' => $name ) );
62
 
63
+ Flamingo_Inbound_Message::add( array(
64
+ 'channel' => 'contact-form-7',
65
+ 'subject' => $subject,
66
+ 'from' => trim( sprintf( '%s <%s>', $name, $email ) ),
67
+ 'from_name' => $name,
68
+ 'from_email' => $email,
69
+ 'fields' => $posted_data,
70
+ 'meta' => $meta,
71
+ 'akismet' => $akismet ) );
72
  }
73
 
74
  ?>
modules/special-mail-tags.php CHANGED
@@ -13,6 +13,9 @@ function wpcf7_special_mail_tag( $output, $name ) {
13
  if ( '_remote_ip' == $name )
14
  $output = preg_replace( '/[^0-9a-f.:, ]/', '', $_SERVER['REMOTE_ADDR'] );
15
 
 
 
 
16
  elseif ( '_url' == $name ) {
17
  $url = untrailingslashit( home_url() );
18
  $url = preg_replace( '%(?<!:|/)/.*$%', '', $url );
@@ -70,4 +73,32 @@ function wpcf7_special_mail_tag_for_post_data( $output, $name ) {
70
  return $output;
71
  }
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  ?>
13
  if ( '_remote_ip' == $name )
14
  $output = preg_replace( '/[^0-9a-f.:, ]/', '', $_SERVER['REMOTE_ADDR'] );
15
 
16
+ elseif ( '_user_agent' == $name )
17
+ $output = substr( $_SERVER['HTTP_USER_AGENT'], 0, 254 );
18
+
19
  elseif ( '_url' == $name ) {
20
  $url = untrailingslashit( home_url() );
21
  $url = preg_replace( '%(?<!:|/)/.*$%', '', $url );
73
  return $output;
74
  }
75
 
76
+ add_filter( 'wpcf7_special_mail_tags', 'wpcf7_special_mail_tag_for_raw_post', 10, 3 );
77
+
78
+ function wpcf7_special_mail_tag_for_raw_post( $output, $name, $html ) {
79
+ if ( ! preg_match( '/^_raw_(.+)/', $name, $matches ) )
80
+ return $output;
81
+
82
+ $tag_name = trim( $matches[1] );
83
+
84
+ if ( empty( $_POST[$tag_name] ) )
85
+ return $output;
86
+
87
+ $submitted = $_POST[$tag_name];
88
+
89
+ if ( is_array( $submitted ) )
90
+ $replaced = implode( ', ', $submitted );
91
+ else
92
+ $replaced = $submitted;
93
+
94
+ if ( $html ) {
95
+ $replaced = strip_tags( $replaced );
96
+ $replaced = wptexturize( $replaced );
97
+ }
98
+
99
+ $replaced = apply_filters( 'wpcf7_mail_tag_replaced', $replaced, $submitted, $html );
100
+
101
+ return stripslashes( $replaced );
102
+ }
103
+
104
  ?>
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: takayukister
3
  Donate link: http://contactform7.com/donate/
4
  Tags: contact, form, contact form, feedback, email, ajax, captcha, akismet, multilingual
5
- Requires at least: 3.2
6
- Tested up to: 3.4.1
7
- Stable tag: 3.2.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -113,30 +113,20 @@ Do you have questions or issues with Contact Form 7? Use these support channels
113
 
114
  == Changelog ==
115
 
116
- = 3.2.1 =
117
-
118
- * Fixed: Error for use of array_key_exists function with invalid first argument.
119
- * Fixed: Adding unnecessary rewrite rules.
120
- * Fixed: "Screen Options" doesn't appear on each contact form edit screen.
121
- * Change the comment_type value sent to Akismet from 'contactform7' to 'contact-form' following their blog post.
122
- * Introduce wpcf7_add_meta_boxes function and action with the same name. This makes it easier to add custom meta boxes to the edit screen.
123
- * Pass meta informations of each form submission (e.g. client's IP address) to Flamingo.
124
- * The jQuery Form Plugin (jquery.form.js) has been updated to 3.14 and compressed with YUI compressor.
125
- * Translation for Basque has been created.
126
- * Translations for German, Italian, and Polish have been updated.
127
-
128
- = 3.2 =
129
-
130
- * Enhanced admin panel. Introduced list table view for contact forms.
131
- * Moved the Contact menu to the upper position (just below the Comments).
132
- * Show alert message when Jetpack contact form is active.
133
- * Introduced Flamingo module.
134
- * Made capabilities more customizable.
135
- * wpcf7_admin_url() is deprecated. Use admin_url() or menu_page_url() instead.
136
- * Changed the default defined value of constants WPCF7_PLUGIN_DIR and WPCF7_PLUGIN_URL.
137
- * The jQuery Form Plugin (jquery.form.js) has been updated to 3.09 and compressed with YUI compressor.
138
- * Translations for Latvian, Swedish, and Czech have been updated.
139
 
140
  == Upgrade Notice ==
141
 
142
- The current version of Contact Form 7 requires WordPress 3.2 or higher. If you use older version of WordPress, you need to upgrade WordPress first.
2
  Contributors: takayukister
3
  Donate link: http://contactform7.com/donate/
4
  Tags: contact, form, contact form, feedback, email, ajax, captcha, akismet, multilingual
5
+ Requires at least: 3.3
6
+ Tested up to: 3.4.2
7
+ Stable tag: 3.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
113
 
114
  == Changelog ==
115
 
116
+ = 3.3 =
117
+
118
+ * New: Introduce a new special mail tag [_user_agent] for user agent information.
119
+ * New: Make WordPress Comment Blacklist applicable for inputs through contact forms.
120
+ * New: Introduce new form of mail tag [\_raw\_{field name}]. This allows to output raw user input those have not been modified with pipes.
121
+ * New: Make mail tags available in response messages.
122
+ * New: Introduce new additional setting on_submit. It works like on_sent_ok and has one-line JavaScript code, but on_submit code is fired regardless of whether or not the mail has been sent successfully.
123
+ * New: Introduce 5 new jQuery custom event triggers (invalid.wpcf7, spam.wpcf7, mailsent.wpcf7, mailfailed.wpcf7, submit.wpcf7).
124
+ * Fix: Nonce used in a form have been changed to have no time limit.
125
+ * Fix: Make every post meta’s key have underscore prefix.
126
+ * The jQuery Form Plugin (jquery.form.js) has been updated to 3.15 and compressed with YUI compressor.
127
+ * The required WordPress version has been changed and now requires WordPress 3.3 or higher. If you use WordPress 3.2, you will need to upgrade WordPress.
128
+ * Translations for Arabic and German have been updated.
 
 
 
 
 
 
 
 
 
 
129
 
130
  == Upgrade Notice ==
131
 
132
+ The current version of Contact Form 7 requires WordPress 3.3 or higher. If you use older version of WordPress, you need to upgrade WordPress first.
screenshot-1.png DELETED
Binary file
settings.php CHANGED
@@ -141,13 +141,39 @@ function wpcf7_convert_to_cpt( $new_ver, $old_ver ) {
141
  $metas = array( 'form', 'mail', 'mail_2', 'messages', 'additional_settings' );
142
 
143
  foreach ( $metas as $meta ) {
144
- update_post_meta( $post_id, $meta,
145
  wpcf7_normalize_newline_deep( maybe_unserialize( $row->{$meta} ) ) );
146
  }
147
  }
148
  }
149
  }
150
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  /* Install and default settings */
152
 
153
  add_action( 'activate_' . WPCF7_PLUGIN_BASENAME, 'wpcf7_install' );
141
  $metas = array( 'form', 'mail', 'mail_2', 'messages', 'additional_settings' );
142
 
143
  foreach ( $metas as $meta ) {
144
+ update_post_meta( $post_id, '_' . $meta,
145
  wpcf7_normalize_newline_deep( maybe_unserialize( $row->{$meta} ) ) );
146
  }
147
  }
148
  }
149
  }
150
 
151
+ add_action( 'wpcf7_upgrade', 'wpcf7_prepend_underscore', 10, 2 );
152
+
153
+ function wpcf7_prepend_underscore( $new_ver, $old_ver ) {
154
+ if ( version_compare( $old_ver, '3.0-dev', '<' ) )
155
+ return;
156
+
157
+ if ( ! version_compare( $old_ver, '3.3-dev', '<' ) )
158
+ return;
159
+
160
+ $posts = WPCF7_ContactForm::find( array(
161
+ 'post_status' => 'any',
162
+ 'posts_per_page' => -1 ) );
163
+
164
+ foreach ( $posts as $post ) {
165
+ $props = $post->get_properties();
166
+
167
+ foreach ( $props as $prop => $value ) {
168
+ if ( metadata_exists( 'post', $post->id, '_' . $prop ) )
169
+ continue;
170
+
171
+ update_post_meta( $post->id, '_' . $prop, $value );
172
+ delete_post_meta( $post->id, $prop );
173
+ }
174
+ }
175
+ }
176
+
177
  /* Install and default settings */
178
 
179
  add_action( 'activate_' . WPCF7_PLUGIN_BASENAME, 'wpcf7_install' );
wp-contact-form-7.php CHANGED
@@ -7,7 +7,7 @@ Author: Takayuki Miyoshi
7
  Author URI: http://ideasilo.wordpress.com/
8
  Text Domain: wpcf7
9
  Domain Path: /languages/
10
- Version: 3.2.1
11
  */
12
 
13
  /* Copyright 2007-2012 Takayuki Miyoshi (email: takayukister at gmail.com)
@@ -27,9 +27,9 @@ Version: 3.2.1
27
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
  */
29
 
30
- define( 'WPCF7_VERSION', '3.2.1' );
31
 
32
- define( 'WPCF7_REQUIRED_WP_VERSION', '3.2' );
33
 
34
  if ( ! defined( 'WPCF7_PLUGIN_BASENAME' ) )
35
  define( 'WPCF7_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
7
  Author URI: http://ideasilo.wordpress.com/
8
  Text Domain: wpcf7
9
  Domain Path: /languages/
10
+ Version: 3.3
11
  */
12
 
13
  /* Copyright 2007-2012 Takayuki Miyoshi (email: takayukister at gmail.com)
27
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
  */
29
 
30
+ define( 'WPCF7_VERSION', '3.3' );
31
 
32
+ define( 'WPCF7_REQUIRED_WP_VERSION', '3.3' );
33
 
34
  if ( ! defined( 'WPCF7_PLUGIN_BASENAME' ) )
35
  define( 'WPCF7_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );