ACF qTranslate - Version 1.7.16

Version Description

  • Bug Fix: Fixed ACF4 support for standard WYSIWYG field
  • Bug Fix: Updated ACF4 qTranslate WYSIWYG field
  • Bug Fix: Prevent translation of key acf-field-group fields
Download this release

Release Info

Developer funkjedi
Plugin Icon wp plugin ACF qTranslate
Version 1.7.16
Comparing to
See all releases

Code changes from version 1.7.15 to 1.7.16

acf-qtranslate.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Advanced Custom Fields: qTranslate
4
  Plugin URI: http://github.com/funkjedi/acf-qtranslate
5
  Description: Provides multilingual versions of the text, text area, and wysiwyg fields.
6
- Version: 1.7.15
7
  Author: funkjedi
8
  Author URI: http://funkjedi.com
9
  License: GPLv2 or later
3
  Plugin Name: Advanced Custom Fields: qTranslate
4
  Plugin URI: http://github.com/funkjedi/acf-qtranslate
5
  Description: Provides multilingual versions of the text, text area, and wysiwyg fields.
6
+ Version: 1.7.16
7
  Author: funkjedi
8
  Author URI: http://funkjedi.com
9
  License: GPLv2 or later
assets/acf_4/qtranslatex.js CHANGED
@@ -27,8 +27,20 @@ jQuery(window).load(function() {
27
  qTranslateConfig.qtx.removeContentHook(this);
28
  });
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  // Watch and add content hooks when new fields are added
31
- var timeoutContentHooksTinyMCE;
32
  jQuery(document).on('acf/setup_fields', function(e, new_field) {
33
  new_field = jQuery(new_field);
34
  new_field.find(field_types).not('.qtranxs-translatable').each(function() {
@@ -40,6 +52,8 @@ jQuery(window).load(function() {
40
  return;
41
  }
42
 
 
 
43
  qTranslateConfig.qtx.addContentHookC(this, field.closest('form').get(0));
44
 
45
  // Since ACFv4 doesn't update tinyMCEPreInit.mceInit so we
@@ -55,17 +69,11 @@ jQuery(window).load(function() {
55
 
56
  // Run in a setTimeout block to give the tinyMCE instance
57
  // enough time to initialize before setting the editor hooks
58
- clearTimeout(timeoutContentHooksTinyMCE);
59
- timeoutContentHooksTinyMCE = setTimeout(function(){
60
- qTranslateConfig.qtx.addContentHooksTinyMCE();
61
  jQuery.each(tinyMCE.editors, function(i, ed){
62
- var mceInit = tinyMCEPreInit.mceInit[ed.id];
63
- console.log('initEditors:',mceInit);
64
- if (mceInit && mceInit.init_instance_callback) {
65
- mceInit.init_instance_callback(ed);
66
- }
67
  });
68
- }, 50);
69
  });
70
 
71
  // Watch and remove content hooks when fields are removed
@@ -76,4 +84,31 @@ jQuery(window).load(function() {
76
  });
77
  });
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  });
27
  qTranslateConfig.qtx.removeContentHook(this);
28
  });
29
 
30
+ var post_type = jQuery('#post_type').val();
31
+
32
+ // Whitelist fields for translation
33
+ function isTranslatableField(field){
34
+ if (post_type === 'acf-field-group') {
35
+ if (field.id.match(/acf-field-field_[a-z0-9]+_label/)) return true;
36
+ if (field.id.match(/acf-field-field_[a-z0-9]+_instructions/)) return true;
37
+ if (field.id.match(/acf-field-field_[a-z0-9]+_default_value/)) return true;
38
+ return false;
39
+ }
40
+ return true;
41
+ }
42
+
43
  // Watch and add content hooks when new fields are added
 
44
  jQuery(document).on('acf/setup_fields', function(e, new_field) {
45
  new_field = jQuery(new_field);
46
  new_field.find(field_types).not('.qtranxs-translatable').each(function() {
52
  return;
53
  }
54
 
55
+ if (!isTranslatableField(field)) return;
56
+
57
  qTranslateConfig.qtx.addContentHookC(this, field.closest('form').get(0));
58
 
59
  // Since ACFv4 doesn't update tinyMCEPreInit.mceInit so we
69
 
70
  // Run in a setTimeout block to give the tinyMCE instance
71
  // enough time to initialize before setting the editor hooks
72
+ setTimeout(function(){
 
 
73
  jQuery.each(tinyMCE.editors, function(i, ed){
74
+ setEditorHooks(ed);
 
 
 
 
75
  });
76
+ },50);
77
  });
78
 
79
  // Watch and remove content hooks when fields are removed
84
  });
