Contact Form 7 - Version 2.4.5

Version Description

  • Fixed the bug that makes it not accept "0" value as watermark.
  • Fixed too much normalization to form-tag shortcode with content.
  • Fixed wrong regexp pattern for form-tag shortcode with content.
  • Check $_POST of checkboxes and select menus to avoid warnings.
  • Use proper action hook for enqueueing scripts: wp_enqueue_scripts and admin_enqueue_scripts.
  • Bundled jquery.form has been updated to 2.72.
  • Translations for Czech (Tomas Vesely) has been updated.
Download this release

Release Info

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

Code changes from version 2.4.4 to 2.4.5

admin/admin.php CHANGED
@@ -143,7 +143,7 @@ function wpcf7_admin_enqueue_styles() {
143
  }
144
  }
145
 
146
- add_action( 'admin_print_scripts', 'wpcf7_admin_enqueue_scripts' );
147
 
148
  function wpcf7_admin_enqueue_scripts() {
149
  global $plugin_page;
143
  }
144
  }
145
 
146
+ add_action( 'admin_enqueue_scripts', 'wpcf7_admin_enqueue_scripts' );
147
 
148
  function wpcf7_admin_enqueue_scripts() {
149
  global $plugin_page;
includes/controller.php CHANGED
@@ -243,7 +243,7 @@ var _wpcf7 = { cached: 1 };
243
  }
244
 
245
  if ( WPCF7_LOAD_JS )
246
- add_action( 'wp_print_scripts', 'wpcf7_enqueue_scripts' );
247
 
248
  function wpcf7_enqueue_scripts() {
249
  // jquery.form.js originally bundled with WordPress is out of date and deprecated
243
  }
244
 
245
  if ( WPCF7_LOAD_JS )
246
+ add_action( 'wp_enqueue_scripts', 'wpcf7_enqueue_scripts' );
247
 
248
  function wpcf7_enqueue_scripts() {
249
  // jquery.form.js originally bundled with WordPress is out of date and deprecated
includes/shortcodes.php CHANGED
@@ -35,7 +35,18 @@ class WPCF7_ShortcodeManager {
35
  if ( $m[1] == '[' && $m[6] == ']' )
36
  return $m[0];
37
 
38
- return preg_replace( '/\s+/', ' ', $m[0] );
 
 
 
 
 
 
 
 
 
 
 
39
  }
40
 
41
  function do_shortcode( $content, $exec = true ) {
@@ -59,7 +70,10 @@ class WPCF7_ShortcodeManager {
59
  $tagnames = array_keys( $this->shortcode_tags );
60
  $tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) );
61
 
62
- return '(\[?)\[(' . $tagregexp . ')(?:\s(.*?))?(?:\s(\/))?\](?:(.+?)\[\/\2\])?(\]?)';
 
 
 
63
  }
64
 
65
  function do_shortcode_tag( $m ) {
35
  if ( $m[1] == '[' && $m[6] == ']' )
36
  return $m[0];
37
 
38
+ $tag = $m[2];
39
+ $attr = trim( preg_replace( '/\s+/', ' ', $m[3] ) );
40
+ $content = trim( $m[5] );
41
+
42
+ $result = $m[1] . '[' . $tag
43
+ . ( $attr ? ' ' . $attr : '' )
44
+ . ( $m[4] ? ' ' . $m[4] : '' )
45
+ . ']'
46
+ . ( $content ? $content . '[/' . $tag . ']' : '' )
47
+ . $m[6];
48
+
49
+ return $result;
50
  }
51
 
52
  function do_shortcode( $content, $exec = true ) {
70
  $tagnames = array_keys( $this->shortcode_tags );
71
  $tagregexp = join( '|', array_map( 'preg_quote', $tagnames ) );
72
 
73
+ return '(\[?)'
74
+ . '\[(' . $tagregexp . ')(?:\s(.*?))?(?:\s(\/))?\]'
75
+ . '(?:((?!.*?\[(?:' . $tagregexp . ')\s).+?)\[\/\2\])?'
76
+ . '(\]?)';
77
  }
