139 * @param object $args Plugin API arguments. |
147 * @param object $args Plugin API arguments. |
140 */ |
148 */ |
141 $res = apply_filters( 'plugins_api', false, $action, $args ); |
149 $res = apply_filters( 'plugins_api', false, $action, $args ); |
142 |
150 |
143 if ( false === $res ) { |
151 if ( false === $res ) { |
144 // include an unmodified $wp_version |
152 |
145 include( ABSPATH . WPINC . '/version.php' ); |
153 $url = 'http://api.wordpress.org/plugins/info/1.2/'; |
146 |
154 $url = add_query_arg( |
147 $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/'; |
155 array( |
148 if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) |
156 'action' => $action, |
|
157 'request' => $args, |
|
158 ), |
|
159 $url |
|
160 ); |
|
161 |
|
162 $http_url = $url; |
|
163 if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) { |
149 $url = set_url_scheme( $url, 'https' ); |
164 $url = set_url_scheme( $url, 'https' ); |
|
165 } |
150 |
166 |
151 $http_args = array( |
167 $http_args = array( |
152 'timeout' => 15, |
168 'timeout' => 15, |
153 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ), |
169 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ), |
154 'body' => array( |
|
155 'action' => $action, |
|
156 'request' => serialize( $args ) |
|
157 ) |
|
158 ); |
170 ); |
159 $request = wp_remote_post( $url, $http_args ); |
171 $request = wp_remote_get( $url, $http_args ); |
160 |
172 |
161 if ( $ssl && is_wp_error( $request ) ) { |
173 if ( $ssl && is_wp_error( $request ) ) { |
162 trigger_error( |
174 trigger_error( |
163 sprintf( |
175 sprintf( |
164 /* translators: %s: support forums URL */ |
176 /* translators: %s: support forums URL */ |
165 __( '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>.' ), |
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>.' ), |
166 __( 'https://wordpress.org/support/' ) |
178 __( 'https://wordpress.org/support/' ) |
167 ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), |
179 ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), |
168 headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE |
180 headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE |
169 ); |
181 ); |
170 $request = wp_remote_post( $http_url, $http_args ); |
182 $request = wp_remote_get( $http_url, $http_args ); |
171 } |
183 } |
172 |
184 |
173 if ( is_wp_error($request) ) { |
185 if ( is_wp_error( $request ) ) { |
174 $res = new WP_Error( 'plugins_api_failed', |
186 $res = new WP_Error( |
|
187 'plugins_api_failed', |
175 sprintf( |
188 sprintf( |
176 /* translators: %s: support forums URL */ |
189 /* translators: %s: support forums URL */ |
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>.' ), |
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>.' ), |
178 __( 'https://wordpress.org/support/' ) |
191 __( 'https://wordpress.org/support/' ) |
179 ), |
192 ), |
180 $request->get_error_message() |
193 $request->get_error_message() |
181 ); |
194 ); |
182 } else { |
195 } else { |
183 $res = maybe_unserialize( wp_remote_retrieve_body( $request ) ); |
196 $res = json_decode( wp_remote_retrieve_body( $request ), true ); |
184 if ( ! is_object( $res ) && ! is_array( $res ) ) { |
197 if ( is_array( $res ) ) { |
185 $res = new WP_Error( 'plugins_api_failed', |
198 // Object casting is required in order to match the info/1.0 format. |
|
199 $res = (object) $res; |
|
200 } elseif ( null === $res ) { |
|
201 $res = new WP_Error( |
|
202 'plugins_api_failed', |
186 sprintf( |
203 sprintf( |
187 /* translators: %s: support forums URL */ |
204 /* translators: %s: support forums URL */ |
188 __( '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>.' ), |
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>.' ), |
189 __( 'https://wordpress.org/support/' ) |
206 __( 'https://wordpress.org/support/' ) |
190 ), |
207 ), |
191 wp_remote_retrieve_body( $request ) |
208 wp_remote_retrieve_body( $request ) |
192 ); |
209 ); |
193 } |
210 } |
194 } |
211 |
195 } elseif ( !is_wp_error($res) ) { |
212 if ( isset( $res->error ) ) { |
|
213 $res = new WP_Error( 'plugins_api_failed', $res->error ); |
|
214 } |
|
215 } |
|
216 } elseif ( ! is_wp_error( $res ) ) { |
196 $res->external = true; |
217 $res->external = true; |
197 } |
218 } |
198 |
219 |
199 /** |
220 /** |
200 * Filters the Plugin Installation API response results. |
221 * Filters the Plugin Installation API response results. |
239 <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> |
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> |
240 |
263 |
241 <?php display_plugins_table(); ?> |
264 <?php display_plugins_table(); ?> |
242 |
265 |
243 <div class="plugins-popular-tags-wrapper"> |
266 <div class="plugins-popular-tags-wrapper"> |
244 <h2><?php _e( 'Popular tags' ) ?></h2> |
267 <h2><?php _e( 'Popular tags' ); ?></h2> |
245 <p><?php _e( 'You may also browse based on the most popular tags in the Plugin Directory:' ) ?></p> |
268 <p><?php _e( 'You may also browse based on the most popular tags in the Plugin Directory:' ); ?></p> |
246 <?php |
269 <?php |
247 |
270 |
248 $api_tags = install_popular_tags(); |
271 $api_tags = install_popular_tags(); |
249 |
272 |
250 echo '<p class="popular-tags">'; |
273 echo '<p class="popular-tags">'; |
251 if ( is_wp_error($api_tags) ) { |
274 if ( is_wp_error( $api_tags ) ) { |
252 echo $api_tags->get_error_message(); |
275 echo $api_tags->get_error_message(); |
253 } else { |
276 } else { |
254 //Set up the tags in a way which can be interpreted by wp_generate_tag_cloud() |
277 //Set up the tags in a way which can be interpreted by wp_generate_tag_cloud() |
255 $tags = array(); |
278 $tags = array(); |
256 foreach ( (array) $api_tags as $tag ) { |
279 foreach ( (array) $api_tags as $tag ) { |
257 $url = self_admin_url( 'plugin-install.php?tab=search&type=tag&s=' . urlencode( $tag['name'] ) ); |
280 $url = self_admin_url( 'plugin-install.php?tab=search&type=tag&s=' . urlencode( $tag['name'] ) ); |
258 $data = array( |
281 $data = array( |
259 'link' => esc_url( $url ), |
282 'link' => esc_url( $url ), |
260 'name' => $tag['name'], |
283 'name' => $tag['name'], |
261 'slug' => $tag['slug'], |
284 'slug' => $tag['slug'], |
262 'id' => sanitize_title_with_dashes( $tag['name'] ), |
285 'id' => sanitize_title_with_dashes( $tag['name'] ), |
263 'count' => $tag['count'] |
286 'count' => $tag['count'], |
264 ); |
287 ); |
265 $tags[ $tag['name'] ] = (object) $data; |
288 $tags[ $tag['name'] ] = (object) $data; |
266 } |
289 } |
267 echo wp_generate_tag_cloud($tags, array( 'single_text' => __('%s plugin'), 'multiple_text' => __('%s plugins') ) ); |
290 echo wp_generate_tag_cloud( |
|
291 $tags, |
|
292 array( |
|
293 'single_text' => __( '%s plugin' ), |
|
294 'multiple_text' => __( '%s plugins' ), |
|
295 ) |
|
296 ); |
268 } |
297 } |
269 echo '</p><br class="clear" /></div>'; |
298 echo '</p><br class="clear" /></div>'; |
270 } |
299 } |
271 |
300 |
272 /** |
301 /** |
278 * @param bool $deprecated Not used. |
307 * @param bool $deprecated Not used. |
279 */ |
308 */ |
280 function install_search_form( $deprecated = true ) { |
309 function install_search_form( $deprecated = true ) { |
281 $type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term'; |
310 $type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term'; |
282 $term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : ''; |
311 $term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : ''; |
283 ?><form class="search-form search-plugins" method="get"> |
312 ?> |
|
313 <form class="search-form search-plugins" method="get"> |
284 <input type="hidden" name="tab" value="search" /> |
314 <input type="hidden" name="tab" value="search" /> |
285 <label class="screen-reader-text" for="typeselector"><?php _e( 'Search plugins by:' ); ?></label> |
315 <label class="screen-reader-text" for="typeselector"><?php _e( 'Search plugins by:' ); ?></label> |
286 <select name="type" id="typeselector"> |
316 <select name="type" id="typeselector"> |
287 <option value="term"<?php selected( 'term', $type ); ?>><?php _e( 'Keyword' ); ?></option> |
317 <option value="term"<?php selected( 'term', $type ); ?>><?php _e( 'Keyword' ); ?></option> |
288 <option value="author"<?php selected( 'author', $type ); ?>><?php _e( 'Author' ); ?></option> |
318 <option value="author"<?php selected( 'author', $type ); ?>><?php _e( 'Author' ); ?></option> |
289 <option value="tag"<?php selected( 'tag', $type ); ?>><?php _ex( 'Tag', 'Plugin Installer' ); ?></option> |
319 <option value="tag"<?php selected( 'tag', $type ); ?>><?php _ex( 'Tag', 'Plugin Installer' ); ?></option> |
290 </select> |
320 </select> |
291 <label><span class="screen-reader-text"><?php _e( 'Search Plugins' ); ?></span> |
321 <label><span class="screen-reader-text"><?php _e( 'Search Plugins' ); ?></span> |
292 <input type="search" name="s" value="<?php echo esc_attr( $term ) ?>" class="wp-filter-search" placeholder="<?php esc_attr_e( 'Search plugins...' ); ?>" /> |
322 <input type="search" name="s" value="<?php echo esc_attr( $term ); ?>" class="wp-filter-search" placeholder="<?php esc_attr_e( 'Search plugins...' ); ?>" /> |
293 </label> |
323 </label> |
294 <?php submit_button( __( 'Search Plugins' ), 'hide-if-js', false, false, array( 'id' => 'search-submit' ) ); ?> |
324 <?php submit_button( __( 'Search Plugins' ), 'hide-if-js', false, false, array( 'id' => 'search-submit' ) ); ?> |
295 </form><?php |
325 </form> |
|
326 <?php |
296 } |
327 } |
297 |
328 |
298 /** |
329 /** |
299 * Upload from zip |
330 * Upload from zip |
|
331 * |
300 * @since 2.8.0 |
332 * @since 2.8.0 |
301 */ |
333 */ |
302 function install_plugins_upload() { |
334 function install_plugins_upload() { |
303 ?> |
335 ?> |
304 <div class="upload-plugin"> |
336 <div class="upload-plugin"> |
305 <p class="install-help"><?php _e('If you have a plugin in a .zip format, you may install it by uploading it here.'); ?></p> |
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> |
306 <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url('update.php?action=upload-plugin'); ?>"> |
338 <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url( 'update.php?action=upload-plugin' ); ?>"> |
307 <?php wp_nonce_field( 'plugin-upload' ); ?> |
339 <?php wp_nonce_field( 'plugin-upload' ); ?> |
308 <label class="screen-reader-text" for="pluginzip"><?php _e( 'Plugin zip file' ); ?></label> |
340 <label class="screen-reader-text" for="pluginzip"><?php _e( 'Plugin zip file' ); ?></label> |
309 <input type="file" id="pluginzip" name="pluginzip" /> |
341 <input type="file" id="pluginzip" name="pluginzip" /> |
310 <?php submit_button( __( 'Install Now' ), '', 'install-plugin-submit', false ); ?> |
342 <?php submit_button( __( 'Install Now' ), '', 'install-plugin-submit', false ); ?> |
311 </form> |
343 </form> |
312 </div> |
344 </div> |
313 <?php |
345 <?php |
314 } |
346 } |
315 |
347 |
316 /** |
348 /** |
317 * Show a username form for the favorites page |
349 * Show a username form for the favorites page |
|
350 * |
318 * @since 3.5.0 |
351 * @since 3.5.0 |
319 * |
|
320 */ |
352 */ |
321 function install_plugins_favorites_form() { |
353 function install_plugins_favorites_form() { |
322 $user = get_user_option( 'wporg_favorites' ); |
354 $user = get_user_option( 'wporg_favorites' ); |
323 $action = 'save_wporg_username_' . get_current_user_id(); |
355 $action = 'save_wporg_username_' . get_current_user_id(); |
324 ?> |
356 ?> |
383 * @type string $url Plugin installation URL. |
415 * @type string $url Plugin installation URL. |
384 * @type string $version The most recent version of the plugin. |
416 * @type string $version The most recent version of the plugin. |
385 * @type string $file Plugin filename relative to the plugins directory. |
417 * @type string $file Plugin filename relative to the plugins directory. |
386 * } |
418 * } |
387 */ |
419 */ |
388 function install_plugin_install_status($api, $loop = false) { |
420 function install_plugin_install_status( $api, $loop = false ) { |
389 // This function is called recursively, $loop prevents further loops. |
421 // This function is called recursively, $loop prevents further loops. |
390 if ( is_array($api) ) |
422 if ( is_array( $api ) ) { |
391 $api = (object) $api; |
423 $api = (object) $api; |
|
424 } |
392 |
425 |
393 // Default to a "new" plugin |
426 // Default to a "new" plugin |
394 $status = 'install'; |
427 $status = 'install'; |
395 $url = false; |
428 $url = false; |
396 $update_file = false; |
429 $update_file = false; |
|
430 $version = ''; |
397 |
431 |
398 /* |
432 /* |
399 * Check to see if this plugin is known to be installed, |
433 * Check to see if this plugin is known to be installed, |
400 * and has an update awaiting it. |
434 * and has an update awaiting it. |
401 */ |
435 */ |
402 $update_plugins = get_site_transient('update_plugins'); |
436 $update_plugins = get_site_transient( 'update_plugins' ); |
403 if ( isset( $update_plugins->response ) ) { |
437 if ( isset( $update_plugins->response ) ) { |
404 foreach ( (array)$update_plugins->response as $file => $plugin ) { |
438 foreach ( (array) $update_plugins->response as $file => $plugin ) { |
405 if ( $plugin->slug === $api->slug ) { |
439 if ( $plugin->slug === $api->slug ) { |
406 $status = 'update_available'; |
440 $status = 'update_available'; |
407 $update_file = $file; |
441 $update_file = $file; |
408 $version = $plugin->new_version; |
442 $version = $plugin->new_version; |
409 if ( current_user_can('update_plugins') ) |
443 if ( current_user_can( 'update_plugins' ) ) { |
410 $url = wp_nonce_url(self_admin_url('update.php?action=upgrade-plugin&plugin=' . $update_file), 'upgrade-plugin_' . $update_file); |
444 $url = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' . $update_file ), 'upgrade-plugin_' . $update_file ); |
|
445 } |
411 break; |
446 break; |
412 } |
447 } |
413 } |
448 } |
414 } |
449 } |
415 |
450 |
416 if ( 'install' == $status ) { |
451 if ( 'install' == $status ) { |
417 if ( is_dir( WP_PLUGIN_DIR . '/' . $api->slug ) ) { |
452 if ( is_dir( WP_PLUGIN_DIR . '/' . $api->slug ) ) { |
418 $installed_plugin = get_plugins('/' . $api->slug); |
453 $installed_plugin = get_plugins( '/' . $api->slug ); |
419 if ( empty($installed_plugin) ) { |
454 if ( empty( $installed_plugin ) ) { |
420 if ( current_user_can('install_plugins') ) |
455 if ( current_user_can( 'install_plugins' ) ) { |
421 $url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $api->slug), 'install-plugin_' . $api->slug); |
456 $url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $api->slug ), 'install-plugin_' . $api->slug ); |
|
457 } |
422 } else { |
458 } else { |
423 $key = array_keys( $installed_plugin ); |
459 $key = array_keys( $installed_plugin ); |
424 $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 |
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 |
425 $update_file = $api->slug . '/' . $key; |
461 $update_file = $api->slug . '/' . $key; |
426 if ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '=') ){ |
462 if ( version_compare( $api->version, $installed_plugin[ $key ]['Version'], '=' ) ) { |
427 $status = 'latest_installed'; |
463 $status = 'latest_installed'; |
428 } elseif ( version_compare($api->version, $installed_plugin[ $key ]['Version'], '<') ) { |
464 } elseif ( version_compare( $api->version, $installed_plugin[ $key ]['Version'], '<' ) ) { |
429 $status = 'newer_installed'; |
465 $status = 'newer_installed'; |
430 $version = $installed_plugin[ $key ]['Version']; |
466 $version = $installed_plugin[ $key ]['Version']; |
431 } else { |
467 } else { |
432 //If the above update check failed, Then that probably means that the update checker has out-of-date information, force a refresh |
468 //If the above update check failed, Then that probably means that the update checker has out-of-date information, force a refresh |
433 if ( ! $loop ) { |
469 if ( ! $loop ) { |
434 delete_site_transient('update_plugins'); |
470 delete_site_transient( 'update_plugins' ); |
435 wp_update_plugins(); |
471 wp_update_plugins(); |
436 return install_plugin_install_status($api, true); |
472 return install_plugin_install_status( $api, true ); |
437 } |
473 } |
438 } |
474 } |
439 } |
475 } |
440 } else { |
476 } else { |
441 // "install" & no directory with that slug |
477 // "install" & no directory with that slug |
442 if ( current_user_can('install_plugins') ) |
478 if ( current_user_can( 'install_plugins' ) ) { |
443 $url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $api->slug), 'install-plugin_' . $api->slug); |
479 $url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $api->slug ), 'install-plugin_' . $api->slug ); |
444 } |
480 } |
445 } |
481 } |
446 if ( isset($_GET['from']) ) |
482 } |
|
483 if ( isset( $_GET['from'] ) ) { |
447 $url .= '&from=' . urlencode( wp_unslash( $_GET['from'] ) ); |
484 $url .= '&from=' . urlencode( wp_unslash( $_GET['from'] ) ); |
|
485 } |
448 |
486 |
449 $file = $update_file; |
487 $file = $update_file; |
450 return compact( 'status', 'url', 'version', 'file' ); |
488 return compact( 'status', 'url', 'version', 'file' ); |
451 } |
489 } |
452 |
490 |
462 |
500 |
463 if ( empty( $_REQUEST['plugin'] ) ) { |
501 if ( empty( $_REQUEST['plugin'] ) ) { |
464 return; |
502 return; |
465 } |
503 } |
466 |
504 |
467 $api = plugins_api( 'plugin_information', array( |
505 $api = plugins_api( |
468 'slug' => wp_unslash( $_REQUEST['plugin'] ), |
506 'plugin_information', |
469 'is_ssl' => is_ssl(), |
507 array( |
470 'fields' => array( |
508 'slug' => wp_unslash( $_REQUEST['plugin'] ), |
471 'banners' => true, |
|
472 'reviews' => true, |
|
473 'downloaded' => false, |
|
474 'active_installs' => true |
|
475 ) |
509 ) |
476 ) ); |
510 ); |
477 |
511 |
478 if ( is_wp_error( $api ) ) { |
512 if ( is_wp_error( $api ) ) { |
479 wp_die( $api ); |
513 wp_die( $api ); |
480 } |
514 } |
481 |
515 |
482 $plugins_allowedtags = array( |
516 $plugins_allowedtags = array( |
483 'a' => array( 'href' => array(), 'title' => array(), 'target' => array() ), |
517 'a' => array( |
484 'abbr' => array( 'title' => array() ), 'acronym' => array( 'title' => array() ), |
518 'href' => array(), |
485 'code' => array(), 'pre' => array(), 'em' => array(), 'strong' => array(), |
519 'title' => array(), |
486 'div' => array( 'class' => array() ), 'span' => array( 'class' => array() ), |
520 'target' => array(), |
487 'p' => array(), 'br' => array(), 'ul' => array(), 'ol' => array(), 'li' => array(), |
521 ), |
488 'h1' => array(), 'h2' => array(), 'h3' => array(), 'h4' => array(), 'h5' => array(), 'h6' => array(), |
522 'abbr' => array( 'title' => array() ), |
489 'img' => array( 'src' => array(), 'class' => array(), 'alt' => array() ), |
523 'acronym' => array( 'title' => array() ), |
|
524 'code' => array(), |
|
525 'pre' => array(), |
|
526 'em' => array(), |
|
527 'strong' => array(), |
|
528 'div' => array( 'class' => array() ), |
|
529 'span' => array( 'class' => array() ), |
|
530 'p' => array(), |
|
531 'br' => array(), |
|
532 'ul' => array(), |
|
533 'ol' => array(), |
|
534 'li' => array(), |
|
535 'h1' => array(), |
|
536 'h2' => array(), |
|
537 'h3' => array(), |
|
538 'h4' => array(), |
|
539 'h5' => array(), |
|
540 'h6' => array(), |
|
541 'img' => array( |
|
542 'src' => array(), |
|
543 'class' => array(), |
|
544 'alt' => array(), |
|
545 ), |
490 'blockquote' => array( 'cite' => true ), |
546 'blockquote' => array( 'cite' => true ), |
491 ); |
547 ); |
492 |
548 |
493 $plugins_section_titles = array( |
549 $plugins_section_titles = array( |
494 'description' => _x( 'Description', 'Plugin installer section title' ), |
550 'description' => _x( 'Description', 'Plugin installer section title' ), |
495 'installation' => _x( 'Installation', 'Plugin installer section title' ), |
551 'installation' => _x( 'Installation', 'Plugin installer section title' ), |
496 'faq' => _x( 'FAQ', 'Plugin installer section title' ), |
552 'faq' => _x( 'FAQ', 'Plugin installer section title' ), |
497 'screenshots' => _x( 'Screenshots', 'Plugin installer section title' ), |
553 'screenshots' => _x( 'Screenshots', 'Plugin installer section title' ), |
498 'changelog' => _x( 'Changelog', 'Plugin installer section title' ), |
554 'changelog' => _x( 'Changelog', 'Plugin installer section title' ), |
499 'reviews' => _x( 'Reviews', 'Plugin installer section title' ), |
555 'reviews' => _x( 'Reviews', 'Plugin installer section title' ), |
500 'other_notes' => _x( 'Other Notes', 'Plugin installer section title' ) |
556 'other_notes' => _x( 'Other Notes', 'Plugin installer section title' ), |
501 ); |
557 ); |
502 |
558 |
503 // Sanitize HTML |
559 // Sanitize HTML |
504 foreach ( (array) $api->sections as $section_name => $content ) { |
560 foreach ( (array) $api->sections as $section_name => $content ) { |
505 $api->sections[$section_name] = wp_kses( $content, $plugins_allowedtags ); |
561 $api->sections[ $section_name ] = wp_kses( $content, $plugins_allowedtags ); |
506 } |
562 } |
507 |
563 |
508 foreach ( array( 'version', 'author', 'requires', 'tested', 'homepage', 'downloaded', 'slug' ) as $key ) { |
564 foreach ( array( 'version', 'author', 'requires', 'tested', 'homepage', 'downloaded', 'slug' ) as $key ) { |
509 if ( isset( $api->$key ) ) { |
565 if ( isset( $api->$key ) ) { |
510 $api->$key = wp_kses( $api->$key, $plugins_allowedtags ); |
566 $api->$key = wp_kses( $api->$key, $plugins_allowedtags ); |
597 /* translators: %s: version number */ |
658 /* translators: %s: version number */ |
598 printf( __( '%s or higher' ), $api->requires_php ); |
659 printf( __( '%s or higher' ), $api->requires_php ); |
599 ?> |
660 ?> |
600 </li> |
661 </li> |
601 <?php } if ( isset( $api->active_installs ) ) { ?> |
662 <?php } if ( isset( $api->active_installs ) ) { ?> |
602 <li><strong><?php _e( 'Active Installations:' ); ?></strong> <?php |
663 <li><strong><?php _e( 'Active Installations:' ); ?></strong> |
603 if ( $api->active_installs >= 1000000 ) { |
664 <?php |
604 _ex( '1+ Million', 'Active plugin installations' ); |
665 if ( $api->active_installs >= 1000000 ) { |
605 } elseif ( 0 == $api->active_installs ) { |
666 $active_installs_millions = floor( $api->active_installs / 1000000 ); |
606 _ex( 'Less Than 10', 'Active plugin installations' ); |
667 printf( |
607 } else { |
668 _nx( '%s+ Million', '%s+ Million', $active_installs_millions, 'Active plugin installations' ), |
608 echo number_format_i18n( $api->active_installs ) . '+'; |
669 number_format_i18n( $active_installs_millions ) |
609 } |
670 ); |
610 ?></li> |
671 } elseif ( 0 == $api->active_installs ) { |
|
672 _ex( 'Less Than 10', 'Active plugin installations' ); |
|
673 } else { |
|
674 echo number_format_i18n( $api->active_installs ) . '+'; |
|
675 } |
|
676 ?> |
|
677 </li> |
611 <?php } if ( ! empty( $api->slug ) && empty( $api->external ) ) { ?> |
678 <?php } if ( ! empty( $api->slug ) && empty( $api->external ) ) { ?> |
612 <li><a target="_blank" href="<?php echo __( 'https://wordpress.org/plugins/' ) . $api->slug; ?>/"><?php _e( 'WordPress.org Plugin Page »' ); ?></a></li> |
679 <li><a target="_blank" href="<?php echo __( 'https://wordpress.org/plugins/' ) . $api->slug; ?>/"><?php _e( 'WordPress.org Plugin Page »' ); ?></a></li> |
613 <?php } if ( ! empty( $api->homepage ) ) { ?> |
680 <?php } if ( ! empty( $api->homepage ) ) { ?> |
614 <li><a target="_blank" href="<?php echo esc_url( $api->homepage ); ?>"><?php _e( 'Plugin Homepage »' ); ?></a></li> |
681 <li><a target="_blank" href="<?php echo esc_url( $api->homepage ); ?>"><?php _e( 'Plugin Homepage »' ); ?></a></li> |
615 <?php } if ( ! empty( $api->donate_link ) && empty( $api->contributors ) ) { ?> |
682 <?php } if ( ! empty( $api->donate_link ) && empty( $api->contributors ) ) { ?> |
616 <li><a target="_blank" href="<?php echo esc_url( $api->donate_link ); ?>"><?php _e( 'Donate to this plugin »' ); ?></a></li> |
683 <li><a target="_blank" href="<?php echo esc_url( $api->donate_link ); ?>"><?php _e( 'Donate to this plugin »' ); ?></a></li> |
617 <?php } ?> |
684 <?php } ?> |
618 </ul> |
685 </ul> |
619 <?php if ( ! empty( $api->rating ) ) { ?> |
686 <?php if ( ! empty( $api->rating ) ) { ?> |
620 <h3><?php _e( 'Average Rating' ); ?></h3> |
687 <h3><?php _e( 'Average Rating' ); ?></h3> |
621 <?php wp_star_rating( array( 'rating' => $api->rating, 'type' => 'percent', 'number' => $api->num_ratings ) ); ?> |
688 <?php |
|
689 wp_star_rating( |
|
690 array( |
|
691 'rating' => $api->rating, |
|
692 'type' => 'percent', |
|
693 'number' => $api->num_ratings, |
|
694 ) |
|
695 ); |
|
696 ?> |
622 <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> |
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> |
623 <?php } |
698 <?php |
624 |
699 } |
625 if ( ! empty( $api->ratings ) && array_sum( (array) $api->ratings ) > 0 ) { ?> |
700 |
|
701 if ( ! empty( $api->ratings ) && array_sum( (array) $api->ratings ) > 0 ) { |
|
702 ?> |
626 <h3><?php _e( 'Reviews' ); ?></h3> |
703 <h3><?php _e( 'Reviews' ); ?></h3> |
627 <p class="fyi-description"><?php _e( 'Read all reviews on WordPress.org or write your own!' ); ?></p> |
704 <p class="fyi-description"><?php _e( 'Read all reviews on WordPress.org or write your own!' ); ?></p> |
628 <?php |
705 <?php |
629 foreach ( $api->ratings as $key => $ratecount ) { |
706 foreach ( $api->ratings as $key => $ratecount ) { |
630 // Avoid div-by-zero. |
707 // Avoid div-by-zero. |
631 $_rating = $api->num_ratings ? ( $ratecount / $api->num_ratings ) : 0; |
708 $_rating = $api->num_ratings ? ( $ratecount / $api->num_ratings ) : 0; |
632 /* translators: 1: number of stars (used to determine singular/plural), 2: number of reviews */ |
709 /* translators: 1: number of stars (used to determine singular/plural), 2: number of reviews */ |
633 $aria_label = esc_attr( sprintf( _n( 'Reviews with %1$d star: %2$s. Opens in a new window.', 'Reviews with %1$d stars: %2$s. Opens in a new window.', $key ), |
710 $aria_label = esc_attr( |
634 $key, |
711 sprintf( |
635 number_format_i18n( $ratecount ) |
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 ), |
636 ) ); |
713 $key, |
|
714 number_format_i18n( $ratecount ) |
|
715 ) |
|
716 ); |
637 ?> |
717 ?> |
638 <div class="counter-container"> |
718 <div class="counter-container"> |
639 <span class="counter-label"><a href="https://wordpress.org/support/plugin/<?php echo $api->slug; ?>/reviews/?filter=<?php echo $key; ?>" |
719 <span class="counter-label"> |
640 target="_blank" aria-label="<?php echo $aria_label; ?>"><?php printf( _n( '%d star', '%d stars', $key ), $key ); ?></a></span> |
720 <a href="https://wordpress.org/support/plugin/<?php echo $api->slug; ?>/reviews/?filter=<?php echo $key; ?>" |
|
721 target="_blank" aria-label="<?php echo $aria_label; ?>"><?php printf( _n( '%d star', '%d stars', $key ), $key ); ?></a> |
|
722 </span> |
641 <span class="counter-back"> |
723 <span class="counter-back"> |
642 <span class="counter-bar" style="width: <?php echo 92 * $_rating; ?>px;"></span> |
724 <span class="counter-bar" style="width: <?php echo 92 * $_rating; ?>px;"></span> |
643 </span> |
725 </span> |
644 <span class="counter-count" aria-hidden="true"><?php echo number_format_i18n( $ratecount ); ?></span> |
726 <span class="counter-count" aria-hidden="true"><?php echo number_format_i18n( $ratecount ); ?></span> |
645 </div> |
727 </div> |
646 <?php |
728 <?php |
647 } |
729 } |
648 } |
730 } |
649 if ( ! empty( $api->contributors ) ) { ?> |
731 if ( ! empty( $api->contributors ) ) { |
|
732 ?> |
650 <h3><?php _e( 'Contributors' ); ?></h3> |
733 <h3><?php _e( 'Contributors' ); ?></h3> |
651 <ul class="contributors"> |
734 <ul class="contributors"> |
652 <?php |
735 <?php |
653 foreach ( (array) $api->contributors as $contrib_username => $contrib_profile ) { |
736 foreach ( (array) $api->contributors as $contrib_username => $contrib_details ) { |
654 if ( empty( $contrib_username ) && empty( $contrib_profile ) ) { |
737 $contrib_name = $contrib_details['display_name']; |
655 continue; |
738 if ( ! $contrib_name ) { |
|
739 $contrib_name = $contrib_username; |
656 } |
740 } |
657 if ( empty( $contrib_username ) ) { |
741 $contrib_name = esc_html( $contrib_name ); |
658 $contrib_username = preg_replace( '/^.+\/(.+)\/?$/', '\1', $contrib_profile ); |
742 |
659 } |
743 $contrib_profile = esc_url( $contrib_details['profile'] ); |
660 $contrib_username = sanitize_user( $contrib_username ); |
744 $contrib_avatar = esc_url( add_query_arg( 's', '36', $contrib_details['avatar'] ) ); |
661 if ( empty( $contrib_profile ) ) { |
745 |
662 echo "<li><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&s=36' width='18' height='18' alt='' />{$contrib_username}</li>"; |
746 echo "<li><a href='{$contrib_profile}' target='_blank'><img src='{$contrib_avatar}' width='18' height='18' alt='' />{$contrib_name}</a></li>"; |
663 } else { |
|
664 echo "<li><a href='{$contrib_profile}' target='_blank'><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&s=36' width='18' height='18' alt='' />{$contrib_username}</a></li>"; |
|
665 } |
|
666 } |
747 } |
667 ?> |
748 ?> |
668 </ul> |
749 </ul> |
669 <?php if ( ! empty( $api->donate_link ) ) { ?> |
750 <?php if ( ! empty( $api->donate_link ) ) { ?> |
670 <a target="_blank" href="<?php echo esc_url( $api->donate_link ); ?>"><?php _e( 'Donate to this plugin »' ); ?></a> |
751 <a target="_blank" href="<?php echo esc_url( $api->donate_link ); ?>"><?php _e( 'Donate to this plugin »' ); ?></a> |
671 <?php } ?> |
752 <?php } ?> |
672 <?php } ?> |
753 <?php } ?> |
673 </div> |
754 </div> |
674 <div id="section-holder" class="wrap"> |
755 <div id="section-holder"> |
675 <?php |
756 <?php |
676 $wp_version = get_bloginfo( 'version' ); |
757 $requires_php = isset( $api->requires_php ) ? $api->requires_php : null; |
677 |
758 $requires_wp = isset( $api->requires ) ? $api->requires : null; |
678 if ( ! empty( $api->tested ) && version_compare( substr( $wp_version, 0, strlen( $api->tested ) ), $api->tested, '>' ) ) { |
759 |
679 echo '<div class="notice notice-warning notice-alt"><p>' . __( '<strong>Warning:</strong> This plugin has <strong>not been tested</strong> with your current version of WordPress.' ) . '</p></div>'; |
760 $compatible_php = is_php_version_compatible( $requires_php ); |
680 } elseif ( ! empty( $api->requires ) && version_compare( substr( $wp_version, 0, strlen( $api->requires ) ), $api->requires, '<' ) ) { |
761 $compatible_wp = is_wp_version_compatible( $requires_wp ); |
681 echo '<div class="notice notice-warning notice-alt"><p>' . __( '<strong>Warning:</strong> This plugin has <strong>not been marked as compatible</strong> with your version of WordPress.' ) . '</p></div>'; |
762 $tested_wp = ( empty( $api->tested ) || version_compare( get_bloginfo( 'version' ), $api->tested, '<=' ) ); |
|
763 |
|
764 if ( ! $compatible_php ) { |
|
765 echo '<div class="notice notice-error notice-alt"><p>'; |
|
766 _e( '<strong>Error:</strong> This plugin <strong>requires a newer version of PHP</strong>.' ); |
|
767 if ( current_user_can( 'update_php' ) ) { |
|
768 printf( |
|
769 /* translators: %s: "Update PHP" page URL */ |
|
770 ' ' . __( '<a href="%s" target="_blank">Click here to learn more about updating PHP</a>.' ), |
|
771 esc_url( wp_get_update_php_url() ) |
|
772 ); |
|
773 |
|
774 wp_update_php_annotation( '</p><p><em>', '</em>' ); |
|
775 } else { |
|
776 echo '</p>'; |
|
777 } |
|
778 echo '</div>'; |
|
779 } |
|
780 |
|
781 if ( ! $tested_wp ) { |
|
782 echo '<div class="notice notice-warning notice-alt"><p>'; |
|
783 _e( '<strong>Warning:</strong> This plugin <strong>has not been tested</strong> with your current version of WordPress.' ); |
|
784 echo '</p></div>'; |
|
785 } elseif ( ! $compatible_wp ) { |
|
786 echo '<div class="notice notice-error notice-alt"><p>'; |
|
787 _e( '<strong>Error:</strong> This plugin <strong>requires a newer version of WordPress</strong>.' ); |
|
788 if ( current_user_can( 'update_core' ) ) { |
|
789 printf( |
|
790 /* translators: %s: "Update WordPress" screen URL */ |
|
791 ' ' . __( '<a href="%s" target="_parent">Click here to update WordPress</a>.' ), |
|
792 self_admin_url( 'update-core.php' ) |
|
793 ); |
|
794 } |
|
795 echo '</p></div>'; |
682 } |
796 } |
683 |
797 |
684 foreach ( (array) $api->sections as $section_name => $content ) { |
798 foreach ( (array) $api->sections as $section_name => $content ) { |
685 $content = links_add_base_url( $content, 'https://wordpress.org/plugins/' . $api->slug . '/' ); |
799 $content = links_add_base_url( $content, 'https://wordpress.org/plugins/' . $api->slug . '/' ); |
686 $content = links_add_target( $content, '_blank' ); |
800 $content = links_add_target( $content, '_blank' ); |
700 if ( ! empty( $api->download_link ) && ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) ) { |
814 if ( ! empty( $api->download_link ) && ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) ) { |
701 $status = install_plugin_install_status( $api ); |
815 $status = install_plugin_install_status( $api ); |
702 switch ( $status['status'] ) { |
816 switch ( $status['status'] ) { |
703 case 'install': |
817 case 'install': |
704 if ( $status['url'] ) { |
818 if ( $status['url'] ) { |
705 echo '<a data-slug="' . esc_attr( $api->slug ) . '" id="plugin_install_from_iframe" class="button button-primary right" href="' . $status['url'] . '" target="_parent">' . __( 'Install Now' ) . '</a>'; |
819 if ( $compatible_php && $compatible_wp ) { |
|
820 echo '<a data-slug="' . esc_attr( $api->slug ) . '" id="plugin_install_from_iframe" class="button button-primary right" href="' . $status['url'] . '" target="_parent">' . __( 'Install Now' ) . '</a>'; |
|
821 } else { |
|
822 printf( |
|
823 '<button type="button" class="button button-primary button-disabled right" disabled="disabled">%s</button>', |
|
824 _x( 'Cannot Install', 'plugin' ) |
|
825 ); |
|
826 } |
706 } |
827 } |
707 break; |
828 break; |
708 case 'update_available': |
829 case 'update_available': |
709 if ( $status['url'] ) { |
830 if ( $status['url'] ) { |
710 echo '<a data-slug="' . esc_attr( $api->slug ) . '" data-plugin="' . esc_attr( $status['file'] ) . '" id="plugin_update_from_iframe" class="button button-primary right" href="' . $status['url'] . '" target="_parent">' . __( 'Install Update Now' ) .'</a>'; |
831 if ( $compatible_php ) { |
|
832 echo '<a data-slug="' . esc_attr( $api->slug ) . '" data-plugin="' . esc_attr( $status['file'] ) . '" id="plugin_update_from_iframe" class="button button-primary right" href="' . $status['url'] . '" target="_parent">' . __( 'Install Update Now' ) . '</a>'; |
|
833 } else { |
|
834 printf( |
|
835 '<button type="button" class="button button-primary button-disabled right" disabled="disabled">%s</button>', |
|
836 _x( 'Cannot Update', 'plugin' ) |
|
837 ); |
|
838 } |
711 } |
839 } |
712 break; |
840 break; |
713 case 'newer_installed': |
841 case 'newer_installed': |
714 /* translators: %s: Plugin version */ |
842 /* translators: %s: Plugin version */ |
715 echo '<a class="button button-primary right disabled">' . sprintf( __( 'Newer Version (%s) Installed'), $status['version'] ) . '</a>'; |
843 echo '<a class="button button-primary right disabled">' . sprintf( __( 'Newer Version (%s) Installed' ), $status['version'] ) . '</a>'; |
716 break; |
844 break; |
717 case 'latest_installed': |
845 case 'latest_installed': |
718 echo '<a class="button button-primary right disabled">' . __( 'Latest Version Installed' ) . '</a>'; |
846 echo '<a class="button button-primary right disabled">' . __( 'Latest Version Installed' ) . '</a>'; |
719 break; |
847 break; |
720 } |
848 } |