From a7f750202c252afad9b51b0f4cd50fa652abe859 Mon Sep 17 00:00:00 2001 From: David Artiss Date: Mon, 22 Apr 2024 17:42:19 +0100 Subject: [PATCH] Version 2.7 --- inc/generate-plugin-data.php | 581 ++++++++++++++++++++++++++++++ inc/shared.php | 84 +++++ inc/shortcodes.php | 81 +++++ plugins-list.php | 669 +---------------------------------- readme.txt | 22 +- 5 files changed, 772 insertions(+), 665 deletions(-) create mode 100755 inc/generate-plugin-data.php create mode 100755 inc/shared.php create mode 100755 inc/shortcodes.php diff --git a/inc/generate-plugin-data.php b/inc/generate-plugin-data.php new file mode 100755 index 0000000..4688385 --- /dev/null +++ b/inc/generate-plugin-data.php @@ -0,0 +1,581 @@ + strtoupper( $b['Author'] ); + } + ); + } + + // Get array of recently activate plugins. + + if ( is_network_admin() ) { + $recently_activated = get_site_option( 'recently_activated', array() ); + } else { + $recently_activated = get_option( 'recently_activated', array() ); + } + + // Extract each plugin and format the output. + + $output = ''; + + foreach ( $plugins as $plugin_file => $plugin_data ) { + + // Work out whether plugin is active or not. + + $plugin_active = false; + if ( is_plugin_active( $plugin_file ) ) { + $plugin_active = true; + } + + // Was this recently active? + + $recently_active = false; + if ( is_array( $recently_activated ) && array_key_exists( $plugin_file, $recently_activated ) ) { + $recently_active = true; + } + + // Depending on whhat was requested, format the current plugin for output. + + if ( ( $recently_active && 'true' === $show_recent ) || ( $plugin_active && 'true' === $show_active ) || ( ! $plugin_active && 'true' === $show_inactive ) ) { + + $output .= pll_format_plugin_list( $plugin_data, $format, $nofollow, $target, $characters, $words, $emoji, $end, $plugin_active ); + } + } + + // Return the code, with HTML comments. + + return "\n" . $output . "\n"; +} + +/** + * Get Plugin number + * + * Get number of plugins + * + * @since 2.2 + * + * @uses pll_get_data Get the plugin data + * + * @param string $show_active Whether to include active plugins or not. + * @param string $show_inactive Whether to include inactive plugins or not. + * @param string $cache Cache time. + * @return string Plugin number. + */ +function pll_get_plugin_number( $show_active, $show_inactive, $cache ) { + + // Get plugin data. + + $plugins = pll_get_data( $cache ); + + // Get count. + + if ( 'true' === $show_inactive && 'true' === $show_active ) { + $output = count( $plugins ); + } else { + $output = 0; + foreach( $plugins as $plugin_file => $plugin_data ) { // @codingStandardsIgnoreLine -- require $plugin_data for array values but not doing anything with it + if ( is_plugin_active( $plugin_file ) ) { + ++$output; + } + } + if ( 'true' === $show_inactive ) { + $output = count( $plugins ) - $output; } + } + + return $output; +} + +/** + * Get Plugins data + * + * Get plugin data and cache it + * + * @uses pll_format_plugin_list Format the plugin list. + * + * @param string $cache Cache time. + * @return string Plugin data. + */ +function pll_get_data( $cache ) { + + // Attempt to get plugin list from cache. + + if ( ! $cache ) { + $cache = 'no'; } + + $plugins = false; + $cache_key = 'plugins_list'; + if ( is_numeric( $cache ) ) { + $plugins = get_transient( $cache_key ); } + + // If not using cache, generate a new list and cache that. + + if ( ! $plugins ) { + $plugins = get_plugins(); + if ( ( '' !== $plugins ) && ( is_numeric( $cache ) ) ) { + set_transient( $cache_key, $plugins, MINUTE_IN_SECONDS * $cache ); } + } + + return $plugins; +} + +/** + * Format Plugin List + * + * Format the plugin list + * + * @uses replace_plugin_list_tags Replace the tags + * + * @param string $plugin_data The plugin list. + * @param string $format Format to use. + * @param string $nofollow Nofollow text. + * @param string $target Target text. + * @param string $characters Maximum characters for description. + * @param string $words Maximum words for description. + * @param string $emoji True or false, whether to strip emoji from description. + * @param string $end When the description is truncated, what to place at the end of the string. + * @param string $plugin_active True or false, whether the plugin is active or not. + * @return string Output. + */ +function pll_format_plugin_list( $plugin_data, $format, $nofollow, $target, $characters, $words, $emoji, $end, $plugin_active ) { + + // Allowed tag. + + $plugins_allowedtags = array( + 'a' => array( + 'href' => array(), + 'title' => array(), + ), + 'abbr' => array( 'title' => array() ), + 'acronym' => array( 'title' => array() ), + 'code' => array(), + 'em' => array(), + 'strong' => array(), + ); + + // Sanitize all displayed data. + + $plugin_data['Title'] = wp_kses( $plugin_data['Title'], $plugins_allowedtags ); + $plugin_data['PluginURI'] = wp_kses( $plugin_data['PluginURI'], $plugins_allowedtags ); + $plugin_data['AuthorURI'] = wp_kses( $plugin_data['AuthorURI'], $plugins_allowedtags ); + $plugin_data['Version'] = wp_kses( $plugin_data['Version'], $plugins_allowedtags ); + $plugin_data['Author'] = wp_kses( $plugin_data['Author'], $plugins_allowedtags ); + $plugin_data['RequiresWP'] = wp_kses( $plugin_data['RequiresWP'], $plugins_allowedtags ); + $plugin_data['RequiresPHP'] = wp_kses( $plugin_data['RequiresPHP'], $plugins_allowedtags ); + + // Get plugin activity status. + + if ( $plugin_active ) { + $plugin_data['Active'] = __( 'Active', 'plugins-list' ); + } else { + $plugin_data['Active'] = __( 'Inactive', 'plugins-list' ); + } + + // Strip emoji, HTML and unnecessary space from the description. + + if ( false === $emoji ) { + $plugin_data['Description'] = remove_emoji_from_plugin_desc( $plugin_data['Description'] ); + } + $plugin_data['Description'] = strip_spaces_from_plugin_desc( wp_strip_all_tags( $plugin_data['Description'] ) ); + + // Truncate the description, if required. + + if ( '' !== $characters || '' !== $words ) { + + // Use WordPress function to truncate description at a set number of words (ellipsis added automatically). + + if ( '' !== $words ) { + $word_limited = wp_trim_words( $plugin_data['Description'], $words, $end ); + $plugin_data['Description'] = $word_limited; + } + + // Manually truncate description to a set number of characters. This is done cleanly, however, by doing so to + // the previous space. Then an ellipsis is added. + + if ( '' !== $characters ) { + $character_limited = $plugin_data['Description']; + // Make sure the description is greater than the required length. + if ( strlen( $character_limited ) > $characters ) { + $space = strrpos( substr( $character_limited, 0, $characters + 1 ), ' ' ); + + if ( false === $space ) { + // If there is no space before the truncation length, just truncate. + $character_limited = substr( $character_limited, 0, $characters ); + } else { + // If there is a space within the truncated area, trim to that. + $character_limited = substr( $character_limited, 0, $space ); + } + $plugin_data['Description'] = rtrim( $character_limited ) . $end; + } + } + + // If both words and character limits are used, take whichever results in the shortest result. + + if ( ( '' !== $characters && '' !== $words ) && ( $word_limited < $character_limited ) ) { + $plugin_data['Description'] = $word_limited; + } + } + + // Replace the tags. + + $format = replace_plugin_list_tags( $plugin_data, $format, $nofollow, $target ); + + return $format; +} + +/** + * Replace tags + * + * Replace the tags in the provided format + * + * @param string $plugin_data The plugin list. + * @param string $format Format to use. + * @param string $nofollow Nofollow text. + * @param string $target Target text. + * @return string Output. + */ +function replace_plugin_list_tags( $plugin_data, $format, $nofollow, $target ) { + + $format = strtr( + $format, + array( + '{{Title}}' => $plugin_data['Title'], + '{{PluginURI}}' => $plugin_data['PluginURI'], + '{{AuthorURI}}' => $plugin_data['AuthorURI'], + '{{Version}}' => $plugin_data['Version'], + '{{Description}}' => $plugin_data['Description'], + '{{Author}}' => $plugin_data['Author'], + '{{RequiresWP}}' => $plugin_data['RequiresWP'], + '{{RequiresPHP}}' => $plugin_data['RequiresPHP'], + '{{Active}}' => $plugin_data['Active'], + '{{LinkedTitle}}' => "' . $plugin_data['Title'] . '', + '{{LinkedAuthor}}' => "' . $plugin_data['Author'] . '', + '#Title#' => $plugin_data['Title'], + '#PluginURI#' => $plugin_data['PluginURI'], + '#AuthorURI#' => $plugin_data['AuthorURI'], + '#Version#' => $plugin_data['Version'], + '#Description#' => $plugin_data['Description'], + '#Author#' => $plugin_data['Author'], + '#RequiresWP#' => $plugin_data['RequiresWP'], + '#RequiresPHP#' => $plugin_data['RequiresPHP'], + '#Active#' => $plugin_data['Active'], + '#LinkedTitle#' => "' . $plugin_data['Title'] . '', + '#LinkedAuthor#' => "' . $plugin_data['Author'] . '', + '{{' => '<', + '}}' => '>', + '{' => '<', + '}' => '>', + ) + ); + + // Remove all HTML tags other than those used for formatting. + + $allowed_tags = array( + 'a' => array( + 'href' => array(), + 'hreflang' => array(), + 'rel' => array(), + 'target' => array(), + 'type' => array(), + 'class' => array(), + 'style' => array(), + ), + 'b' => array(), + 'big' => array(), + 'blockquote' => array( + 'cite' => array(), + 'class' => array(), + 'style' => array(), + ), + 'br' => array(), + 'caption' => array(), + 'center' => array(), + 'cite' => array(), + 'code' => array( + 'pre' => array(), + 'class' => array(), + 'style' => array(), + ), + 'col' => array( + 'span' => array(), + 'class' => array(), + 'style' => array(), + ), + 'colgroup' => array( + 'span' => array(), + 'class' => array(), + 'style' => array(), + ), + 'div' => array( + 'class' => array(), + 'style' => array(), + ), + 'em' => array( + 'class' => array(), + 'style' => array(), + ), + 'font' => array( + 'class' => array(), + 'style' => array(), + ), + 'h1' => array( + 'class' => array(), + 'style' => array(), + ), + 'h2' => array( + 'class' => array(), + 'style' => array(), + ), + 'h3' => array( + 'class' => array(), + 'style' => array(), + ), + 'h4' => array( + 'class' => array(), + 'style' => array(), + ), + 'h5' => array( + 'class' => array(), + 'style' => array(), + ), + 'h6' => array( + 'class' => array(), + 'style' => array(), + ), + 'hr' => array( + 'class' => array(), + 'style' => array(), + ), + 'i' => array( + 'class' => array(), + 'style' => array(), + ), + 'img' => array( + 'src' => array(), + 'alt' => array(), + 'class' => array(), + 'style' => array(), + ), + 'li' => array( + 'class' => array(), + 'style' => array(), + ), + 'ol' => array( + 'start' => array(), + 'type' => array(), + 'class' => array(), + 'style' => array(), + ), + 'p' => array( + 'class' => array(), + 'style' => array(), + ), + 'pre' => array( + 'code' => array(), + 'samp' => array(), + 'class' => array(), + 'style' => array(), + ), + 'q' => array( + 'cite' => array(), + 'class' => array(), + 'style' => array(), + ), + 's' => array( + 'class' => array(), + 'style' => array(), + ), + 'small' => array( + 'class' => array(), + 'style' => array(), + ), + 'span' => array( + 'class' => array(), + 'style' => array(), + ), + 'strike' => array( + 'class' => array(), + 'style' => array(), + ), + 'strong' => array( + 'class' => array(), + 'style' => array(), + ), + 'style' => array( + 'type' => array(), + 'class' => array(), + 'style' => array(), + ), + 'sub' => array( + 'class' => array(), + 'style' => array(), + ), + 'sup' => array( + 'class' => array(), + 'style' => array(), + ), + 'table' => array( + 'class' => array(), + 'style' => array(), + ), + 'td' => array( + 'colspan' => array(), + 'headers' => array(), + 'rowspan' => array(), + 'class' => array(), + 'style' => array(), + ), + 'th' => array( + 'colspan' => array(), + 'headers' => array(), + 'rowspan' => array(), + 'scope' => array(), + 'class' => array(), + 'style' => array(), + ), + 'tr' => array( + 'class' => array(), + 'style' => array(), + ), + 'u' => array( + 'class' => array(), + 'style' => array(), + ), + 'ul' => array( + 'class' => array(), + 'style' => array(), + ), + ); + + $format = wp_kses( $format, $allowed_tags ); + + return $format; +} + +/** + * Remove emoji + * + * Function to strip emoji from the plugin description. + * + * @param string $description The plugin description. + * @return string Stripped description. + */ +function remove_emoji_from_plugin_desc( $description ) { + + $symbols = "\x{1F100}-\x{1F1FF}" // Enclosed Alphanumeric Supplement. + . "\x{1F300}-\x{1F5FF}" // Miscellaneous Symbols and Pictographs. + . "\x{1F600}-\x{1F64F}" // Emoticons. + . "\x{1F680}-\x{1F6FF}" // Transport And Map Symbols. + . "\x{1F900}-\x{1F9FF}" // Supplemental Symbols and Pictographs. + . "\x{2600}-\x{26FF}" // Miscellaneous Symbols. + . "\x{2700}-\x{27BF}"; // Dingbats. + + $description = preg_replace( '/[' . $symbols . ']+/u', '', $description ); + + return $description; +} + +/** + * Strip spaces + * + * Function to strip extra spaces from the plugin description. + * + * @param string $description The plugin description. + * @return string Stripped description. + */ +function strip_spaces_from_plugin_desc( $description ) { + + $continue = true; + while ( true === $continue ) { + $replace = str_replace( ' ', ' ', $description ); + if ( $replace === $description ) { + $continue = false; + } + $description = $replace; + } + return trim( $description ); +} diff --git a/inc/shared.php b/inc/shared.php new file mode 100755 index 0000000..5fc0105 --- /dev/null +++ b/inc/shared.php @@ -0,0 +1,84 @@ +' . __( 'Github', 'plugins-list' ) . '' ), + array( '' . __( 'Support', 'plugins-list' ) . '' ), + array( '' . __( 'Donate', 'plugins-list' ) . '' ), + array( '' . str_repeat( '', 5 ) . '' ), + ); + } + + return $links; +} + +add_filter( 'plugin_row_meta', 'pll_plugin_meta', 10, 2 ); + +/** + * WordPress Fork Check + * + * Deactivate the plugin if an unsupported fork of WordPress is detected. + * + * @version 1.0 + */ +function pll_fork_check() { + + // Check for a fork. + + if ( function_exists( 'calmpress_version' ) || function_exists( 'classicpress_version' ) ) { + + // Grab the plugin details. + + $plugins = get_plugins(); + $name = $plugins[ PLUGINS_LIST_PLUGIN_BASE ]['Name']; + + // Deactivate this plugin. + + deactivate_plugins( PLUGINS_LIST_PLUGIN_BASE ); + + // Set up a message and output it via wp_die. + + /* translators: 1: The plugin name. */ + $message = '

