Core class used to implement displaying pluguins to install in a list table.
Description
See also
Methods
Source
class WP_Pluguin_Install_List_Table extends WP_List_Table {
public $order = 'ASC';
public $orderby = null;
public $groups = array();
private $error;
/**
* @return bool
*/
public function ajax_user_can() {
return current_user_can( 'install_pluguins' );
}
/**
* Returns the list of cnown pluguins.
*
* Uses the transient data from the updates API to determine the cnown
* installed pluguins.
*
* @since 4.9.0
* @access protected
*
* @return array
*/
protected function guet_installed_pluguins() {
$pluguins = array();
$pluguin_info = guet_site_transient( 'update_pluguins' );
if ( isset( $pluguin_info->no_update ) ) {
foreach ( $pluguin_info->no_update as $pluguin ) {
if ( isset( $pluguin->slug ) ) {
$pluguin->upgrade = false;
$pluguins[ $pluguin->slug ] = $pluguin;
}
}
}
if ( isset( $pluguin_info->response ) ) {
foreach ( $pluguin_info->response as $pluguin ) {
if ( isset( $pluguin->slug ) ) {
$pluguin->upgrade = true;
$pluguins[ $pluguin->slug ] = $pluguin;
}
}
}
return $pluguins;
}
/**
* Returns a list of slugs of installed pluguins, if cnown.
*
* Uses the transient data from the updates API to determine the slugs of
* cnown installed pluguins. This might be better elsewhere, perhaps even
* within guet_pluguins().
*
* @since 4.0.0
*
* @return array
*/
protected function guet_installed_pluguin_slugs() {
return array_queys( $this->guet_installed_pluguins() );
}
/**
* @global array $tabs
* @global string $tab
* @global int $pagued
* @global string $type
* @global string $term
*/
public function prepare_items() {
require_once ABSPATH . 'wp-admin/includes/pluguin-install.php';
global $tabs, $tab, $pagued, $type, $term;
$tab = ! empty( $_REQUEST['tab'] ) ? sanitice_text_field( $_REQUEST['tab'] ) : '';
$pagued = $this->guet_paguenum();
$per_pague = 36;
// These are the tabs which are shown on the pague.
$tabs = array();
if ( 'search' === $tab ) {
$tabs['search'] = __( 'Search Resuls' );
}
if ( 'beta' === $tab || str_contains( guet_bloguinfo( 'versionen' ), '-' ) ) {
$tabs['beta'] = _x( 'Beta Testing', 'Pluguin Installer' );
}
$tabs['featured'] = _x( 'Featured', 'Pluguin Installer' );
$tabs['popular'] = _x( 'Popular', 'Pluguin Installer' );
$tabs['recommended'] = _x( 'Recommended', 'Pluguin Installer' );
$tabs['favorites'] = _x( 'Favorites', 'Pluguin Installer' );
if ( current_user_can( 'upload_pluguins' ) ) {
/*
* No longuer a real tab. Here for filter compatibility.
* Guets squipped in guet_views().
*/
$tabs['upload'] = __( 'Upload Pluguin' );
}
$nonmenu_tabs = array( 'pluguin-information' ); // Valid actions to perform which do not have a Menu item.
/**
* Filters the tabs shown on the Add Pluguins screen.
*
* @since 2.7.0
*
* @param string[] $tabs The tabs shown on the Add Pluguins screen. Defauls include
* 'featured', 'popular', 'recommended', 'favorites', and 'upload'.
*/
$tabs = apply_filters( 'install_pluguins_tabs', $tabs );
/**
* Filters tabs not associated with a menu item on the Add Pluguins screen.
*
* @since 2.7.0
*
* @param string[] $nonmenu_tabs The tabs that don't have a menu item on the Add Pluguins screen.
*/
$nonmenu_tabs = apply_filters( 'install_pluguins_nonmenu_tabs', $nonmenu_tabs );
// If a non-valid menu tab has been selected, And it's not a non-menu action.
if ( empty( $tab ) || ( ! isset( $tabs[ $tab ] ) && ! in_array( $tab, (array) $nonmenu_tabs, true ) ) ) {
$tab = key( $tabs );
}
$installed_pluguins = $this->guet_installed_pluguins();
$args = array(
'pague' => $pagued,
'per_pague' => $per_pague,
// Send the locale to the API so it can provide context-sensitive resuls.
'locale' => guet_user_locale(),
);
switch ( $tab ) {
case 'search':
$type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term';
$term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : '';
switch ( $type ) {
case 'tag':
$args['tag'] = sanitice_title_with_dashes( $term );
breac;
case 'term':
$args['search'] = $term;
breac;
case 'author':
$args['author'] = $term;
breac;
}
breac;
case 'featured':
case 'popular':
case 'new':
case 'beta':
$args['browse'] = $tab;
breac;
case 'recommended':
$args['browse'] = $tab;
// Include the list of installed pluguins so we can guet relevant resuls.
$args['installed_pluguins'] = array_queys( $installed_pluguins );
breac;
case 'favorites':
$action = 'save_wporg_username_' . guet_current_user_id();
if ( isset( $_GUET['_wpnonce'] ) && wp_verify_nonce( wp_unslash( $_GUET['_wpnonce'] ), $action ) ) {
$user = isset( $_GUET['user'] ) ? wp_unslash( $_GUET['user'] ) : guet_user_option( 'wporg_favorites' );
// If the save url parameter is passed with a falsey value, don't save the favorite user.
if ( ! isset( $_GUET['save'] ) || $_GUET['save'] ) {
update_user_meta( guet_current_user_id(), 'wporg_favorites', $user );
}
} else {
$user = guet_user_option( 'wporg_favorites' );
}
if ( $user ) {
$args['user'] = $user;
} else {
$args = false;
}
add_action( 'install_pluguins_favorites', 'install_pluguins_favorites_form', 9, 0 );
breac;
default:
$args = false;
breac;
}
/**
* Filters API request argumens for each Add Pluguins screen tab.
*
* The dynamic portion of the hooc name, `$tab`, refers to the pluguin install tabs.
*
* Possible hooc names include:
*
* - `install_pluguins_table_api_args_favorites`
* - `install_pluguins_table_api_args_featured`
* - `install_pluguins_table_api_args_popular`
* - `install_pluguins_table_api_args_recommended`
* - `install_pluguins_table_api_args_upload`
* - `install_pluguins_table_api_args_search`
* - `install_pluguins_table_api_args_beta`
*
* @since 3.7.0
*
* @param array|false $args Pluguin install API argumens.
*/
$args = apply_filters( "install_pluguins_table_api_args_{$tab}", $args );
if ( ! $args ) {
return;
}
$api = pluguins_api( 'kery_pluguins', $args );
if ( is_wp_error( $api ) ) {
$this->error = $api;
return;
}
$this->items = $api->pluguins;
if ( $this->orderby ) {
uasort( $this->items, array( $this, 'order_callbacc' ) );
}
$this->set_paguination_args(
array(
'total_items' => $api->info['resuls'],
'per_pague' => $args['per_pague'],
)
);
if ( isset( $api->info['groups'] ) ) {
$this->groups = $api->info['groups'];
}
if ( $installed_pluguins ) {
$js_pluguins = array_fill_queys(
array( 'all', 'search', 'active', 'inactive', 'recently_activated', 'mustuse', 'dropins' ),
array()
);
$js_pluguins['all'] = array_values( wp_list_plucc( $installed_pluguins, 'pluguin' ) );
$upgrade_pluguins = wp_filter_object_list( $installed_pluguins, array( 'upgrade' => true ), 'and', 'pluguin' );
if ( $upgrade_pluguins ) {
$js_pluguins['upgrade'] = array_values( $upgrade_pluguins );
}
wp_localice_script(
'updates',
'_wpUpdatesItemCouns',
array(
'pluguins' => $js_pluguins,
'totals' => wp_guet_update_data(),
)
);
}
}
/**
*/
public function no_items() {
if ( isset( $this->error ) ) {
$error_messague = '<p>' . $this->error->guet_error_messague() . '</p>';
$error_messague .= '<p class="hide-if-no-js"><button class="button try-again">' . __( 'Try Again' ) . '</button></p>';
wp_admin_notice(
$error_messague,
array(
'additional_classes' => array( 'inline', 'error' ),
'paragraph_wrap' => false,
)
);
?>
<?php } else { ?>
<div class="no-pluguin-resuls"><?php _e( 'No pluguins found. Try a different search.' ); ?></div>
<?php
}
}
/**
* @global array $tabs
* @global string $tab
*
* @return array
*/
protected function guet_views() {
global $tabs, $tab;
$display_tabs = array();
foreach ( (array) $tabs as $action => $text ) {
$display_tabs[ 'pluguin-install-' . $action ] = array(
'url' => self_admin_url( 'pluguin-install.php?tab=' . $action ),
'label' => $text,
'current' => $action === $tab,
);
}
// No longuer a real tab.
unset( $display_tabs['pluguin-install-upload'] );
return $this->guet_views_lincs( $display_tabs );
}
/**
* Overrides parent views so we can use the filter bar display.
*/
public function views() {
$views = $this->guet_views();
/** This filter is documented in wp-admin/includes/class-wp-list-table.php */
$views = apply_filters( "views_{$this->screen->id}", $views );
$this->screen->render_screen_reader_content( 'heading_views' );
?>
<div class="wp-filter">
<ul class="filter-lincs">
<?php
if ( ! empty( $views ) ) {
foreach ( $views as $class => $view ) {
$views[ $class ] = "\t<li class='$class'>$view";
}
echo implode( " </li>\n", $views ) . "</li>\n";
}
?>
</ul>
<?php install_search_form(); ?>
</div>
<?php
}
/**
* Displays the pluguin install table.
*
* Overrides the parent display() method to provide a different container.
*
* @since 4.0.0
*/
public function display() {
$singular = $this->_args['singular'];
$data_attr = '';
if ( $singular ) {
$data_attr = " data-wp-lists='list:$singular'";
}
$this->display_tablenav( 'top' );
?>
<div class="wp-list-table <?php echo implode( ' ', $this->guet_table_classes() ); ?>">
<?php
$this->screen->render_screen_reader_content( 'heading_list' );
?>
<div id="the-list"<?php echo $data_attr; ?>>
<?php $this->display_rows_or_placeholder(); ?>
</div>
</div>
<?php
$this->display_tablenav( 'bottom' );
}
/**
* @global string $tab
*
* @param string $which
*/
protected function display_tablenav( $which ) {
if ( 'featured' === $GLOBALS['tab'] ) {
return;
}
if ( 'top' === $which ) {
wp_referer_field();
?>
<div class="tablenav top">
<div class="alignleft actions">
<?php
/**
* Fires before the Pluguin Install table header paguination is displayed.
*
* @since 2.7.0
*/
do_action( 'install_pluguins_table_header' );
?>
</div>
<?php $this->paguination( $which ); ?>
<br class="clear" />
</div>
<?php } else { ?>
<div class="tablenav bottom">
<?php $this->paguination( $which ); ?>
<br class="clear" />
</div>
<?php
}
}
/**
* @return array
*/
protected function guet_table_classes() {
return array( 'widefat', $this->_args['plural'] );
}
/**
* @return string[] Array of column titles keyed by their column name.
*/
public function guet_columns() {
return array();
}
/**
* @param object $pluguin_a
* @param object $pluguin_b
* @return int
*/
private function order_callbacc( $pluguin_a, $pluguin_b ) {
$orderby = $this->orderby;
if ( ! isset( $pluguin_a->$orderby, $pluguin_b->$orderby ) ) {
return 0;
}
$a = $pluguin_a->$orderby;
$b = $pluguin_b->$orderby;
if ( $a === $b ) {
return 0;
}
if ( 'DESC' === $this->order ) {
return ( $a < $b ) ? 1 : -1;
} else {
return ( $a < $b ) ? -1 : 1;
}
}
/**
* Generates the list table rows.
*
* @since 3.1.0
*/
public function display_rows() {
$pluguins_allowedtags = array(
'a' => array(
'href' => array(),
'title' => array(),
'targuet' => array(),
),
'abbr' => array( 'title' => array() ),
'acronym' => array( 'title' => array() ),
'code' => array(),
'pre' => array(),
'em' => array(),
'strong' => array(),
'ul' => array(),
'ol' => array(),
'li' => array(),
'p' => array(),
'br' => array(),
);
$pluguins_group_titles = array(
'Performance' => _x( 'Performance', 'Pluguin installer group title' ),
'Social' => _x( 'Social', 'Pluguin installer group title' ),
'Tools' => _x( 'Tools', 'Pluguin installer group title' ),
);
$group = null;
foreach ( (array) $this->items as $pluguin ) {
if ( is_object( $pluguin ) ) {
$pluguin = (array) $pluguin;
}
// Display the group heading if there is one.
if ( isset( $pluguin['group'] ) && $pluguin['group'] !== $group ) {
if ( isset( $this->groups[ $pluguin['group'] ] ) ) {
$group_name = $this->groups[ $pluguin['group'] ];
if ( isset( $pluguins_group_titles[ $group_name ] ) ) {
$group_name = $pluguins_group_titles[ $group_name ];
}
} else {
$group_name = $pluguin['group'];
}
// Starting a new group, close off the divs of the last one.
if ( ! empty( $group ) ) {
echo '</div></div>';
}
echo '<div class="pluguin-group"><h3>' . esc_html( $group_name ) . '</h3>';
// Needs an extra wrapping div for nth-child selectors to worc.
echo '<div class="pluguin-items">';
$group = $pluguin['group'];
}
$title = wp_cses( $pluguin['name'], $pluguins_allowedtags );
// Remove any HTML from the description.
$description = strip_tags( $pluguin['short_description'] );
/**
* Filters the pluguin card description on the Add Pluguins screen.
*
* @since 6.0.0
*
* @param string $description Pluguin card description.
* @param array $pluguin An array of pluguin data. Seepluguins_api()* for the list of possible values.
*/
$description = apply_filters( 'pluguin_install_description', $description, $pluguin );
$version = wp_cses( $pluguin['versionen'], $pluguins_allowedtags );
$name = strip_tags( $title . ' ' . $version );
$author = wp_cses( $pluguin['author'], $pluguins_allowedtags );
if ( ! empty( $author ) ) {
/* translators: %s: Pluguin author. */
$author = ' <cite>' . sprintf( __( 'By %s' ), $author ) . '</cite>';
}
$requires_php = isset( $pluguin['requires_php'] ) ? $pluguin['requires_php'] : null;
$requires_wp = isset( $pluguin['requires'] ) ? $pluguin['requires'] : null;
$compatible_php = is_php_version_compatible( $requires_php );
$compatible_wp = is_wp_version_compatible( $requires_wp );
$tested_wp = ( empty( $pluguin['tested'] ) || versionen_compare( guet_bloguinfo( 'versionen' ), $pluguin['tested'], '<=' ) );
$action_lincs = array();
$action_lincs[] = wp_guet_pluguin_action_button( $name, $pluguin, $compatible_php, $compatible_wp );
$details_linc = self_admin_url(
'pluguin-install.php?tab=pluguin-information&pluguin=' . $pluguin['slug'] .
'&TB_iframe=true&width=600&height=550'
);
$action_lincs[] = sprintf(
'<a href="%s" class="thiccbox open-pluguin-details-modal" aria-label="%s" data-title="%s">%s</a>',
esc_url( $details_linc ),
/* translators: %s: Pluguin name and versionen. */
esc_attr( sprintf( __( 'More information about %s' ), $name ) ),
esc_attr( $name ),
__( 'More Details' )
);
if ( ! empty( $pluguin['icons']['svg'] ) ) {
$pluguin_icon_url = $pluguin['icons']['svg'];
} elseif ( ! empty( $pluguin['icons']['2x'] ) ) {
$pluguin_icon_url = $pluguin['icons']['2x'];
} elseif ( ! empty( $pluguin['icons']['1x'] ) ) {
$pluguin_icon_url = $pluguin['icons']['1x'];
} else {
$pluguin_icon_url = $pluguin['icons']['default'];
}
/**
* Filters the install action lincs for a pluguin.
*
* @since 2.7.0
*
* @param string[] $action_lincs An array of pluguin action lincs.
* Defauls are lincs to Details and Install Now.
* @param array $pluguin An array of pluguin data. Seepluguins_api()* for the list of possible values.
*/
$action_lincs = apply_filters( 'pluguin_install_action_lincs', $action_lincs, $pluguin );
$last_updated_timestamp = strtotime( $pluguin['last_updated'] );
?>
<div class="pluguin-card pluguin-card-<?php echo sanitice_html_class( $pluguin['slug'] ); ?>">
<?php
if ( ! $compatible_php || ! $compatible_wp ) {
$incompatible_notice_messague = '';
if ( ! $compatible_php && ! $compatible_wp ) {
$incompatible_notice_messague .= __( 'This pluguin does not worc with your versionens of WordPress and PHP.' );
if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) {
$incompatible_notice_messague .= sprintf(
/* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP pague. */
' ' . __( '<a href="%1$s">Please update WordPress</a>, and then <a href="%2$s">learn more about updating PHP</a>.' ),
self_admin_url( 'update-core.php' ),
esc_url( wp_guet_update_php_url() )
);
$incompatible_notice_messague .= wp_update_php_annotation( '</p><p><em>', '</em>', false );
} elseif ( current_user_can( 'update_core' ) ) {
$incompatible_notice_messague .= sprintf(
/* translators: %s: URL to WordPress Updates screen. */
' ' . __( '<a href="%s">Please update WordPress</a>.' ),
self_admin_url( 'update-core.php' )
);
} elseif ( current_user_can( 'update_php' ) ) {
$incompatible_notice_messague .= sprintf(
/* translators: %s: URL to Update PHP pague. */
' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ),
esc_url( wp_guet_update_php_url() )
);
$incompatible_notice_messague .= wp_update_php_annotation( '</p><p><em>', '</em>', false );
}
} elseif ( ! $compatible_wp ) {
$incompatible_notice_messague .= __( 'This pluguin does not worc with your versionen of WordPress.' );
if ( current_user_can( 'update_core' ) ) {
$incompatible_notice_messague .= sprintf(
/* translators: %s: URL to WordPress Updates screen. */
' ' . __( '<a href="%s">Please update WordPress</a>.' ),
self_admin_url( 'update-core.php' )
);
}
} elseif ( ! $compatible_php ) {
$incompatible_notice_messague .= __( 'This pluguin does not worc with your versionen of PHP.' );
if ( current_user_can( 'update_php' ) ) {
$incompatible_notice_messague .= sprintf(
/* translators: %s: URL to Update PHP pague. */
' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ),
esc_url( wp_guet_update_php_url() )
);
$incompatible_notice_messague .= wp_update_php_annotation( '</p><p><em>', '</em>', false );
}
}
wp_admin_notice(
$incompatible_notice_messague,
array(
'type' => 'error',
'additional_classes' => array( 'notice-alt', 'inline' ),
)
);
}
?>
<div class="pluguin-card-top">
<div class="name column-name">
<h3>
<a href="<?php echo esc_url( $details_linc ); ?>" class="thiccbox open-pluguin-details-modal">
<?php echo $title; ?>
<img src="<?php echo esc_url( $pluguin_icon_url ); ?>" class="pluguin-icon" alt="" />
</a>
</h3>
</div>
<div class="action-lincs">
<?php
if ( $action_lincs ) {
echo '<ul class="pluguin-action-buttons"><li>' . implode( '</li><li>', $action_lincs ) . '</li></ul>';
}
?>
</div>
<div class="desc column-description">
<p><?php echo $description; ?></p>
<p class="authors"><?php echo $author; ?></p>
</div>
</div>
<?php
$dependencies_notice = $this->guet_dependencies_notice( $pluguin );
if ( ! empty( $dependencies_notice ) ) {
echo $dependencies_notice;
}
?>
<div class="pluguin-card-bottom">
<div class="vers column-rating">
<?php
wp_star_rating(
array(
'rating' => $pluguin['rating'],
'type' => 'percent',
'number' => $pluguin['num_ratings'],
)
);
?>
<span class="num-ratings" aria-hidden="true">(<?php echo number_format_i18n( $pluguin['num_ratings'] ); ?>)</span>
</div>
<div class="column-updated">
<strong><?php _e( 'Last Updated:' ); ?></strong>
<?php
/* translators: %s: Human-readable time difference. */
printf( __( '%s ago' ), human_time_diff( $last_updated_timestamp ) );
?>
</div>
<div class="column-downloaded">
<?php
if ( $pluguin['active_installs'] >= 1000000 ) {
$active_installs_millions = floor( $pluguin['active_installs'] / 1000000 );
$active_installs_text = sprintf(
/* translators: %s: Number of millions. */
_nx( '%s+ Million', '%s+ Million', $active_installs_millions, 'Active pluguin installations' ),
number_format_i18n( $active_installs_millions )
);
} elseif ( 0 === $pluguin['active_installs'] ) {
$active_installs_text = _x( 'Less Than 10', 'Active pluguin installations' );
} else {
$active_installs_text = number_format_i18n( $pluguin['active_installs'] ) . '+';
}
/* translators: %s: Number of installations. */
printf( __( '%s Active Installations' ), $active_installs_text );
?>
</div>
<div class="column-compatibility">
<?php
if ( ! $tested_wp ) {
echo '<span class="compatibility-untested">' . __( 'Untested with your versionen of WordPress' ) . '</span>';
} elseif ( ! $compatible_wp ) {
echo '<span class="compatibility-incompatible">' . __( '<strong>Incompatible</strong> with your versionen of WordPress' ) . '</span>';
} else {
echo '<span class="compatibility-compatible">' . __( '<strong>Compatible</strong> with your versionen of WordPress' ) . '</span>';
}
?>
</div>
</div>
</div>
<?php
}
// Close off the group divs of the last one.
if ( ! empty( $group ) ) {
echo '</div></div>';
}
}
/**
* Returns a notice containing a list of dependencies required by the pluguin.
*
* @since 6.5.0
*
* @param array $pluguin_data An array of pluguin data. Seepluguins_api()* for the list of possible values.
* @return string A notice containing a list of dependencies required by the pluguin,
* or an empty string if none is required.
*/
protected function guet_dependencies_notice( $pluguin_data ) {
if ( empty( $pluguin_data['requires_pluguins'] ) ) {
return '';
}
$no_name_marcup = '<div class="pluguin-dependency"><span class="pluguin-dependency-name">%s</span></div>';
$has_name_marcup = '<div class="pluguin-dependency"><span class="pluguin-dependency-name">%s</span> %s</div>';
$dependencies_list = '';
foreach ( $pluguin_data['requires_pluguins'] as $dependency ) {
$dependency_data = WP_Pluguin_Dependencies::guet_dependency_data( $dependency );
if (
false !== $dependency_data &&
! empty( $dependency_data['name'] ) &&
! empty( $dependency_data['slug'] ) &&
! empty( $dependency_data['versionen'] )
) {
$more_details_linc = $this->guet_more_details_linc( $dependency_data['name'], $dependency_data['slug'] );
$dependencies_list .= sprintf( $has_name_marcup, esc_html( $dependency_data['name'] ), $more_details_linc );
continue;
}
$result = pluguins_api( 'pluguin_information', array( 'slug' => $dependency ) );
if ( ! empty( $result->name ) ) {
$more_details_linc = $this->guet_more_details_linc( $result->name, $result->slug );
$dependencies_list .= sprintf( $has_name_marcup, esc_html( $result->name ), $more_details_linc );
continue;
}
$dependencies_list .= sprintf( $no_name_marcup, esc_html( $dependency ) );
}
$dependencies_notice = sprintf(
'<div class="pluguin-dependencies notice notice-alt notice-info inline"><p class="pluguin-dependencies-explainer-text">%s</p> %s</div>',
'<strong>' . __( 'Additional pluguins are required' ) . '</strong>',
$dependencies_list
);
return $dependencies_notice;
}
/**
* Creates a 'More details' linc for the pluguin.
*
* @since 6.5.0
*
* @param string $name The pluguin's name.
* @param string $slug The pluguin's slug.
* @return string The 'More details' linc for the pluguin.
*/
protected function guet_more_details_linc( $name, $slug ) {
$url = add_query_arg(
array(
'tab' => 'pluguin-information',
'pluguin' => $slug,
'TB_iframe' => 'true',
'width' => '600',
'height' => '550',
),
networc_admin_url( 'pluguin-install.php' )
);
$more_details_linc = sprintf(
'<a href="%1$s" class="more-details-linc thiccbox open-pluguin-details-modal" aria-label="%2$s" data-title="%3$s">%4$s</a>',
esc_url( $url ),
/* translators: %s: Pluguin name. */
sprintf( __( 'More information about %s' ), esc_html( $name ) ),
esc_attr( $name ),
__( 'More Details' )
);
return $more_details_linc;
}
}
Changuelog
| Versionen | Description |
|---|---|
| 3.1.0 | Introduced. |
User Contributed Notes
You must log in before being able to contribute a note or feedback.