85
  });
86
 
87
+
88
+ // Extracted from qTranslate-X
89
+ // admin/js/common.js#L840
90
+ function setEditorHooks(ed) {
91
+ var id = ed.id;
92
+ if (!id) return;
93
+ var h=qTranslateConfig.qtx.hasContentHook(id);
94
+ if(!h || h.mce) return;
95
+ h.mce=ed;
96
+ ed.getContainer().className += ' qtranxs-translatable';
97
+ ed.getElement().className += ' qtranxs-translatable';
98
+ var updateTinyMCEonInit = h.updateTinyMCEonInit;
99
+ if (updateTinyMCEonInit == null) {
100
+ var text_e = ed.getContent({format: 'html'}).replace(/\s+/g,'');
101
+ var text_h = h.contentField.value.replace(/\s+/g,'');
102
+ updateTinyMCEonInit = text_e != text_h;
103
+ }
104
+ if (updateTinyMCEonInit) {
105
+ text = h.contentField.value;
106
+ if (h.wpautop && window.switchEditors) {
107
+ text = window.switchEditors.wpautop(text);
108
+ }
109
+ h.mce.setContent(text,{format: 'html'});
110
+ }
111
+ return h;
112
+ }
113
+
114
  });
assets/acf_5/qtranslatex.js CHANGED
@@ -36,6 +36,19 @@
36
  qTranslateConfig.qtx.removeContentHook(this);
