Qtranslate Slug - Version 1.1.7

Version Description

  • removed styles from html elements and added options to use .css file or print inline styles
  • fixed tag creation on post edit.
  • fixed earlier bad post slug introduced in 1.1.6
Download this release

Release Info

Developer carlos_a_sanz
Plugin Icon wp plugin Qtranslate Slug
Version 1.1.7
Comparing to
See all releases

Code changes from version 1.1.6 to 1.1.7

README.txt ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Qtranslate Slug ===
2
+ Contributors: Carlos Sanz García
3
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=SYC46KSLRC4Q8
4
+ Tags: qtranslate, slug, multilanguage
5
+ Requires at least: 3.3
6
+ Tested up to: 3.9.1
7
+ Version: 1.1.7
8
+ License: GPLv2 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ Adds support for permalink translations and fix some QTranslate deficiencies since wordpress 3.0
12
+
13
+ == Description ==
14
+
15
+ [Qtranslate](http://wordpress.org/extend/plugins/qtranslate/) is a nice plugin but unfortunately today is **outdated**. **Qtranslate Slug** is an addon to QTranslate, which adds support for permalinks translations and fix some QTranslate deficiencies since wordpress 3.0.
16
+
17
+ **Version 1.0** has been written from scratch using OOP. The code has been structured better, the functions have been marked and commented and everything is better integrated with Wordpress API.
18
+
19
+ = Requirements: =
20
+
21
+ * Wordpress 3.3 (PHP 5.2 and MySQL 5)
22
+ * mQtranslate 2.6.2.4 or Qtranslate 2.5.8
23
+
24
+ = New in version 1.1.7 =
25
+ * removed styles from html elements and added options to use .css file or print inline styles
26
+ * fixed tag creation on post edit.
27
+ * fixed earlier bad post slug introduced in 1.1.6
28
+
29
+ **Advice: If you're using a multisite installation, you will must activate qtranslate plugins by separately on each site.**
30
+
31
+
32
+ You can also check the [project website](http://not-only-code.github.com/qtranslate-slug/) hosted on [GitHub](http://not-only-code.github.com).
33
+ Thanks for use this plugin!
34
+
35
+ == Installation ==
36
+ **This plugins requires [Qtranslate](http://wordpress.org/extend/plugins/qtranslate/) or [mqTranslate](https://wordpress.org/plugins/mqtranslate/) installed previously, if not, it will not activate.**
37
+
38
+ 1. Upload `qtranslate-slug` to the `/wp-content/plugins/` directory.
39
+ 1. Activate the plugin through the 'Plugins' menu in WordPress.
40
+ 1. That's all!
41
+
42
+ = Changing base permastructs =
43
+
44
+ 1. In admin: navigate to *Settings/Slug options*.
45
+ 1. Set the base permastructs for **post types** and **taxonomies** (If you setup a base permastruct for *categories* or *tags* in *Settings/Permalinks*, these will be overwritten by the translated ones).
46
+ 1. Save settings and that's all!
47
+
48
+ == Frequently Asked Questions ==
49
+
50
+ = It works with posts and pages, but with other content type? =
51
+
52
+ This plugin allows to translate slugs of: posts, pages, custom post types, categories, tags and custom taxonomies.
53
+
54
+ = Do I have to configure anything? =
55
+
56
+ If you want to translate also the base permastructs (ex. *category*, *tag*, etc). Visit the plugin settings page in the admin *Settings/Slug options*
57
+
58
+ = How can i insert a language selector in my theme ? =
59
+
60
+ You can choose to:
61
+ * use **Qtranslate Slug Widget** in your sidebar.
62
+ * place in your template `<?php if (function_exists('qts_language_menu') ) qts_language_menu('text'); ?>`. Options are: `dropdown`, `text`, `image`, and `both`.
63
+
64
+ = Appears an error 404, what can i do? =
65
+
66
+ In the admin go to *Settings/Permalinks* or *Settings/Slug options* and save.
67
+
68
+ = I can't manage translations in Nav Menus. =
69
+
70
+ That's because language selector metabox is hidden, if you are in admin *nav menus* screen, press the button **Screen options** (on top and right) and after, check the option *Languages*. It will appear a **Language** meta box on top of the left sidebar.
71
+
72
+ == Screenshots ==
73
+
74
+ 1. Edit page for: post / page / post_type, you can see the meta box for translated slugs on top and right.
75
+ 2. Add new taxonomy page
76
+ 3. Edit taxonomy page
77
+ 4. Qtranslate Slug options page for translate base permastructs of post_types and taxonomies.
78
+
79
+ == Changelog ==
80
+ = 1.1.7 =
81
+ * removed styles from html elements and added options to use .css file or print inline styles
82
+ * fixed tag creation on post edit.
83
+ * fixed earlier bad post slug introduced in 1.1.6
84
+
85
+ = 1.1.6 =
86
+ * compatible with mqtranslate
87
+ * php5.4+ compatible
88
+
89
+ = 1.1.5 =
90
+ * bugfixes
91
+
92
+ = 1.1 =
93
+ * added multisite support
94
+ * fixed some parse url bugs
95
+ * fixed slug bases validation
96
+
97
+ = 1.0 =
98
+ * **works** with any permalink combination and qtranslate mode.
99
+ * new branch, the plugin has been rewritten: now the code is commented and wrapped inside a class, much code has change and the performance has been increased (use caches).
100
+ * data system changed, no ID for slug type, then it don't needs install `qtrasnlate_slug` table. That means slugs now are stored on meta tables and installation creates a termmeta table with some new *core functions* to access/save data, based on [simple term meta](http://wordpress.org/extend/plugins/simple-term-meta/). Upgrade process when the plugin updates from older versions.
101
+ * the plugin generates translated slug automatically from title in empty cases.
102
+ * the plugin checks if the slug already exists (per each language and `post_type`/`taxonomy`), and adds a progressive number in this case. Works on ajax requests for example when new taxonomies are created in edit post page.
103
+ * possibility to translate the base of permastructs for *post_types* and *taxonomies*, uses [$wp_rewrite](http://codex.wordpress.org/Class_Reference/WP_Rewrite). New admin options page for save the base permastructs.
104
+ * added some filters, see in [other notes](http://wordpress.org/extend/plugins/qtranslate-slug/other_notes/).
105
+ * added plugin language textdomain (.pot file).
106
+ * updated **Language selector Widget**, and some new conventions like accessible functions for templating.
107
+ * some bug fixes.
108
+ * some Qtranslate patches.
109
+
110
+ = 0.9 =
111
+ * some wordpress qTranslate bug fixes
112
+ * adds a javascript solution for qTranslate Nav Menus
113
+
114
+ = 0.8 =
115
+ * added support por Categories
116
+ * added support por Tags
117
+ * added support por Taxonomies
118
+ * added support por Custom Post Types
119
+
120
+ = 0.7 = [Zapo](http://www.qianqin.de/qtranslate/forum/viewtopic.php?f=4&t=1049&start=50#p7499)
121
+ * added suport for qTranslate TLD domain mode (en: domain.com | fr: domain.fr) visit
122
+
123
+ = 0.5 and 0.6 enhanched by Marco Del Percio =
124
+
125
+ == Upgrade Notice ==
126
+
127
+ = 1.0 =
128
+ Major version, the plugin has been rewritten. Better performance, and some enhancements.
129
+
130
+ = 0.9 =
131
+ This version fix some bugs and allow multilanguage in nav-menus.
132
+
133
+ = 0.8 =
134
+ A lot of slugs content allowed
135
+
136
+ = 0.7 =
137
+ This version allows TLD domain option for a different Qtranslate fork maded by Zappo
138
+
139
+
140
+ == Other notes ==
141
+
142
+ Plugin filters reference:
143
+
144
+ = qts_validate_post_slug =
145
+ filter to process the post slug before is saved on the database.
146
+ `args: $post (object), $slug (string), $lang (string)`
147
+
148
+ = qts_validate_term_slug =
149
+ filter to process the term slug before is saved on the database.
150
+ `args: $term (object), $slug (string), $lang (string)`
151
+
152
+ = qts_url_args =
153
+ filter to process the entire url after it has been generated.
154
+ `args: $url (string), $lang (string)`
155
+
156
+ = qts_permastruct =
157
+ filter to process the permastruct, used for change the base.
158
+ `args: $permastruct (string), $name (string)`
159
+
160
+
161
+ = Todo =
162
+
163
+ * detect Slug for each language and redirect accordingly in parse_query.
164
+ * expand qtranslate for translate attachment names and descriptions ( useful for galleries )
165
+ * translate other slugs like attachments.
166
+ * qtranslate integration with other plugins like Jigoshop, e-commerce, etc. Addapt **$wp_rewrite**.
assets/css/qts-default.css ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .qts_type_image .qts_lang_item {
2
+ float: left;
3
+ margin-right: 7px;
4
+ }
5
+ .qts_type_image .qts_lang_item.last-child {
6
+ margin-right: 0;
7
+ }
8
+ .qts_lang_item{
9
+ margin-top: 7px;
10
+ margin-bottom: 7px;
11
+ }
12
+ .qts_both {
13
+ padding-left: 25px;
14
+ white-space: nowrap;
15
+ line-height:1em;
16
+ }
assets/css/qts-settings.css CHANGED
@@ -1,4 +1,4 @@
1
- /*messages*/
2
  .error {color:#cc0000;}
3
 
4
  .form-table th {
@@ -10,6 +10,12 @@
10
  display: inline-block;
11
  min-width: 100px;
12
  }
 
 
 
 
 
 
13
  .qts-slug {
14
  width: 35%;
15
  }
1
+ /*messages*/
2
  .error {color:#cc0000;}
3
 
4
  .form-table th {
10
  display: inline-block;
11
  min-width: 100px;
12
  }
13
+
14
+ .form-table label {
15
+ display: block;
16
+ margin-bottom: 8px;
17
+ }
18
+
19
  .qts-slug {
20
  width: 35%;
21
  }
qtranslate-slug-settings-options.php CHANGED
@@ -13,6 +13,7 @@ function qts_options_page_sections() {
13
  $sections = array();
14
  $sections['post_types'] = __('Post types', 'qts');
15
  $sections['taxonomies'] = __('Taxonomies', 'qts');
 
16
 
17
  return $sections;
18
  }
@@ -43,6 +44,43 @@ function get_multi_txt_choices($name = false) {
43
  }
44
 
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  /**
47
  * Define our form fields (settings)
48
  *
@@ -116,6 +154,7 @@ function qts_options_page_fields() {
116
  endforeach;
117
  // end each extra taxonomy
118
 
 
119
  return $options;
120
  }
121
 
13
  $sections = array();
14
  $sections['post_types'] = __('Post types', 'qts');
15
  $sections['taxonomies'] = __('Taxonomies', 'qts');
16
+ $sections['styles'] = __('Styles', 'qts');
17
 
18
  return $sections;
19
  }
44
  }
45
 
46
 
47
+
48
+ /**
49
+ * Define our form fields (settings) for displaying the default styles
50
+ *
51
+ * @package Qtranslate Slug
52
+ * @subpackage Settings
53
+ * @version 1.1.7
54
+ *
55
+ * @return array
56
+ */
57
+ function qts_options_page_styles() {
58
+ global $q_config;
59
+
60
+ $options[] = array(
61
+ "section" => "styles",
62
+ "id" => QTS_PREFIX . "styles",
63
+ "title" => __('Change styles type', 'qts'),
64
+ "desc" => array(
65
+ __("adds a file (qts-default.css) file to the theme's header.", "qts"),
66
+ __("prints the styles directly into the theme's header.", "qts"),
67
+ __("neither include not print the default style.", "qts")
68
+ ),
69
+ "type" => "multi-radio",
70
+ 'class' => 'qts-style',
71
+ "choices" => array(
72
+ "file",
73
+ "inline",
74
+ "none"
75
+ ),
76
+ "std" => "file"
77
+ );
78
+
79
+ return $options;
80
+ }
81
+
82
+
83
+
84
  /**
85
  * Define our form fields (settings)
86
  *
154
  endforeach;
155
  // end each extra taxonomy
156
 
157
+
158
  return $options;
159
  }
160
 
qtranslate-slug-settings.php CHANGED
@@ -180,9 +180,12 @@ function qts_get_settings() {
180
  // put together the output array
181
  $output['qts_option_name'] = QTS_OPTIONS_NAME; // the option name as used in the get_option() call.
182
  $output['qts_page_title'] = __('Qtranslate Slug options', 'qts'); // the settings page title
183
- $output['qts_page_sections'] = qts_options_page_sections(); // the setting section
184
- $output['qts_page_fields'] = qts_options_page_fields(); // the setting fields
185
- $output['qts_contextual_help'] = qts_options_page_contextual_help(); // the contextual help
 
 
 
186
 
187
  return $output;
188
  }
@@ -203,14 +206,14 @@ return $output;
203
  function qts_create_settings_field( $args = array() ) {
204
  // default array to overwrite when calling the function
205
  $defaults = array(
206
- 'id' => 'default_field', // the ID of the setting in our options array, and the ID of the HTML form element
207
- 'title' => 'Default Field', // the label for the HTML form element
208
  'desc' => 'This is a default description.', // the description displayed under the HTML form element
209
- 'std' => '', // the default value for this setting
210
- 'type' => 'text', // the HTML form element to use
211
- 'section' => 'main_section', // the section this setting belongs to must match the array key of a section in qts_options_page_sections()
212
- 'choices' => array(), // (optional): the values in radio buttons or a drop-down menu
213
- 'class' => '' // the HTML form element class. Is used for validation purposes and may be also use for styling if needed.
214
  );
215
 
216
  // "extract" to be able to use the array keys as variables in our function output below
@@ -226,6 +229,8 @@ function qts_create_settings_field( $args = array() ) {
226
  'label_for' => $id,
227
  'class' => $class
228
  );
 
 
229
 
230
  add_settings_field( $id, $title, 'qts_show_form_field', __FILE__, $section, $field_args );
231
 
@@ -265,6 +270,13 @@ function qts_register_settings(){
265
  qts_create_settings_field($option);
266
  }
267
  }
 
 
 
 
 
 
 
268
  }
269
  add_action( 'admin_init', 'qts_register_settings' );
270
 
@@ -350,6 +362,10 @@ function qts_section_fn($page_section = false) {
350
 
351
  echo "<p>" . __('For example, the taxonomy <kbd>category</kbd>, in Spanish would be displayed as <code>http://example.org/es/categoria/taxonomy-name/</code>. If you leave this blank will use the default option when you <a href="http://codex.wordpress.org/Function_Reference/register_taxonomy">registered</a> the taxonomy (if you previously setup a base permastruct for <u>categories</u> or <u>tags</u> in <a href="options-permalink.php">permalinks</a> page, these bases will be overwritten by the translated ones).', 'qts') . "</p>";
352
  break;
 
 
 
 
353
  }
354
  }
355
 
@@ -468,6 +484,28 @@ function qts_show_form_field($args = array()) {
468
  }
469
  echo ($desc != '') ? "<br /><span class='description'>$desc</span>" : "";
470
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
471
  }
472
  }
473
 
@@ -533,6 +571,7 @@ function qts_show_settings_page() {
533
  qts_upgrade();
534
  // http://codex.wordpress.org/Function_Reference/settings_fields
535
  settings_fields($settings_output['qts_option_name']);
 
536
  // http://codex.wordpress.org/Function_Reference/do_settings_sections
537
  do_settings_sections(__FILE__);
538
  // rewrite rules
@@ -563,13 +602,18 @@ function qts_validate_options($input) {
563
  // for enhanced security, create a new empty array
564
  $valid_input = array();
565
 
566
- // collect only the values we expect and fill the new $valid_input array i.e. whitelist our option IDs
 
567
 
568
  // get the settings sections array
569
  $settings_output = qts_get_settings();
570
 
571
- $options = $settings_output['qts_page_fields'];
 
 
572
 
 
 
573
  // run a foreach and switch on option type
574
  foreach ($options as $option):
575
 
@@ -662,10 +706,13 @@ function qts_validate_options($input) {
662
  'i' => array (),
663
  'strong' => array()
664
  );
665
-
666
- $input[$option['id']] = trim($input[$option['id']]); // trim whitespace
667
- $input[$option['id']] = force_balance_tags($input[$option['id']]); // find incorrectly nested or missing closing tags and fix markup
668
- $input[$option['id']] = wp_kses( $input[$option['id']], $allowed_html); // need to add slashes still before sending to the database
 
 
 
669
  $valid_input[$option['id']] = addslashes($input[$option['id']]);
670
  break;
671
  }
@@ -731,23 +778,29 @@ function qts_validate_options($input) {
731
  //for only inline html
732
  case 'inlinehtml':
733
  // accept only inline html
734
- $input[$option['id']] = trim($input[$option['id']]); // trim whitespace
735
- $input[$option['id']] = force_balance_tags($input[$option['id']]); // find incorrectly nested or missing closing tags and fix markup
736
- $input[$option['id']] = addslashes($input[$option['id']]); //wp_filter_kses expects content to be escaped!
737
- $valid_input[$option['id']] = wp_filter_kses($input[$option['id']]); //calls stripslashes then addslashes
 
 
 
 
738
  break;
739
 
740
  //for no html
741
  case 'nohtml':
742
  //accept the input only after stripping out all html, extra white space etc!
743
- $input[$option['id']] = sanitize_text_field($input[$option['id']]); // need to add slashes still before sending to the database
 
744
  $valid_input[$option['id']] = addslashes($input[$option['id']]);
745
  break;
746
 
747
  //for allowlinebreaks
748
  case 'allowlinebreaks':
749
  //accept the input only after stripping out all html, extra white space etc!
750
- $input[$option['id']] = wp_strip_all_tags($input[$option['id']]); // need to add slashes still before sending to the database
 
751
  $valid_input[$option['id']] = addslashes($input[$option['id']]);
752
  break;
753
 
@@ -769,7 +822,7 @@ function qts_validate_options($input) {
769
  'ol' => array(),
770
  'p' => array(),
771
  'q' => array('cite' => array ()),
772
- 'strong' => array(),
773
  'ul' => array(),
774
  'h1' => array('align' => array (),'class' => array (),'id' => array (), 'style' => array ()),
775
  'h2' => array('align' => array (),'class' => array (),'id' => array (), 'style' => array ()),
@@ -840,12 +893,23 @@ function qts_validate_options($input) {
840
  $valid_input[$option['id']] = $checkboxarray;
841
  }
842
  break;
 
 
 
 
843
 
844
  endswitch;
845
-
 
 
 
 
 
846
  endforeach;
847
 
848
- return qts_sanitize_bases($valid_input);
 
 
849
  }
850
 
851
 
@@ -883,10 +947,12 @@ function qts_admin_msgs() {
883
 
884
  // check for our settings page - need this in conditional further down
885
  $qts_settings_pg = isset($_GET['page']) ? strpos($_GET['page'], QTS_PAGE_BASENAME) : '';
886
- // collect setting errors/notices: //http://codex.wordpress.org/Function_Reference/get_settings_errors
 
887
  $set_errors = get_settings_errors();
888
 
889
- //display admin message only for the admin to see, only on our settings page and only when setting errors/notices are returned!
 
890
  if(current_user_can ('manage_options') && $qts_settings_pg !== false && !empty($set_errors)){
891
 
892
  // have our settings succesfully been updated?
180
  // put together the output array
181
  $output['qts_option_name'] = QTS_OPTIONS_NAME; // the option name as used in the get_option() call.
182
  $output['qts_page_title'] = __('Qtranslate Slug options', 'qts'); // the settings page title
183
+ $output['qts_page_sections'] = qts_options_page_sections(); // the settings sections
184
+ $output['qts_page_fields'] = qts_options_page_fields(); // the settings fields
185
+ $output['qts_page_styles'] = qts_options_page_styles(); // the settings for style
186
+
187
+
188
+ $output['qts_contextual_help'] = qts_options_page_contextual_help(); // the contextual help
189
 
190
  return $output;
191
  }
206
  function qts_create_settings_field( $args = array() ) {
207
  // default array to overwrite when calling the function
208
  $defaults = array(
209
+ 'id' => 'default_field', // the ID of the setting in our options array, and the ID of the HTML form element
210
+ 'title' => 'Default Field', // the label for the HTML form element
211
  'desc' => 'This is a default description.', // the description displayed under the HTML form element
212
+ 'std' => '', // the default value for this setting
213
+ 'type' => 'text', // the HTML form element to use
214
+ 'section' => 'main_section', // the section this setting belongs to must match the array key of a section in qts_options_page_sections()
215
+ 'choices' => array(), // (optional): the values in radio buttons or a drop-down menu
216
+ 'class' => '' // the HTML form element class. Is used for validation purposes and may be also use for styling if needed.
217
  );
218
 
219
  // "extract" to be able to use the array keys as variables in our function output below
229
  'label_for' => $id,
230
  'class' => $class
231
  );
232
+
233
+
234
 
235
  add_settings_field( $id, $title, 'qts_show_form_field', __FILE__, $section, $field_args );
236
 
270
  qts_create_settings_field($option);
271
  }
272
  }
273
+ //style
274
+ if(!empty($settings_output['qts_page_styles'])){
275
+ // call the "add_settings_field" for each
276
+ foreach ($settings_output['qts_page_styles'] as $styleoption) {
277
+ qts_create_settings_field($styleoption);
278
+ }
279
+ }
280
  }
281
  add_action( 'admin_init', 'qts_register_settings' );
282
 
362
 
363
  echo "<p>" . __('For example, the taxonomy <kbd>category</kbd>, in Spanish would be displayed as <code>http://example.org/es/categoria/taxonomy-name/</code>. If you leave this blank will use the default option when you <a href="http://codex.wordpress.org/Function_Reference/register_taxonomy">registered</a> the taxonomy (if you previously setup a base permastruct for <u>categories</u> or <u>tags</u> in <a href="options-permalink.php">permalinks</a> page, these bases will be overwritten by the translated ones).', 'qts') . "</p>";
364
  break;
365
+ case 'styles':
366
+
367
+ echo "<p>" . __('The default styles are very minimal, and you can include them or not.', 'qts') . "</p>\n";
368
+ break;
369
  }
370
  }
371
 
484
  }
485
  echo ($desc != '') ? "<br /><span class='description'>$desc</span>" : "";
486
  break;
487
+
488
+ case "multi-radio":
489
+ foreach($choices as $index => $item) {
490
+
491
+ $item = explode("|",$item);
492
+ $item_key = (count($item) > 1) ? esc_html($item[0], 'qts') : esc_html(end($item), 'qts');
493
+ $item_value = (count($item) > 1) ? esc_html($item[1], 'qts') : esc_html(end($item), 'qts');
494
+
495
+ $checked = '';
496
+
497
+ if ( isset($options[$id]) && $options[$id] === $item_value) {
498
+ $checked = 'checked="checked"';
499
+ }
500
+
501
+ echo "<label for='$id|$item_value'><input class='radio$field_class' type='radio' id='$id|$item_value' name='" . QTS_OPTIONS_NAME . "[$id]' value='$item_value' $checked /> <strong>$item_key</strong>";
502
+ if (isset($desc[$index]) && !empty($desc[$index])) {
503
+ echo ": " . $desc[$index];
504
+ }
505
+ echo "</label>";
506
+ }
507
+ echo (!is_array($desc) && $desc != '') ? "<br /><span class='description'>$desc</span>" : "";
508
+ break;
509
  }
510
  }
511
 
571
  qts_upgrade();
572
  // http://codex.wordpress.org/Function_Reference/settings_fields
573
  settings_fields($settings_output['qts_option_name']);
574
+
575
  // http://codex.wordpress.org/Function_Reference/do_settings_sections
576
  do_settings_sections(__FILE__);
577
  // rewrite rules
602
  // for enhanced security, create a new empty array
603
  $valid_input = array();
604
 
605
+ // collect only the values we expect and fill the new $valid_input array
606
+ // i.e. whitelist our option IDs
607
 
608
  // get the settings sections array
609
  $settings_output = qts_get_settings();
610
 
611
+ $styleoptions = $settings_output['qts_page_styles'];
612
+
613
+ $slugoptions = $settings_output['qts_page_fields'];
614
 
615
+ $options = array_merge($styleoptions,$slugoptions);
616
+
617
  // run a foreach and switch on option type
618
  foreach ($options as $option):
619
 
706
  'i' => array (),
707
  'strong' => array()
708
  );
709
+ // trim whitespace
710
+ $input[$option['id']] = trim($input[$option['id']]);
711
+ // find incorrectly nested or missing closing tags and fix markup
712
+ $input[$option['id']] = force_balance_tags($input[$option['id']]);
713
+ // need to add slashes still before sending to the database
714
+ $input[$option['id']] = wp_kses( $input[$option['id']], $allowed_html);
715
+
716
  $valid_input[$option['id']] = addslashes($input[$option['id']]);
717
  break;
718
  }
778
  //for only inline html
779
  case 'inlinehtml':
780
  // accept only inline html
781
+ // trim whitespace
782
+ $input[$option['id']] = trim($input[$option['id']]);
783
+ // find incorrectly nested or missing closing tags and fix markup
784
+ $input[$option['id']] = force_balance_tags($input[$option['id']]);
785
+ //wp_filter_kses expects content to be escaped!
786
+ $input[$option['id']] = addslashes($input[$option['id']]);
787
+ //calls stripslashes then addslashes
788
+ $valid_input[$option['id']] = wp_filter_kses($input[$option['id']]);
789
  break;
790
 
791
  //for no html
792
  case 'nohtml':
793
  //accept the input only after stripping out all html, extra white space etc!
794
+ // need to add slashes still before sending to the database
795
+ $input[$option['id']] = sanitize_text_field($input[$option['id']]);
796
  $valid_input[$option['id']] = addslashes($input[$option['id']]);
797
  break;
798
 
799
  //for allowlinebreaks
800
  case 'allowlinebreaks':
801
  //accept the input only after stripping out all html, extra white space etc!
802
+ // need to add slashes still before sending to the database
803
+ $input[$option['id']] = wp_strip_all_tags($input[$option['id']]);
804
  $valid_input[$option['id']] = addslashes($input[$option['id']]);
805
  break;
806
 
822
  'ol' => array(),
823
  'p' => array(),
824
  'q' => array('cite' => array ()),
825
+ 'strong' => array(),
826
  'ul' => array(),
827
  'h1' => array('align' => array (),'class' => array (),'id' => array (), 'style' => array ()),
828
  'h2' => array('align' => array (),'class' => array (),'id' => array (), 'style' => array ()),
893
  $valid_input[$option['id']] = $checkboxarray;
894
  }
895
  break;
896
+
897
+ case 'multi-radio':
898
+ $valid_input[$option['id']] = $input[$option['id']];
899
+ break;
900
 
901
  endswitch;
902
+
903
+ if( $valid_input[$option['class']] === "qts-slug" )
904
+ $valid_input = qts_sanitize_bases($valid_input);
905
+ else
906
+ $valid_input= $valid_input;
907
+
908
  endforeach;
909
 
910
+
911
+
912
+ return $valid_input;
913
  }
914
 
915
 
947
 
948
  // check for our settings page - need this in conditional further down
949
  $qts_settings_pg = isset($_GET['page']) ? strpos($_GET['page'], QTS_PAGE_BASENAME) : '';
950
+ // collect setting errors/notices:
951
+ // http://codex.wordpress.org/Function_Reference/get_settings_errors
952
  $set_errors = get_settings_errors();
953
 
954
+ // display admin message only for the admin to see, only on our settings page
955
+ // and only when setting errors/notices are returned!
956
  if(current_user_can ('manage_options') && $qts_settings_pg !== false && !empty($set_errors)){
957
 
958
  // have our settings succesfully been updated?
qtranslate-slug.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: qTranslate slug
4
  Plugin URI: http://not-only-code.github.com/qtranslate-slug/
5
  Description: Allows to define a slug for each language and some qTranslate bug fixes
6
- Version: 1.1.6
7
  Author: Carlos Sanz Garcia
8
  Author URI: http://github.com/not-only-code
9
  */
@@ -203,9 +203,9 @@ class QtranslateSlug {
203
  * @since 1.0
204
  */
205
  public function set_options() {
206
- if (empty($this->options))
207
  $this->options = get_option(QTS_OPTIONS_NAME);
208
-
209
  if (!$this->options)
210
  add_option(QTS_OPTIONS_NAME, array());
211
 
@@ -310,20 +310,56 @@ class QtranslateSlug {
310
  // checks version and do the installation
311
  if ( !$qts_version || $qts_version != QTS_VERSION ) {
312
 
313
- // install termmeta table using functions from Simple-Term-Meta ( http://wordpress.org/extend/plugins/simple-term-meta/ )
 
314
  install_term_meta_table();
315
 
316
  // update installed option
317
  update_option('qts_version', QTS_VERSION);
318
  }
319
-
320
- // regenerate rewrite rules in db
321
  add_action( 'generate_rewrite_rules', array(&$this, 'modify_rewrite_rules') );
322
  flush_rewrite_rules();
323
  }
 
324
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
 
326
-
327
  /**
328
  * actions when deactivating the plugin
329
  *
@@ -337,8 +373,8 @@ class QtranslateSlug {
337
  $wp_rewrite->flush_rules();
338
  }
339
 
340
-
341
-
342
  /**
343
  * admin notice: update your old data
344
  *
@@ -350,8 +386,8 @@ class QtranslateSlug {
350
  if ($current_screen->id != 'settings_page_qtranslate-slug-settings'):
351
 
352
  echo "<div class=\"updated\">" . PHP_EOL;
353
- echo "<p><strong>Qtranslate Slug:</strong></p>" . PHP_EOL;
354
- printf("<p>%s <a href=\"%s\" class=\"button\">%s</a></p>", __('Please update your old data to the new system.', 'qts'), add_query_arg(array('page' => 'qtranslate-slug-settings'), 'options-general.php'), __('upgrade now', 'qts')) . PHP_EOL;
355
  echo "</div>" . PHP_EOL;
356
 
357
  endif;
@@ -419,7 +455,7 @@ class QtranslateSlug {
419
  * @since 1.0
420
  */
421
  function init() {
422
-
423
  load_plugin_textdomain( 'qts', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
424
 
425
  // checking plugin activate
@@ -428,7 +464,7 @@ class QtranslateSlug {
428
  add_action('admin_notices', array(&$this, 'notice_dependences'));
429
  return;
430
  }
431
-
432
  // caching qts options
433
  $this->set_options();
434
 
@@ -461,6 +497,14 @@ class QtranslateSlug {
461
  } else {
462
 
463
  add_filter( 'request', array(&$this, 'filter_request') );
 
 
 
 
 
 
 
 
464
  }
465
 
466
  add_filter( 'query_vars', array(&$this, 'query_vars'));
@@ -489,17 +533,20 @@ class QtranslateSlug {
489
 
490
 
491
  /**
492
- * Add a class based on the current language
493
- * @param array $classes list of classes
494
- */
495
  public function qts_body_class( $classes ) {
496
- // add 'class-name' to the $classes array
497
- $classes[] = qtrans_getLanguage();
498
- // return the $classes array
499
- return $classes;
 
500
  }
 
501
  /**
502
- * Adds news rules to translate the URL bases, this function must be called on flush_rewrite or 'flush_rewrite_rules'
 
503
  *
504
  * @param object $wp_rewrite
505
  *
@@ -631,7 +678,7 @@ class QtranslateSlug {
631
  if ( empty($this->permalink_structure) || $q_config['url_mode'] == 1 )
632
  $base_args['lang'] = $this->get_lang();
633
 
634
- // rebulid query with all args
635
  $url = add_query_arg($base_args, $url);
636
 
637
  $url = str_replace('/?', '?', $url); // TODO: hack: improve this code
@@ -691,7 +738,7 @@ class QtranslateSlug {
691
  $req_uri = preg_replace("|^$home_path|", '', $req_uri);
692
  $req_uri = trim($req_uri, '/');
693
  if ($GLOBALS['q_config']['url_mode'] == QT_URL_PATH)
694
- $req_uri = preg_replace("/^{$GLOBALS['q_config']['language']}(\/|$)/", '', $req_uri);
695
  $pathinfo = trim($pathinfo, '/');
696
  $pathinfo = preg_replace("|^$home_path|", '', $pathinfo);
697
  $pathinfo = trim($pathinfo, '/');
@@ -704,7 +751,8 @@ class QtranslateSlug {
704
  if ( ! empty($pathinfo) && !preg_match('|^.*' . $wp_rewrite->index . '$|', $pathinfo) ) {
705
  $request = $pathinfo;
706
  } else {
707
- // If the request uri is the index, blank it out so that we don't try to match it against a rule.
 
708
  if ( $req_uri == $wp_rewrite->index )
709
  $req_uri = '';
710
  $request = $req_uri;
@@ -1547,7 +1595,7 @@ class QtranslateSlug {
1547
 
1548
  // Although in post edit page the tags in 'most
1549
  // used' list are translated, but when saving the
1550
- // post Wordpess considers the translated tags as
1551
  // new tags. Due to this issue I skip this 'hack'
1552
  // for tags in post edit page.
1553
  if ( $pagenow != 'admin-ajax.php' ) {
@@ -1586,7 +1634,7 @@ class QtranslateSlug {
1586
  global $pagenow;
1587
 
1588
  // Although in post edit page the tags are translated,
1589
- // but when saving/updating the post Wordpess considers
1590
  // the translated tags as new tags. Due to this
1591
  // issue I limit this 'hack' to the post manage
1592
  // page only.
@@ -1838,7 +1886,7 @@ class QtranslateSlug {
1838
 
1839
 
1840
  if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) // check autosave
1841
- || (!isset($_POST['post_ID']) || $post_id != $_POST['post_ID']) // check revision
1842
  || (!wp_verify_nonce( $_POST['qts_nonce'], 'qts_nonce')) // verify nonce
1843
  || (!current_user_can($post_type_object->cap->edit_post, $post_id))) { // check permission
1844
  return $post_id;
@@ -1880,7 +1928,7 @@ class QtranslateSlug {
1880
  $value = ( $slug ) ? htmlspecialchars( $slug , ENT_QUOTES ) : '';
1881
 
1882
  echo "<tr class=\"form-field form-required\">" . PHP_EOL;
1883
- echo "<th scope=\"row\" valig=\"top\"><label for=\"qts_{$lang}_slug\">Slug (".__($q_config['language_name'][$lang], 'qtranslate').")</label></th>" . PHP_EOL;
1884
  echo "<td><input type=\"text\" name=\"qts_{$lang}_slug\" value=\"$value\" /></td></tr>" . PHP_EOL;
1885
 
1886
  endforeach;
@@ -1901,7 +1949,7 @@ class QtranslateSlug {
1901
 
1902
 
1903
  echo "<label for=\"qts_{$lang}_slug\">Slug (".__($q_config['language_name'][$lang], 'qtranslate').")</label>" . PHP_EOL;
1904
- echo "<input type=\"text\" name=\"qts_{$lang}_slug\" value=\"$value\" aria-required=\"true\">" . PHP_EOL;
1905
 
1906
  echo '</div>';
1907
 
@@ -1923,6 +1971,8 @@ class QtranslateSlug {
1923
  * @since 1.0
1924
  */
1925
  public function validate_term_slug( $slug, $term, $lang ) {
 
 
1926
  global $q_config;
1927
 
1928
  $lang_name = $q_config['term_name'][$term->name][$lang];
@@ -1932,7 +1982,7 @@ class QtranslateSlug {
1932
  $post_name = isset($_POST['name']) ? $_POST['name'] : '';
1933
 
1934
  $term_name = isset($_POST[$ajax_name]) ? trim($_POST[$ajax_name]) : $post_name;
1935
-
1936
  if (empty($term_name)) return $slug;
1937
 
1938
  $name = ( $lang_name == '' || strlen($lang_name) == 0 ) ? $term_name : $lang_name;
@@ -1957,40 +2007,40 @@ class QtranslateSlug {
1957
  * @since 1.0
1958
  */
1959
  public function unique_term_slug($slug, $term, $lang) {
 
1960
  global $wpdb;
1961
-
1962
- $meta_key_name = $this->get_meta_key($lang);
1963
- $query = $wpdb->prepare("SELECT term_id FROM $wpdb->termmeta WHERE meta_key = '%s' AND meta_value = '%s' AND term_id != %d ",
1964
- $meta_key_name,
1965
- $slug,
1966
- $term->term_id);
1967
- $exists_slug = $wpdb->get_results($query);
1968
-
1969
- if ( empty($exists_slug) )
1970
- return $slug;
1971
-
1972
- // If we didn't get a unique slug, try appending a number to make it unique.
1973
- $query = $wpdb->prepare(
1974
- "SELECT meta_value FROM $wpdb->termmeta WHERE meta_key = '%s' AND meta_value = '%s' AND term_id != %d",
1975
- $meta_key_name,
1976
- $slug,
1977
- $term->term_id);
1978
-
1979
- if ( $wpdb->get_var( $query ) ) {
1980
- $num = 2;
1981
- do {
1982
- $alt_slug = $slug . "-$num";
1983
- $num++;
1984
- $slug_check = $wpdb->get_var(
1985
- $wpdb->prepare(
1986
- "SELECT meta_value FROM $wpdb->termmeta WHERE meta_key = '%s' AND meta_value = '%s'",
1987
- $meta_key_name,
1988
- $alt_slug) );
1989
- } while ( $slug_check );
1990
- $slug = $alt_slug;
1991
- }
1992
-
1993
  return $slug;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1994
  }
1995
 
1996
 
@@ -2008,7 +2058,7 @@ class QtranslateSlug {
2008
  global $q_config;
2009
 
2010
  if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) // check autosave
2011
- || ( !current_user_can('edit_posts') ) ) { // check permission
2012
  return $term_id;
2013
  }
2014
 
@@ -2017,7 +2067,19 @@ class QtranslateSlug {
2017
  foreach( $q_config['enabled_languages'] as $lang ):
2018
 
2019
  $meta_name = $this->get_meta_key($lang);
2020
- $meta_value = apply_filters( 'qts_validate_term_slug', $_POST["qts_{$lang}_slug"], $term, $lang);
 
 
 
 
 
 
 
 
 
 
 
 
2021
 
2022
  delete_term_meta($term_id, $meta_name);
2023
  update_term_meta($term_id, $meta_name, $meta_value);
@@ -2205,7 +2267,7 @@ class QtranslateSlug {
2205
  case 'text':
2206
  case 'both':
2207
 
2208
- echo "<ul id=\"{$args['id']}\" class=\"{$args['class']}\">". PHP_EOL;
2209
 
2210
  foreach( $languages as $index => $lang ):
2211
 
@@ -2215,7 +2277,8 @@ class QtranslateSlug {
2215
  if ( (string)$q_config['language'] == (string)$lang ) $item_class[] = 'current-menu-item';
2216
  if ( $index == (count($languages) - 1) ) $item_class[] = 'last-child';
2217
 
2218
- $item_class = empty($item_class) ? '' : ' class="' . implode(' ', $item_class) . '"';
 
2219
 
2220
  $language_name = ($args['short']) ? $lang : $q_config['language_name'][$lang];
2221
 
@@ -2223,7 +2286,7 @@ class QtranslateSlug {
2223
  $link_class = " class=\"qtrans_flag qtrans_flag_$lang\"";
2224
  $link_content = "<span style=\"display:none\">$language_name</span>";
2225
  } else if ( $type == 'both' ) {
2226
- $link_class = " class=\"qtrans_flag qtrans_flag_$lang\" style=\"padding-left:25px\"";
2227
  $link_content = "$language_name";
2228
 
2229
  } else {
@@ -2272,11 +2335,11 @@ class QtranslateSlug {
2272
  *
2273
  * @since 1.0
2274
  */
2275
- if (!defined("QTS_VERSION")) define("QTS_VERSION", '1.0');
2276
- if (!defined("QTS_PREFIX")) define("QTS_PREFIX", '_qts_');
2277
  if (!defined("QTS_PAGE_BASENAME")) define('QTS_PAGE_BASENAME', 'qtranslate-slug-settings');
2278
  if (!defined("QTS_OPTIONS_NAME")) define("QTS_OPTIONS_NAME", 'qts_options');
2279
- if (!defined("PHP_EOL")) define("PHP_EOL", "\r\n");
2280
 
2281
  ////////////////////////////////////////////////////////////////////////////////////////
2282
 
@@ -2376,7 +2439,7 @@ add_filter( 'plugin_action_links', 'qts_add_settings_link', 10, 2 );
2376
 
2377
 
2378
  /**
2379
- * Delete plugin stored data ( options, termmeta table and postmeta data ) ################################################ test this function
2380
  *
2381
  * @package Qtranslate Slug
2382
  * @subpackage Settings
3
  Plugin Name: qTranslate slug
4
  Plugin URI: http://not-only-code.github.com/qtranslate-slug/
5
  Description: Allows to define a slug for each language and some qTranslate bug fixes
6
+ Version: 1.1.7
7
  Author: Carlos Sanz Garcia
8
  Author URI: http://github.com/not-only-code
9
  */
203
  * @since 1.0
204
  */
205
  public function set_options() {
206
+ if (empty($this->options)) {
207
  $this->options = get_option(QTS_OPTIONS_NAME);
208
+ }
209
  if (!$this->options)
210
  add_option(QTS_OPTIONS_NAME, array());
211
 
310
  // checks version and do the installation
311
  if ( !$qts_version || $qts_version != QTS_VERSION ) {
312
 
313
+ // install termmeta table using functions from Simple-Term-Meta
314
+ // ( http://wordpress.org/extend/plugins/simple-term-meta/ )
315
  install_term_meta_table();
316
 
317
  // update installed option
318
  update_option('qts_version', QTS_VERSION);
319
  }
320
+
321
+ // regenerate rewrite rules in db
322
  add_action( 'generate_rewrite_rules', array(&$this, 'modify_rewrite_rules') );
323
  flush_rewrite_rules();
324
  }
325
+
326
 
327
+
328
+ /**
329
+ * register front end styles and enqueue
330
+ *
331
+ * @since 1.1.7
332
+ */
333
+ public function register_plugin_styles() {
334
+ wp_register_style( 'qts_front_styles', plugins_url( '/assets/css/qts-default.css', __FILE__ ) );
335
+ wp_enqueue_style( 'qts_front_styles' );
336
+ }
337
+
338
+
339
+
340
+ /**
341
+ * print front end styles
342
+ *
343
+ * @since 1.1.7
344
+ */
345
+ public function print_plugin_styles() {
346
+
347
+ $css_path = dirname(__FILE__).'/assets/css/qts-default.css';
348
+
349
+ if (!file_exists($css_path) || !is_readable($css_path)) {
350
+ return;
351
+ }
352
+
353
+ $default_css_file = file_get_contents($css_path, FILE_USE_INCLUDE_PATH);
354
+
355
+ $css = "<style media=\"screen\">\n";
356
+ $css .= "$default_css_file\n";
357
+ $css .="</style>\n";
358
+ echo $css;
359
+ }
360
+
361
 
362
+
363
  /**
364
  * actions when deactivating the plugin
365
  *
373
  $wp_rewrite->flush_rules();
374
  }
375
 
376
+
377
+
378
  /**
379
  * admin notice: update your old data
380
  *
386
  if ($current_screen->id != 'settings_page_qtranslate-slug-settings'):
387
 
388
  echo "<div class=\"updated\">" . PHP_EOL;
389
+ echo "<p><strong>Qtranslate Slug:</strong></p>" . PHP_EOL;
390
+ printf("<p>%s <a href=\"%s\" class=\"button\">%s</a></p>", __('Please update your old data to the new system.', 'qts'), add_query_arg(array('page' => 'qtranslate-slug-settings'), 'options-general.php'), __('upgrade now', 'qts')) . PHP_EOL;
391
  echo "</div>" . PHP_EOL;
392
 
393
  endif;
455
  * @since 1.0
456
  */
457
  function init() {
458
+
459
  load_plugin_textdomain( 'qts', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
460
 
461
  // checking plugin activate
464
  add_action('admin_notices', array(&$this, 'notice_dependences'));
465
  return;
466
  }
467
+
468
  // caching qts options
469
  $this->set_options();
470
 
497
  } else {
498
 
499
  add_filter( 'request', array(&$this, 'filter_request') );
500
+
501
+ // adds external style file
502
+ $qts_options = $this->get_options();
503
+ if ( !isset($qts_options[QTS_PREFIX.'styles']) || $qts_options[QTS_PREFIX.'styles'] == "file" ) {
504
+ add_action( 'wp_enqueue_scripts', array( &$this, 'register_plugin_styles' ) );
505
+ } elseif ($qts_options[QTS_PREFIX.'styles'] == "inline" ) {
506
+ add_action( 'wp_print_styles', array( &$this, 'print_plugin_styles' ), 20 );
507
+ }
508
  }
509
 
510
  add_filter( 'query_vars', array(&$this, 'query_vars'));
533
 
534
 
535
  /**
536
+ * Add a class based on the current language
537
+ * @param array $classes list of classes
538
+ */
539
  public function qts_body_class( $classes ) {
540
+ // add 'class-name' to the $classes array
541
+ $classes[] = qtrans_getLanguage();
542
+
543
+ // return the $classes array
544
+ return $classes;
545
  }
546
+
547
  /**
548
+ * Adds news rules to translate the URL bases,
549
+ * this function must be called on flush_rewrite or 'flush_rewrite_rules'
550
  *
551
  * @param object $wp_rewrite
552
  *
678
  if ( empty($this->permalink_structure) || $q_config['url_mode'] == 1 )
679
  $base_args['lang'] = $this->get_lang();
680
 
681
+ // rebuild query with all args
682
  $url = add_query_arg($base_args, $url);
683
 
684
  $url = str_replace('/?', '?', $url); // TODO: hack: improve this code
738
  $req_uri = preg_replace("|^$home_path|", '', $req_uri);
739
  $req_uri = trim($req_uri, '/');
740
  if ($GLOBALS['q_config']['url_mode'] == QT_URL_PATH)
741
+ $req_uri = preg_replace("/^{$GLOBALS['q_config']['language']}(\/|$)/", '', $req_uri);
742
  $pathinfo = trim($pathinfo, '/');
743
  $pathinfo = preg_replace("|^$home_path|", '', $pathinfo);
744
  $pathinfo = trim($pathinfo, '/');
751
  if ( ! empty($pathinfo) && !preg_match('|^.*' . $wp_rewrite->index . '$|', $pathinfo) ) {
752
  $request = $pathinfo;
753
  } else {
754
+ // If the request uri is the index, blank it out so that
755
+ // we don't try to match it against a rule.
756
  if ( $req_uri == $wp_rewrite->index )
757
  $req_uri = '';
758
  $request = $req_uri;
1595
 
1596
  // Although in post edit page the tags in 'most
1597
  // used' list are translated, but when saving the
1598
+ // post Wordpress considers the translated tags as
1599
  // new tags. Due to this issue I skip this 'hack'
1600
  // for tags in post edit page.
1601
  if ( $pagenow != 'admin-ajax.php' ) {
1634
  global $pagenow;
1635
 
1636
  // Although in post edit page the tags are translated,
1637
+ // but when saving/updating the post Wordpress considers
1638
  // the translated tags as new tags. Due to this
1639
  // issue I limit this 'hack' to the post manage
1640
  // page only.
1886
 
1887
 
1888
  if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) // check autosave
1889
+ || (!isset($_POST['post_ID']) || $post_id != $_POST['post_ID']) // check revision
1890
  || (!wp_verify_nonce( $_POST['qts_nonce'], 'qts_nonce')) // verify nonce
1891
  || (!current_user_can($post_type_object->cap->edit_post, $post_id))) { // check permission
1892
  return $post_id;
1928
  $value = ( $slug ) ? htmlspecialchars( $slug , ENT_QUOTES ) : '';
1929
 
1930
  echo "<tr class=\"form-field form-required\">" . PHP_EOL;
1931
+ echo "<th scope=\"row\" valig=\"top\"><label for=\"qts_term_{$lang}_slug\">Slug (".__($q_config['language_name'][$lang], 'qtranslate').")</label></th>" . PHP_EOL;
1932
  echo "<td><input type=\"text\" name=\"qts_{$lang}_slug\" value=\"$value\" /></td></tr>" . PHP_EOL;
1933
 
1934
  endforeach;
1949
 
1950
 
1951
  echo "<label for=\"qts_{$lang}_slug\">Slug (".__($q_config['language_name'][$lang], 'qtranslate').")</label>" . PHP_EOL;
1952
+ echo "<input type=\"text\" name=\"qts_term_{$lang}_slug\" value=\"$value\" aria-required=\"true\">" . PHP_EOL;
1953
 
1954
  echo '</div>';
1955
 
1971
  * @since 1.0
1972
  */
1973
  public function validate_term_slug( $slug, $term, $lang ) {
1974
+
1975
+
1976
  global $q_config;
1977
 
1978
  $lang_name = $q_config['term_name'][$term->name][$lang];
1982
  $post_name = isset($_POST['name']) ? $_POST['name'] : '';
1983
 
1984
  $term_name = isset($_POST[$ajax_name]) ? trim($_POST[$ajax_name]) : $post_name;
1985
+
1986
  if (empty($term_name)) return $slug;
1987
 
1988
  $name = ( $lang_name == '' || strlen($lang_name) == 0 ) ? $term_name : $lang_name;
2007
  * @since 1.0
2008
  */
2009
  public function unique_term_slug($slug, $term, $lang) {
2010
+
2011
  global $wpdb;
2012
+ $meta_key_name = $this->get_meta_key($lang);
2013
+ $query = $wpdb->prepare("SELECT term_id FROM $wpdb->termmeta WHERE meta_key = '%s' AND meta_value = '%s' AND term_id != %d ",
2014
+ $meta_key_name,
2015
+ $slug,
2016
+ $term->term_id);
2017
+ $exists_slug = $wpdb->get_results($query);
2018
+
2019
+ if ( empty($exists_slug) )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2020
  return $slug;
2021
+
2022
+ // If we didn't get a unique slug, try appending a number to make it unique.
2023
+ $query = $wpdb->prepare(
2024
+ "SELECT meta_value FROM $wpdb->termmeta WHERE meta_key = '%s' AND meta_value = '%s' AND term_id != %d",
2025
+ $meta_key_name,
2026
+ $slug,
2027
+ $term->term_id);
2028
+
2029
+ if ( $wpdb->get_var( $query ) ) {
2030
+ $num = 2;
2031
+ do {
2032
+ $alt_slug = $slug . "-$num";
2033
+ $num++;
2034
+ $slug_check = $wpdb->get_var(
2035
+ $wpdb->prepare(
2036
+ "SELECT meta_value FROM $wpdb->termmeta WHERE meta_key = '%s' AND meta_value = '%s'",
2037
+ $meta_key_name,
2038
+ $alt_slug) );
2039
+ } while ( $slug_check );
2040
+ $slug = $alt_slug;
2041
+ }
2042
+
2043
+ return $slug;
2044
  }
2045
 
2046
 
2058
  global $q_config;
2059
 
2060
  if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) // check autosave
2061
+ || ( !current_user_can('edit_posts') ) ) { // check permission
2062
  return $term_id;
2063
  }
2064
 
2067
  foreach( $q_config['enabled_languages'] as $lang ):
2068
 
2069
  $meta_name = $this->get_meta_key($lang);
2070
+
2071
+
2072
+ //LC43: when at the post edit screen and creating a new tag
2073
+ // the $slug comes from $_POST with the value of the post slug,
2074
+ // not with the term slug.
2075
+ if( $_POST['action'] == "editpost"){
2076
+ // so we use the slug wp gave it
2077
+ $term_slug = $term->slug;
2078
+ } else {
2079
+ // otherwise, its the edit term screen
2080
+ $term_slug = $_POST["qts_term_{$lang}_slug"];
2081
+ }
2082
+ $meta_value = apply_filters( 'qts_validate_term_slug', $term_slug, $term, $lang);
2083
 
2084
  delete_term_meta($term_id, $meta_name);
2085
  update_term_meta($term_id, $meta_name, $meta_value);
2267
  case 'text':
2268
  case 'both':
2269
 
2270
+ echo "<ul id=\"{$args['id']}\" class=\"qts_type_{$type} {$args['class']}\">". PHP_EOL;
2271
 
2272
  foreach( $languages as $index => $lang ):
2273
 
2277
  if ( (string)$q_config['language'] == (string)$lang ) $item_class[] = 'current-menu-item';
2278
  if ( $index == (count($languages) - 1) ) $item_class[] = 'last-child';
2279
 
2280
+
2281
+ $item_class = ' class="qts_lang_item ' . implode(' ', $item_class) . '"';
2282
 
2283
  $language_name = ($args['short']) ? $lang : $q_config['language_name'][$lang];
2284
 
2286
  $link_class = " class=\"qtrans_flag qtrans_flag_$lang\"";
2287
  $link_content = "<span style=\"display:none\">$language_name</span>";
2288
  } else if ( $type == 'both' ) {
2289
+ $link_class = " class=\"qts_both qtrans_flag qtrans_flag_$lang\"";
2290
  $link_content = "$language_name";
2291
 
2292
  } else {
2335
  *
2336
  * @since 1.0
2337
  */
2338
+ if (!defined("QTS_VERSION")) define("QTS_VERSION", '1.1.7');
2339
+ if (!defined("QTS_PREFIX")) define("QTS_PREFIX", '_qts_');
2340
  if (!defined("QTS_PAGE_BASENAME")) define('QTS_PAGE_BASENAME', 'qtranslate-slug-settings');
2341
  if (!defined("QTS_OPTIONS_NAME")) define("QTS_OPTIONS_NAME", 'qts_options');
2342
+ if (!defined("PHP_EOL")) define("PHP_EOL", "\r\n");
2343
 
2344
  ////////////////////////////////////////////////////////////////////////////////////////
2345
 
2439
 
2440
 
2441
  /**
2442
+ * Delete plugin stored data ( options, termmeta table and postmeta data ) ################################################ TODO: test this function
2443
  *
2444
  * @package Qtranslate Slug
2445
  * @subpackage Settings
readme.txt ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Qtranslate Slug ===
2
+ Contributors: Carlos Sanz García
3
+ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=SYC46KSLRC4Q8
4
+ Tags: qtranslate, slug, multilanguage
5
+ Requires at least: 3.3
6
+ Tested up to: 3.9.1
7
+ Version: 1.1.7
8
+ License: GPLv2 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ Adds support for permalink translations and fix some QTranslate deficiencies since wordpress 3.0
12
+
13
+ == Description ==
14
+
15
+ [Qtranslate](http://wordpress.org/extend/plugins/qtranslate/) is a nice plugin but unfortunately today is **outdated**. **Qtranslate Slug** is an addon to QTranslate, which adds support for permalinks translations and fix some QTranslate deficiencies since wordpress 3.0.
16
+
17
+ **Version 1.0** has been written from scratch using OOP. The code has been structured better, the functions have been marked and commented and everything is better integrated with Wordpress API.
18
+
19
+ = Requirements: =
20
+
21
+ * Wordpress 3.3 (PHP 5.2 and MySQL 5)
22
+ * mQtranslate 2.6.2.4 or Qtranslate 2.5.8
23
+
24
+ = New in version 1.1.7 =
25
+ * removed styles from html elements and added options to use .css file or print inline styles
26
+ * fixed tag creation on post edit.
27
+ * fixed earlier bad post slug introduced in 1.1.6
28
+
29
+ **Advice: If you're using a multisite installation, you will must activate qtranslate plugins by separately on each site.**
30
+
31
+
32
+ You can also check the [project website](http://not-only-code.github.com/qtranslate-slug/) hosted on [GitHub](http://not-only-code.github.com).
33
+ Thanks for use this plugin!
34
+
35
+ == Installation ==
36
+ **This plugins requires [Qtranslate](http://wordpress.org/extend/plugins/qtranslate/) or [mqTranslate](https://wordpress.org/plugins/mqtranslate/) installed previously, if not, it will not activate.**
37
+
38
+ 1. Upload `qtranslate-slug` to the `/wp-content/plugins/` directory.
39
+ 1. Activate the plugin through the 'Plugins' menu in WordPress.
40
+ 1. That's all!
41
+
42
+ = Changing base permastructs =
43
+
44
+ 1. In admin: navigate to *Settings/Slug options*.
45
+ 1. Set the base permastructs for **post types** and **taxonomies** (If you setup a base permastruct for *categories* or *tags* in *Settings/Permalinks*, these will be overwritten by the translated ones).
46
+ 1. Save settings and that's all!
47
+
48
+ == Frequently Asked Questions ==
49
+
50
+ = It works with posts and pages, but with other content type? =
51
+
52
+ This plugin allows to translate slugs of: posts, pages, custom post types, categories, tags and custom taxonomies.
53
+
54
+ = Do I have to configure anything? =
55
+
56
+ If you want to translate also the base permastructs (ex. *category*, *tag*, etc). Visit the plugin settings page in the admin *Settings/Slug options*
57
+
58
+ = How can i insert a language selector in my theme ? =
59
+
60
+ You can choose to:
61
+ * use **Qtranslate Slug Widget** in your sidebar.
62
+ * place in your template `<?php if (function_exists('qts_language_menu') ) qts_language_menu('text'); ?>`. Options are: `dropdown`, `text`, `image`, and `both`.
63
+
64
+ = Appears an error 404, what can i do? =
65
+
66
+ In the admin go to *Settings/Permalinks* or *Settings/Slug options* and save.
67
+
68
+ = I can't manage translations in Nav Menus. =
69
+
70
+ That's because language selector metabox is hidden, if you are in admin *nav menus* screen, press the button **Screen options** (on top and right) and after, check the option *Languages*. It will appear a **Language** meta box on top of the left sidebar.
71
+
72
+ == Screenshots ==
73
+
74
+ 1. Edit page for: post / page / post_type, you can see the meta box for translated slugs on top and right.
75
+ 2. Add new taxonomy page
76
+ 3. Edit taxonomy page
77
+ 4. Qtranslate Slug options page for translate base permastructs of post_types and taxonomies.
78
+
79
+ == Changelog ==
80
+ = 1.1.7 =
81
+ * removed styles from html elements and added options to use .css file or print inline styles
82
+ * fixed tag creation on post edit.
83
+ * fixed earlier bad post slug introduced in 1.1.6
84
+
85
+ = 1.1.6 =
86
+ * compatible with mqtranslate
87
+ * php5.4+ compatible
88
+
89
+ = 1.1.5 =
90
+ * bugfixes
91
+
92
+ = 1.1 =
93
+ * added multisite support
94
+ * fixed some parse url bugs
95
+ * fixed slug bases validation
96
+
97
+ = 1.0 =
98
+ * **works** with any permalink combination and qtranslate mode.
99
+ * new branch, the plugin has been rewritten: now the code is commented and wrapped inside a class, much code has change and the performance has been increased (use caches).
100
+ * data system changed, no ID for slug type, then it don't needs install `qtrasnlate_slug` table. That means slugs now are stored on meta tables and installation creates a termmeta table with some new *core functions* to access/save data, based on [simple term meta](http://wordpress.org/extend/plugins/simple-term-meta/). Upgrade process when the plugin updates from older versions.
101
+ * the plugin generates translated slug automatically from title in empty cases.
102
+ * the plugin checks if the slug already exists (per each language and `post_type`/`taxonomy`), and adds a progressive number in this case. Works on ajax requests for example when new taxonomies are created in edit post page.
103
+ * possibility to translate the base of permastructs for *post_types* and *taxonomies*, uses [$wp_rewrite](http://codex.wordpress.org/Class_Reference/WP_Rewrite). New admin options page for save the base permastructs.
104
+ * added some filters, see in [other notes](http://wordpress.org/extend/plugins/qtranslate-slug/other_notes/).
105
+ * added plugin language textdomain (.pot file).
106
+ * updated **Language selector Widget**, and some new conventions like accessible functions for templating.
107
+ * some bug fixes.
108
+ * some Qtranslate patches.
109
+
110
+ = 0.9 =
111
+ * some wordpress qTranslate bug fixes
112
+ * adds a javascript solution for qTranslate Nav Menus
113
+
114
+ = 0.8 =
115
+ * added support por Categories
116
+ * added support por Tags
117
+ * added support por Taxonomies
118
+ * added support por Custom Post Types
119
+
120
+ = 0.7 = [Zapo](http://www.qianqin.de/qtranslate/forum/viewtopic.php?f=4&t=1049&start=50#p7499)
121
+ * added suport for qTranslate TLD domain mode (en: domain.com | fr: domain.fr) visit
122
+
123
+ = 0.5 and 0.6 enhanched by Marco Del Percio =
124
+
125
+ == Upgrade Notice ==
126
+
127
+ = 1.0 =
128
+ Major version, the plugin has been rewritten. Better performance, and some enhancements.
129
+
130
+ = 0.9 =
131
+ This version fix some bugs and allow multilanguage in nav-menus.
132
+
133
+ = 0.8 =
134
+ A lot of slugs content allowed
135
+
136
+ = 0.7 =
137
+ This version allows TLD domain option for a different Qtranslate fork maded by Zappo
138
+
139
+
140
+ == Other notes ==
141
+
142
+ Plugin filters reference:
143
+
144
+ = qts_validate_post_slug =
145
+ filter to process the post slug before is saved on the database.
146
+ `args: $post (object), $slug (string), $lang (string)`
147
+
148
+ = qts_validate_term_slug =
149
+ filter to process the term slug before is saved on the database.
150
+ `args: $term (object), $slug (string), $lang (string)`
151
+
152
+ = qts_url_args =
153
+ filter to process the entire url after it has been generated.
154
+ `args: $url (string), $lang (string)`
155
+
156
+ = qts_permastruct =
157
+ filter to process the permastruct, used for change the base.
158
+ `args: $permastruct (string), $name (string)`
159
+
160
+
161
+ = Todo =
162
+
163
+ * detect Slug for each language and redirect accordingly in parse_query.
164
+ * expand qtranslate for translate attachment names and descriptions ( useful for galleries )
165
+ * translate other slugs like attachments.
166
+ * qtranslate integration with other plugins like Jigoshop, e-commerce, etc. Addapt **$wp_rewrite**.
version.txt CHANGED
@@ -1,3 +1,8 @@
 
 
 
 
 
1
  = 1.1.6 =
2
  * compatible with mqtranslate
3
  * php5.4+ compatible
1
+ = 1.1.7 =
2
+ * removed styles from html elements and added options to use .css file or print inline styles
3
+ * fixed tag creation on post edit.
4
+ * fixed earlier bad post slug introduced in 1.1.6
5
+
6
  = 1.1.6 =
7
  * compatible with mqtranslate
8
  * php5.4+ compatible