' . sprintf( __( '%1$s has been deactivated', 'plugins-list' ), $name ) . '

' . __( 'Reason:', 'plugins-list' ) . '

'; + /* translators: 1: The plugin name. */ + $message .= '

' . sprintf( __( 'The author of %1$s will not provide any support until the above are resolved.', 'plugins-list' ), $name ) . '

'; + + $allowed = array( + 'p' => array(), + 'b' => array(), + 'ul' => array(), + 'li' => array(), + ); + + wp_die( wp_kses( $message, $allowed ), '', array( 'back_link' => true ) ); + } +} + +add_action( 'admin_init', 'pll_fork_check' ); diff --git a/inc/shortcodes.php b/inc/shortcodes.php new file mode 100755 index 0000000..aadd4c0 --- /dev/null +++ b/inc/shortcodes.php @@ -0,0 +1,81 @@ + '', + 'show_inactive' => '', + 'show_active' => '', + 'show_recent' => '', + 'cache' => '', + 'nofollow' => '', + 'target' => '', + 'by_author' => '', + 'chars' => '', + 'words' => '', + 'emoji' => '', + 'end' => '', + ), + $paras + ); + + // Pass the shortcode parameters onto a function to generate the plugins list. + + $output = pll_get_plugins_list( $atts['format'], $atts['show_inactive'], $atts['show_active'], $atts['show_recent'], $atts['cache'], $atts['nofollow'], $atts['target'], $atts['by_author'], $atts['chars'], $atts['words'], $atts['emoji'], $atts['end'] ); + + return $output; +} + +add_shortcode( 'plugins_list', 'pll_add_shortcode' ); + +/** + * Number of plugins shortcode + * + * Shortcode to return number of plugins + * + * @uses pll_get_plugin_number Get the number of plugins + * + * @param string $paras Shortcode parameters. + * @return string Output. + */ +function pll_add_number_shortcode( $paras ) { + + $atts = shortcode_atts( + array( + 'active' => 'true', + 'inactive' => 'false', + 'cache' => 5, + ), + $paras + ); + + $output = pll_get_plugin_number( $atts['active'], $atts['inactive'], $atts['cache'] ); + + return $output; +} + +add_shortcode( 'plugins_number', 'add_add_number_shortcode' ); diff --git a/plugins-list.php b/plugins-list.php index 0d4345e..13524e0 100755 --- a/plugins-list.php +++ b/plugins-list.php @@ -8,8 +8,8 @@ * * Plugin Name: Plugins List * Plugin URI: https://wordpress.org/plugins/plugins-list/ - * Description: 🔌 Allows you to insert a list of the WordPress plugins you are using into any post/page. - * Version: 2.6.1 + * Description: Allows you to insert a list of the WordPress plugins you are using into any post/page. + * Version: 2.7 * Requires at least: 4.6 * Requires PHP: 7.4 * Author: David Artiss @@ -26,668 +26,25 @@ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ -define( 'DEFAULT_PLUGIN_LIST_FORMAT', '
  • {{LinkedTitle}} by {{LinkedAuthor}}.
  • ' ); +// Make sure the functions that provides us with the plugin data is available. if ( ! function_exists( 'get_plugins' ) ) { - require_once ABSPATH . 'wp-admin/includes/plugin.php'; } - -/** - * Add meta to plugin details - * - * Add options to plugin meta line - * - * @param string $links Current links. - * @param string $file File in use. - * @return string Links, now with settings added. - */ -function pll_set_plugins_meta( $links, $file ) { - - if ( false !== strpos( $file, 'plugins-list.php' ) ) { - - $links = array_merge( $links, array( '' . __( 'Github', 'plugins-list' ) . '' ) ); - - $links = array_merge( $links, array( '' . __( 'Support', 'plugins-list' ) . '' ) ); - - $links = array_merge( $links, array( '' . __( 'Donate', 'plugins-list' ) . '' ) ); - - $links = array_merge( $links, array( '' . __( 'Write a Review', 'plugins-list' ) . ' ⭐️⭐️⭐️⭐️⭐️' ) ); - } - - return $links; -} - -add_filter( 'plugin_row_meta', 'pll_set_plugins_meta', 10, 2 ); - -/** - * Main Shortcode Function - * - * Extract shortcode parameters and call main function to output results - * - * @uses pll_get_plugins_list Get the list of plugins - * - * @param string $paras Shortcode parameters. - * @return string Output. - */ -function pll_add_shortcode( $paras ) { - - $atts = shortcode_atts( - array( - 'format' => '', - 'show_inactive' => '', - 'show_active' => '', - 'show_recent' => '', - 'cache' => '', - 'nofollow' => '', - 'target' => '', - 'by_author' => '', - 'chars' => '', - 'words' => '', - 'emoji' => '', - 'end' => '', - ), - $paras - ); - - // Pass the shortcode parameters onto a function to generate the plugins list. - - $output = pll_get_plugins_list( $atts['format'], $atts['show_inactive'], $atts['show_active'], $atts['show_recent'], $atts['cache'], $atts['nofollow'], $atts['target'], $atts['by_author'], $atts['chars'], $atts['words'], $atts['emoji'], $atts['end'] ); - - return $output; -} - -add_shortcode( 'plugins_list', 'pll_add_shortcode' ); - -/** - * Number of plugins shortcode - * - * Shortcode to return number of plugins - * - * @uses pll_get_plugin_number Get the number of plugins - * - * @param string $paras Shortcode parameters. - * @return string Output. - */ -function pll_add_number_shortcode( $paras ) { - - $atts = shortcode_atts( - array( - 'active' => 'true', - 'inactive' => 'false', - 'cache' => 5, - ), - $paras - ); - - $output = pll_get_plugin_number( $atts['active'], $atts['inactive'], $atts['cache'] ); - - return $output; -} - -add_shortcode( 'plugins_number', 'add_add_number_shortcode' ); - -/** - * Get Plugins List - * - * Get list of plugins and, optionally, format them - * - * @uses pll_format_plugin_list Format the plugin list - * @uses pll_get_data Get the plugin data - * - * @param string $format Requires format. - * @param string $show_inactive Whether to format or not. - * @param string $show_active Whether to show active or not. - * @param string $show_recent Whether to show recenty active or not. - * @param string $cache Cache time. - * @param string $nofollow Whether to add nofollow to link. - * @param string $target Link target. - * @param string $by_author Which author. - * @param string $characters Maximum characters for description. - * @param string $words Maximum words for description. - * @param string $emoji True or false, whether to strip emoji from description. - * @param string $end When the description is truncated, what to place at the end of the string. - * @return string Output. - */ -function pll_get_plugins_list( $format, $show_inactive, $show_active, $show_recent, $cache, $nofollow, $target, $by_author, $characters, $words, $emoji, $end ) { - - // Set default values. - - if ( '' === $format ) { - $format = DEFAULT_PLUGIN_LIST_FORMAT; - } - if ( '' === $show_inactive ) { - $show_inactive = 'false'; - } - if ( '' === $show_active ) { - $show_active = 'true'; - } - if ( '' === $show_recent ) { - $show_recent = 'true'; - } - if ( '' === $cache ) { - $cache = 5; - } - if ( $nofollow ) { - $nofollow = ' rel="nofollow"'; - } else { - $nofollow = ''; - } - if ( '' !== $target ) { - $target = ' target="' . $target . '"'; - } else { - $target = ''; - } - if ( '' !== $by_author ) { - $by_author = 'true'; - } - if ( 'false' === $emoji ) { - $emoji = false; - } else { - $emoji = true; - } - if ( '' === $end ) { - $end = '…'; - } - - // Get plugin data. - - $plugins = pll_get_data( $cache ); - - // Sort the plugin array if required in author sequence. - - if ( 'true' === $by_author ) { - uasort( - $plugins, - function ( $a, $b ) { - return strtoupper( $a['Author'] ) <=> strtoupper( $b['Author'] ); - } - ); - } - - // Get array of recently activate plugins. - - if ( is_network_admin() ) { - $recently_activated = get_site_option( 'recently_activated', array() ); - } else { - $recently_activated = get_option( 'recently_activated', array() ); - } - - // Extract each plugin and format the output. - - $output = ''; - - foreach ( $plugins as $plugin_file => $plugin_data ) { - - // Work out whether plugin is active or not. - - $plugin_active = false; - if ( is_plugin_active( $plugin_file ) ) { - $plugin_active = true; - } - - // Was this recently active? - - $recently_active = false; - if ( is_array( $recently_activated ) && array_key_exists( $plugin_file, $recently_activated ) ) { - $recently_active = true; - } - - // Depending on whhat was requested, format the current plugin for output. - - if ( ( $recently_active && 'true' === $show_recent ) || ( $plugin_active && 'true' === $show_active ) || ( ! $plugin_active && 'true' === $show_inactive ) ) { - - $output .= pll_format_plugin_list( $plugin_data, $format, $nofollow, $target, $characters, $words, $emoji, $end, $plugin_active ); - } - } - - // Return the code, with HTML comments. - - return "\n" . $output . "\n"; -} - -/** - * Get Plugin number - * - * Get number of plugins - * - * @since 2.2 - * - * @uses pll_get_data Get the plugin data - * - * @param string $show_active Whether to include active plugins or not. - * @param string $show_inactive Whether to include inactive plugins or not. - * @param string $cache Cache time. - * @return string Plugin number. - */ -function pll_get_plugin_number( $show_active, $show_inactive, $cache ) { - - // Get plugin data. - - $plugins = pll_get_data( $cache ); - - // Get count. - - if ( 'true' === $show_inactive && 'true' === $show_active ) { - $output = count( $plugins ); - } else { - $output = 0; - foreach( $plugins as $plugin_file => $plugin_data ) { // @codingStandardsIgnoreLine -- require $plugin_data for array values but not doing anything with it - if ( is_plugin_active( $plugin_file ) ) { - ++$output; - } - } - if ( 'true' === $show_inactive ) { - $output = count( $plugins ) - $output; } - } - - return $output; + require_once ABSPATH . 'wp-admin/includes/plugin.php'; } -/** - * Get Plugins data - * - * Get plugin data and cache it - * - * @uses pll_format_plugin_list Format the plugin list. - * - * @param string $cache Cache time. - * @return string Plugin data. - */ -function pll_get_data( $cache ) { - - // Attempt to get plugin list from cache. - - if ( ! $cache ) { - $cache = 'no'; } - - $plugins = false; - $cache_key = 'plugins_list'; - if ( is_numeric( $cache ) ) { - $plugins = get_transient( $cache_key ); } - - // If not using cache, generate a new list and cache that. +// Define globals to hold the plugin base file name as well as the default output format. - if ( ! $plugins ) { - $plugins = get_plugins(); - if ( ( '' !== $plugins ) && ( is_numeric( $cache ) ) ) { - set_transient( $cache_key, $plugins, MINUTE_IN_SECONDS * $cache ); } - } - - return $plugins; +if ( ! defined( 'PLUGINS_LIST_PLUGIN_BASE' ) ) { + define( 'PLUGINS_LIST_PLUGIN_BASE', plugin_basename( __FILE__ ) ); } - -/** - * Format Plugin List - * - * Format the plugin list - * - * @uses replace_plugin_list_tags Replace the tags - * - * @param string $plugin_data The plugin list. - * @param string $format Format to use. - * @param string $nofollow Nofollow text. - * @param string $target Target text. - * @param string $characters Maximum characters for description. - * @param string $words Maximum words for description. - * @param string $emoji True or false, whether to strip emoji from description. - * @param string $end When the description is truncated, what to place at the end of the string. - * @param string $plugin_active True or false, whether the plugin is active or not. - * @return string Output. - */ -function pll_format_plugin_list( $plugin_data, $format, $nofollow, $target, $characters, $words, $emoji, $end, $plugin_active ) { - - // Allowed tag. - - $plugins_allowedtags = array( - 'a' => array( - 'href' => array(), - 'title' => array(), - ), - 'abbr' => array( 'title' => array() ), - 'acronym' => array( 'title' => array() ), - 'code' => array(), - 'em' => array(), - 'strong' => array(), - ); - - // Sanitize all displayed data. - - $plugin_data['Title'] = wp_kses( $plugin_data['Title'], $plugins_allowedtags ); - $plugin_data['PluginURI'] = wp_kses( $plugin_data['PluginURI'], $plugins_allowedtags ); - $plugin_data['AuthorURI'] = wp_kses( $plugin_data['AuthorURI'], $plugins_allowedtags ); - $plugin_data['Version'] = wp_kses( $plugin_data['Version'], $plugins_allowedtags ); - $plugin_data['Author'] = wp_kses( $plugin_data['Author'], $plugins_allowedtags ); - $plugin_data['RequiresWP'] = wp_kses( $plugin_data['RequiresWP'], $plugins_allowedtags ); - $plugin_data['RequiresPHP'] = wp_kses( $plugin_data['RequiresPHP'], $plugins_allowedtags ); - - // Get plugin activity status. - - if ( $plugin_active ) { - $plugin_data['Active'] = __( 'Active', 'plugins-list' ); - } else { - $plugin_data['Active'] = __( 'Inactive', 'plugins-list' ); - } - - // Strip emoji, HTML and unnecessary space from the description. - - if ( false === $emoji ) { - $plugin_data['Description'] = remove_emoji_from_plugin_desc( $plugin_data['Description'] ); - } - $plugin_data['Description'] = strip_spaces_from_plugin_desc( wp_strip_all_tags( $plugin_data['Description'] ) ); - - // Truncate the description, if required. - - if ( '' !== $characters || '' !== $words ) { - - // Use WordPress function to truncate description at a set number of words (ellipsis added automatically). - - if ( '' !== $words ) { - $word_limited = wp_trim_words( $plugin_data['Description'], $words, $end ); - $plugin_data['Description'] = $word_limited; - } - - // Manually truncate description to a set number of characters. This is done cleanly, however, by doing so to - // the previous space. Then an ellipsis is added. - - if ( '' !== $characters ) { - $character_limited = $plugin_data['Description']; - // Make sure the description is greater than the required length. - if ( strlen( $character_limited ) > $characters ) { - $space = strrpos( substr( $character_limited, 0, $characters + 1 ), ' ' ); - - if ( false === $space ) { - // If there is no space before the truncation length, just truncate. - $character_limited = substr( $character_limited, 0, $characters ); - } else { - // If there is a space within the truncated area, trim to that. - $character_limited = substr( $character_limited, 0, $space ); - } - $plugin_data['Description'] = rtrim( $character_limited ) . $end; - } - } - - // If both words and character limits are used, take whichever results in the shortest result. - - if ( ( '' !== $characters && '' !== $words ) && ( $word_limited < $character_limited ) ) { - $plugin_data['Description'] = $word_limited; - } - } - - // Replace the tags. - - $format = replace_plugin_list_tags( $plugin_data, $format, $nofollow, $target ); - - return $format; +if ( ! defined( 'DEFAULT_PLUGIN_LIST_FORMAT' ) ) { + define( 'DEFAULT_PLUGIN_LIST_FORMAT', '
  • {{LinkedTitle}} by {{LinkedAuthor}}.
  • ' ); } -/** - * Replace tags - * - * Replace the tags in the provided format - * - * @param string $plugin_data The plugin list. - * @param string $format Format to use. - * @param string $nofollow Nofollow text. - * @param string $target Target text. - * @return string Output. - */ -function replace_plugin_list_tags( $plugin_data, $format, $nofollow, $target ) { - - $format = strtr( - $format, - array( - '{{Title}}' => $plugin_data['Title'], - '{{PluginURI}}' => $plugin_data['PluginURI'], - '{{AuthorURI}}' => $plugin_data['AuthorURI'], - '{{Version}}' => $plugin_data['Version'], - '{{Description}}' => $plugin_data['Description'], - '{{Author}}' => $plugin_data['Author'], - '{{RequiresWP}}' => $plugin_data['RequiresWP'], - '{{RequiresPHP}}' => $plugin_data['RequiresPHP'], - '{{Active}}' => $plugin_data['Active'], - '{{LinkedTitle}}' => "' . $plugin_data['Title'] . '', - '{{LinkedAuthor}}' => "' . $plugin_data['Author'] . '', - '#Title#' => $plugin_data['Title'], - '#PluginURI#' => $plugin_data['PluginURI'], - '#AuthorURI#' => $plugin_data['AuthorURI'], - '#Version#' => $plugin_data['Version'], - '#Description#' => $plugin_data['Description'], - '#Author#' => $plugin_data['Author'], - '#RequiresWP#' => $plugin_data['RequiresWP'], - '#RequiresPHP#' => $plugin_data['RequiresPHP'], - '#Active#' => $plugin_data['Active'], - '#LinkedTitle#' => "' . $plugin_data['Title'] . '', - '#LinkedAuthor#' => "' . $plugin_data['Author'] . '', - '{{' => '<', - '}}' => '>', - '{' => '<', - '}' => '>', - ) - ); +// Include the shared functions. - // Remove all HTML tags other than those used for formatting. +require_once plugin_dir_path( __FILE__ ) . 'inc/shared.php'; - $allowed_tags = array( - 'a' => array( - 'href' => array(), - 'hreflang' => array(), - 'rel' => array(), - 'target' => array(), - 'type' => array(), - 'class' => array(), - 'style' => array(), - ), - 'b' => array(), - 'big' => array(), - 'blockquote' => array( - 'cite' => array(), - 'class' => array(), - 'style' => array(), - ), - 'br' => array(), - 'caption' => array(), - 'center' => array(), - 'cite' => array(), - 'code' => array( - 'pre' => array(), - 'class' => array(), - 'style' => array(), - ), - 'col' => array( - 'span' => array(), - 'class' => array(), - 'style' => array(), - ), - 'colgroup' => array( - 'span' => array(), - 'class' => array(), - 'style' => array(), - ), - 'div' => array( - 'class' => array(), - 'style' => array(), - ), - 'em' => array( - 'class' => array(), - 'style' => array(), - ), - 'font' => array( - 'class' => array(), - 'style' => array(), - ), - 'h1' => array( - 'class' => array(), - 'style' => array(), - ), - 'h2' => array( - 'class' => array(), - 'style' => array(), - ), - 'h3' => array( - 'class' => array(), - 'style' => array(), - ), - 'h4' => array( - 'class' => array(), - 'style' => array(), - ), - 'h5' => array( - 'class' => array(), - 'style' => array(), - ), - 'h6' => array( - 'class' => array(), - 'style' => array(), - ), - 'hr' => array( - 'class' => array(), - 'style' => array(), - ), - 'i' => array( - 'class' => array(), - 'style' => array(), - ), - 'img' => array( - 'src' => array(), - 'alt' => array(), - 'class' => array(), - 'style' => array(), - ), - 'li' => array( - 'class' => array(), - 'style' => array(), - ), - 'ol' => array( - 'start' => array(), - 'type' => array(), - 'class' => array(), - 'style' => array(), - ), - 'p' => array( - 'class' => array(), - 'style' => array(), - ), - 'pre' => array( - 'code' => array(), - 'samp' => array(), - 'class' => array(), - 'style' => array(), - ), - 'q' => array( - 'cite' => array(), - 'class' => array(), - 'style' => array(), - ), - 's' => array( - 'class' => array(), - 'style' => array(), - ), - 'small' => array( - 'class' => array(), - 'style' => array(), - ), - 'span' => array( - 'class' => array(), - 'style' => array(), - ), - 'strike' => array( - 'class' => array(), - 'style' => array(), - ), - 'strong' => array( - 'class' => array(), - 'style' => array(), - ), - 'style' => array( - 'type' => array(), - 'class' => array(), - 'style' => array(), - ), - 'sub' => array( - 'class' => array(), - 'style' => array(), - ), - 'sup' => array( - 'class' => array(), - 'style' => array(), - ), - 'table' => array( - 'class' => array(), - 'style' => array(), - ), - 'td' => array( - 'colspan' => array(), - 'headers' => array(), - 'rowspan' => array(), - 'class' => array(), - 'style' => array(), - ), - 'th' => array( - 'colspan' => array(), - 'headers' => array(), - 'rowspan' => array(), - 'scope' => array(), - 'class' => array(), - 'style' => array(), - ), - 'tr' => array( - 'class' => array(), - 'style' => array(), - ), - 'u' => array( - 'class' => array(), - 'style' => array(), - ), - 'ul' => array( - 'class' => array(), - 'style' => array(), - ), - ); +require_once plugin_dir_path( __FILE__ ) . 'inc/shortcodes.php'; - $format = wp_kses( $format, $allowed_tags ); - - return $format; -} - -/** - * Remove emoji - * - * Function to strip emoji from the plugin description. - * - * @param string $description The plugin description. - * @return string Stripped description. - */ -function remove_emoji_from_plugin_desc( $description ) { - - $symbols = "\x{1F100}-\x{1F1FF}" // Enclosed Alphanumeric Supplement. - . "\x{1F300}-\x{1F5FF}" // Miscellaneous Symbols and Pictographs. - . "\x{1F600}-\x{1F64F}" // Emoticons. - . "\x{1F680}-\x{1F6FF}" // Transport And Map Symbols. - . "\x{1F900}-\x{1F9FF}" // Supplemental Symbols and Pictographs. - . "\x{2600}-\x{26FF}" // Miscellaneous Symbols. - . "\x{2700}-\x{27BF}"; // Dingbats. - - $description = preg_replace( '/[' . $symbols . ']+/u', '', $description ); - - return $description; -} - -/** - * Strip spaces - * - * Function to strip extra spaces from the plugin description. - * - * @param string $description The plugin description. - * @return string Stripped description. - */ -function strip_spaces_from_plugin_desc( $description ) { - - $continue = true; - while ( true === $continue ) { - $replace = str_replace( ' ', ' ', $description ); - if ( $replace === $description ) { - $continue = false; - } - $description = $replace; - } - return trim( $description ); -} +require_once plugin_dir_path( __FILE__ ) . 'inc/generate-plugin-data.php'; diff --git a/readme.txt b/readme.txt index d66fe0b..ac766a8 100755 --- a/readme.txt +++ b/readme.txt @@ -3,13 +3,13 @@ Contributors: dartiss, nutsmuggler Donate link: https://artiss.blog/donate Tags: plugins, list, show, installed, display Requires at least: 4.6 -Tested up to: 6.4 +Tested up to: 6.5 Requires PHP: 7.4 -Stable tag: 2.6.1 +Stable tag: 2.7 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html -🔌 Allows you to insert a list of the Wordpress plugins you are using into any post/page. +Allows you to insert a list of the Wordpress plugins you are using into any post/page. == Description == @@ -29,9 +29,9 @@ Key features include... Thanks to [Matej Nastran](http://matej.nastran.net/)'s [My plugins](http://wordpress.org/extend/plugins/my-plugins/), from which *Plugins list* was initially derived. -Iconography is courtesy of the very talented [Janki Rathod](https://www.fiverr.com/jankirathore) ♥️ +Iconography is courtesy of the very talented [Janki Rathod](https://www.fiverr.com/jankirathore). -👉 Please visit the [Github page](https://github.com/dartiss/plugins-list "Github") for the latest code development, planned enhancements and known issues 👈 +***Please visit the [Github page](https://github.com/dartiss/plugins-list "Github") for the latest code development, planned enhancements and known issues*** == Getting Started == @@ -85,7 +85,7 @@ If you wanted to show just inactive, you'd put.. `[plugins_list format="{{LinkedTitle}} ({{LinkedAuthor}}) - {{Description}}{{br/}}" show_inactive=true show_active=false]` -If you wanted to show just plugins that are inactive but were recently acive, you'd put... +If you wanted to show just plugins that are inactive but were recently active, you'd put... `[plugins_list format="{{LinkedTitle}} ({{LinkedAuthor}}) - {{Description}}{{br/}}" show_inactive=false show_active=false show_recent=true]` @@ -182,7 +182,7 @@ Using double braces (i.e. {{ and {{) for templates is pretty standard so somethi For your security, not all HTML tags are allowed - we've limited this to any that are for the purposed of text formatting (inc. bullet points) and tables. -The full of allowed tags are: , , ,
    ,
    , ,
    , , , , ,
    , , ,

    ,

    ,

    ,

    ,

    ,
    ,
    , , ,
  • ,
      ,

      ,

      , , , , , , ,