37
  });
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  // Setup field types
40
  jQuery.each(field_types, function(field_type, selector) {
41
 
@@ -43,6 +56,7 @@
43
  acf.get_fields({ type: field_type }).each(function() {
44
  var form = jQuery(this).closest('form').get(0);
45
  var field = jQuery(this).find(selector).get(0);
 
46
  qTranslateConfig.qtx.addContentHookC(field, form);
47
  });
48
 
@@ -50,6 +64,7 @@
50
  acf.add_action('append_field/type=' + field_type, function($el) {
51
  var form = $el.closest('form').get(0);
52
  var field = $el.find(selector).get(0);
 
53
  qTranslateConfig.qtx.addContentHookC(field, form);
54
 
55
  if (jQuery(field).hasClass('wp-editor-area')) {
36
  qTranslateConfig.qtx.removeContentHook(this);
37
  });
38
 
39
+ var post_type = jQuery('#post_type').val();
40
+
41
+ // Whitelist fields for translation
42
+ function isTranslatableField(field){
43
+ if (post_type === 'acf-field-group') {
44
+ if (field.id.match(/acf_fields-\d+-label/)) return true;
45
+ if (field.id.match(/acf_fields-\d+-instructions/)) return true;
46
+ if (field.id.match(/acf_fields-\d+-default_value/)) return true;
47
+ return false;
48
+ }
49
+ return true;
50
+ }
51
+
52
  // Setup field types
53
  jQuery.each(field_types, function(field_type, selector) {
54
 
56
  acf.get_fields({ type: field_type }).each(function() {
57
  var form = jQuery(this).closest('form').get(0);
58
  var field = jQuery(this).find(selector).get(0);
59
+ if (!isTranslatableField(field)) return;
60
  qTranslateConfig.qtx.addContentHookC(field, form);
61
  });
62
 
64
  acf.add_action('append_field/type=' + field_type, function($el) {
65
  var form = $el.closest('form').get(0);
66
  var field = $el.find(selector).get(0);
67
+ if (!isTranslatableField(field)) return;
68
  qTranslateConfig.qtx.addContentHookC(field, form);
69
 
70
  if (jQuery(field).hasClass('wp-editor-area')) {
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: funkjedi
3
  Tags: acf, advanced custom fields, qtranslate, add-on, admin
4
  Requires at least: 3.5.0
5
  Tested up to: 4.6.1
6
- Version: 1.7.15
7
- Stable tag: 1.7.15
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -59,6 +59,11 @@ The plugin is based on code samples posted to the ACF support forums by taeo bac
59
 
60
  == Changelog ==
61
 
 
 
 
 
 
62
  = 1.7.15 =
63
  * Core: Display LSB on ACF Option pages
64
 
3
  Tags: acf, advanced custom fields, qtranslate, add-on, admin
4
  Requires at least: 3.5.0
5
  Tested up to: 4.6.1
6
+ Version: 1.7.16
7
+ Stable tag: 1.7.16
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
59
 
60
  == Changelog ==
61
 
62
+ = 1.7.16 =
63
+ * Bug Fix: Fixed ACF4 support for standard WYSIWYG field
64
+ * Bug Fix: Updated ACF4 qTranslate WYSIWYG field
65
+ * Bug Fix: Prevent translation of key `acf-field-group` fields
66
+
67
  = 1.7.15 =
68
  * Core: Display LSB on ACF Option pages
69
 
src/acf_4/fields/wysiwyg.php CHANGED
@@ -29,7 +29,28 @@ class acf_qtranslate_acf_4_wysiwyg extends acf_field_wysiwyg {
29
  'default_value' => '',
30
  );
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  acf_field::__construct();
 
 
 
 
33
  }
34
 
35
  /*
@@ -61,17 +82,24 @@ class acf_qtranslate_acf_4_wysiwyg extends acf_field_wysiwyg {
61
  $languages = qtrans_getSortedLanguages(true);
62
  $values = qtrans_split($field['value'], $quicktags = true);
63
  $currentLanguage = $this->plugin->get_active_language();
64
-
 
 
 
 
 
65
  // filter value for editor
66
- remove_all_filters('acf_the_editor_content');
67
-
 
 
68
  // WP 4.3
69
- if( version_compare($wp_version, '4.3', '>=' ) ) {
70
- add_filter( 'acf_the_editor_content', 'format_for_editor' );
71
  // WP < 4.3
72
- } else {
73
- $function = user_can_richedit() ? 'wp_richedit_pre' : 'wp_htmledit_pre';
74
- add_filter('acf_the_editor_content', $function);
75
  }
76
 
77
  echo '<div class="multi-language-field multi-language-field-wysiwyg">';
@@ -82,32 +110,25 @@ class acf_qtranslate_acf_4_wysiwyg extends acf_field_wysiwyg {
82
  }
83
 
84
  foreach ($languages as $language):
85
- $value = $values[$language];
86
  $id = 'wysiwyg-' . $field['id'] . '-' . uniqid();
87
  $name = $field['name'] . "[$language]";
88
- $class = ($language === $currentLanguage) ? 'acf_wysiwyg wp-editor-wrap current-language' : 'acf_wysiwyg wp-editor-wrap';
 
89
 
90
  ?>
91
- <div id="wp-<?php echo $id; ?>-wrap" class="<?php echo $class; ?>" data-toolbar="<?php echo $field['toolbar']; ?>" data-upload="<?php echo $field['media_upload']; ?>" data-language="<?php echo $language; ?>">
92
- <?php if( user_can_richedit() && $field['media_upload'] == 'yes' ): ?>
93
- <?php if( version_compare($wp_version, '3.3', '<') ): ?>
94
- <div id="editor-toolbar">
95
- <div id="media-buttons" class="hide-if-no-js">
96
- <?php do_action( 'media_buttons' ); ?>
97
- </div>
98
- </div>
99
- <?php else: ?>
100
- <div id="wp-<?php echo $id; ?>-editor-tools" class="wp-editor-tools">
101
- <div id="wp-<?php echo $id; ?>-media-buttons" class="hide-if-no-js wp-media-buttons">
102
- <?php do_action( 'media_buttons' ); ?>
103
- </div>
104
- </div>
105
  <?php endif; ?>
106
- <?php endif; ?>
107
  <div id="wp-<?php echo $id; ?>-editor-container" class="wp-editor-container">
108
- <textarea id="<?php echo $id; ?>" class="qtx-wp-editor-area" name="<?php echo $name; ?>" ><?php echo apply_filters( 'acf_the_editor_content', $value, 'tinymce' ); ?></textarea>
109
  </div>
110
  </div>
 
111
  <?php endforeach;
112
 
113
  echo '</div>';
29
  'default_value' => '',
30
  );
31
 
32
+ // Create an acf version of the_content filter (acf_the_content)
33
+ if( isset($GLOBALS['wp_embed']) ) {
34
+
35
+ add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'run_shortcode' ), 8 );
36
+ add_filter( 'acf_the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 );
37
+
38
+ }
39
+
40
+ add_filter( 'acf_the_content', 'capital_P_dangit', 11 );
41
+ add_filter( 'acf_the_content', 'wptexturize' );
42
+ add_filter( 'acf_the_content', 'convert_smilies' );
43
+ add_filter( 'acf_the_content', 'convert_chars' );
44
+ add_filter( 'acf_the_content', 'wpautop' );
45
+ add_filter( 'acf_the_content', 'shortcode_unautop' );
46
+ //add_filter( 'acf_the_content', 'prepend_attachment' ); *should only be for the_content (causes double image on attachment page)
47
+ add_filter( 'acf_the_content', 'do_shortcode', 11);
48
+
49
  acf_field::__construct();
50
+
51
+ // filters
52
+ add_filter( 'acf/fields/wysiwyg/toolbars', array( $this, 'toolbars'), 1, 1 );
53
+ add_filter( 'mce_external_plugins', array( $this, 'mce_external_plugins'), 20, 1 );
54
  }
55
 
56
  /*
82
  $languages = qtrans_getSortedLanguages(true);
83
  $values = qtrans_split($field['value'], $quicktags = true);
84
  $currentLanguage = $this->plugin->get_active_language();
85
+
86
+ // vars
87
+ //$id = uniqid('acf-editor-');
88
+ $id = 'wysiwyg-' . $field['id'] . '-' . uniqid();
89
+ $default_editor = 'tinymce';
90
+
91
  // filter value for editor
92
+ remove_filter( 'acf_the_editor_content', 'format_for_editor', 10, 2 );
93
+ remove_filter( 'acf_the_editor_content', 'wp_htmledit_pre', 10, 1 );
94
+ remove_filter( 'acf_the_editor_content', 'wp_richedit_pre', 10, 1 );
95
+
96
  // WP 4.3
97
+ if( version_compare($wp_version, '4.3', '>=' ) ) {
98
+ add_filter( 'acf_the_editor_content', 'format_for_editor', 10, 2 );
99
  // WP < 4.3
100
+ } else {
101
+ $function = user_can_richedit() ? 'wp_richedit_pre' : 'wp_htmledit_pre';
102
+ add_filter('acf_the_editor_content', $function, 10, 1);
103
  }
104
 
105
  echo '<div class="multi-language-field multi-language-field-wysiwyg">';
110
  }
111
 
112
  foreach ($languages as $language):
 
113
  $id = 'wysiwyg-' . $field['id'] . '-' . uniqid();
114
  $name = $field['name'] . "[$language]";
115
+ $class = ($language === $currentLanguage) ? 'current-language' : '';
116
+ $value = apply_filters('acf_the_editor_content', $values[$language], 'tinymce');
117
 
118
  ?>
119
+ <div id="wp-<?php echo $id; ?>-wrap" class="acf_wysiwyg wp-core-ui wp-editor-wrap tmce-active <?php echo $class; ?>" data-toolbar="<?php echo $field['toolbar']; ?>" data-upload="<?php echo $field['media_upload']; ?>" data-language="<?php echo $language; ?>">
120
+ <div id="wp-<?php echo $id; ?>-editor-tools" class="wp-editor-tools hide-if-no-js">
121
+ <?php if( user_can_richedit() && $field['media_upload'] == 'yes' ): ?>
122
+ <div id="wp-<?php echo $id; ?>-media-buttons" class="wp-media-buttons">
123
+ <?php do_action( 'media_buttons', $id ); ?>
124
+ </div>
 
 
 
 
 
 
 
 
125
  <?php endif; ?>
126
+ </div>
127
  <div id="wp-<?php echo $id; ?>-editor-container" class="wp-editor-container">
128
+ <textarea id="<?php echo $id; ?>" class="qtx-wp-editor-area" name="<?php echo $name; ?>"><?php echo $value; ?></textarea>
129
  </div>
130
  </div>
131
+
132
  <?php endforeach;
133
 
134
  echo '</div>';
src/plugin.php CHANGED
@@ -16,6 +16,7 @@ class acf_qtranslate_plugin {
16
  public function __construct() {
17
  add_action('after_setup_theme', array($this, 'after_setup_theme'), -10);
18
  add_action('acf/input/admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
 
19
  add_action('admin_menu', array($this, 'admin_menu'));
20
  add_action('admin_init', array($this, 'admin_init'));
21
 
@@ -165,6 +166,14 @@ class acf_qtranslate_plugin {
165
  wp_enqueue_script('acf_qtranslate_common', plugins_url('/assets/common.js', ACF_QTRANSLATE_PLUGIN), array('acf-input','underscore'));
166
  }
167
 
 
 
 
 
 
 
 
 
168
  /**
169
  * Add settings link on plugin page.
170
  * @param array
@@ -182,20 +191,45 @@ class acf_qtranslate_plugin {
182
  */
183
  public function qtranslate_load_admin_page_config($config)
184
  {
185
- $config['acf-options-page'] = array(
186
- 'pages' => array('admin.php' => 'page='),
187
- 'anchors' => array('poststuff' => array('where' => 'first last')),
188
- 'forms' => array(
189
- 'post' => array(
190
  'fields' => array(
191
- 'acf4-field-group-hX' => array(
 
 
 
 
192
  'jquery' => '.acf_postbox h2 span,.acf_postbox h3 span',
193
  'encode' => 'display',
194
  ),
195
- 'acf5-field-group-hX' => array(
196
  'jquery' => '.acf-postbox h2 span,.acf-postbox h3 span',
197
  'encode' => 'display',
198
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  )),
200
  ),
201
  );
16
  public function __construct() {
17
  add_action('after_setup_theme', array($this, 'after_setup_theme'), -10);
18
  add_action('acf/input/admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
19
+ add_action('admin_footer', array($this, 'admin_footer'));
20
  add_action('admin_menu', array($this, 'admin_menu'));
21
  add_action('admin_init', array($this, 'admin_init'));
22
 
166
  wp_enqueue_script('acf_qtranslate_common', plugins_url('/assets/common.js', ACF_QTRANSLATE_PLUGIN), array('acf-input','underscore'));
167
  }
168
 
169
+ /**
170
+ * Output a hidden block that can be use to force qTranslate-X
171
+ * to include the LSB.
172
+ */
173
+ public function admin_footer() {
174
+ echo '<span id="acf-qtranslate-lsb-shim" style="display:none">[:en]LSB[:]</span>';
175
+ }
176
+
177
  /**
178
  * Add settings link on plugin page.
179
  * @param array
191
  */
192
  public function qtranslate_load_admin_page_config($config)
193
  {
194
+ $config['acf-display-nodes'] = array(
195
+ 'pages' => array('post.php' => '', 'admin.php' => 'page='),
196
+ 'forms' => array(
197
+ 'wpwrap' => array(
 
198
  'fields' => array(
199
+ 'lsb-shim' => array(
200
+ 'jquery' => '#acf-qtranslate-lsb-shim',
201
+ 'encode' => 'display',
202
+ ),
203
+ 'acf4-field-group-handle' => array(
204
  'jquery' => '.acf_postbox h2 span,.acf_postbox h3 span',
205
  'encode' => 'display',
206
  ),
207
+ 'acf5-field-group-handle' => array(
208
  'jquery' => '.acf-postbox h2 span,.acf-postbox h3 span',
209
  'encode' => 'display',
210
  ),
211
+ 'acf5-field-label' => array(
212
+ 'jquery' => '.acf-field .acf-label label',
213
+ 'encode' => 'display',
214
+ ),
215
+ 'acf5-field-description' => array(
216
+ 'jquery' => '.acf-field .acf-label p.description',
217
+ 'encode' => 'display',
218
+ ),
219
+ )),
220
+ ),
221
+ );
222
+
223
+ $config['acf-field-group'] = array(
224
+ 'pages' => array('post.php' => ''),
225
+ 'post_type' => 'acf-field-group',
226
+ 'forms' => array(
227
+ 'post' => array(
228
+ 'fields' => array(
229
+ 'field-group-object-label' => array(
230
+ 'jquery' => '.li-field-label .edit-field',
231
+ 'encode' => 'display',
232
+ ),
233
  )),
234
  ),
235
  );