PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 2.0.25
Advanced Ads – Ad Manager & AdSense v2.0.25
2.0.25 2.0.24 2.0.23 2.0.22 2.0.21 1.38.0 1.39.0 1.39.1 1.39.2 1.39.3 1.39.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.40.0 1.40.1 1.40.2 1.41.0 1.42.0 1.42.1 1.42.2 1.43.0 1.44.0 1.44.1 1.45.0 1.45.1 1.46.0 1.47.0 1.47.1 1.47.2 1.47.3 1.47.4 1.47.5 1.48.0 1.48.1 1.49.0 1.5.0 1.5.0.1 1.5.1 1.5.2 1.5.2.1 1.5.4 1.5.4.1 1.5.5 1.50.0 1.51.0 1.51.1 1.51.2 1.51.3 1.52.0 1.52.1 1.52.2 1.52.3 1.52.4 1.53.0 1.53.1 1.53.2 1.54.0 1.54.1 1.55.0 1.56.0 1.56.1 1.56.2 1.56.3 1.56.4 1.6 1.6.1 1.6.10 1.6.10.1 1.6.10.2 1.6.11 1.6.11.1 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.17.1 1.6.17.2 1.6.2 1.6.2.1 1.6.3 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.6.1 1.6.7 1.6.7.1 1.6.8 1.6.8.1 1.6.8.2 1.6.8.3 1.6.9 1.6.9.1 1.6.9.2 1.6.9.3 1.6.9.4 1.7 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.1.1 1.7.1.2 1.7.1.3 1.7.1.4 1.7.1.5 1.7.10 trunk 1.7.11 1.0.1 1.7.12 1.0.2 1.7.13 1.0.3 1.7.14 1.1.0 1.7.15 1.1.1 1.7.16 1.1.2 1.7.17 1.1.3 1.7.18 1.10 1.7.19 1.10.1 1.7.2 1.10.10 1.7.2.1 1.10.11 1.7.20 1.10.12 1.7.21 1.10.2 1.7.22 1.10.3 1.7.23 1.10.4 1.7.24 1.10.5 1.7.25 1.10.6 1.7.3 1.10.7 1.7.4 1.10.8 1.7.4.1 1.10.9 1.7.4.2 1.11 1.7.4.3 1.11.1 1.7.4.4 1.11.2 1.7.4.5 1.12 1.7.5 1.13 1.7.5.1 1.13.1 1.7.6 1.13.2 1.7.7 1.13.3 1.7.8 1.13.4 1.7.9 1.13.5 1.7.9.1 1.13.6 1.7.9.2 1.13.7 1.7.9.3 1.13.8 1.8 1.14 1.8.1 1.14.1 1.8.10 1.14.10 1.8.11 1.14.11 1.8.12 1.14.2 1.8.13 1.14.3 1.8.14 1.14.4 1.8.15 1.14.5 1.8.16 1.14.6 1.8.17 1.14.7 1.8.18 1.14.8 1.8.19 1.14.9 1.8.2 1.15 1.8.20 1.16 1.8.21 1.16.1 1.8.22 1.17 1.8.23 1.17.1 1.8.24 1.17.10 1.8.25 1.17.10-rc.1 1.8.26 1.17.11 1.8.27 1.17.12 1.8.28 1.17.12-rc.1 1.8.29 1.17.2 1.8.3 1.17.3 1.8.30 1.17.4 1.8.4 1.17.5 1.8.5 1.17.6 1.8.6 1.17.7 1.8.7 1.17.8 1.8.8 1.17.9 1.8.9 1.17.9-beta.1 1.9 1.18.0 2.0.0 1.19.0 2.0.1 1.19.1 2.0.10 1.2 2.0.11 1.2.1 2.0.12 1.2.2 2.0.13 1.2.3 2.0.14 1.2.4 2.0.15 1.2.5 2.0.16 1.2.6 2.0.17 1.2.7 2.0.18 1.20.0 2.0.19 1.20.0-rc.1 2.0.2 1.20.0-rc.2 2.0.20 1.20.1 2.0.3 1.20.2 2.0.4 1.20.3 2.0.5 1.21.0 2.0.6 1.21.1 2.0.7 1.22.0 2.0.8 1.22.1 2.0.9 1.22.2 1.23.0 1.23.1 1.23.2 1.24.0 1.24.1 1.24.2 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.29.0 1.29.1 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.30.0 1.30.1 1.30.2 1.30.2-rc.1 1.30.3 1.30.4 1.30.4-rc.1 1.30.5 1.31.0 1.31.1 1.32.0 1.32.0-rc.1 1.33.0 1.33.1 1.33.2 1.34.0 1.35.0 1.35.1 1.36.0 1.36.1 1.36.2 1.36.3 1.37.0 1.37.1 1.37.2
advanced-ads / includes / admin / class-translation-promo.php
advanced-ads / includes / admin Last commit date
ads 1 week ago groups 1 week ago metaboxes 1 year ago pages 1 day ago placements 1 day ago class-action-links.php 1 week ago class-addon-box.php 1 day ago class-addon-updater.php 1 day ago class-admin-menu.php 1 day ago class-admin-notices.php 1 year ago class-ajax.php 1 day ago class-app.php 1 day ago class-assets.php 1 day ago class-authors.php 1 year ago class-edd-updater.php 1 day ago class-license-admin-post.php 1 day ago class-list-filters.php 1 week ago class-marketing.php 1 year ago class-metabox-ad-settings.php 1 year ago class-metabox-ad.php 1 year ago class-misc.php 1 week ago class-page-quick-edit.php 1 day ago class-plugin-auto-update.php 1 day ago class-plugin-installer.php 1 day ago class-post-list.php 1 year ago class-post-types.php 1 week ago class-screen-options.php 3 months ago class-settings.php 1 day ago class-shortcode-creator.php 1 year ago class-system-info.php 1 year ago class-tinymce.php 2 years ago class-translation-promo.php 1 year ago class-upgrades.php 1 year ago class-version-control.php 3 months ago class-welcome.php 1 year ago class-wordpress-dashboard.php 1 year ago index.php 2 years ago
class-translation-promo.php
457 lines
1 <?php
2 /**
3 * Translation Promo.
4 *
5 * @package AdvancedAds
6 * @author Advanced Ads <info@wpadvancedads.com>
7 * @since 1.45.0
8 */
9
10 namespace AdvancedAds\Admin;
11
12 defined( 'ABSPATH' ) || exit;
13
14 /**
15 * This class defines a promo box and checks your translation site's API for stats about it.
16 *
17 * @copyright Yoast i18n https://github.com/Yoast/i18n-module
18 *
19 * phpcs:disable WordPress.WP.I18n.NonSingularStringLiteralDomain
20 */
21 class Translation_Promo {
22
23 /**
24 * Your translation site's logo.
25 *
26 * @var string
27 */
28 private $glotpress_logo;
29
30 /**
31 * Your translation site's name.
32 *
33 * @var string
34 */
35 private $glotpress_name;
36
37 /**
38 * Your translation site's URL.
39 *
40 * @var string
41 */
42 private $glotpress_url;
43
44 /**
45 * The URL to actually do the API request to.
46 *
47 * @var string
48 */
49 private $api_url;
50
51 /**
52 * Hook where you want to show the promo box.
53 *
54 * @var string
55 */
56 private $hook;
57
58 /**
59 * Will contain the site's locale.
60 *
61 * @access private
62 * @var string
63 */
64 private $locale;
65
66 /**
67 * Will contain the locale's name, obtained from your translation site.
68 *
69 * @access private
70 * @var string
71 */
72 private $locale_name;
73
74 /**
75 * Will contain the percentage translated for the plugin translation project in the locale.
76 *
77 * @access private
78 * @var int
79 */
80 private $percent_translated;
81
82 /**
83 * Name of your plugin.
84 *
85 * @var string
86 */
87 private $plugin_name;
88
89 /**
90 * Project slug for the project on your translation site.
91 *
92 * @var string
93 */
94 private $project_slug;
95
96 /**
97 * URL to point to for registration links.
98 *
99 * @var string
100 */
101 private $register_url;
102
103 /**
104 * Your plugins textdomain.
105 *
106 * @var string
107 */
108 private $textdomain;
109
110 /**
111 * Indicates whether there's a translation available at all.
112 *
113 * @access private
114 * @var bool
115 */
116 private $translation_exists;
117
118 /**
119 * Indicates whether the translation's loaded.
120 *
121 * @access private
122 * @var bool
123 */
124 private $translation_loaded;
125
126 /**
127 * Constructs the i18n module for wordpress.org.
128 *
129 * Required fields are the 'textdomain', 'plugin_name' and 'hook'.
130 *
131 * @param array $args The settings for the i18n module.
132 * @param bool $show_translation_box Whether the translation box should be shown.
133 */
134 public function __construct( $args, $show_translation_box = true ) {
135 if ( ! is_admin() ) {
136 return;
137 }
138
139 $args = $this->set_defaults( $args );
140 $this->locale = $this->get_admin_locale();
141 if ( $this->is_default_language( $this->locale ) ) {
142 return;
143 }
144
145 $this->init( $args );
146
147 if ( $show_translation_box ) {
148 add_action( $this->hook, [ $this, 'promo' ] );
149 }
150
151 $this->set_api_url( $args['textdomain'] );
152 }
153
154 /**
155 * Returns whether the language is en_US.
156 *
157 * @param string $language The language to check.
158 *
159 * @return bool Returns true if the language is en_US.
160 */
161 protected function is_default_language( $language ) {
162 return 'en_US' === $language;
163 }
164
165 /**
166 * Returns the locale used in the admin.
167 *
168 * WordPress 4.7 introduced the ability for users to specify an Admin language
169 * different from the language used on the front end. This checks if the feature
170 * is available and returns the user's language, with a fallback to the site's language.
171 * Can be removed when support for WordPress 4.6 will be dropped, in favor
172 * of WordPress get_user_locale() that already fallbacks to the site’s locale.
173 *
174 * @returns string The locale.
175 */
176 private function get_admin_locale() {
177 if ( function_exists( 'get_user_locale' ) ) {
178 return get_user_locale();
179 }
180
181 return get_locale();
182 }
183
184 /**
185 * This is where you decide where to display the messages and where you set the plugin specific variables.
186 *
187 * @access private
188 *
189 * @param array $args Contains the settings for the class.
190 */
191 private function init( $args ) {
192 foreach ( $args as $key => $arg ) {
193 $this->$key = $arg;
194 }
195 }
196
197 /**
198 * Check whether the promo should be hidden or not.
199 *
200 * @access private
201 *
202 * @return bool
203 */
204 private function hide_promo() {
205 $hide_promo = get_transient( 'yoast_i18n_' . $this->project_slug . '_promo_hide' );
206 if ( ! $hide_promo ) {
207 if ( filter_input( INPUT_GET, 'remove_i18n_promo', FILTER_VALIDATE_INT ) === 1 ) {
208 // No expiration time, so this would normally not expire, but it wouldn't be copied to other sites etc.
209 set_transient( 'yoast_i18n_' . $this->project_slug . '_promo_hide', true );
210 $hide_promo = true;
211 }
212 }
213 return $hide_promo;
214 }
215
216 /**
217 * Returns the i18n_promo message from the i18n_module. Returns en empty string if the promo shouldn't be shown.
218 *
219 * @access public
220 *
221 * @return string The i18n promo message.
222 */
223 public function get_promo_message() {
224 if ( ! $this->is_default_language( $this->locale ) && ! $this->hide_promo() ) {
225 return $this->promo_message();
226 }
227
228 return '';
229 }
230
231 /**
232 * Generates a promo message.
233 *
234 * @access private
235 *
236 * @return bool|string $message
237 */
238 private function promo_message() {
239
240 $this->translation_details();
241
242 $message = false;
243
244 if ( $this->translation_exists && $this->translation_loaded && $this->percent_translated < 90 ) {
245 /* translators: 1: language name; 3: completion percentage; 4: link to translation platform. */
246 $message = __( 'As you can see, there is a translation of this plugin in %1$s. This translation is currently %3$d%% complete. We need your help to make it complete and to fix any errors. Please register at %4$s to help complete the translation to %1$s!', $this->textdomain );
247 } elseif ( ! $this->translation_loaded && $this->translation_exists ) {
248 /* translators: 1: language name; 2: plugin name; 3: completion percentage; 4: link to translation platform. */
249 $message = __( 'You\'re using WordPress in %1$s. While %2$s has been translated to %1$s for %3$d%%, it\'s not been shipped with the plugin yet. You can help! Register at %4$s to help complete the translation to %1$s!', $this->textdomain );
250 } elseif ( ! $this->translation_exists ) {
251 /* translators: 2: plugin name; 4: link to translation platform. */
252 $message = __( 'You\'re using WordPress in a language we don\'t support yet. We\'d love for %2$s to be translated in that language too, but unfortunately, it isn\'t right now. You can change that! Register at %4$s to help translate it!', $this->textdomain );
253 }
254
255 $registration_link = sprintf(
256 '<a href="%1$s">%2$s</a>',
257 esc_url( $this->register_url ),
258 esc_html( $this->glotpress_name )
259 );
260
261 $message = sprintf(
262 esc_html( $message ),
263 esc_html( $this->locale_name ),
264 esc_html( $this->plugin_name ),
265 (int) $this->percent_translated,
266 $registration_link
267 );
268
269 if ( $message ) {
270 $message = '<p>' . $message . '</p><p><a href="' . esc_url( $this->register_url ) . '">' . esc_html__( 'Register now &raquo;', $this->textdomain ) . '</a></p>';
271 }
272
273 return $message;
274 }
275
276 /**
277 * Returns a button that can be used to dismiss the i18n-message.
278 *
279 * @access private
280 *
281 * @return string
282 */
283 public function get_dismiss_i18n_message_button() {
284 return sprintf(
285 /* translators: %1$s is the notification dismissal link start tag, %2$s is the link closing tag. */
286 esc_html__( '%1$sPlease don\'t show me this notification anymore%2$s', $this->textdomain ),
287 '<a class="button" href="' . esc_url( add_query_arg( [ 'remove_i18n_promo' => '1' ] ) ) . '">',
288 '</a>'
289 );
290 }
291
292 /**
293 * Sets the default values for wordpress.org
294 *
295 * @param array $args The arguments to set defaults for.
296 *
297 * @return array The arguments with the arguments set.
298 */
299 private function set_defaults( $args ) {
300
301 if ( ! isset( $args['glotpress_logo'] ) ) {
302 $args['glotpress_logo'] = 'https://plugins.svn.wordpress.org/' . $args['textdomain'] . '/assets/icon-128x128.png';
303 }
304
305 if ( ! isset( $args['register_url'] ) ) {
306 $args['register_url'] = 'https://translate.wordpress.org/projects/wp-plugins/' . $args['textdomain'] . '/';
307 }
308
309 if ( ! isset( $args['glotpress_name'] ) ) {
310 $args['glotpress_name'] = 'Translating WordPress';
311 }
312
313 if ( ! isset( $args['project_slug'] ) ) {
314 $args['project_slug'] = $args['textdomain'];
315 }
316
317 return $args;
318 }
319
320 /**
321 * Outputs a promo box.
322 *
323 * @access public
324 */
325 public function promo() {
326 $message = $this->get_promo_message();
327
328 if ( $message ) {
329 echo '<div id="i18n_promo_box" style="border:1px solid #ccc;background-color:#fff;padding:10px;max-width:650px; overflow: hidden;">';
330 echo '<a href="' . esc_url( add_query_arg( [ 'remove_i18n_promo' => '1' ] ) ) . '" style="color:#333;text-decoration:none;font-weight:bold;font-size:16px;border:1px solid #ccc;padding:1px 4px;" class="alignright">X</a>';
331
332 echo '<div>';
333 /* translators: %s: plugin name. */
334 echo '<h2>' . sprintf( esc_html__( 'Translation of %s', $this->textdomain ), esc_html( $this->plugin_name ) ) . '</h2>';
335 if ( isset( $this->glotpress_logo ) && is_string( $this->glotpress_logo ) && '' !== $this->glotpress_logo ) {
336 echo '<a href="' . esc_url( $this->register_url ) . '"><img class="alignright" style="margin:0 5px 5px 5px;max-width:200px;" src="' . esc_url( $this->glotpress_logo ) . '" alt="' . esc_attr( $this->glotpress_name ) . '"/></a>';
337 }
338 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- correctly escaped in promo_message() method.
339 echo $message;
340 echo '</div>';
341 echo '</div>';
342 }
343 }
344
345 /**
346 * Try to find the transient for the translation set or retrieve them.
347 *
348 * @access private
349 *
350 * @return object|null
351 */
352 private function find_or_initialize_translation_details() {
353 $set = get_transient( 'yoast_i18n_' . $this->project_slug . '_' . $this->locale );
354
355 if ( ! $set ) {
356 $set = $this->retrieve_translation_details();
357 set_transient( 'yoast_i18n_' . $this->project_slug . '_' . $this->locale, $set, DAY_IN_SECONDS );
358 }
359
360 return $set;
361 }
362
363 /**
364 * Try to get translation details from cache, otherwise retrieve them, then parse them.
365 *
366 * @access private
367 */
368 private function translation_details() {
369 $set = $this->find_or_initialize_translation_details();
370
371 $this->translation_exists = ! is_null( $set );
372 $this->translation_loaded = is_textdomain_loaded( $this->textdomain );
373
374 $this->parse_translation_set( $set );
375 }
376
377 /**
378 * Set the API URL on the i18n object.
379 *
380 * @param string $textdomain The textdomain to use for the API URL.
381 */
382 private function set_api_url( $textdomain ) {
383 $this->api_url = 'https://translate.wordpress.org/api/projects/wp-plugins/' . $textdomain . '/stable/';
384 }
385
386 /**
387 * Returns the API URL to use when requesting translation information.
388 *
389 * @return string
390 */
391 private function get_api_url() {
392 if ( empty( $this->api_url ) ) {
393 $this->api_url = trailingslashit( $this->glotpress_url ) . 'api/projects/' . $this->project_slug;
394 }
395
396 return $this->api_url;
397 }
398
399 /**
400 * Retrieve the translation details from Yoast Translate.
401 *
402 * @access private
403 *
404 * @return object|null
405 */
406 private function retrieve_translation_details() {
407 $api_url = $this->get_api_url();
408
409 $resp = wp_remote_get( $api_url );
410 if ( is_wp_error( $resp ) || wp_remote_retrieve_response_code( $resp ) !== 200 ) {
411 return null;
412 }
413 $body = wp_remote_retrieve_body( $resp );
414 unset( $resp );
415
416 if ( $body ) {
417 $body = json_decode( $body );
418 if ( empty( $body->translation_sets ) ) {
419 return null;
420 }
421 foreach ( $body->translation_sets as $set ) {
422 if ( ! property_exists( $set, 'wp_locale' ) ) {
423 continue;
424 }
425
426 // For informal and formal locales, we have to complete the locale code by concatenating the slug ('formal' or 'informal') to the xx_XX part.
427 if ( 'default' !== $set->slug && strtolower( $this->locale ) === strtolower( $set->wp_locale . '_' . $set->slug ) ) {
428 return $set;
429 }
430
431 if ( $this->locale === $set->wp_locale ) {
432 return $set;
433 }
434 }
435 }
436
437 return null;
438 }
439
440 /**
441 * Set the needed private variables based on the results from Yoast Translate.
442 *
443 * @param object $set The translation set.
444 *
445 * @access private
446 */
447 private function parse_translation_set( $set ) {
448 $this->locale_name = '';
449 $this->percent_translated = '';
450
451 if ( $this->translation_exists && is_object( $set ) ) {
452 $this->locale_name = $set->name;
453 $this->percent_translated = $set->percent_translated;
454 }
455 }
456 }
457