1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
4
|
|
|
exit; // Exit if accessed directly |
5
|
|
|
} |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Sensei Language Pack manager class |
9
|
|
|
* |
10
|
|
|
* Downloads the language pack available. |
11
|
|
|
* |
12
|
|
|
* @package WordPress |
13
|
|
|
* @subpackage Sensei |
14
|
|
|
* @category Core |
15
|
|
|
* @author WooThemes |
16
|
|
|
* @since 1.9.0 |
17
|
|
|
*/ |
18
|
|
|
class Sensei_Language_Pack_Manager { |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Languages repository |
22
|
|
|
* |
23
|
|
|
* @var string |
24
|
|
|
*/ |
25
|
|
|
protected static $repo = 'https://github.com/woothemes/sensei-language-packs/raw/'; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Initialize the language pack manager |
29
|
|
|
*/ |
30
|
|
|
public function __construct() { |
31
|
|
|
add_action( 'update_option_WPLANG', array( $this, 'updated_language_option' ), 10, 2 ); |
32
|
|
|
add_filter( 'admin_init', array( $this, 'language_package_actions' ), 10 ); |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Get translation package URI. |
37
|
|
|
* |
38
|
|
|
* @param string $locale |
39
|
|
|
* |
40
|
|
|
* @return string |
41
|
|
|
*/ |
42
|
|
|
public static function get_package_uri( $locale ) { |
43
|
|
|
return self::$repo . Sensei()->version . '/packages/' . $locale . '.zip'; |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Get settings URI. |
48
|
|
|
* |
49
|
|
|
* @param string $action |
50
|
|
|
* |
51
|
|
|
* @return string |
52
|
|
|
*/ |
53
|
|
|
protected static function get_settings_uri( $action ) { |
54
|
|
|
return wp_nonce_url( admin_url( 'admin.php?page=woothemes-sensei-settings&action=' . $action ), 'language_pack', '_sensei_language_nonce' ); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Get the install language package URI. |
59
|
|
|
* |
60
|
|
|
* @return string |
61
|
|
|
*/ |
62
|
|
|
public static function get_install_uri() { |
63
|
|
|
return self::get_settings_uri( 'language_pack_install' ); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Get the dismiss language package message URI. |
68
|
|
|
* |
69
|
|
|
* @return string |
70
|
|
|
*/ |
71
|
|
|
public static function get_dismiss_uri() { |
72
|
|
|
return self::get_settings_uri( 'dismiss_language_pack_notice' ); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Triggered when WPLANG is changed |
77
|
|
|
* |
78
|
|
|
* @param string $old |
79
|
|
|
* @param string $new |
80
|
|
|
*/ |
81
|
|
|
public function updated_language_option( $old, $new ) { |
82
|
|
|
self::has_language_pack_available( $new ); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Check if has available language pack install |
87
|
|
|
* |
88
|
|
|
* @param string $locale |
89
|
|
|
* |
90
|
|
|
* @return bool |
91
|
|
|
*/ |
92
|
|
|
public static function has_language_pack_available( $locale = null ) { |
93
|
|
|
|
94
|
|
|
if ( is_null( $locale ) ) { |
95
|
|
|
|
96
|
|
|
$locale = get_locale(); |
97
|
|
|
|
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
if ( 'en_US' === $locale ) { |
101
|
|
|
|
102
|
|
|
return false; |
103
|
|
|
|
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
if ( 'yes' === get_option( 'sensei_needs_language_pack_install' ) ) { |
107
|
|
|
|
108
|
|
|
return true; |
109
|
|
|
|
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
if( isset( $_GET['translation_updated'] ) && 5 == $_GET['translation_updated'] ){ |
113
|
|
|
|
114
|
|
|
return false; |
115
|
|
|
|
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
$version = get_option( 'woothemes_sensei_language_pack_version', array( '0', $locale ) ); |
119
|
|
|
|
120
|
|
|
if ( ! is_array( $version ) || version_compare( $version[0], Sensei()->version, '<' ) || $version[1] !== $locale ) { |
121
|
|
|
if ( self::check_if_language_pack_exists( $locale ) ) { |
122
|
|
|
update_option( 'sensei_needs_language_pack_install', 'yes' ); |
123
|
|
|
|
124
|
|
|
return true; |
125
|
|
|
} else { |
126
|
|
|
// Updated the woothemes_sensei_language_pack_version to avoid searching translations for this release again |
127
|
|
|
self::update_language_pack_version( $locale ); |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
return false; |
132
|
|
|
|
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Check if language pack exists |
137
|
|
|
* |
138
|
|
|
* @return bool |
139
|
|
|
*/ |
140
|
|
|
public static function check_if_language_pack_exists( $locale ) { |
141
|
|
|
$response = wp_safe_remote_get( self::get_package_uri( $locale ), array( 'timeout' => 60 ) ); |
142
|
|
|
|
143
|
|
|
if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 ) { |
144
|
|
|
return true; |
145
|
|
|
} else { |
146
|
|
|
return false; |
147
|
|
|
} |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* Update language pack version. |
152
|
|
|
* |
153
|
|
|
* @param string $locale |
154
|
|
|
*/ |
155
|
|
|
public static function update_language_pack_version( $locale ) { |
156
|
|
|
// Update the language pack version |
157
|
|
|
update_option( 'woothemes_sensei_language_pack_version', array( Sensei()->version, $locale ) ); |
158
|
|
|
|
159
|
|
|
// Remove the translation upgrade notice |
160
|
|
|
update_option( 'sensei_needs_language_pack_install', 'no' ); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Manual language update. |
165
|
|
|
*/ |
166
|
|
|
public function language_package_actions() { |
167
|
|
|
if ( |
168
|
|
|
is_admin() |
169
|
|
|
&& current_user_can( 'update_plugins' ) |
170
|
|
|
&& isset( $_GET['page'] ) |
171
|
|
|
&& 'woothemes-sensei-settings' === $_GET['page'] |
172
|
|
|
&& isset( $_GET['action'] ) |
173
|
|
|
) { |
174
|
|
|
|
175
|
|
|
if ( 'language_pack_install' === $_GET['action'] ) { |
176
|
|
|
$this->language_pack_install(); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
if ( 'dismiss_language_pack_notice' ) { |
180
|
|
|
$this->dismiss_language_pack_notice(); |
181
|
|
|
} |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* Install language pack. |
187
|
|
|
*/ |
188
|
|
|
protected function language_pack_install() { |
189
|
|
|
$url = wp_nonce_url( admin_url( 'admin.php?page=woothemes-sensei-settings&action=language_pack_install' ), 'language_install' ); |
190
|
|
|
$settings_url = admin_url( 'admin.php?page=woothemes-sensei-settings' ); |
191
|
|
|
$locale = get_locale(); |
192
|
|
|
|
193
|
|
|
if ( ! isset( $_REQUEST['_sensei_language_nonce'] ) && wp_verify_nonce( $_REQUEST['_sensei_language_nonce'], 'language_pack' ) ) { |
194
|
|
|
wp_redirect( add_query_arg( array( 'translation_updated' => 2 ), $settings_url ) ); |
195
|
|
|
exit; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
if ( 'en_US' === $locale || ! self::check_if_language_pack_exists( $locale ) ) { |
199
|
|
|
wp_redirect( add_query_arg( array( 'translation_updated' => 3 ), $settings_url ) ); |
200
|
|
|
exit; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
View Code Duplication |
if ( false === ( $creds = request_filesystem_credentials( $url, '', false, false, null ) ) ) { |
|
|
|
|
204
|
|
|
wp_redirect( add_query_arg( array( 'translation_updated' => 4 ), $settings_url ) ); |
205
|
|
|
exit; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
View Code Duplication |
if ( ! WP_Filesystem( $creds ) ) { |
|
|
|
|
209
|
|
|
request_filesystem_credentials( $url, '', true, false, null ); |
210
|
|
|
|
211
|
|
|
wp_redirect( add_query_arg( array( 'translation_updated' => 4 ), $settings_url ) ); |
212
|
|
|
exit; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
// Download the language pack |
216
|
|
|
$response = wp_safe_remote_get( self::get_package_uri( $locale ), array( 'timeout' => 60 ) ); |
217
|
|
|
if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 ) { |
218
|
|
|
global $wp_filesystem; |
219
|
|
|
|
220
|
|
|
$upload_dir = wp_upload_dir(); |
221
|
|
|
$file = trailingslashit( $upload_dir['path'] ) . $locale . '.zip'; |
222
|
|
|
|
223
|
|
|
// Save the zip file |
224
|
|
|
if ( ! $wp_filesystem->put_contents( $file, $response['body'], FS_CHMOD_FILE ) ) { |
225
|
|
|
wp_redirect( add_query_arg( array( 'translation_updated' => 4 ), $settings_url ) ); |
226
|
|
|
exit; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
// Unzip the file to wp-content/languages/plugins directory |
230
|
|
|
$dir = trailingslashit( WP_LANG_DIR ) . 'plugins/'; |
231
|
|
|
$unzip = unzip_file( $file, $dir ); |
232
|
|
|
if ( true !== $unzip ) { |
233
|
|
|
wp_redirect( add_query_arg( array( 'translation_updated' => 4 ), $settings_url ) ); |
234
|
|
|
exit; |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
// Delete the package file |
238
|
|
|
$wp_filesystem->delete( $file ); |
239
|
|
|
|
240
|
|
|
// Update version and remove notice |
241
|
|
|
self::update_language_pack_version( $locale ); |
242
|
|
|
|
243
|
|
|
// Redirect and show a success message |
244
|
|
|
wp_redirect( add_query_arg( array( 'translation_updated' => 1 ), $settings_url ) ); |
245
|
|
|
exit; |
246
|
|
|
} else { |
247
|
|
|
// Don't have a valid package for the current language! |
248
|
|
|
wp_redirect( add_query_arg( array( 'translation_updated' => 5 ), $settings_url ) ); |
249
|
|
|
exit; |
250
|
|
|
} |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
/** |
254
|
|
|
* Hide language pack notice. |
255
|
|
|
*/ |
256
|
|
|
protected function dismiss_language_pack_notice() { |
257
|
|
|
if ( ! isset( $_REQUEST['_sensei_language_nonce'] ) && wp_verify_nonce( $_REQUEST['_sensei_language_nonce'], 'language_pack' ) ) { |
258
|
|
|
wp_die( __( 'Cheatin’ huh?', 'woothemes-sensei' ) ); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
// Update version and remove notice |
262
|
|
|
self::update_language_pack_version( get_locale() ); |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
/** |
266
|
|
|
* Language pack messages |
267
|
|
|
*/ |
268
|
|
|
public static function messages() { |
269
|
|
|
if ( empty( $_GET['translation_updated'] ) ) { |
270
|
|
|
return; |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
switch ( $_GET['translation_updated'] ) { |
274
|
|
View Code Duplication |
case 2 : |
|
|
|
|
275
|
|
|
echo '<div class="error"><p>' . __( 'Failed to install/update the translation:', 'woothemes-sensei' ) . ' ' . __( 'Seems you don\'t have permission to do this!', 'woothemes-sensei' ) . '</p></div>'; |
276
|
|
|
break; |
277
|
|
View Code Duplication |
case 3 : |
|
|
|
|
278
|
|
|
echo '<div class="error"><p>' . __( 'Failed to install/update the translation:', 'woothemes-sensei' ) . ' ' . __( 'There is no translation available for your language!', 'woothemes-sensei' ) . '</p></div>'; |
279
|
|
|
break; |
280
|
|
View Code Duplication |
case 4 : |
|
|
|
|
281
|
|
|
echo '<div class="error"><p>' . __( 'Failed to install/update the translation:', 'woothemes-sensei' ) . ' ' . sprintf( __( 'An authentication error occurred while updating the translation. Please try again or configure your %sUpgrade Constants%s.', 'woothemes-sensei' ), '<a href="http://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants">', '</a>' ) . '</p></div>'; |
282
|
|
|
break; |
283
|
|
View Code Duplication |
case 5 : |
|
|
|
|
284
|
|
|
echo '<div class="error"><p>' . __( 'Failed to install/update the translation:', 'woothemes-sensei' ) . ' ' . __( 'Sorry but there is no translation available for your language =/', 'woothemes-sensei' ) . '</p></div>'; |
285
|
|
|
break; |
286
|
|
|
|
287
|
|
|
default : |
288
|
|
|
echo '<div class="updated"><p>' . __( 'Translations installed/updated successfully!', 'woothemes-sensei' ) . '</p></div>'; |
289
|
|
|
break; |
290
|
|
|
} |
291
|
|
|
} |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
new Sensei_Language_Pack_Manager(); |
295
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.