71 * @type bool $description Whether to return the plugin full description. Default false. |
71 * @type bool $description Whether to return the plugin full description. Default false. |
72 * @type bool $sections Whether to return the plugin readme sections: description, installation, |
72 * @type bool $sections Whether to return the plugin readme sections: description, installation, |
73 * FAQ, screenshots, other notes, and changelog. Default false. |
73 * FAQ, screenshots, other notes, and changelog. Default false. |
74 * @type bool $tested Whether to return the 'Compatible up to' value. Default true. |
74 * @type bool $tested Whether to return the 'Compatible up to' value. Default true. |
75 * @type bool $requires Whether to return the required WordPress version. Default true. |
75 * @type bool $requires Whether to return the required WordPress version. Default true. |
|
76 * @type bool $requires_php Whether to return the required PHP version. Default true. |
76 * @type bool $rating Whether to return the rating in percent and total number of ratings. |
77 * @type bool $rating Whether to return the rating in percent and total number of ratings. |
77 * Default true. |
78 * Default true. |
78 * @type bool $ratings Whether to return the number of rating for each star (1-5). Default true. |
79 * @type bool $ratings Whether to return the number of rating for each star (1-5). Default true. |
79 * @type bool $downloaded Whether to return the download count. Default true. |
80 * @type bool $downloaded Whether to return the download count. Default true. |
80 * @type bool $downloadlink Whether to return the download link for the package. Default true. |
81 * @type bool $downloadlink Whether to return the download link for the package. Default true. |
97 * @return object|array|WP_Error Response object or array on success, WP_Error on failure. See the |
98 * @return object|array|WP_Error Response object or array on success, WP_Error on failure. See the |
98 * {@link https://developer.wordpress.org/reference/functions/plugins_api/ function reference article} |
99 * {@link https://developer.wordpress.org/reference/functions/plugins_api/ function reference article} |
99 * for more information on the make-up of possible return values depending on the value of `$action`. |
100 * for more information on the make-up of possible return values depending on the value of `$action`. |
100 */ |
101 */ |
101 function plugins_api( $action, $args = array() ) { |
102 function plugins_api( $action, $args = array() ) { |
102 // include an unmodified $wp_version |
103 // Include an unmodified $wp_version. |
103 include( ABSPATH . WPINC . '/version.php' ); |
104 require ABSPATH . WPINC . '/version.php'; |
104 |
105 |
105 if ( is_array( $args ) ) { |
106 if ( is_array( $args ) ) { |
106 $args = (object) $args; |
107 $args = (object) $args; |
107 } |
108 } |
108 |
109 |
109 if ( 'query_plugins' == $action ) { |
110 if ( 'query_plugins' === $action ) { |
110 if ( ! isset( $args->per_page ) ) { |
111 if ( ! isset( $args->per_page ) ) { |
111 $args->per_page = 24; |
112 $args->per_page = 24; |
112 } |
113 } |
113 } |
114 } |
114 |
115 |
115 if ( ! isset( $args->locale ) ) { |
116 if ( ! isset( $args->locale ) ) { |
116 $args->locale = get_user_locale(); |
117 $args->locale = get_user_locale(); |
117 } |
118 } |
118 |
119 |
119 if ( ! isset( $args->wp_version ) ) { |
120 if ( ! isset( $args->wp_version ) ) { |
120 $args->wp_version = substr( $wp_version, 0, 3 ); // X.y |
121 $args->wp_version = substr( $wp_version, 0, 3 ); // x.y |
121 } |
122 } |
122 |
123 |
123 /** |
124 /** |
124 * Filters the WordPress.org Plugin Installation API arguments. |
125 * Filters the WordPress.org Plugin Installation API arguments. |
125 * |
126 * |
158 ), |
159 ), |
159 $url |
160 $url |
160 ); |
161 ); |
161 |
162 |
162 $http_url = $url; |
163 $http_url = $url; |
163 if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) { |
164 $ssl = wp_http_supports( array( 'ssl' ) ); |
|
165 if ( $ssl ) { |
164 $url = set_url_scheme( $url, 'https' ); |
166 $url = set_url_scheme( $url, 'https' ); |
165 } |
167 } |
166 |
168 |
167 $http_args = array( |
169 $http_args = array( |
168 'timeout' => 15, |
170 'timeout' => 15, |
169 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ), |
171 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ), |
170 ); |
172 ); |
171 $request = wp_remote_get( $url, $http_args ); |
173 $request = wp_remote_get( $url, $http_args ); |
172 |
174 |
173 if ( $ssl && is_wp_error( $request ) ) { |
175 if ( $ssl && is_wp_error( $request ) ) { |
174 trigger_error( |
176 if ( ! wp_is_json_request() ) { |
175 sprintf( |
177 trigger_error( |
176 /* translators: %s: support forums URL */ |
178 sprintf( |
177 __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), |
179 /* translators: %s: Support forums URL. */ |
178 __( 'https://wordpress.org/support/' ) |
180 __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), |
179 ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), |
181 __( 'https://wordpress.org/support/forums/' ) |
180 headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE |
182 ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), |
181 ); |
183 headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE |
|
184 ); |
|
185 } |
|
186 |
182 $request = wp_remote_get( $http_url, $http_args ); |
187 $request = wp_remote_get( $http_url, $http_args ); |
183 } |
188 } |
184 |
189 |
185 if ( is_wp_error( $request ) ) { |
190 if ( is_wp_error( $request ) ) { |
186 $res = new WP_Error( |
191 $res = new WP_Error( |
187 'plugins_api_failed', |
192 'plugins_api_failed', |
188 sprintf( |
193 sprintf( |
189 /* translators: %s: support forums URL */ |
194 /* translators: %s: Support forums URL. */ |
190 __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), |
195 __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), |
191 __( 'https://wordpress.org/support/' ) |
196 __( 'https://wordpress.org/support/forums/' ) |
192 ), |
197 ), |
193 $request->get_error_message() |
198 $request->get_error_message() |
194 ); |
199 ); |
195 } else { |
200 } else { |
196 $res = json_decode( wp_remote_retrieve_body( $request ), true ); |
201 $res = json_decode( wp_remote_retrieve_body( $request ), true ); |
199 $res = (object) $res; |
204 $res = (object) $res; |
200 } elseif ( null === $res ) { |
205 } elseif ( null === $res ) { |
201 $res = new WP_Error( |
206 $res = new WP_Error( |
202 'plugins_api_failed', |
207 'plugins_api_failed', |
203 sprintf( |
208 sprintf( |
204 /* translators: %s: support forums URL */ |
209 /* translators: %s: Support forums URL. */ |
205 __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), |
210 __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), |
206 __( 'https://wordpress.org/support/' ) |
211 __( 'https://wordpress.org/support/forums/' ) |
207 ), |
212 ), |
208 wp_remote_retrieve_body( $request ) |
213 wp_remote_retrieve_body( $request ) |
209 ); |
214 ); |
210 } |
215 } |
211 |
216 |
257 /** |
263 /** |
258 * @since 2.7.0 |
264 * @since 2.7.0 |
259 */ |
265 */ |
260 function install_dashboard() { |
266 function install_dashboard() { |
261 ?> |
267 ?> |
262 <p><?php printf( __( 'Plugins extend and expand the functionality of WordPress. You may automatically install plugins from the <a href="%1$s">WordPress Plugin Directory</a> or upload a plugin in .zip format by clicking the button at the top of this page.' ), __( 'https://wordpress.org/plugins/' ) ); ?></p> |
268 <p> |
|
269 <?php |
|
270 printf( |
|
271 /* translators: %s: https://wordpress.org/plugins/ */ |
|
272 __( 'Plugins extend and expand the functionality of WordPress. You may automatically install plugins from the <a href="%s">WordPress Plugin Directory</a> or upload a plugin in .zip format by clicking the button at the top of this page.' ), |
|
273 __( 'https://wordpress.org/plugins/' ) |
|
274 ); |
|
275 ?> |
|
276 </p> |
263 |
277 |
264 <?php display_plugins_table(); ?> |
278 <?php display_plugins_table(); ?> |
265 |
279 |
266 <div class="plugins-popular-tags-wrapper"> |
280 <div class="plugins-popular-tags-wrapper"> |
267 <h2><?php _e( 'Popular tags' ); ?></h2> |
281 <h2><?php _e( 'Popular tags' ); ?></h2> |
272 |
286 |
273 echo '<p class="popular-tags">'; |
287 echo '<p class="popular-tags">'; |
274 if ( is_wp_error( $api_tags ) ) { |
288 if ( is_wp_error( $api_tags ) ) { |
275 echo $api_tags->get_error_message(); |
289 echo $api_tags->get_error_message(); |
276 } else { |
290 } else { |
277 //Set up the tags in a way which can be interpreted by wp_generate_tag_cloud() |
291 // Set up the tags in a way which can be interpreted by wp_generate_tag_cloud(). |
278 $tags = array(); |
292 $tags = array(); |
279 foreach ( (array) $api_tags as $tag ) { |
293 foreach ( (array) $api_tags as $tag ) { |
280 $url = self_admin_url( 'plugin-install.php?tab=search&type=tag&s=' . urlencode( $tag['name'] ) ); |
294 $url = self_admin_url( 'plugin-install.php?tab=search&type=tag&s=' . urlencode( $tag['name'] ) ); |
281 $data = array( |
295 $data = array( |
282 'link' => esc_url( $url ), |
296 'link' => esc_url( $url ), |
288 $tags[ $tag['name'] ] = (object) $data; |
302 $tags[ $tag['name'] ] = (object) $data; |
289 } |
303 } |
290 echo wp_generate_tag_cloud( |
304 echo wp_generate_tag_cloud( |
291 $tags, |
305 $tags, |
292 array( |
306 array( |
|
307 /* translators: %s: Number of plugins. */ |
293 'single_text' => __( '%s plugin' ), |
308 'single_text' => __( '%s plugin' ), |
|
309 /* translators: %s: Number of plugins. */ |
294 'multiple_text' => __( '%s plugins' ), |
310 'multiple_text' => __( '%s plugins' ), |
295 ) |
311 ) |
296 ); |
312 ); |
297 } |
313 } |
298 echo '</p><br class="clear" /></div>'; |
314 echo '</p><br class="clear" /></div>'; |
316 <select name="type" id="typeselector"> |
332 <select name="type" id="typeselector"> |
317 <option value="term"<?php selected( 'term', $type ); ?>><?php _e( 'Keyword' ); ?></option> |
333 <option value="term"<?php selected( 'term', $type ); ?>><?php _e( 'Keyword' ); ?></option> |
318 <option value="author"<?php selected( 'author', $type ); ?>><?php _e( 'Author' ); ?></option> |
334 <option value="author"<?php selected( 'author', $type ); ?>><?php _e( 'Author' ); ?></option> |
319 <option value="tag"<?php selected( 'tag', $type ); ?>><?php _ex( 'Tag', 'Plugin Installer' ); ?></option> |
335 <option value="tag"<?php selected( 'tag', $type ); ?>><?php _ex( 'Tag', 'Plugin Installer' ); ?></option> |
320 </select> |
336 </select> |
321 <label><span class="screen-reader-text"><?php _e( 'Search Plugins' ); ?></span> |
337 <label class="screen-reader-text" for="search-plugins"><?php _e( 'Search Plugins' ); ?></label> |
322 <input type="search" name="s" value="<?php echo esc_attr( $term ); ?>" class="wp-filter-search" placeholder="<?php esc_attr_e( 'Search plugins...' ); ?>" /> |
338 <input type="search" name="s" id="search-plugins" value="<?php echo esc_attr( $term ); ?>" class="wp-filter-search" placeholder="<?php esc_attr_e( 'Search plugins...' ); ?>" /> |
323 </label> |
|
324 <?php submit_button( __( 'Search Plugins' ), 'hide-if-js', false, false, array( 'id' => 'search-submit' ) ); ?> |
339 <?php submit_button( __( 'Search Plugins' ), 'hide-if-js', false, false, array( 'id' => 'search-submit' ) ); ?> |
325 </form> |
340 </form> |
326 <?php |
341 <?php |
327 } |
342 } |
328 |
343 |
332 * @since 2.8.0 |
347 * @since 2.8.0 |
333 */ |
348 */ |
334 function install_plugins_upload() { |
349 function install_plugins_upload() { |
335 ?> |
350 ?> |
336 <div class="upload-plugin"> |
351 <div class="upload-plugin"> |
337 <p class="install-help"><?php _e( 'If you have a plugin in a .zip format, you may install it by uploading it here.' ); ?></p> |
352 <p class="install-help"><?php _e( 'If you have a plugin in a .zip format, you may install or update it by uploading it here.' ); ?></p> |
338 <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url( 'update.php?action=upload-plugin' ); ?>"> |
353 <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url( 'update.php?action=upload-plugin' ); ?>"> |
339 <?php wp_nonce_field( 'plugin-upload' ); ?> |
354 <?php wp_nonce_field( 'plugin-upload' ); ?> |
340 <label class="screen-reader-text" for="pluginzip"><?php _e( 'Plugin zip file' ); ?></label> |
355 <label class="screen-reader-text" for="pluginzip"><?php _e( 'Plugin zip file' ); ?></label> |
341 <input type="file" id="pluginzip" name="pluginzip" /> |
356 <input type="file" id="pluginzip" name="pluginzip" accept=".zip" /> |
342 <?php submit_button( __( 'Install Now' ), '', 'install-plugin-submit', false ); ?> |
357 <?php submit_button( __( 'Install Now' ), '', 'install-plugin-submit', false ); ?> |
343 </form> |
358 </form> |
344 </div> |
359 </div> |
345 <?php |
360 <?php |
346 } |
361 } |
352 */ |
367 */ |
353 function install_plugins_favorites_form() { |
368 function install_plugins_favorites_form() { |
354 $user = get_user_option( 'wporg_favorites' ); |
369 $user = get_user_option( 'wporg_favorites' ); |
355 $action = 'save_wporg_username_' . get_current_user_id(); |
370 $action = 'save_wporg_username_' . get_current_user_id(); |
356 ?> |
371 ?> |
357 <p class="install-help"><?php _e( 'If you have marked plugins as favorites on WordPress.org, you can browse them here.' ); ?></p> |
372 <p><?php _e( 'If you have marked plugins as favorites on WordPress.org, you can browse them here.' ); ?></p> |
358 <form method="get"> |
373 <form method="get"> |
359 <input type="hidden" name="tab" value="favorites" /> |
374 <input type="hidden" name="tab" value="favorites" /> |
360 <p> |
375 <p> |
361 <label for="user"><?php _e( 'Your WordPress.org username:' ); ?></label> |
376 <label for="user"><?php _e( 'Your WordPress.org username:' ); ?></label> |
362 <input type="search" id="user" name="user" value="<?php echo esc_attr( $user ); ?>" /> |
377 <input type="search" id="user" name="user" value="<?php echo esc_attr( $user ); ?>" /> |
386 case 'install_plugins_recommended': |
401 case 'install_plugins_recommended': |
387 echo '<p>' . __( 'These suggestions are based on the plugins you and other users have installed.' ) . '</p>'; |
402 echo '<p>' . __( 'These suggestions are based on the plugins you and other users have installed.' ) . '</p>'; |
388 break; |
403 break; |
389 case 'install_plugins_beta': |
404 case 'install_plugins_beta': |
390 printf( |
405 printf( |
|
406 /* translators: %s: URL to "Features as Plugins" page. */ |
391 '<p>' . __( 'You are using a development version of WordPress. These feature plugins are also under development. <a href="%s">Learn more</a>.' ) . '</p>', |
407 '<p>' . __( 'You are using a development version of WordPress. These feature plugins are also under development. <a href="%s">Learn more</a>.' ) . '</p>', |
392 'https://make.wordpress.org/core/handbook/about/release-cycle/features-as-plugins/' |
408 'https://make.wordpress.org/core/handbook/about/release-cycle/features-as-plugins/' |
393 ); |
409 ); |
394 break; |
410 break; |
395 } |
411 } |
404 /** |
420 /** |
405 * Determine the status we can perform on a plugin. |
421 * Determine the status we can perform on a plugin. |
406 * |
422 * |
407 * @since 3.0.0 |
423 * @since 3.0.0 |
408 * |
424 * |
409 * @param array|object $api Data about the plugin retrieved from the API. |
425 * @param array|object $api Data about the plugin retrieved from the API. |
410 * @param bool $loop Optional. Disable further loops. Default false. |
426 * @param bool $loop Optional. Disable further loops. Default false. |
411 * @return array { |
427 * @return array { |
412 * Plugin installation status data. |
428 * Plugin installation status data. |
413 * |
429 * |
414 * @type string $status Status of a plugin. Could be one of 'install', 'update_available', 'latest_installed' or 'newer_installed'. |
430 * @type string $status Status of a plugin. Could be one of 'install', 'update_available', 'latest_installed' or 'newer_installed'. |
415 * @type string $url Plugin installation URL. |
431 * @type string $url Plugin installation URL. |
446 break; |
462 break; |
447 } |
463 } |
448 } |
464 } |
449 } |
465 } |
450 |
466 |
451 if ( 'install' == $status ) { |
467 if ( 'install' === $status ) { |
452 if ( is_dir( WP_PLUGIN_DIR . '/' . $api->slug ) ) { |
468 if ( is_dir( WP_PLUGIN_DIR . '/' . $api->slug ) ) { |
453 $installed_plugin = get_plugins( '/' . $api->slug ); |
469 $installed_plugin = get_plugins( '/' . $api->slug ); |
454 if ( empty( $installed_plugin ) ) { |
470 if ( empty( $installed_plugin ) ) { |
455 if ( current_user_can( 'install_plugins' ) ) { |
471 if ( current_user_can( 'install_plugins' ) ) { |
456 $url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $api->slug ), 'install-plugin_' . $api->slug ); |
472 $url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $api->slug ), 'install-plugin_' . $api->slug ); |
457 } |
473 } |
458 } else { |
474 } else { |
459 $key = array_keys( $installed_plugin ); |
475 $key = array_keys( $installed_plugin ); |
460 $key = reset( $key ); //Use the first plugin regardless of the name, Could have issues for multiple-plugins in one directory if they share different version numbers |
476 // Use the first plugin regardless of the name. |
|
477 // Could have issues for multiple plugins in one directory if they share different version numbers. |
|
478 $key = reset( $key ); |
|
479 |
461 $update_file = $api->slug . '/' . $key; |
480 $update_file = $api->slug . '/' . $key; |
462 if ( version_compare( $api->version, $installed_plugin[ $key ]['Version'], '=' ) ) { |
481 if ( version_compare( $api->version, $installed_plugin[ $key ]['Version'], '=' ) ) { |
463 $status = 'latest_installed'; |
482 $status = 'latest_installed'; |
464 } elseif ( version_compare( $api->version, $installed_plugin[ $key ]['Version'], '<' ) ) { |
483 } elseif ( version_compare( $api->version, $installed_plugin[ $key ]['Version'], '<' ) ) { |
465 $status = 'newer_installed'; |
484 $status = 'newer_installed'; |
466 $version = $installed_plugin[ $key ]['Version']; |
485 $version = $installed_plugin[ $key ]['Version']; |
467 } else { |
486 } else { |
468 //If the above update check failed, Then that probably means that the update checker has out-of-date information, force a refresh |
487 // If the above update check failed, then that probably means that the update checker has out-of-date information, force a refresh. |
469 if ( ! $loop ) { |
488 if ( ! $loop ) { |
470 delete_site_transient( 'update_plugins' ); |
489 delete_site_transient( 'update_plugins' ); |
471 wp_update_plugins(); |
490 wp_update_plugins(); |
472 return install_plugin_install_status( $api, true ); |
491 return install_plugin_install_status( $api, true ); |
473 } |
492 } |
474 } |
493 } |
475 } |
494 } |
476 } else { |
495 } else { |
477 // "install" & no directory with that slug |
496 // "install" & no directory with that slug. |
478 if ( current_user_can( 'install_plugins' ) ) { |
497 if ( current_user_can( 'install_plugins' ) ) { |
479 $url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $api->slug ), 'install-plugin_' . $api->slug ); |
498 $url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $api->slug ), 'install-plugin_' . $api->slug ); |
480 } |
499 } |
481 } |
500 } |
482 } |
501 } |
554 'changelog' => _x( 'Changelog', 'Plugin installer section title' ), |
573 'changelog' => _x( 'Changelog', 'Plugin installer section title' ), |
555 'reviews' => _x( 'Reviews', 'Plugin installer section title' ), |
574 'reviews' => _x( 'Reviews', 'Plugin installer section title' ), |
556 'other_notes' => _x( 'Other Notes', 'Plugin installer section title' ), |
575 'other_notes' => _x( 'Other Notes', 'Plugin installer section title' ), |
557 ); |
576 ); |
558 |
577 |
559 // Sanitize HTML |
578 // Sanitize HTML. |
560 foreach ( (array) $api->sections as $section_name => $content ) { |
579 foreach ( (array) $api->sections as $section_name => $content ) { |
561 $api->sections[ $section_name ] = wp_kses( $content, $plugins_allowedtags ); |
580 $api->sections[ $section_name ] = wp_kses( $content, $plugins_allowedtags ); |
562 } |
581 } |
563 |
582 |
564 foreach ( array( 'version', 'author', 'requires', 'tested', 'homepage', 'downloaded', 'slug' ) as $key ) { |
583 foreach ( array( 'version', 'author', 'requires', 'tested', 'homepage', 'downloaded', 'slug' ) as $key ) { |
567 } |
586 } |
568 } |
587 } |
569 |
588 |
570 $_tab = esc_attr( $tab ); |
589 $_tab = esc_attr( $tab ); |
571 |
590 |
572 $section = isset( $_REQUEST['section'] ) ? wp_unslash( $_REQUEST['section'] ) : 'description'; // Default to the Description tab, Do not translate, API returns English. |
591 // Default to the Description tab, Do not translate, API returns English. |
|
592 $section = isset( $_REQUEST['section'] ) ? wp_unslash( $_REQUEST['section'] ) : 'description'; |
573 if ( empty( $section ) || ! isset( $api->sections[ $section ] ) ) { |
593 if ( empty( $section ) || ! isset( $api->sections[ $section ] ) ) { |
574 $section_titles = array_keys( (array) $api->sections ); |
594 $section_titles = array_keys( (array) $api->sections ); |
575 $section = reset( $section_titles ); |
595 $section = reset( $section_titles ); |
576 } |
596 } |
577 |
597 |
635 <?php } if ( ! empty( $api->author ) ) { ?> |
655 <?php } if ( ! empty( $api->author ) ) { ?> |
636 <li><strong><?php _e( 'Author:' ); ?></strong> <?php echo links_add_target( $api->author, '_blank' ); ?></li> |
656 <li><strong><?php _e( 'Author:' ); ?></strong> <?php echo links_add_target( $api->author, '_blank' ); ?></li> |
637 <?php } if ( ! empty( $api->last_updated ) ) { ?> |
657 <?php } if ( ! empty( $api->last_updated ) ) { ?> |
638 <li><strong><?php _e( 'Last Updated:' ); ?></strong> |
658 <li><strong><?php _e( 'Last Updated:' ); ?></strong> |
639 <?php |
659 <?php |
640 /* translators: %s: Time since the last update */ |
660 /* translators: %s: Human-readable time difference. */ |
641 printf( __( '%s ago' ), human_time_diff( strtotime( $api->last_updated ) ) ); |
661 printf( __( '%s ago' ), human_time_diff( strtotime( $api->last_updated ) ) ); |
642 ?> |
662 ?> |
643 </li> |
663 </li> |
644 <?php } if ( ! empty( $api->requires ) ) { ?> |
664 <?php } if ( ! empty( $api->requires ) ) { ?> |
645 <li> |
665 <li> |
646 <strong><?php _e( 'Requires WordPress Version:' ); ?></strong> |
666 <strong><?php _e( 'Requires WordPress Version:' ); ?></strong> |
647 <?php |
667 <?php |
648 /* translators: %s: version number */ |
668 /* translators: %s: Version number. */ |
649 printf( __( '%s or higher' ), $api->requires ); |
669 printf( __( '%s or higher' ), $api->requires ); |
650 ?> |
670 ?> |
651 </li> |
671 </li> |
652 <?php } if ( ! empty( $api->tested ) ) { ?> |
672 <?php } if ( ! empty( $api->tested ) ) { ?> |
653 <li><strong><?php _e( 'Compatible up to:' ); ?></strong> <?php echo $api->tested; ?></li> |
673 <li><strong><?php _e( 'Compatible up to:' ); ?></strong> <?php echo $api->tested; ?></li> |
654 <?php } if ( ! empty( $api->requires_php ) ) { ?> |
674 <?php } if ( ! empty( $api->requires_php ) ) { ?> |
655 <li> |
675 <li> |
656 <strong><?php _e( 'Requires PHP Version:' ); ?></strong> |
676 <strong><?php _e( 'Requires PHP Version:' ); ?></strong> |
657 <?php |
677 <?php |
658 /* translators: %s: version number */ |
678 /* translators: %s: Version number. */ |
659 printf( __( '%s or higher' ), $api->requires_php ); |
679 printf( __( '%s or higher' ), $api->requires_php ); |
660 ?> |
680 ?> |
661 </li> |
681 </li> |
662 <?php } if ( isset( $api->active_installs ) ) { ?> |
682 <?php } if ( isset( $api->active_installs ) ) { ?> |
663 <li><strong><?php _e( 'Active Installations:' ); ?></strong> |
683 <li><strong><?php _e( 'Active Installations:' ); ?></strong> |
664 <?php |
684 <?php |
665 if ( $api->active_installs >= 1000000 ) { |
685 if ( $api->active_installs >= 1000000 ) { |
666 $active_installs_millions = floor( $api->active_installs / 1000000 ); |
686 $active_installs_millions = floor( $api->active_installs / 1000000 ); |
667 printf( |
687 printf( |
|
688 /* translators: %s: Number of millions. */ |
668 _nx( '%s+ Million', '%s+ Million', $active_installs_millions, 'Active plugin installations' ), |
689 _nx( '%s+ Million', '%s+ Million', $active_installs_millions, 'Active plugin installations' ), |
669 number_format_i18n( $active_installs_millions ) |
690 number_format_i18n( $active_installs_millions ) |
670 ); |
691 ); |
671 } elseif ( 0 == $api->active_installs ) { |
692 } elseif ( 0 == $api->active_installs ) { |
672 _ex( 'Less Than 10', 'Active plugin installations' ); |
693 _ex( 'Less Than 10', 'Active plugin installations' ); |
692 'type' => 'percent', |
713 'type' => 'percent', |
693 'number' => $api->num_ratings, |
714 'number' => $api->num_ratings, |
694 ) |
715 ) |
695 ); |
716 ); |
696 ?> |
717 ?> |
697 <p aria-hidden="true" class="fyi-description"><?php printf( _n( '(based on %s rating)', '(based on %s ratings)', $api->num_ratings ), number_format_i18n( $api->num_ratings ) ); ?></p> |
718 <p aria-hidden="true" class="fyi-description"> |
|
719 <?php |
|
720 printf( |
|
721 /* translators: %s: Number of ratings. */ |
|
722 _n( '(based on %s rating)', '(based on %s ratings)', $api->num_ratings ), |
|
723 number_format_i18n( $api->num_ratings ) |
|
724 ); |
|
725 ?> |
|
726 </p> |
698 <?php |
727 <?php |
699 } |
728 } |
700 |
729 |
701 if ( ! empty( $api->ratings ) && array_sum( (array) $api->ratings ) > 0 ) { |
730 if ( ! empty( $api->ratings ) && array_sum( (array) $api->ratings ) > 0 ) { |
702 ?> |
731 ?> |
703 <h3><?php _e( 'Reviews' ); ?></h3> |
732 <h3><?php _e( 'Reviews' ); ?></h3> |
704 <p class="fyi-description"><?php _e( 'Read all reviews on WordPress.org or write your own!' ); ?></p> |
733 <p class="fyi-description"><?php _e( 'Read all reviews on WordPress.org or write your own!' ); ?></p> |
705 <?php |
734 <?php |
706 foreach ( $api->ratings as $key => $ratecount ) { |
735 foreach ( $api->ratings as $key => $ratecount ) { |
707 // Avoid div-by-zero. |
736 // Avoid div-by-zero. |
708 $_rating = $api->num_ratings ? ( $ratecount / $api->num_ratings ) : 0; |
737 $_rating = $api->num_ratings ? ( $ratecount / $api->num_ratings ) : 0; |
709 /* translators: 1: number of stars (used to determine singular/plural), 2: number of reviews */ |
|
710 $aria_label = esc_attr( |
738 $aria_label = esc_attr( |
711 sprintf( |
739 sprintf( |
712 _n( 'Reviews with %1$d star: %2$s. Opens in a new tab.', 'Reviews with %1$d stars: %2$s. Opens in a new tab.', $key ), |
740 /* translators: 1: Number of stars (used to determine singular/plural), 2: Number of reviews. */ |
|
741 _n( |
|
742 'Reviews with %1$d star: %2$s. Opens in a new tab.', |
|
743 'Reviews with %1$d stars: %2$s. Opens in a new tab.', |
|
744 $key |
|
745 ), |
713 $key, |
746 $key, |
714 number_format_i18n( $ratecount ) |
747 number_format_i18n( $ratecount ) |
715 ) |
748 ) |
716 ); |
749 ); |
717 ?> |
750 ?> |
718 <div class="counter-container"> |
751 <div class="counter-container"> |
719 <span class="counter-label"> |
752 <span class="counter-label"> |
720 <a href="https://wordpress.org/support/plugin/<?php echo $api->slug; ?>/reviews/?filter=<?php echo $key; ?>" |
753 <?php |
721 target="_blank" aria-label="<?php echo $aria_label; ?>"><?php printf( _n( '%d star', '%d stars', $key ), $key ); ?></a> |
754 printf( |
|
755 '<a href="%s" target="_blank" aria-label="%s">%s</a>', |
|
756 "https://wordpress.org/support/plugin/{$api->slug}/reviews/?filter={$key}", |
|
757 $aria_label, |
|
758 /* translators: %s: Number of stars. */ |
|
759 sprintf( _n( '%d star', '%d stars', $key ), $key ) |
|
760 ); |
|
761 ?> |
722 </span> |
762 </span> |
723 <span class="counter-back"> |
763 <span class="counter-back"> |
724 <span class="counter-bar" style="width: <?php echo 92 * $_rating; ?>px;"></span> |
764 <span class="counter-bar" style="width: <?php echo 92 * $_rating; ?>px;"></span> |
725 </span> |
765 </span> |
726 <span class="counter-count" aria-hidden="true"><?php echo number_format_i18n( $ratecount ); ?></span> |
766 <span class="counter-count" aria-hidden="true"><?php echo number_format_i18n( $ratecount ); ?></span> |
764 if ( ! $compatible_php ) { |
804 if ( ! $compatible_php ) { |
765 echo '<div class="notice notice-error notice-alt"><p>'; |
805 echo '<div class="notice notice-error notice-alt"><p>'; |
766 _e( '<strong>Error:</strong> This plugin <strong>requires a newer version of PHP</strong>.' ); |
806 _e( '<strong>Error:</strong> This plugin <strong>requires a newer version of PHP</strong>.' ); |
767 if ( current_user_can( 'update_php' ) ) { |
807 if ( current_user_can( 'update_php' ) ) { |
768 printf( |
808 printf( |
769 /* translators: %s: "Update PHP" page URL */ |
809 /* translators: %s: URL to Update PHP page. */ |
770 ' ' . __( '<a href="%s" target="_blank">Click here to learn more about updating PHP</a>.' ), |
810 ' ' . __( '<a href="%s" target="_blank">Click here to learn more about updating PHP</a>.' ), |
771 esc_url( wp_get_update_php_url() ) |
811 esc_url( wp_get_update_php_url() ) |
772 ); |
812 ); |
773 |
813 |
774 wp_update_php_annotation( '</p><p><em>', '</em>' ); |
814 wp_update_php_annotation( '</p><p><em>', '</em>' ); |
785 } elseif ( ! $compatible_wp ) { |
825 } elseif ( ! $compatible_wp ) { |
786 echo '<div class="notice notice-error notice-alt"><p>'; |
826 echo '<div class="notice notice-error notice-alt"><p>'; |
787 _e( '<strong>Error:</strong> This plugin <strong>requires a newer version of WordPress</strong>.' ); |
827 _e( '<strong>Error:</strong> This plugin <strong>requires a newer version of WordPress</strong>.' ); |
788 if ( current_user_can( 'update_core' ) ) { |
828 if ( current_user_can( 'update_core' ) ) { |
789 printf( |
829 printf( |
790 /* translators: %s: "Update WordPress" screen URL */ |
830 /* translators: %s: URL to WordPress Updates screen. */ |
791 ' ' . __( '<a href="%s" target="_parent">Click here to update WordPress</a>.' ), |
831 ' ' . __( '<a href="%s" target="_parent">Click here to update WordPress</a>.' ), |
792 self_admin_url( 'update-core.php' ) |
832 self_admin_url( 'update-core.php' ) |
793 ); |
833 ); |
794 } |
834 } |
795 echo '</p></div>'; |
835 echo '</p></div>'; |