78
 
79
  function do_shortcode_tag( $m ) {
jquery.form.js CHANGED
@@ -1,6 +1,6 @@
1
  /*!
2
  * jQuery Form Plugin
3
- * version: 2.52 (07-DEC-2010)
4
  * @requires jQuery v1.3.2 or later
5
  *
6
  * Examples and documentation at: http://malsup.com/jquery/form/
@@ -64,7 +64,8 @@ $.fn.ajaxSubmit = function(options) {
64
 
65
  options = $.extend(true, {
66
  url: url,
67
- type: this.attr('method') || 'GET',
 
68
  iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
69
  }, options);
70
 
@@ -168,7 +169,7 @@ $.fn.ajaxSubmit = function(options) {
168
  }
169
  }
170
  else {
171
- $.ajax(options);
172
  }
173
 
174
  // fire 'notify' event
@@ -190,15 +191,7 @@ $.fn.ajaxSubmit = function(options) {
190
  var s = $.extend(true, {}, $.ajaxSettings, options);
191
  s.context = s.context || s;
192
  var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id;
193
- window[fn] = function() {
194
- var f = $io.data('form-plugin-onload');
195
- if (f) {
196
- f();
197
- window[fn] = undefined;
198
- try { delete window[fn]; } catch(e){}
199
- }
200
- }
201
- var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" onload="window[\'_\'+this.id]()" />');
202
  var io = $io[0];
203
 
204
  $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
@@ -212,9 +205,15 @@ $.fn.ajaxSubmit = function(options) {
212
  getAllResponseHeaders: function() {},
213
  getResponseHeader: function() {},
214
  setRequestHeader: function() {},
215
- abort: function() {
 
 
216
  this.aborted = 1;
217
  $io.attr('src', s.iframeSrc); // abort op in progress
 
 
 
 
218
  }
219
  };
220
 
@@ -237,8 +236,7 @@ $.fn.ajaxSubmit = function(options) {
237
  return;
238
  }
239
 
240
- var cbInvoked = false;
241
- var timedOut = 0;
242
 
243
  // add submitting element to data if we know it
244
  var sub = form.clk;
@@ -278,7 +276,7 @@ $.fn.ajaxSubmit = function(options) {
278
 
279
  // support timout
280
  if (s.timeout) {
281
- setTimeout(function() { timedOut = true; cb(); }, s.timeout);
282
  }
283
 
284
  // add "extra" data to form if provided in options
@@ -294,7 +292,7 @@ $.fn.ajaxSubmit = function(options) {
294
 
295
  // add iframe to doc and submit the form
296
  $io.appendTo('body');
297
- $io.data('form-plugin-onload', cb);
298
  form.submit();
299
  }
300
  finally {
@@ -316,23 +314,31 @@ $.fn.ajaxSubmit = function(options) {
316
  setTimeout(doSubmit, 10); // this lets dom updates render
317
  }
318
 
319
- var data, doc, domCheckCount = 50;
320
 
321
- function cb() {
322
- if (cbInvoked) {
 
 
 
 
323
  return;
324
  }
325
-
326
- $io.removeData('form-plugin-onload');
327
 
 
 
 
 
 
 
 
 
328
  var ok = true;
329
  try {
330
  if (timedOut) {
331
  throw 'timeout';
332
  }
333
- // extract the server response from the iframe
334
- doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
335
-
336
  var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
337
  log('isXml='+isXml);
338
  if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
@@ -349,15 +355,16 @@ $.fn.ajaxSubmit = function(options) {
349
  }
350
 
351
  //log('response detected');
352
- cbInvoked = true;
353
- xhr.responseText = doc.documentElement ? doc.documentElement.innerHTML : null;
354
  xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
 
 
355
  xhr.getResponseHeader = function(header){
356
  var headers = {'content-type': s.dataType};
357
  return headers[header];
358
  };
359
 
360
- var scr = /(json|script)/.test(s.dataType);
361
  if (scr || s.textarea) {
362
  // see if user embedded response in textarea
363
  var ta = doc.getElementsByTagName('textarea')[0];
@@ -379,13 +386,15 @@ $.fn.ajaxSubmit = function(options) {
379
  else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
380
  xhr.responseXML = toXml(xhr.responseText);
381
  }
382
- data = $.httpData(xhr, s.dataType);
 
383
  }
384
  catch(e){
385
  log('error caught:',e);
386
  ok = false;
387
  xhr.error = e;
388
- $.handleError(s, xhr, 'error', e);
 
389
  }
390
 
391
  if (xhr.aborted) {
@@ -395,20 +404,21 @@ $.fn.ajaxSubmit = function(options) {
395
 
396
  // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
397
  if (ok) {
398
- s.success.call(s.context, data, 'success', xhr);
399
- if (g) {
400
- $.event.trigger("ajaxSuccess", [xhr, s]);
401
- }
402
- }
403
- if (g) {
404
- $.event.trigger("ajaxComplete", [xhr, s]);
405
  }
 
 
 
406
  if (g && ! --$.active) {
407
  $.event.trigger("ajaxStop");
408
  }
409
- if (s.complete) {
410
- s.complete.call(s.context, xhr, ok ? 'success' : 'error');
411
- }
 
 
 
412
 
413
  // clean up
414
  setTimeout(function() {
@@ -418,7 +428,7 @@ $.fn.ajaxSubmit = function(options) {
418
  }, 100);
419
  }
420
 
421
- function toXml(s, doc) {
422
  if (window.ActiveXObject) {
423
  doc = new ActiveXObject('Microsoft.XMLDOM');
424
  doc.async = 'false';
@@ -427,8 +437,32 @@ $.fn.ajaxSubmit = function(options) {
427
  else {
428
  doc = (new DOMParser()).parseFromString(s, 'text/xml');
429
  }
430
- return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
431
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
  }
433
  };
434
 
1
  /*!
2
  * jQuery Form Plugin
3
+ * version: 2.72 (28-APR-2011)
4
  * @requires jQuery v1.3.2 or later
5
  *
6
  * Examples and documentation at: http://malsup.com/jquery/form/
64
 
65
  options = $.extend(true, {
66
  url: url,
67
+ success: $.ajaxSettings.success,
68
+ type: this[0].getAttribute('method') || 'GET', // IE7 massage (see issue 57)
69
  iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
70
  }, options);
71
 
169
  }
170
  }
171
  else {
172
+ $.ajax(options);
173
  }
174
 
175
  // fire 'notify' event
191
  var s = $.extend(true, {}, $.ajaxSettings, options);
192
  s.context = s.context || s;
193
  var id = 'jqFormIO' + (new Date().getTime()), fn = '_'+id;
194
+ var $io = $('<iframe id="' + id + '" name="' + id + '" src="'+ s.iframeSrc +'" />');
 
 
 
 
 
 
 
 
195
  var io = $io[0];
196
 
197
  $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
205
  getAllResponseHeaders: function() {},
206
  getResponseHeader: function() {},
207
  setRequestHeader: function() {},
208
+ abort: function(status) {
209
+ var e = (status === 'timeout' ? 'timeout' : 'aborted');
210
+ log('aborting upload... ' + e);
211
  this.aborted = 1;
212
  $io.attr('src', s.iframeSrc); // abort op in progress
213
+ xhr.error = e;
214
+ s.error && s.error.call(s.context, xhr, e, e);
215
+ g && $.event.trigger("ajaxError", [xhr, s, e]);
216
+ s.complete && s.complete.call(s.context, xhr, e);
217
  }
218
  };
219
 
236
  return;
237
  }
238
 
239
+ var timedOut = 0, timeoutHandle;
 
240
 
241
  // add submitting element to data if we know it
242
  var sub = form.clk;
276
 
277
  // support timout
278
  if (s.timeout) {
279
+ timeoutHandle = setTimeout(function() { timedOut = true; cb(true); }, s.timeout);
280
  }
281
 
282
  // add "extra" data to form if provided in options
292
 
293
  // add iframe to doc and submit the form
294
  $io.appendTo('body');
295
+ io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
296
  form.submit();
297
  }
298
  finally {
314
  setTimeout(doSubmit, 10); // this lets dom updates render
315
  }
316
 
317
+ var data, doc, domCheckCount = 50, callbackProcessed;
318
 
319
+ function cb(e) {
320
+ if (xhr.aborted || callbackProcessed) {
321
+ return;
322
+ }
323
+ if (e === true && xhr) {
324
+ xhr.abort('timeout');
325
  return;
326
  }
 
 
327
 
328
+ var doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
329
+ if (!doc || doc.location.href == s.iframeSrc) {
330
+ // response not received yet
331
+ if (!timedOut)
332
+ return;
333
+ }
334
+ io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
335
+
336
  var ok = true;
337
  try {
338
  if (timedOut) {
339
  throw 'timeout';
340
  }
341
+
 
 
342
  var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
343
  log('isXml='+isXml);
344
  if (!isXml && window.opera && (doc.body == null || doc.body.innerHTML == '')) {
355
  }
356
 
357
  //log('response detected');
358
+ xhr.responseText = doc.body ? doc.body.innerHTML : doc.documentElement ? doc.documentElement.innerHTML : null;
 
359
  xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
360
+ if (!xhr.responseText && xhr.responseXML && !s.dataType)
361
+ s.dataType = 'xml';
362
  xhr.getResponseHeader = function(header){
363
  var headers = {'content-type': s.dataType};
364
  return headers[header];
365
  };
366
 
367
+ var scr = /(json|script|text)/.test(s.dataType);
368
  if (scr || s.textarea) {
369
  // see if user embedded response in textarea
370
  var ta = doc.getElementsByTagName('textarea')[0];
386
  else if (s.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
387
  xhr.responseXML = toXml(xhr.responseText);
388
  }
389
+
390
+ data = httpData(xhr, s.dataType, s);
391
  }
392
  catch(e){
393
  log('error caught:',e);
394
  ok = false;
395
  xhr.error = e;
396
+ s.error && s.error.call(s.context, xhr, 'error', e);
397
+ g && $.event.trigger("ajaxError", [xhr, s, e]);
398
  }
399
 
400
  if (xhr.aborted) {
404
 
405
  // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
406
  if (ok) {
407
+ s.success && s.success.call(s.context, data, 'success', xhr);
408
+ g && $.event.trigger("ajaxSuccess", [xhr, s]);
 
 
 
 
 
409
  }
410
+
411
+ g && $.event.trigger("ajaxComplete", [xhr, s]);
412
+
413
  if (g && ! --$.active) {
414
  $.event.trigger("ajaxStop");
415
  }
416
+
417
+ s.complete && s.complete.call(s.context, xhr, ok ? 'success' : 'error');
418
+
419
+ callbackProcessed = true;
420
+ if (s.timeout)
421
+ clearTimeout(timeoutHandle);
422
 
423
  // clean up
424
  setTimeout(function() {
428
  }, 100);
429
  }
430
 
431
+ var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
432
  if (window.ActiveXObject) {
433
  doc = new ActiveXObject('Microsoft.XMLDOM');
434
  doc.async = 'false';
437
  else {
438
  doc = (new DOMParser()).parseFromString(s, 'text/xml');
439
  }
440
+ return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
441
+ };
442
+ var parseJSON = $.parseJSON || function(s) {
443
+ return window['eval']('(' + s + ')');
444
+ };
445
+
446
+ var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
447
+ var ct = xhr.getResponseHeader('content-type') || '',
448
+ xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
449
+ data = xml ? xhr.responseXML : xhr.responseText;
450
+
451
+ if (xml && data.documentElement.nodeName === 'parsererror') {
452
+ $.error && $.error('parsererror');
453
+ }
454
+ if (s && s.dataFilter) {
455
+ data = s.dataFilter(data, type);
456
+ }
457
+ if (typeof data === 'string') {
458
+ if (type === 'json' || !type && ct.indexOf('json') >= 0) {
459
+ data = parseJSON(data);
460
+ } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
461
+ $.globalEval(data);
462
+ }
463
+ }
464
+ return data;
465
+ };
466
  }
467
  };
468
 
languages/wpcf7-cs_CZ.mo CHANGED
Binary file
modules/checkbox.php CHANGED
@@ -90,7 +90,7 @@ function wpcf7_checkbox_shortcode_handler( $tag ) {
90
  foreach ( $values as $key => $value ) {
91
  $checked = false;
92
 
93
- if ( $posted ) {
94
  if ( $multiple && in_array( esc_sql( $value ), (array) $_POST[$name] ) )
95
  $checked = true;
96
  if ( ! $multiple && $_POST[$name] == esc_sql( $value ) )
@@ -150,16 +150,18 @@ function wpcf7_checkbox_validation_filter( $result, $tag ) {
150
  $name = $tag['name'];
151
  $values = $tag['values'];
152
 
153
- if ( is_array( $_POST[$name] ) ) {
154
- foreach ( $_POST[$name] as $key => $value ) {
155
- $value = stripslashes( $value );
156
- if ( ! in_array( $value, (array) $values ) ) // Not in given choices.
157
- unset( $_POST[$name][$key] );
 
 
 
 
 
 
158
  }
159
- } else {
160
- $value = stripslashes( $_POST[$name] );
161
- if ( ! in_array( $value, (array) $values ) ) // Not in given choices.
162
- $_POST[$name] = '';
163
  }
164
 
165
  if ( 'checkbox*' == $type ) {
90
  foreach ( $values as $key => $value ) {
91
  $checked = false;
92
 
93
+ if ( $posted && ! empty( $_POST[$name] ) ) {
94
  if ( $multiple && in_array( esc_sql( $value ), (array) $_POST[$name] ) )
95
  $checked = true;
96
  if ( ! $multiple && $_POST[$name] == esc_sql( $value ) )
150
  $name = $tag['name'];
151
  $values = $tag['values'];
152
 
153
+ if ( ! empty( $_POST[$name] ) ) {
154
+ if ( is_array( $_POST[$name] ) ) {
155
+ foreach ( $_POST[$name] as $key => $value ) {
156
+ $value = stripslashes( $value );
157
+ if ( ! in_array( $value, (array) $values ) ) // Not in given choices.
158
+ unset( $_POST[$name][$key] );
159
+ }
160
+ } else {
161
+ $value = stripslashes( $_POST[$name] );
162
+ if ( ! in_array( $value, (array) $values ) ) // Not in given choices.
163
+ $_POST[$name] = '';
164
  }
 
 
 
 
165
  }
166
 
167
  if ( 'checkbox*' == $type ) {
modules/select.php CHANGED
@@ -74,7 +74,7 @@ function wpcf7_select_shortcode_handler( $tag ) {
74
  foreach ( $values as $key => $value ) {
75
  $selected = false;
76
 
77
- if ( $posted ) {
78
  if ( $multiple && in_array( esc_sql( $value ), (array) $_POST[$name] ) )
79
  $selected = true;
80
  if ( ! $multiple && $_POST[$name] == esc_sql( $value ) )
@@ -117,16 +117,18 @@ function wpcf7_select_validation_filter( $result, $tag ) {
117
  $name = $tag['name'];
118
  $values = $tag['values'];
119
 
120
- if ( is_array( $_POST[$name] ) ) {
121
- foreach ( $_POST[$name] as $key => $value ) {
122
- $value = stripslashes( $value );
123
- if ( ! in_array( $value, (array) $values ) ) // Not in given choices.
124
- unset( $_POST[$name][$key] );
 
 
 
 
 
 
125
  }
126
- } else {
127
- $value = stripslashes( $_POST[$name] );
128
- if ( ! in_array( $value, (array) $values ) ) // Not in given choices.
129
- $_POST[$name] = '';
130
  }
131
 
132
  if ( 'select*' == $type ) {
74
  foreach ( $values as $key => $value ) {
75
  $selected = false;
76
 
77
+ if ( $posted && ! empty( $_POST[$name] ) ) {
78
  if ( $multiple && in_array( esc_sql( $value ), (array) $_POST[$name] ) )
79
  $selected = true;
80
  if ( ! $multiple && $_POST[$name] == esc_sql( $value ) )
117
  $name = $tag['name'];
118
  $values = $tag['values'];
119
 
120
+ if ( ! empty( $_POST[$name] ) ) {
121
+ if ( is_array( $_POST[$name] ) ) {
122
+ foreach ( $_POST[$name] as $key => $value ) {
123
+ $value = stripslashes( $value );
124
+ if ( ! in_array( $value, (array) $values ) ) // Not in given choices.
125
+ unset( $_POST[$name][$key] );
126
+ }
127
+ } else {
128
+ $value = stripslashes( $_POST[$name] );
129
+ if ( ! in_array( $value, (array) $values ) ) // Not in given choices.
130
+ $_POST[$name] = '';
131
  }
 
 
 
 
132
  }
133
 
134
  if ( 'select*' == $type ) {
modules/text.php CHANGED
@@ -57,7 +57,7 @@ function wpcf7_text_shortcode_handler( $tag ) {
57
 
58
  $value = (string) reset( $values );
59
 
60
- if ( wpcf7_script_is() && $value && preg_grep( '%^watermark$%', $options ) ) {
61
  $class_att .= ' wpcf7-use-title-as-watermark';
62
  $title_att .= sprintf( ' %s', $value );
63
  $value = '';
57
 
58
  $value = (string) reset( $values );
59
 
60
+ if ( wpcf7_script_is() && preg_grep( '%^watermark$%', $options ) ) {
61
  $class_att .= ' wpcf7-use-title-as-watermark';
62
  $title_att .= sprintf( ' %s', $value );
63
  $value = '';
modules/textarea.php CHANGED
@@ -54,7 +54,7 @@ function wpcf7_textarea_shortcode_handler( $tag ) {
54
  if ( ! empty( $content ) )
55
  $value = $content;
56
 
57
- if ( wpcf7_script_is() && $value && preg_grep( '%^watermark$%', $options ) ) {
58
  $class_att .= ' wpcf7-use-title-as-watermark';
59
  $title_att .= sprintf( ' %s', $value );
60
  $value = '';
54
  if ( ! empty( $content ) )
55
  $value = $content;
56
 
57
+ if ( wpcf7_script_is() && preg_grep( '%^watermark$%', $options ) ) {
58
  $class_att .= ' wpcf7-use-title-as-watermark';
59
  $title_att .= sprintf( ' %s', $value );
60
  $value = '';
readme.txt CHANGED
@@ -3,7 +3,7 @@ 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: 2.9
6
- Tested up to: 3.0.5
7
  Stable tag: 2.4.4
8
 
9
  Just another contact form plugin. Simple but flexible.
@@ -36,7 +36,7 @@ It is hard to continue development and support for this plugin without contribut
36
  * Chinese, Simplified (zh_CN) - [Soz](http://www.webtoolol.com/), [Keefe Dunn](http://dengkefu.com/)
37
  * Chinese, Traditional (zh_TW) - [James Wu](http://jameswublog.com)
38
  * Croatian (hr) - [tolingo Translation Services](http://www.tolingo.com)
39
- * Czech (cs_CZ) - Korry, [Radovan Fiser](http://algymsa.cz/)
40
  * Danish (da_DK) - [Jens Griebel](http://www.kompas-it.dk/), [Georg S. Adamsen](http://wordpress.blogos.dk/)
41
  * Dutch (nl_NL) - [Chris Devriese](http://www.100it.be/), [Martin Hein](http://www.split-a-pixel.nl/), [Rene](http://wpwebshop.com/)
42
  * Estonian (et) - [Peeter Rahuvarm](http://www.kraabus.ee), Egon Elbre
@@ -104,6 +104,16 @@ Do you have questions or issues with Contact Form 7? Use these support channels
104
 
105
  == Changelog ==
106
 
 
 
 
 
 
 
 
 
 
 
107
  = 2.4.4 =
108
 
109
  * Translation for Sinhala has been created by Nitin Aggarwal.
3
  Donate link: http://contactform7.com/donate/
4
  Tags: contact, form, contact form, feedback, email, ajax, captcha, akismet, multilingual
5
  Requires at least: 2.9
6
+ Tested up to: 3.1.2
7
  Stable tag: 2.4.4
8
 
9
  Just another contact form plugin. Simple but flexible.
36
  * Chinese, Simplified (zh_CN) - [Soz](http://www.webtoolol.com/), [Keefe Dunn](http://dengkefu.com/)
37
  * Chinese, Traditional (zh_TW) - [James Wu](http://jameswublog.com)
38
  * Croatian (hr) - [tolingo Translation Services](http://www.tolingo.com)
39
+ * Czech (cs_CZ) - Korry, [Radovan Fiser](http://algymsa.cz/), [Tomas Vesely](http://www.mcmotylek.cz/)
40
  * Danish (da_DK) - [Jens Griebel](http://www.kompas-it.dk/), [Georg S. Adamsen](http://wordpress.blogos.dk/)
41
  * Dutch (nl_NL) - [Chris Devriese](http://www.100it.be/), [Martin Hein](http://www.split-a-pixel.nl/), [Rene](http://wpwebshop.com/)
42
  * Estonian (et) - [Peeter Rahuvarm](http://www.kraabus.ee), Egon Elbre
104
 
105
  == Changelog ==
106
 
107
+ = 2.4.5 =
108
+
109
+ * Fixed the bug that makes it not accept "0" value as watermark.
110
+ * Fixed too much normalization to form-tag shortcode with content.
111
+ * Fixed wrong regexp pattern for form-tag shortcode with content.
112
+ * Check $_POST of checkboxes and select menus to avoid warnings.
113
+ * Use proper action hook for enqueueing scripts: wp_enqueue_scripts and admin_enqueue_scripts.
114
+ * Bundled jquery.form has been updated to 2.72.
115
+ * Translations for Czech (Tomas Vesely) has been updated.
116
+
117
  = 2.4.4 =
118
 
119
  * Translation for Sinhala has been created by Nitin Aggarwal.
wp-contact-form-7.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI: http://contactform7.com/
5
  Description: Just another contact form plugin. Simple but flexible.
6
  Author: Takayuki Miyoshi
7
  Author URI: http://ideasilo.wordpress.com/
8
- Version: 2.4.4
9
  */
10
 
11
  /* Copyright 2007-2011 Takayuki Miyoshi (email: takayukister at gmail.com)
@@ -25,7 +25,7 @@ Version: 2.4.4
25
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
  */
27
 
28
- define( 'WPCF7_VERSION', '2.4.4' );
29
 
30
  if ( ! defined( 'WPCF7_PLUGIN_BASENAME' ) )
31
  define( 'WPCF7_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
5
  Description: Just another contact form plugin. Simple but flexible.
6
  Author: Takayuki Miyoshi
7
  Author URI: http://ideasilo.wordpress.com/
8
+ Version: 2.4.5
9
  */
10
 
11
  /* Copyright 2007-2011 Takayuki Miyoshi (email: takayukister at gmail.com)
25
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
  */
27
 
28
+ define( 'WPCF7_VERSION', '2.4.5' );
29
 
30
  if ( ! defined( 'WPCF7_PLUGIN_BASENAME' ) )
31
  define( 'WPCF7_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );