diff --git a/admin/includes/class-plugin-manager.php b/admin/includes/class-plugin-manager.php
new file mode 100644
index 0000000..bb6d80f
--- /dev/null
+++ b/admin/includes/class-plugin-manager.php
@@ -0,0 +1,343 @@
+plugins);
+ wp_send_json_success($html);
+ return;
+ } catch (Exception $e) {
+ error_log('Error displaying cached plugins: ' . $e->getMessage());
+ // Fall through to fetch fresh data
+ }
+ }
+
+ error_log('Fetching fresh data for category: ' . $category);
+ error_log('Plugins to fetch: ' . implode(', ', $recommended_plugins[$category]));
+
+ try {
+ $plugins = array();
+
+ // Only fetch plugins that are in our recommended list for this category
+ foreach ($recommended_plugins[$category] as $slug) {
+ try {
+ error_log('Fetching plugin data for: ' . $slug);
+ $plugin_data = plugins_api('plugin_information', array(
+ 'slug' => $slug,
+ 'fields' => array(
+ 'short_description' => true,
+ 'sections' => false,
+ 'requires' => true,
+ 'rating' => true,
+ 'ratings' => false,
+ 'downloaded' => true,
+ 'last_updated' => true,
+ 'added' => false,
+ 'tags' => false,
+ 'compatibility' => false,
+ 'homepage' => true,
+ 'versions' => false,
+ 'donate_link' => false,
+ 'reviews' => false,
+ 'banners' => false,
+ 'icons' => true,
+ 'active_installs' => true,
+ 'group' => false,
+ 'contributors' => false,
+ )
+ ));
+
+ if (is_wp_error($plugin_data)) {
+ error_log('Error fetching plugin data for ' . $slug . ': ' . $plugin_data->get_error_message());
+ } else {
+ $plugins[] = $plugin_data;
+ error_log('Successfully fetched data for: ' . $slug);
+ }
+ } catch (Exception $e) {
+ error_log('Exception fetching plugin data for ' . $slug . ': ' . $e->getMessage());
+ continue;
+ }
+ }
+
+ if (empty($plugins)) {
+ wp_send_json_error('No plugin data could be retrieved for category: ' . $category);
+ return;
+ }
+
+ error_log('Total plugins fetched: ' . count($plugins));
+
+ // Create response object
+ $res = (object) array(
+ 'info' => array(
+ 'page' => 1,
+ 'pages' => 1,
+ 'results' => count($plugins),
+ ),
+ 'plugins' => $plugins
+ );
+
+ // Cache the results
+ self::set_cached_plugins($category, $res);
+
+ // Generate plugin cards HTML
+ $html = self::generate_plugin_cards($plugins);
+ wp_send_json_success($html);
+
+ } catch (Exception $e) {
+ error_log('Failed to fetch plugin data: ' . $e->getMessage());
+ wp_send_json_error('Failed to fetch plugin data: ' . $e->getMessage());
+ }
+ }
+
+ /**
+ * Generate HTML for plugin cards
+ *
+ * @param array $plugins Array of plugin data
+ * @return string HTML for the plugin cards
+ */
+ public static function generate_plugin_cards($plugins) {
+ if (empty($plugins)) {
+ return '
';
+ }
+
+ ob_start();
+ ?>
+
+
+
+
+
+
+
+ name); ?>
+
+
+
+
+
short_description); ?>
+
+ author); ?>
+
+
+
+
+
+ $plugin->rating, 'type' => 'percent', 'number' => $plugin->num_ratings)); ?>
+ (num_ratings); ?>)
+
+
+
+ last_updated))); ?>
+
+
+ active_installs >= 1000000) {
+ $active_installs_millions = floor($plugin->active_installs / 1000000);
+ $active_installs_text = sprintf(
+ _n('%s+ Million Active Installations', '%s+ Million Active Installations', $active_installs_millions),
+ number_format_i18n($active_installs_millions)
+ );
+ } elseif (0 == $plugin->active_installs) {
+ $active_installs_text = _x('Less Than 10 Active Installations', 'Active plugin installations');
+ } else {
+ $active_installs_text = sprintf(
+ _n('%s+ Active Installation', '%s+ Active Installations', $plugin->active_installs),
+ number_format_i18n($plugin->active_installs)
+ );
+ }
+ /* translators: %s: number of active installations */
+ echo esc_html($active_installs_text);
+ ?>
+
+
+ tested) && version_compare($version, $plugin->tested, '>')) {
+ echo '' . __('Untested with your version of WordPress') . '';
+ } elseif (!empty($plugin->requires) && version_compare($version, $plugin->requires, '<')) {
+ echo '' . __('Incompatible with your version of WordPress') . '';
+ } else {
+ echo '' . __('Compatible with your version of WordPress') . '';
+ }
+ ?>
+
+
+
+
+
+
+ slug])) {
+ $pro_plugin = $pro_plugins[$plugin->slug];
+ $pro_url = self::get_pro_plugin_url($pro_plugin);
+
+ if (!empty($pro_url)) {
+ echo '' . esc_html__('PRO', 'wp-allstars') . '';
+ }
+ }
+ }
+
+ /**
+ * Get the URL for a pro plugin from its config
+ *
+ * @param array $pro_plugin The pro plugin configuration array
+ * @return string The URL for the pro plugin
+ */
+ public static function get_pro_plugin_url($pro_plugin) {
+ // First check if there's a button_group defined
+ if (isset($pro_plugin['button_group']) && is_array($pro_plugin['button_group'])) {
+ foreach ($pro_plugin['button_group'] as $button) {
+ // Return the URL for the primary button if available
+ if (isset($button['primary']) && $button['primary'] && !empty($button['url'])) {
+ return $button['url'];
+ }
+ }
+
+ // If no primary button found, return the first button URL
+ if (!empty($pro_plugin['button_group'][0]['url'])) {
+ return $pro_plugin['button_group'][0]['url'];
+ }
+ }
+
+ // Fall back to the main URL if available
+ if (!empty($pro_plugin['url'])) {
+ return $pro_plugin['url'];
+ }
+
+ return '';
+ }
+
+ /**
+ * Clear plugin cache when plugins are updated, activated, or deactivated
+ */
+ public static function clear_plugin_cache() {
+ $recommended_plugins = wp_allstars_get_recommended_plugins();
+ foreach (array_keys($recommended_plugins) as $category) {
+ delete_transient('wp_allstars_plugins_' . $category);
+ }
+ }
+}
+
+// Initialize the class
+WP_Allstars_Plugin_Manager::init();
diff --git a/admin/settings.php b/admin/settings.php
index 434dbae..1512def 100644
--- a/admin/settings.php
+++ b/admin/settings.php
@@ -41,312 +41,17 @@ require_once dirname(__FILE__) . '/data/hosting-providers.php';
// Include recommended plugins data
require_once dirname(__FILE__) . '/data/recommended-plugins.php';
-// Add transient caching for plugin data
-function wp_allstars_get_cached_plugins($category) {
- $cache_key = 'wp_allstars_plugins_' . $category;
- $cached_data = get_transient($cache_key);
-
- if ($cached_data !== false) {
- return $cached_data;
- }
-
- return false;
-}
+// Include the Plugin Manager class
+require_once dirname(__FILE__) . '/includes/class-plugin-manager.php';
-function wp_allstars_set_cached_plugins($category, $data) {
- $cache_key = 'wp_allstars_plugins_' . $category;
- set_transient($cache_key, $data, 12 * HOUR_IN_SECONDS);
-}
+// Initialize the Plugin Manager
+global $wp_allstars_plugin_manager;
+$wp_allstars_plugin_manager = new WP_Allstars_Plugin_Manager();
-// Add AJAX endpoint for plugin list
-function wp_allstars_ajax_get_plugins() {
- // Check nonce with the correct action name
- if (!check_ajax_referer('wp-allstars-nonce', '_wpnonce', false)) {
- wp_send_json_error('Invalid security token sent.');
- return;
- }
-
- if (!current_user_can('install_plugins')) {
- wp_die(-1);
- }
-
- $category = isset($_POST['category']) ? sanitize_key($_POST['category']) : 'minimal';
-
- require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
-
- // Get our recommended plugins for this category
- $recommended_plugins = wp_allstars_get_recommended_plugins();
- if (!isset($recommended_plugins[$category])) {
- wp_send_json_error('Invalid category: ' . $category);
- return;
- }
-
- // Try to get cached data first
- $cached_data = wp_allstars_get_cached_plugins($category);
- if ($cached_data !== false) {
- error_log('Using cached data for category: ' . $category);
- try {
- // Generate plugin cards HTML
- $html = wp_allstars_generate_plugin_cards($cached_data->plugins);
- wp_send_json_success($html);
- return;
- } catch (Exception $e) {
- error_log('Error displaying cached plugins: ' . $e->getMessage());
- // Fall through to fetch fresh data
- }
- }
-
- error_log('Fetching fresh data for category: ' . $category);
- error_log('Plugins to fetch: ' . implode(', ', $recommended_plugins[$category]));
-
- try {
- $plugins = array();
-
- // Only fetch plugins that are in our recommended list for this category
- foreach ($recommended_plugins[$category] as $slug) {
- try {
- error_log('Fetching plugin data for: ' . $slug);
- $plugin_data = plugins_api('plugin_information', array(
- 'slug' => $slug,
- 'fields' => array(
- 'short_description' => true,
- 'sections' => false,
- 'requires' => true,
- 'rating' => true,
- 'ratings' => false,
- 'downloaded' => true,
- 'last_updated' => true,
- 'added' => false,
- 'tags' => false,
- 'compatibility' => false,
- 'homepage' => true,
- 'versions' => false,
- 'donate_link' => false,
- 'reviews' => false,
- 'banners' => false,
- 'icons' => true,
- 'active_installs' => true,
- 'group' => false,
- 'contributors' => false,
- )
- ));
-
- if (is_wp_error($plugin_data)) {
- error_log('Error fetching plugin data for ' . $slug . ': ' . $plugin_data->get_error_message());
- } else {
- $plugins[] = $plugin_data;
- error_log('Successfully fetched data for: ' . $slug);
- }
- } catch (Exception $e) {
- error_log('Exception fetching plugin data for ' . $slug . ': ' . $e->getMessage());
- continue;
- }
- }
-
- if (empty($plugins)) {
- wp_send_json_error('No plugin data could be retrieved for category: ' . $category);
- return;
- }
-
- error_log('Total plugins fetched: ' . count($plugins));
-
- // Create response object
- $res = (object) array(
- 'info' => array(
- 'page' => 1,
- 'pages' => 1,
- 'results' => count($plugins),
- ),
- 'plugins' => $plugins
- );
-
- // Cache the results
- wp_allstars_set_cached_plugins($category, $res);
-
- // Generate plugin cards HTML
- $html = wp_allstars_generate_plugin_cards($plugins);
- wp_send_json_success($html);
-
- } catch (Exception $e) {
- error_log('Failed to fetch plugin data: ' . $e->getMessage());
- wp_send_json_error('Failed to fetch plugin data: ' . $e->getMessage());
- }
-}
-add_action('wp_ajax_wp_allstars_get_plugins', 'wp_allstars_ajax_get_plugins');
-
-// Function to generate plugin cards HTML
-function wp_allstars_generate_plugin_cards($plugins) {
- if (empty($plugins)) {
- return '';
- }
-
- ob_start();
- ?>
-
-
-
-
-
-
-
- name); ?>
-
-
-
- icons) && !empty($plugin->icons['1x'])): ?>
-
-
; ?>)
-
-
-
-
short_description); ?>
-
- author); ?>
-
-
-
-
-
- $plugin->rating, 'type' => 'percent', 'number' => $plugin->num_ratings)); ?>
- (num_ratings); ?>)
-
-
-
- last_updated))); ?>
-
-
- downloaded), number_format_i18n($plugin->downloaded)); ?>
-
-
- tested) && version_compare(substr($GLOBALS['wp_version'], 0, strlen($plugin->tested)), $plugin->tested, '>')) {
- echo '' . __('Untested with your version of WordPress') . '';
- } elseif (!empty($plugin->requires) && version_compare($GLOBALS['wp_version'], $plugin->requires, '<')) {
- echo '' . __('Incompatible with your version of WordPress') . '';
- } else {
- echo '' . __('Compatible with your version of WordPress') . '';
- }
- ?>
-
-
-
-
-
-
- %s',
- esc_url(wp_allstars_get_pro_plugin_url($pro_plugin)),
- esc_html__('Go Pro', 'wp-allstars')
- );
- break;
- }
- }
-
- return $action_links;
-}
-
-/**
- * Helper function to get the pro plugin URL from the button_group array
- *
- * @param array $pro_plugin The pro plugin configuration array
- * @return string The URL for the pro plugin
- */
-function wp_allstars_get_pro_plugin_url($pro_plugin) {
- // Find the primary button URL in the button_group array
- $pro_url = '';
-
- if (!empty($pro_plugin['button_group'])) {
- // First try to find a primary button
- foreach ($pro_plugin['button_group'] as $button) {
- if (isset($button['primary']) && $button['primary']) {
- $pro_url = $button['url'];
- break;
- }
- }
-
- // If no primary button found, use the first button URL
- if (empty($pro_url) && !empty($pro_plugin['button_group'][0]['url'])) {
- $pro_url = $pro_plugin['button_group'][0]['url'];
- }
- }
-
- return $pro_url;
-}
// Remove the old plugins API filter since we're handling everything in the AJAX endpoint
remove_filter('plugins_api_result', 'wp_allstars_plugins_api_result');
-// Clear plugin cache when plugins are updated, activated, or deactivated
-function wp_allstars_clear_plugin_cache() {
- $recommended_plugins = wp_allstars_get_recommended_plugins();
- foreach (array_keys($recommended_plugins) as $category) {
- delete_transient('wp_allstars_plugins_' . $category);
- }
-}
-add_action('upgrader_process_complete', 'wp_allstars_clear_plugin_cache', 10, 0);
-add_action('activated_plugin', 'wp_allstars_clear_plugin_cache');
-add_action('deactivated_plugin', 'wp_allstars_clear_plugin_cache');
-add_action('deleted_plugin', 'wp_allstars_clear_plugin_cache');
-add_action('update_option_active_plugins', 'wp_allstars_clear_plugin_cache');
-
// Add transient caching for theme data
function wp_allstars_get_cached_theme() {
$cache_key = 'wp_allstars_theme_kadence';
@@ -554,7 +259,8 @@ function wp_allstars_settings_page() {
// Clear cache and load required files
if ($active_tab === 'recommended') {
- wp_allstars_clear_plugin_cache();
+ global $wp_allstars_plugin_manager;
+ $wp_allstars_plugin_manager->clear_plugin_cache();
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
wp_enqueue_script('plugin-install');
wp_enqueue_script('updates');