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 '

No plugins found.

'; + } + + ob_start(); + ?> +
+
+ +
+
+
+

+ name); ?> +

+
+ +
+

short_description); ?>

+

+ author); ?> +

+
+
+
+
+ $plugin->rating, 'type' => 'percent', 'number' => $plugin->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 '

    No plugins found.

    '; - } - - 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');