%filename%, %post_title%, %post_id%, %postname%, %timestamp%
@@ -1659,9 +1675,34 @@ function wp_allstars_settings_page() {
line-height: 34px;
text-align: center;
padding: 0 10px;
+ font-size: 13px;
+ font-weight: normal;
margin: 0;
+ border: 1px solid #0071a1 !important;
+ border-radius: 3px !important;
+ background: #f6f7f7;
+ color: #0071a1;
+ display: inline-block;
+ vertical-align: top;
+ box-shadow: none;
+ cursor: pointer;
}
- @media (max-width: 782px) {
+ .theme-actions .button:hover {
+ background: #f0f0f1;
+ border-color: #0071a1;
+ color: #0071a1;
+ }
+ .theme-actions .button-primary {
+ background: #0071a1;
+ border-color: #0071a1;
+ color: #fff;
+ }
+ .theme-actions .button-primary:hover {
+ background: #005d8c;
+ border-color: #005d8c;
+ color: #fff;
+ }
+ @media screen and (max-width: 782px) {
.theme-actions {
flex-direction: column;
gap: 10px;
@@ -1679,7 +1720,7 @@ function wp_allstars_settings_page() {
@@ -1945,14 +1975,14 @@ function wp_allstars_settings_page() {
@@ -2051,11 +2081,12 @@ function wp_allstars_settings_page() {
.wpa-pro-plugin .button.button-primary:hover {
background: #135e96;
border-color: #135e96 !important;
+ color: #fff;
}
wp_create_nonce('wp-allstars-nonce'),
+ wp_localize_script('seoprostack-admin', 'wpSeoProStack', array(
+ 'nonce' => wp_create_nonce('wp-seoprostack-nonce'),
'ajaxurl' => admin_url('admin-ajax.php')
));
}
-add_action('admin_enqueue_scripts', 'wp_allstars_admin_enqueue_scripts');
\ No newline at end of file
+add_action('admin_enqueue_scripts', 'wp_seoprostack_admin_enqueue_scripts');
\ No newline at end of file
diff --git a/admin/settings/ajax/class-seoprostack-ajax-advanced.php b/admin/settings/ajax/class-seoprostack-ajax-advanced.php
new file mode 100644
index 0000000..3264a6e
--- /dev/null
+++ b/admin/settings/ajax/class-seoprostack-ajax-advanced.php
@@ -0,0 +1,132 @@
+ 'Security check failed'));
+ }
+
+ // Check capabilities
+ if (!current_user_can('manage_options')) {
+ wp_send_json_error(array('message' => 'You do not have permission to change settings'));
+ }
+
+ // Get settings
+ $settings = array(
+ 'disable_emojis' => isset($_POST['disable_emojis']) ? sanitize_text_field($_POST['disable_emojis']) : 'no',
+ 'disable_embeds' => isset($_POST['disable_embeds']) ? sanitize_text_field($_POST['disable_embeds']) : 'no',
+ 'remove_query_strings' => isset($_POST['remove_query_strings']) ? sanitize_text_field($_POST['remove_query_strings']) : 'no',
+ 'disable_xmlrpc' => isset($_POST['disable_xmlrpc']) ? sanitize_text_field($_POST['disable_xmlrpc']) : 'no',
+ 'remove_shortlink' => isset($_POST['remove_shortlink']) ? sanitize_text_field($_POST['remove_shortlink']) : 'no',
+ 'remove_rsd_link' => isset($_POST['remove_rsd_link']) ? sanitize_text_field($_POST['remove_rsd_link']) : 'no',
+ 'remove_wlwmanifest_link' => isset($_POST['remove_wlwmanifest_link']) ? sanitize_text_field($_POST['remove_wlwmanifest_link']) : 'no',
+ 'disable_self_pingbacks' => isset($_POST['disable_self_pingbacks']) ? sanitize_text_field($_POST['disable_self_pingbacks']) : 'no',
+ 'disable_feed_links' => isset($_POST['disable_feed_links']) ? sanitize_text_field($_POST['disable_feed_links']) : 'no',
+ 'remove_rest_api_links' => isset($_POST['remove_rest_api_links']) ? sanitize_text_field($_POST['remove_rest_api_links']) : 'no',
+ 'minify_html' => isset($_POST['minify_html']) ? sanitize_text_field($_POST['minify_html']) : 'no',
+ 'minify_css' => isset($_POST['minify_css']) ? sanitize_text_field($_POST['minify_css']) : 'no',
+ 'minify_js' => isset($_POST['minify_js']) ? sanitize_text_field($_POST['minify_js']) : 'no'
+ );
+
+ // Save settings
+ update_option('seoprostack_advanced_settings', $settings);
+
+ // Flush rewrite rules if necessary
+ if (isset($settings['disable_feed_links']) && $settings['disable_feed_links'] === 'yes') {
+ flush_rewrite_rules();
+ }
+
+ // Send response
+ wp_send_json_success(array('message' => 'Settings saved successfully'));
+ }
+
+ /**
+ * Optimize database.
+ */
+ public function optimize_database() {
+ global $wpdb;
+
+ // Verify nonce
+ if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'seoprostack_ajax_nonce')) {
+ wp_send_json_error(array('message' => 'Security check failed'));
+ }
+
+ // Check capabilities
+ if (!current_user_can('manage_options')) {
+ wp_send_json_error(array('message' => 'You do not have permission to optimize database'));
+ }
+
+ // Tables to optimize
+ $tables = $wpdb->get_col("SHOW TABLES LIKE '{$wpdb->prefix}%'");
+ $optimized = 0;
+ $failed = 0;
+
+ foreach ($tables as $table) {
+ $result = $wpdb->query("OPTIMIZE TABLE $table");
+ if ($result === false) {
+ $failed++;
+ } else {
+ $optimized++;
+ }
+ }
+
+ // Delete post revisions
+ $deleted_revisions = $wpdb->query("DELETE FROM $wpdb->posts WHERE post_type = 'revision'");
+
+ // Delete auto drafts
+ $deleted_drafts = $wpdb->query("DELETE FROM $wpdb->posts WHERE post_status = 'auto-draft'");
+
+ // Delete trashed posts
+ $deleted_trash = $wpdb->query("DELETE FROM $wpdb->posts WHERE post_status = 'trash'");
+
+ // Delete spam comments
+ $deleted_spam = $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_approved = 'spam'");
+
+ // Delete trashed comments
+ $deleted_trash_comments = $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_approved = 'trash'");
+
+ // Delete expired transients
+ $deleted_transients = $wpdb->query("DELETE FROM $wpdb->options WHERE option_name LIKE '_transient_%' AND option_name NOT LIKE '_transient_timeout_%'");
+
+ // Send response
+ wp_send_json_success(array(
+ 'message' => sprintf(
+ 'Database optimization complete. %d tables optimized, %d revisions deleted, %d auto-drafts deleted, %d trash posts deleted, %d spam comments deleted, %d trash comments deleted, %d expired transients deleted.',
+ $optimized,
+ $deleted_revisions ? $deleted_revisions : 0,
+ $deleted_drafts ? $deleted_drafts : 0,
+ $deleted_trash ? $deleted_trash : 0,
+ $deleted_spam ? $deleted_spam : 0,
+ $deleted_trash_comments ? $deleted_trash_comments : 0,
+ $deleted_transients ? $deleted_transients : 0
+ )
+ ));
+ }
+}
\ No newline at end of file
diff --git a/admin/settings/ajax/class-seoprostack-ajax-plugins.php b/admin/settings/ajax/class-seoprostack-ajax-plugins.php
new file mode 100644
index 0000000..5df37fb
--- /dev/null
+++ b/admin/settings/ajax/class-seoprostack-ajax-plugins.php
@@ -0,0 +1,65 @@
+ $plugin) {
+ // Skip the SEO Pro Stack plugin
+ if (strpos($path, 'wp-seoprostack-plugin') !== false) {
+ continue;
+ }
+
+ $is_active = in_array($path, $active_plugins);
+ $plugin_slug = explode('/', $path)[0];
+
+ $plugin_list[] = array(
+ 'name' => $plugin['Name'],
+ 'slug' => $plugin_slug,
+ 'version' => $plugin['Version'],
+ 'active' => $is_active,
+ 'path' => $path
+ );
+ }
+
+ // Sort plugins alphabetically
+ usort($plugin_list, function ($a, $b) {
+ return strcasecmp($a['name'], $b['name']);
+ });
+
+ wp_send_json_success($plugin_list);
+ }
+}
diff --git a/admin/settings/ajax/class-seoprostack-ajax-pro-plugins.php b/admin/settings/ajax/class-seoprostack-ajax-pro-plugins.php
new file mode 100644
index 0000000..13d039c
--- /dev/null
+++ b/admin/settings/ajax/class-seoprostack-ajax-pro-plugins.php
@@ -0,0 +1,194 @@
+ 'Security check failed'));
+ }
+
+ // Get category filter
+ $category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : 'all';
+
+ // Plugin data
+ $plugins = $this->get_plugin_data($category);
+
+ // Send response
+ wp_send_json_success(array('plugins' => $plugins));
+ }
+
+ /**
+ * Activate a plugin.
+ */
+ public function activate_plugin() {
+ // Verify nonce
+ if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'seoprostack_ajax_nonce')) {
+ wp_send_json_error(array('message' => 'Security check failed'));
+ }
+
+ // Check capabilities
+ if (!current_user_can('activate_plugins')) {
+ wp_send_json_error(array('message' => 'You do not have permission to activate plugins'));
+ }
+
+ // Get plugin path
+ if (!isset($_POST['plugin'])) {
+ wp_send_json_error(array('message' => 'No plugin specified'));
+ }
+
+ $plugin = sanitize_text_field($_POST['plugin']);
+
+ // Activate the plugin
+ $result = activate_plugin($plugin);
+
+ if (is_wp_error($result)) {
+ wp_send_json_error(array('message' => $result->get_error_message()));
+ } else {
+ wp_send_json_success(array('message' => 'Plugin activated successfully'));
+ }
+ }
+
+ /**
+ * Get the plugin data based on category.
+ *
+ * @param string $category The plugin category.
+ * @return array The plugin data.
+ */
+ private function get_plugin_data($category) {
+ $plugins = array(
+ array(
+ 'name' => 'Rank Math SEO',
+ 'version' => '1.0.123',
+ 'description' => 'The most advanced SEO plugin for WordPress that helps you optimize your website for search engines.',
+ 'url' => 'https://rankmath.com/',
+ 'status' => 'not-installed',
+ 'active' => false,
+ 'path' => 'rank-math-seo/rank-math.php',
+ 'category' => 'seo'
+ ),
+ array(
+ 'name' => 'WP Rocket',
+ 'version' => '3.14.4',
+ 'description' => 'The best WordPress caching plugin to speed up your website in a few clicks.',
+ 'url' => 'https://wp-rocket.me/',
+ 'status' => 'not-installed',
+ 'active' => false,
+ 'path' => 'wp-rocket/wp-rocket.php',
+ 'category' => 'performance'
+ ),
+ array(
+ 'name' => 'MonsterInsights',
+ 'version' => '8.14.0',
+ 'description' => 'The best Google Analytics plugin for WordPress that connects your website with Google Analytics.',
+ 'url' => 'https://www.monsterinsights.com/',
+ 'status' => 'not-installed',
+ 'active' => false,
+ 'path' => 'google-analytics-for-wordpress/googleanalytics.php',
+ 'category' => 'analytics'
+ ),
+ array(
+ 'name' => 'Yoast SEO',
+ 'version' => '21.2',
+ 'description' => 'The first true all-in-one SEO solution for WordPress, including on-page content analysis, XML sitemaps and much more.',
+ 'url' => 'https://yoast.com/wordpress/plugins/seo/',
+ 'status' => 'not-installed',
+ 'active' => false,
+ 'path' => 'wordpress-seo/wp-seo.php',
+ 'category' => 'seo'
+ ),
+ array(
+ 'name' => 'WP Cloudflare Super Page Cache',
+ 'version' => '4.7.0',
+ 'description' => 'Speed up your website by implementing full page caching using Cloudflare.',
+ 'url' => 'https://wordpress.org/plugins/wp-cloudflare-page-cache/',
+ 'status' => 'not-installed',
+ 'active' => false,
+ 'path' => 'wp-cloudflare-page-cache/wp-cloudflare-super-page-cache.php',
+ 'category' => 'performance'
+ ),
+ array(
+ 'name' => 'ExactMetrics',
+ 'version' => '7.14.1',
+ 'description' => 'Google Analytics Dashboard for WordPress. See how visitors find and use your website.',
+ 'url' => 'https://www.exactmetrics.com/',
+ 'status' => 'not-installed',
+ 'active' => false,
+ 'path' => 'google-analytics-dashboard-for-wp/gadwp.php',
+ 'category' => 'analytics'
+ ),
+ array(
+ 'name' => 'SEOPress',
+ 'version' => '7.2.2',
+ 'description' => 'Boost your SEO with SEOPress, a simple, fast and powerful WordPress SEO plugin.',
+ 'url' => 'https://www.seopress.org/',
+ 'status' => 'not-installed',
+ 'active' => false,
+ 'path' => 'wp-seopress/seopress.php',
+ 'category' => 'seo'
+ ),
+ array(
+ 'name' => 'WP-Optimize',
+ 'version' => '3.2.19',
+ 'description' => 'A comprehensive plugin with database clean-up, image compression and page caching features.',
+ 'url' => 'https://getwpo.com/',
+ 'status' => 'not-installed',
+ 'active' => false,
+ 'path' => 'wp-optimize/wp-optimize.php',
+ 'category' => 'performance'
+ ),
+ array(
+ 'name' => 'Fathom Analytics',
+ 'version' => '3.2.1',
+ 'description' => 'Simple, privacy-focused website analytics that doesn\'t compromise visitor privacy.',
+ 'url' => 'https://usefathom.com/',
+ 'status' => 'not-installed',
+ 'active' => false,
+ 'path' => 'fathom-analytics-wordpress-plugin/fathom-analytics.php',
+ 'category' => 'analytics'
+ )
+ );
+
+ // Update plugin status (check if installed and active)
+ foreach ($plugins as $key => $plugin) {
+ if (file_exists(WP_PLUGIN_DIR . '/' . $plugin['path'])) {
+ $plugins[$key]['status'] = 'installed';
+ $plugins[$key]['active'] = is_plugin_active($plugin['path']);
+ }
+ }
+
+ // Filter by category if needed
+ if ($category !== 'all') {
+ $plugins = array_filter($plugins, function($plugin) use ($category) {
+ return $plugin['category'] === $category;
+ });
+ }
+
+ return array_values($plugins);
+ }
+}
\ No newline at end of file
diff --git a/admin/settings/ajax/class-seoprostack-ajax-settings.php b/admin/settings/ajax/class-seoprostack-ajax-settings.php
new file mode 100644
index 0000000..55979ea
--- /dev/null
+++ b/admin/settings/ajax/class-seoprostack-ajax-settings.php
@@ -0,0 +1,119 @@
+ 'Invalid security token sent.'
+ ));
+ return;
+ }
+
+ // Check permissions
+ if (!current_user_can('manage_options')) {
+ wp_send_json_error(array(
+ 'message' => 'You do not have permission to update settings.'
+ ));
+ return;
+ }
+
+ // Get option data
+ $option_group = isset($_POST['option_group']) ? sanitize_text_field($_POST['option_group']) : '';
+ $option_name = isset($_POST['option_name']) ? sanitize_text_field($_POST['option_name']) : '';
+ $option_value = isset($_POST['option_value']) ? sanitize_text_field($_POST['option_value']) : '';
+
+ if (empty($option_group) || empty($option_name)) {
+ wp_send_json_error(array(
+ 'message' => 'Missing required parameters.'
+ ));
+ return;
+ }
+
+ // Get current option values
+ $options = get_option($option_group, array());
+
+ // Update value
+ $options[$option_name] = $option_value;
+
+ // Save updated options
+ $result = update_option($option_group, $options);
+
+ if ($result) {
+ wp_send_json_success(array(
+ 'message' => 'Option updated successfully',
+ 'option_group' => $option_group,
+ 'option_name' => $option_name,
+ 'option_value' => $option_value
+ ));
+ } else {
+ wp_send_json_error(array(
+ 'message' => 'Failed to update option or no changes were made.'
+ ));
+ }
+ }
+
+ /**
+ * Get plugin options via AJAX.
+ */
+ public function get_options() {
+ // Check nonce
+ if (!check_ajax_referer('seoprostack-nonce', 'nonce', false)) {
+ wp_send_json_error(array(
+ 'message' => 'Invalid security token sent.'
+ ));
+ return;
+ }
+
+ // Check permissions
+ if (!current_user_can('manage_options')) {
+ wp_send_json_error(array(
+ 'message' => 'You do not have permission to retrieve settings.'
+ ));
+ return;
+ }
+
+ // Get option group
+ $option_group = isset($_POST['option_group']) ? sanitize_text_field($_POST['option_group']) : '';
+
+ if (empty($option_group)) {
+ wp_send_json_error(array(
+ 'message' => 'Missing required parameters.'
+ ));
+ return;
+ }
+
+ // Get options
+ $options = get_option($option_group, array());
+
+ wp_send_json_success(array(
+ 'options' => $options
+ ));
+ }
+}
diff --git a/admin/settings/ajax/class-seoprostack-ajax-themes.php b/admin/settings/ajax/class-seoprostack-ajax-themes.php
new file mode 100644
index 0000000..ddd3afe
--- /dev/null
+++ b/admin/settings/ajax/class-seoprostack-ajax-themes.php
@@ -0,0 +1,93 @@
+ $theme_obj) {
+ $theme_list[] = array(
+ 'name' => $theme_obj->get('Name'),
+ 'version' => $theme_obj->get('Version'),
+ 'description' => $theme_obj->get('Description'),
+ 'author' => $theme_obj->get('Author'),
+ 'slug' => $theme_slug,
+ 'active' => ($current_theme->get_stylesheet() === $theme_slug),
+ 'screenshot' => $theme_obj->get_screenshot(),
+ );
+ }
+
+ // Sort themes - active first, then alphabetically
+ usort($theme_list, function ($a, $b) {
+ if ($a['active'] && !$b['active']) return -1;
+ if (!$a['active'] && $b['active']) return 1;
+ return strcasecmp($a['name'], $b['name']);
+ });
+
+ wp_send_json_success($theme_list);
+ }
+
+ /**
+ * Activate a theme.
+ */
+ public function activate_theme() {
+ // Check nonce
+ if (!check_ajax_referer('seoprostack-nonce', 'nonce', false)) {
+ wp_send_json_error('Invalid security token sent.');
+ return;
+ }
+
+ // Check permissions
+ if (!current_user_can('switch_themes')) {
+ wp_send_json_error('You do not have permission to switch themes.');
+ return;
+ }
+
+ $theme_slug = sanitize_text_field($_POST['theme']);
+
+ // Check if theme exists
+ $themes = wp_get_themes();
+ if (!isset($themes[$theme_slug])) {
+ wp_send_json_error('Theme does not exist.');
+ return;
+ }
+
+ // Activate theme
+ switch_theme($theme_slug);
+
+ wp_send_json_success(array(
+ 'message' => sprintf('Theme "%s" has been activated.', $themes[$theme_slug]->get('Name')),
+ ));
+ }
+}
\ No newline at end of file
diff --git a/admin/settings/ajax/class-seoprostack-ajax-tools.php b/admin/settings/ajax/class-seoprostack-ajax-tools.php
new file mode 100644
index 0000000..78b9f16
--- /dev/null
+++ b/admin/settings/ajax/class-seoprostack-ajax-tools.php
@@ -0,0 +1,77 @@
+ 'Security check failed'));
+ }
+
+ // Check capabilities
+ if (!current_user_can('manage_options')) {
+ wp_send_json_error(array('message' => 'You do not have permission to generate robots.txt'));
+ }
+
+ // Generate robots.txt content
+ $site_url = get_home_url();
+ $parsed_url = parse_url($site_url);
+ $host = $parsed_url['host'];
+
+ $content = "# SEO Pro Stack generated robots.txt\n";
+ $content .= "# Generated on: " . date('Y-m-d H:i:s') . "\n\n";
+ $content .= "User-agent: *\n";
+
+ // Disallow WordPress admin
+ $content .= "Disallow: /wp-admin/\n";
+
+ // Allow assets and ajax
+ $content .= "Allow: /wp-admin/admin-ajax.php\n";
+ $content .= "Allow: /wp-includes/*.js\n";
+ $content .= "Allow: /wp-includes/*.css\n";
+ $content .= "Allow: /wp-content/uploads/\n";
+
+ // Disallow common WordPress files and directories
+ $content .= "Disallow: /wp-includes/\n";
+ $content .= "Disallow: /readme.html\n";
+ $content .= "Disallow: /license.txt\n";
+ $content .= "Disallow: /xmlrpc.php\n";
+ $content .= "Disallow: /wp-json/\n";
+
+ // Add sitemap if Yoast SEO or other SEO plugin is active
+ if (function_exists('wpseo_init') || defined('AIOSEO_VERSION') || defined('RANK_MATH_VERSION')) {
+ $content .= "\n# XML Sitemap\n";
+ $content .= "Sitemap: " . trailingslashit($site_url) . "sitemap_index.xml\n";
+ }
+
+ // Send response
+ wp_send_json_success(array(
+ 'message' => 'Robots.txt content generated successfully.',
+ 'content' => $content
+ ));
+ }
+}
\ No newline at end of file
diff --git a/admin/settings/class-seoprostack-settings-page.php b/admin/settings/class-seoprostack-settings-page.php
new file mode 100644
index 0000000..2e94089
--- /dev/null
+++ b/admin/settings/class-seoprostack-settings-page.php
@@ -0,0 +1,193 @@
+get_tabs();
+
+ ?>
+
+
+
+
+
+
+ $tab) : ?>
+
+
+
+
+
+
+
+
+
+
+
+
+ array(
+ 'label' => __('General', 'seoprostack'),
+ 'callback' => array($this, 'render_general_tab'),
+ ),
+ 'advanced' => array(
+ 'label' => __('Advanced', 'seoprostack'),
+ 'callback' => array($this, 'render_advanced_tab'),
+ ),
+ 'workflow' => array(
+ 'label' => __('Workflow', 'seoprostack'),
+ 'callback' => array($this, 'render_workflow_tab'),
+ ),
+ 'recommended' => array(
+ 'label' => __('Free Plugins', 'seoprostack'),
+ 'callback' => array($this, 'render_recommended_plugins_tab'),
+ ),
+ 'pro' => array(
+ 'label' => __('Pro Plugins', 'seoprostack'),
+ 'callback' => array($this, 'render_pro_plugins_tab'),
+ ),
+ 'theme' => array(
+ 'label' => __('Theme', 'seoprostack'),
+ 'callback' => array($this, 'render_theme_tab'),
+ ),
+ 'hosting' => array(
+ 'label' => __('Hosting', 'seoprostack'),
+ 'callback' => array($this, 'render_hosting_tab'),
+ ),
+ 'tools' => array(
+ 'label' => __('Tools', 'seoprostack'),
+ 'callback' => array($this, 'render_tools_tab'),
+ ),
+ );
+
+ return $tabs;
+ }
+
+ /**
+ * Render the General tab.
+ */
+ public function render_general_tab() {
+ require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/tabs/class-seoprostack-tab-general.php';
+ $tab = new SEOProStack_Tab_General();
+ $tab->render();
+ }
+
+ /**
+ * Render the Advanced tab.
+ */
+ public function render_advanced_tab() {
+ require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/tabs/class-seoprostack-tab-advanced.php';
+ $tab = new SEOProStack_Tab_Advanced();
+ $tab->render();
+ }
+
+ /**
+ * Render the Workflow tab.
+ */
+ public function render_workflow_tab() {
+ require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/tabs/class-seoprostack-tab-workflow.php';
+ $tab = new SEOProStack_Tab_Workflow();
+ $tab->render();
+ }
+
+ /**
+ * Render the Recommended Plugins tab.
+ */
+ public function render_recommended_plugins_tab() {
+ require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/tabs/class-seoprostack-tab-recommended-plugins.php';
+ $tab = new SEOProStack_Tab_Recommended_Plugins();
+ $tab->render();
+ }
+
+ /**
+ * Render the Pro Plugins tab.
+ */
+ public function render_pro_plugins_tab() {
+ require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/tabs/class-seoprostack-tab-pro-plugins.php';
+ $tab = new SEOProStack_Tab_Pro_Plugins();
+ $tab->render();
+ }
+
+ /**
+ * Render the Theme tab.
+ */
+ public function render_theme_tab() {
+ require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/tabs/class-seoprostack-tab-theme.php';
+ $tab = new SEOProStack_Tab_Theme();
+ $tab->render();
+ }
+
+ /**
+ * Render the Hosting tab.
+ */
+ public function render_hosting_tab() {
+ require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/tabs/class-seoprostack-tab-hosting.php';
+ $tab = new SEOProStack_Tab_Hosting();
+ $tab->render();
+ }
+
+ /**
+ * Render the Tools tab.
+ */
+ public function render_tools_tab() {
+ require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/tabs/class-seoprostack-tab-tools.php';
+ $tab = new SEOProStack_Tab_Tools();
+ $tab->render();
+ }
+}
\ No newline at end of file
diff --git a/admin/settings/data/hosting-providers.php b/admin/settings/data/hosting-providers.php
new file mode 100644
index 0000000..52c6892
--- /dev/null
+++ b/admin/settings/data/hosting-providers.php
@@ -0,0 +1,229 @@
+ array(
+ 'name' => 'Closte',
+ 'description' => 'Managed WordPress hosting with advanced performance optimization and auto-scaling.',
+ 'features' => array(
+ 'Auto-scaling architecture',
+ 'Global CDN included',
+ 'Advanced caching',
+ 'Free SSL certificates'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://closte.com/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://closte.com/pricing'
+ )
+ )
+ ),
+ 'cloudron' => array(
+ 'name' => 'Cloudron',
+ 'description' => 'Self-hosted platform that makes it easy to run web applications like WordPress on your server.',
+ 'features' => array(
+ 'One-click installation',
+ 'Automatic updates',
+ 'Built-in backups',
+ 'SSL certificate management'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.cloudron.io/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://www.cloudron.io/pricing.html'
+ )
+ )
+ ),
+ 'hostinger' => array(
+ 'name' => 'Hostinger',
+ 'description' => 'Affordable WordPress hosting with good performance and user-friendly management tools.',
+ 'features' => array(
+ 'Free domain name',
+ 'Managed WordPress features',
+ 'LiteSpeed cache',
+ 'Weekly backups'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.hostinger.com/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://www.hostinger.com/wordpress-hosting'
+ )
+ )
+ ),
+ 'hetzner' => array(
+ 'name' => 'Hetzner Cloud',
+ 'description' => 'High-performance cloud servers with excellent price-to-performance ratio for self-managed WordPress hosting.',
+ 'features' => array(
+ 'Scalable cloud instances',
+ 'Per-minute billing',
+ 'Snapshots and backups',
+ 'Global data centers'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.hetzner.com/cloud/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://www.hetzner.com/cloud#pricing'
+ )
+ )
+ ),
+ 'simplehost' => array(
+ 'name' => 'SimpleHost',
+ 'description' => 'Streamlined WordPress hosting with a focus on simplicity and performance.',
+ 'features' => array(
+ 'Simplified hosting dashboard',
+ 'Pre-optimized WordPress',
+ 'Automated backups',
+ 'Email hosting included'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://simplehost.so/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://simplehost.so/#pricing'
+ )
+ )
+ ),
+ 'cloudflare' => array(
+ 'name' => 'Cloudflare',
+ 'description' => 'Global cloud platform that provides CDN, security, and performance optimization services.',
+ 'features' => array(
+ 'Global CDN network',
+ 'DDoS protection',
+ 'Web application firewall',
+ 'Performance optimization'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.cloudflare.com/en-gb/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://www.cloudflare.com/en-gb/plans/'
+ )
+ )
+ ),
+ 'spaceship' => array(
+ 'name' => 'Spaceship',
+ 'description' => 'Modern hosting platform with advanced features for WordPress sites.',
+ 'features' => array(
+ 'Advanced WordPress tools',
+ 'Optimized for speed',
+ 'Developer-friendly features',
+ 'Smart caching system'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.spaceship.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ '101domain' => array(
+ 'name' => '101Domain',
+ 'description' => 'Domain registration and management service with support for hundreds of TLDs.',
+ 'features' => array(
+ 'Extensive TLD selection',
+ 'Domain privacy protection',
+ 'Expert domain support',
+ 'Bulk domain management'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.101domain.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'namecheap' => array(
+ 'name' => 'Namecheap',
+ 'description' => 'Domain registrar and web hosting provider with competitive pricing and good support.',
+ 'features' => array(
+ 'Free WhoisGuard protection',
+ 'Competitive domain pricing',
+ 'Reliable hosting services',
+ 'Excellent support'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.namecheap.com/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://www.namecheap.com/hosting/shared/'
+ )
+ )
+ ),
+ 'updownio' => array(
+ 'name' => 'Updown.io',
+ 'description' => 'Simple and affordable website monitoring service with uptime checks and performance metrics.',
+ 'features' => array(
+ 'Real-time monitoring',
+ 'Performance metrics',
+ 'Notification alerts',
+ 'Detailed reports'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://updown.io/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://updown.io/pricing'
+ )
+ )
+ )
+ );
+}
+
+// Alias for backward compatibility with the old codebase
+function wp_allstars_get_hosting_providers() {
+ return wp_seoprostack_get_hosting_providers();
+}
\ No newline at end of file
diff --git a/admin/settings/data/recommended-plugins.php b/admin/settings/data/recommended-plugins.php
new file mode 100644
index 0000000..5cad4c5
--- /dev/null
+++ b/admin/settings/data/recommended-plugins.php
@@ -0,0 +1,183 @@
+ array(
+ 'antispam-bee',
+ 'compressx',
+ 'fluent-smtp',
+ 'kadence-blocks',
+ 'simple-cloudflare-turnstile'
+ ),
+ 'admin' => array(
+ 'admin-bar-dashboard-control',
+ 'codepress-admin-columns',
+ 'admin-menu-editor',
+ 'hide-admin-notices',
+ 'mainwp-child',
+ 'mainwp-child-reports',
+ 'magic-login',
+ 'manage-notification-emails',
+ 'plugin-groups',
+ 'plugin-toggle'
+ ),
+ 'affiliates' => array(
+ 'pretty-links',
+ 'simple-urls',
+ 'slicewp'
+ ),
+ 'ai' => array(
+ 'ai-engine',
+ ),
+ 'cms' => array(
+ 'auto-post-scheduler',
+ 'block-options',
+ 'bookmark-card',
+ 'browser-shots',
+ 'bulk-actions-select-all',
+ 'bulk-edit-categories-tags',
+ 'bulk-edit-user-profiles-in-spreadsheet',
+ 'carbon-copy',
+ 'code-block-pro',
+ 'iframe-block',
+ 'ics-calendar',
+ 'mammoth-docx-converter',
+ 'nav-menu-roles',
+ 'ninja-tables',
+ 'post-draft-preview',
+ 'post-type-switcher',
+ 'simple-custom-post-order',
+ 'simple-icons',
+ 'sticky-posts-switch',
+ 'term-management-tools',
+ 'the-paste',
+ 'ultimate-addons-for-gutenberg',
+ 'wikipedia-preview',
+ 'wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages'
+ ),
+ 'compliance' => array(
+ 'avatar-privacy',
+ 'complianz-gdpr',
+ 'complianz-terms-conditions',
+ 'really-simple-ssl'
+ ),
+ 'crm' => array(
+ 'fluent-boards',
+ 'fluent-booking',
+ 'fluent-community',
+ 'fluent-crm',
+ 'fluentform',
+ 'fluentforms-pdf',
+ 'fluentform-block',
+ 'fluent-support'
+ ),
+ 'ecommerce' => array(
+ 'woocommerce',
+ 'woo-bulk-edit-products',
+ 'woo-coupons-bulk-editor',
+ 'woocommerce-gateway-gocardless',
+ 'kadence-woocommerce-email-designer',
+ 'pymntpl-paypal-woocommerce',
+ 'woo-stripe-payment'
+ ),
+ 'lms' => array(
+ 'fluent-community',
+ 'masterstudy-lms-learning-management-system',
+ 'tutor'
+ ),
+ 'media' => array(
+ 'easy-watermark',
+ 'enable-media-replace',
+ 'image-copytrack',
+ 'imsanity',
+ 'media-file-renamer',
+ 'safe-svg'
+ ),
+ 'seo' => array(
+ 'burst-statistics',
+ 'pretty-link',
+ 'revive-so',
+ 'seo-by-rank-math',
+ 'syndication-links',
+ 'ultimate-410',
+ 'webmention'
+ ),
+ 'setup' => array(
+ 'kadence-starter-templates',
+ 'wordpress-importer'
+ ),
+ 'social' => array(
+ 'bit-social',
+ 'easy-video-reviews',
+ 'social-engine',
+ 'wp-social-ninja',
+ 'wp-social-reviews'
+ ),
+ 'speed' => array(
+ 'disable-wordpress-updates',
+ 'flying-analytics',
+ 'flying-pages',
+ 'flying-scripts',
+ 'freesoul-deactivate-plugins',
+ 'index-wp-mysql-for-speed',
+ 'litespeed-cache',
+ 'performant-translations',
+ 'wp-optimize',
+ 'wp-widget-disable'
+ ),
+ 'translation' => array(
+ 'hreflang-manager-lite',
+ 'performant-translations',
+ 'translatepress-multilingual'
+ ),
+ 'advanced' => array(
+ 'acf-better-search',
+ 'advanced-custom-fields',
+ 'automatorwp',
+ 'bit-pi',
+ 'bit-integrations',
+ 'code-snippets',
+ 'easy-code-manager',
+ 'favorites',
+ 'remove-cpt-base',
+ 'remove-old-slugspermalinks',
+ 'secure-custom-fields',
+ 'yellow-pencil-visual-theme-customizer'
+ ),
+ 'debug' => array(
+ 'advanced-database-cleaner',
+ 'debug-log-manager',
+ 'gotmls',
+ 'query-monitor',
+ 'string-locator',
+ 'user-switching',
+ 'wp-crontrol'
+ )
+ );
+}
+
+// Alias for backward compatibility with the old codebase
+function wp_allstars_get_recommended_plugins() {
+ return wp_seoprostack_get_recommended_plugins();
+}
+
+// Alias for backward compatibility with the new codebase
+function seoprostack_get_recommended_plugins() {
+ return wp_seoprostack_get_recommended_plugins();
+}
\ No newline at end of file
diff --git a/admin/settings/data/tools.php b/admin/settings/data/tools.php
new file mode 100644
index 0000000..7b61815
--- /dev/null
+++ b/admin/settings/data/tools.php
@@ -0,0 +1,373 @@
+ array(
+ 'name' => 'Advise.so',
+ 'description' => 'Website analytics and optimization tool for improving user experience and conversion rates.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://advise.so/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'seoutils' => array(
+ 'name' => 'SEO Utils',
+ 'description' => 'Collection of SEO tools to analyze and improve website search engine optimization.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://seoutils.app/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'dataforseo' => array(
+ 'name' => 'DataForSEO',
+ 'description' => 'API-based SEO data provider for rank tracking, keyword research and competitive analysis.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://dataforseo.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'ahrefs' => array(
+ 'name' => 'Ahrefs',
+ 'description' => 'Comprehensive SEO toolset for backlink analysis, keyword research, and competitor research.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://ahrefs.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'localrank' => array(
+ 'name' => 'LocalRank.so',
+ 'description' => 'Local SEO tool for tracking and improving local search rankings for businesses.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://localrank.so/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'turnithuman' => array(
+ 'name' => 'Turn It Human',
+ 'description' => 'AI content humanizer that makes AI-generated content sound more natural and authentic.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://turnithuman.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'searchconsole' => array(
+ 'name' => 'Google Search Console',
+ 'description' => 'Free tool from Google to monitor and troubleshoot your site\'s presence in Google Search results.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://search.google.com/search-console/about',
+ 'primary' => true
+ )
+ )
+ ),
+ 'bingwebmaster' => array(
+ 'name' => 'Bing Webmaster Tools',
+ 'description' => 'Free tool from Microsoft to help optimize your website for Bing search engine.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.bing.com/webmasters/about',
+ 'primary' => true
+ )
+ )
+ ),
+ 'fiverr' => array(
+ 'name' => 'Fiverr',
+ 'description' => 'Freelance services marketplace for businesses to find digital services including web development.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.fiverr.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'legiit' => array(
+ 'name' => 'Legiit',
+ 'description' => 'Marketplace for digital marketing services including SEO, content writing, and web design.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://legiit.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'openwebui' => array(
+ 'name' => 'Open WebUI',
+ 'description' => 'Open-source web interface for interacting with AI models and chatbots.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://openwebui.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'nextcloud' => array(
+ 'name' => 'Nextcloud',
+ 'description' => 'Self-hosted productivity platform and file sync solution for secure collaboration.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://nextcloud.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'enpass' => array(
+ 'name' => 'Enpass',
+ 'description' => 'Password manager that stores sensitive information locally on your device.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.enpass.io/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'pdfstudio' => array(
+ 'name' => 'PDF Studio',
+ 'description' => 'Professional PDF editor with advanced features for creating and modifying PDF documents.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.qoppa.com/pdfstudio/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'affinity' => array(
+ 'name' => 'Affinity',
+ 'description' => 'Professional creative software suite including Photo, Designer, and Publisher applications.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://affinity.serif.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'urlmonitor' => array(
+ 'name' => 'URL Monitor',
+ 'description' => 'Website monitoring service that tracks uptime, performance, and alerts you to issues.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://urlmonitor.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'speedyindex' => array(
+ 'name' => 'Speedy Index',
+ 'description' => 'Tool for monitoring website indexing speed and performance in search engines.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://en.speedyindex.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'pagespeed' => array(
+ 'name' => 'PageSpeed Insights',
+ 'description' => 'Google tool that analyzes web page performance on mobile and desktop devices.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://pagespeed.web.dev/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'windsurf' => array(
+ 'name' => 'Codeium Windsurf',
+ 'description' => 'AI-powered IDE with advanced code completion and generation capabilities.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://codeium.com/windsurf',
+ 'primary' => true
+ )
+ )
+ ),
+ 'lowfruits' => array(
+ 'name' => 'Low Fruits',
+ 'description' => 'SEO tool for finding low-competition keywords to target for faster ranking.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://lowfruits.io/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'keysearch' => array(
+ 'name' => 'Keysearch',
+ 'description' => 'Affordable keyword research tool for finding valuable keywords for SEO.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.keysearch.co/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'smartlead' => array(
+ 'name' => 'SmartLead',
+ 'description' => 'Email outreach platform for cold email campaigns and lead generation.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.smartlead.ai/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'zerogptplus' => array(
+ 'name' => 'ZeroGPT Plus',
+ 'description' => 'Advanced AI content detector with improved accuracy and additional features.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.zerogpt.plus/en',
+ 'primary' => true
+ )
+ )
+ ),
+ 'neuronwriter' => array(
+ 'name' => 'NeuronWriter',
+ 'description' => 'AI-powered SEO content optimization tool for creating high-ranking content.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.neuronwriter.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'serposcope' => array(
+ 'name' => 'Serposcope',
+ 'description' => 'Open-source rank tracker to monitor website positions in search engines.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.serposcope.com/en/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'seoptimer' => array(
+ 'name' => 'SEOptimer',
+ 'description' => 'Website audit tool that provides SEO, usability, and performance recommendations.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.seoptimer.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'jitsi' => array(
+ 'name' => 'Jitsi Meet',
+ 'description' => 'Free, open-source video conferencing platform with no account required.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://meet.jit.si/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'libreoffice' => array(
+ 'name' => 'LibreOffice',
+ 'description' => 'Free and open-source office suite compatible with Microsoft Office formats.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.libreoffice.org/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'localwp' => array(
+ 'name' => 'Local',
+ 'description' => 'Local WordPress development tool for creating WordPress sites locally.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://localwp.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'notability' => array(
+ 'name' => 'Notability',
+ 'description' => 'Note-taking app for iPad and Mac with handwriting and PDF annotation features.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://notability.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'ulysses' => array(
+ 'name' => 'Ulysses',
+ 'description' => 'Writing app for Mac, iPad, and iPhone with a clean interface and powerful features.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://ulysses.app/',
+ 'primary' => true
+ )
+ )
+ ),
+ );
+}
+
+// Alias for backward compatibility with the old codebase
+function wp_allstars_get_tools() {
+ return wp_seoprostack_get_tools();
+}
+
+// Alias for backward compatibility with the new codebase
+function seoprostack_get_tools() {
+ return wp_seoprostack_get_tools();
+}
\ No newline at end of file
diff --git a/admin/settings/tabs/class-seoprostack-tab-advanced.php b/admin/settings/tabs/class-seoprostack-tab-advanced.php
new file mode 100644
index 0000000..502a281
--- /dev/null
+++ b/admin/settings/tabs/class-seoprostack-tab-advanced.php
@@ -0,0 +1,159 @@
+ 'yes',
+ 'disable_embeds' => 'yes',
+ 'remove_query_strings' => 'no',
+ 'disable_xmlrpc' => 'yes',
+ 'remove_shortlink' => 'yes',
+ 'remove_rsd_link' => 'yes',
+ 'remove_wlwmanifest_link' => 'yes',
+ 'disable_self_pingbacks' => 'yes',
+ 'disable_feed_links' => 'no',
+ 'remove_rest_api_links' => 'no',
+ 'minify_html' => 'no',
+ 'minify_css' => 'no',
+ 'minify_js' => 'no'
+ ));
+ ?>
+
+
+
+ tab_id;
+ }
+
+ /**
+ * Get the tab title
+ *
+ * @return string The tab title
+ */
+ public function get_title() {
+ return __('Hosting', 'seoprostack');
+ }
+
+ /**
+ * Get the tab description
+ *
+ * @return string The tab description
+ */
+ public function get_description() {
+ return __('Details about your current hosting environment and recommendations for improvement.', 'seoprostack');
+ }
+
+ /**
+ * Get hosting providers
+ * This internalizes the data previously retrieved from wp_seoprostack_get_hosting_providers()
+ *
+ * @return array Array of hosting providers with their details
+ */
+ public function get_hosting_providers() {
+ return array(
+ 'closte' => array(
+ 'name' => 'Closte',
+ 'description' => 'Managed WordPress hosting with advanced performance optimization and auto-scaling.',
+ 'features' => array(
+ 'Auto-scaling architecture',
+ 'Global CDN included',
+ 'Advanced caching',
+ 'Free SSL certificates'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://closte.com/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://closte.com/pricing'
+ )
+ )
+ ),
+ 'cloudron' => array(
+ 'name' => 'Cloudron',
+ 'description' => 'Self-hosted platform that makes it easy to run web applications like WordPress on your server.',
+ 'features' => array(
+ 'One-click installation',
+ 'Automatic updates',
+ 'Built-in backups',
+ 'SSL certificate management'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.cloudron.io/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://www.cloudron.io/pricing.html'
+ )
+ )
+ ),
+ 'hostinger' => array(
+ 'name' => 'Hostinger',
+ 'description' => 'Affordable WordPress hosting with good performance and user-friendly management tools.',
+ 'features' => array(
+ 'Free domain name',
+ 'Managed WordPress features',
+ 'LiteSpeed cache',
+ 'Weekly backups'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.hostinger.com/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://www.hostinger.com/wordpress-hosting'
+ )
+ )
+ ),
+ 'hetzner' => array(
+ 'name' => 'Hetzner Cloud',
+ 'description' => 'High-performance cloud servers with excellent price-to-performance ratio for self-managed WordPress hosting.',
+ 'features' => array(
+ 'Scalable cloud instances',
+ 'Per-minute billing',
+ 'Snapshots and backups',
+ 'Global data centers'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.hetzner.com/cloud/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://www.hetzner.com/cloud#pricing'
+ )
+ )
+ ),
+ 'simplehost' => array(
+ 'name' => 'SimpleHost',
+ 'description' => 'Streamlined WordPress hosting with a focus on simplicity and performance.',
+ 'features' => array(
+ 'Simplified hosting dashboard',
+ 'Pre-optimized WordPress',
+ 'Automated backups',
+ 'Email hosting included'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://simplehost.so/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://simplehost.so/#pricing'
+ )
+ )
+ ),
+ 'cloudflare' => array(
+ 'name' => 'Cloudflare',
+ 'description' => 'Global cloud platform that provides CDN, security, and performance optimization services.',
+ 'features' => array(
+ 'Global CDN network',
+ 'DDoS protection',
+ 'Web application firewall',
+ 'Performance optimization'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.cloudflare.com/en-gb/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://www.cloudflare.com/en-gb/plans/'
+ )
+ )
+ ),
+ 'spaceship' => array(
+ 'name' => 'Spaceship',
+ 'description' => 'Modern hosting platform with advanced features for WordPress sites.',
+ 'features' => array(
+ 'Advanced WordPress tools',
+ 'Optimized for speed',
+ 'Developer-friendly features',
+ 'Smart caching system'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.spaceship.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ '101domain' => array(
+ 'name' => '101Domain',
+ 'description' => 'Domain registration and management service with support for hundreds of TLDs.',
+ 'features' => array(
+ 'Extensive TLD selection',
+ 'Domain privacy protection',
+ 'Expert domain support',
+ 'Bulk domain management'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.101domain.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'namecheap' => array(
+ 'name' => 'Namecheap',
+ 'description' => 'Domain registrar and web hosting provider with competitive pricing and good support.',
+ 'features' => array(
+ 'Free WhoisGuard protection',
+ 'Competitive domain pricing',
+ 'Reliable hosting services',
+ 'Excellent support'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://www.namecheap.com/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://www.namecheap.com/hosting/shared/'
+ )
+ )
+ ),
+ 'updownio' => array(
+ 'name' => 'Updown.io',
+ 'description' => 'Simple and affordable website monitoring service with uptime checks and performance metrics.',
+ 'features' => array(
+ 'Real-time monitoring',
+ 'Performance metrics',
+ 'Notification alerts',
+ 'Detailed reports'
+ ),
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://updown.io/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Pricing',
+ 'url' => 'https://updown.io/pricing'
+ )
+ )
+ )
+ );
+ }
+
+ /**
+ * Render the tab content.
+ */
+ public function render() {
+ // Get server information
+ $server_info = $this->get_server_info();
+
+ // Get hosting providers from the internal method
+ $hosting_providers = $this->get_hosting_providers();
+
+ // For backward compatibility, make hosting providers available through global function
+ if (function_exists('wp_seoprostack_get_hosting_providers') && empty($GLOBALS['_wp_seoprostack_hosting_loaded'])) {
+ // Optional: merge with any providers from the external function to ensure none are lost
+ $external_providers = wp_seoprostack_get_hosting_providers();
+ $hosting_providers = array_merge($external_providers, $hosting_providers);
+ $GLOBALS['_wp_seoprostack_hosting_loaded'] = true;
+ }
+
+ ?>
+
+
+
+
get_description()); ?>
+
+
+
+
+
+ |
+
+
+ get_status_icon($server_info['php_status']); ?>
+ |
+
+
+ |
+
+
+ |
+
+
+ get_status_icon($server_info['mysql_status']); ?>
+ |
+
+
+ |
+
+
+ |
+
+
+ get_status_icon($server_info['wp_status']); ?>
+ |
+
+
+ |
+
+
+ |
+
+
+ get_status_icon($server_info['memory_status']); ?>
+ |
+
+
+ |
+
+
+ |
+
+ seconds
+ get_status_icon($server_info['execution_status']); ?>
+ |
+
+
+ |
+
+
+
+
+
+
+
+ =') ? 'good' : (version_compare($php_version, '7.0', '>=') ? 'warning' : 'bad');
+ $php_note = version_compare($php_version, '7.4', '>=') ? __('Your PHP version is up to date.', 'seoprostack') : __('We recommend PHP 7.4 or higher for optimal performance and security.', 'seoprostack');
+
+ // MySQL version
+ $mysql_version = $wpdb->db_version();
+ $mysql_status = version_compare($mysql_version, '5.6', '>=') ? 'good' : 'warning';
+ $mysql_note = version_compare($mysql_version, '5.6', '>=') ? __('Your MySQL version is sufficient.', 'seoprostack') : __('We recommend MySQL 5.6 or higher for better performance.', 'seoprostack');
+
+ // WordPress version
+ $wp_version = get_bloginfo('version');
+ $wp_status = version_compare($wp_version, '5.8', '>=') ? 'good' : (version_compare($wp_version, '5.5', '>=') ? 'warning' : 'bad');
+ $wp_note = version_compare($wp_version, '5.8', '>=') ? __('Your WordPress version is up to date.', 'seoprostack') : __('We recommend updating to the latest version of WordPress.', 'seoprostack');
+
+ // Memory limit
+ $memory_limit = ini_get('memory_limit');
+ $memory_limit_bytes = wp_convert_hr_to_bytes($memory_limit);
+ $memory_status = $memory_limit_bytes >= 256 * 1024 * 1024 ? 'good' : ($memory_limit_bytes >= 128 * 1024 * 1024 ? 'warning' : 'bad');
+ $memory_note = $memory_limit_bytes >= 256 * 1024 * 1024 ? __('Your memory limit is sufficient.', 'seoprostack') : __('We recommend a memory limit of at least 256MB.', 'seoprostack');
+
+ // Max execution time
+ $max_execution_time = ini_get('max_execution_time');
+ $execution_status = $max_execution_time >= 180 || $max_execution_time == 0 ? 'good' : ($max_execution_time >= 60 ? 'warning' : 'bad');
+ $execution_note = $max_execution_time >= 180 || $max_execution_time == 0 ? __('Your max execution time is sufficient.', 'seoprostack') : __('We recommend a max execution time of at least 180 seconds.', 'seoprostack');
+
+ return array(
+ 'php_version' => $php_version,
+ 'php_status' => $php_status,
+ 'php_note' => $php_note,
+ 'mysql_version' => $mysql_version,
+ 'mysql_status' => $mysql_status,
+ 'mysql_note' => $mysql_note,
+ 'wp_version' => $wp_version,
+ 'wp_status' => $wp_status,
+ 'wp_note' => $wp_note,
+ 'memory_limit' => $memory_limit,
+ 'memory_status' => $memory_status,
+ 'memory_note' => $memory_note,
+ 'max_execution_time' => $max_execution_time,
+ 'execution_status' => $execution_status,
+ 'execution_note' => $execution_note
+ );
+ }
+
+ /**
+ * Get a status icon based on the status.
+ *
+ * @param string $status Status (good, warning, or bad).
+ * @return string Status icon HTML.
+ */
+ private function get_status_icon($status) {
+ switch ($status) {
+ case 'good':
+ return '
';
+ case 'warning':
+ return '
';
+ case 'bad':
+ return '
';
+ default:
+ return '';
+ }
+ }
+}
\ No newline at end of file
diff --git a/admin/settings/tabs/class-seoprostack-tab-pro-plugins.php b/admin/settings/tabs/class-seoprostack-tab-pro-plugins.php
new file mode 100644
index 0000000..6c0704b
--- /dev/null
+++ b/admin/settings/tabs/class-seoprostack-tab-pro-plugins.php
@@ -0,0 +1,176 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ plugin_details = array(
+ 'wordpress-seo' => array(
+ 'name' => 'Yoast SEO (Free)',
+ 'description' => 'The #1 WordPress SEO plugin that helps you with content optimization, XML sitemaps, and more.'
+ ),
+ 'autoptimize' => array(
+ 'name' => 'Autoptimize',
+ 'description' => 'Optimizes your website, concatenating scripts and styles, minifying and compressing them.'
+ ),
+ 'wp-fastest-cache' => array(
+ 'name' => 'WP Fastest Cache',
+ 'description' => 'This plugin creates static html files from your dynamic WordPress site to speed up your website.'
+ ),
+ 'updraftplus' => array(
+ 'name' => 'UpdraftPlus',
+ 'description' => 'Backup your website with ease, including files and database, and restore with one click.'
+ ),
+ 'google-site-kit' => array(
+ 'name' => 'Site Kit by Google',
+ 'description' => 'Get insights from multiple Google products directly in your WordPress dashboard.'
+ ),
+ 'wordfence' => array(
+ 'name' => 'Wordfence Security',
+ 'description' => 'Protect your site from malicious hackers with firewall and malware scanner.'
+ ),
+ 'rank-math-seo' => array(
+ 'name' => 'Rank Math SEO',
+ 'description' => 'SEO plugin that helps you rank higher in search engines with its powerful features and easy-to-use interface.'
+ ),
+ 'all-in-one-seo-pack' => array(
+ 'name' => 'All in One SEO Pack',
+ 'description' => 'Complete SEO solution for WordPress including on-page SEO optimization, XML sitemaps and more.'
+ ),
+ 'compressx' => array(
+ 'name' => 'CompressX',
+ 'description' => 'Comprehensive image optimization plugin for WordPress that improves page load speed.'
+ ),
+ 'wp-rocket' => array(
+ 'name' => 'WP Rocket',
+ 'description' => 'Premium caching plugin that improves site performance and page loading speed.'
+ ),
+ 'contact-form-7' => array(
+ 'name' => 'Contact Form 7',
+ 'description' => 'Simple but flexible contact form plugin with extensive customization options.'
+ )
+ );
+ }
+
+ /**
+ * Get the tab ID
+ *
+ * @return string The tab ID
+ */
+ public function get_tab_id() {
+ return $this->tab_id;
+ }
+
+ /**
+ * Get the tab title
+ *
+ * @return string The tab title
+ */
+ public function get_title() {
+ return __('Recommended Plugins', 'seoprostack');
+ }
+
+ /**
+ * Get the tab description
+ *
+ * @return string The tab description
+ */
+ public function get_description() {
+ return __('These free plugins work well with SEO Pro Stack to enhance your WordPress site.', 'seoprostack');
+ }
+
+ /**
+ * Get recommended plugins
+ * This internalizes the data previously retrieved from wp_seoprostack_get_recommended_plugins()
+ *
+ * @return array Array of recommended plugins categorized by use case
+ */
+ public function get_recommended_plugins() {
+ return array(
+ 'minimal' => array(
+ 'antispam-bee',
+ 'compressx',
+ 'fluent-smtp',
+ 'kadence-blocks',
+ 'simple-cloudflare-turnstile'
+ ),
+ 'admin' => array(
+ 'admin-bar-dashboard-control',
+ 'codepress-admin-columns',
+ 'admin-menu-editor',
+ 'hide-admin-notices',
+ 'mainwp-child',
+ 'mainwp-child-reports',
+ 'magic-login',
+ 'manage-notification-emails',
+ 'plugin-groups',
+ 'plugin-toggle'
+ ),
+ 'affiliates' => array(
+ 'pretty-links',
+ 'simple-urls',
+ 'slicewp'
+ ),
+ 'ai' => array(
+ 'ai-engine',
+ ),
+ 'cms' => array(
+ 'auto-post-scheduler',
+ 'block-options',
+ 'bookmark-card',
+ 'browser-shots',
+ 'bulk-actions-select-all',
+ 'bulk-edit-categories-tags',
+ 'bulk-edit-user-profiles-in-spreadsheet',
+ 'carbon-copy',
+ 'code-block-pro',
+ 'iframe-block',
+ 'ics-calendar',
+ 'mammoth-docx-converter',
+ 'nav-menu-roles',
+ 'ninja-tables',
+ 'post-draft-preview',
+ 'post-type-switcher',
+ 'simple-custom-post-order',
+ 'simple-icons',
+ 'sticky-posts-switch',
+ 'term-management-tools',
+ 'the-paste',
+ 'ultimate-addons-for-gutenberg',
+ 'wikipedia-preview',
+ 'wp-sheet-editor-bulk-spreadsheet-editor-for-posts-and-pages'
+ ),
+ 'compliance' => array(
+ 'avatar-privacy',
+ 'complianz-gdpr',
+ 'complianz-terms-conditions',
+ 'really-simple-ssl'
+ ),
+ 'crm' => array(
+ 'fluent-boards',
+ 'fluent-booking',
+ 'fluent-community',
+ 'fluent-crm',
+ 'fluentform',
+ 'fluentforms-pdf',
+ 'fluentform-block',
+ 'fluent-support'
+ ),
+ 'ecommerce' => array(
+ 'woocommerce',
+ 'woo-bulk-edit-products',
+ 'woo-coupons-bulk-editor',
+ 'woocommerce-gateway-gocardless',
+ 'kadence-woocommerce-email-designer',
+ 'pymntpl-paypal-woocommerce',
+ 'woo-stripe-payment'
+ ),
+ 'lms' => array(
+ 'fluent-community',
+ 'masterstudy-lms-learning-management-system',
+ 'tutor'
+ ),
+ 'media' => array(
+ 'easy-watermark',
+ 'enable-media-replace',
+ 'image-copytrack',
+ 'imsanity',
+ 'media-file-renamer',
+ 'safe-svg'
+ ),
+ 'seo' => array(
+ 'burst-statistics',
+ 'pretty-link',
+ 'revive-so',
+ 'seo-by-rank-math',
+ 'syndication-links',
+ 'ultimate-410',
+ 'webmention'
+ ),
+ 'setup' => array(
+ 'kadence-starter-templates',
+ 'wordpress-importer'
+ ),
+ 'social' => array(
+ 'bit-social',
+ 'easy-video-reviews',
+ 'social-engine',
+ 'wp-social-ninja',
+ 'wp-social-reviews'
+ ),
+ 'speed' => array(
+ 'disable-wordpress-updates',
+ 'flying-analytics',
+ 'flying-pages',
+ 'flying-scripts',
+ 'freesoul-deactivate-plugins',
+ 'index-wp-mysql-for-speed',
+ 'litespeed-cache',
+ 'performant-translations',
+ 'wp-optimize',
+ 'wp-widget-disable'
+ ),
+ 'translation' => array(
+ 'hreflang-manager-lite',
+ 'performant-translations',
+ 'translatepress-multilingual'
+ ),
+ 'advanced' => array(
+ 'acf-better-search',
+ 'advanced-custom-fields',
+ 'automatorwp',
+ 'bit-pi',
+ 'bit-integrations',
+ 'code-snippets',
+ 'easy-code-manager',
+ 'favorites',
+ 'remove-cpt-base',
+ 'remove-old-slugspermalinks',
+ 'secure-custom-fields',
+ 'yellow-pencil-visual-theme-customizer'
+ ),
+ 'debug' => array(
+ 'advanced-database-cleaner',
+ 'debug-log-manager',
+ 'gotmls',
+ 'query-monitor',
+ 'string-locator',
+ 'user-switching',
+ 'wp-crontrol'
+ )
+ );
+ }
+
+ /**
+ * Render the tab content.
+ */
+ public function render() {
+ // Get recommended plugins from the internal method
+ $recommended_plugins = $this->get_recommended_plugins();
+
+ // For backward compatibility, make recommended plugins available through global function
+ if (function_exists('wp_seoprostack_get_recommended_plugins') && empty($GLOBALS['_wp_seoprostack_recommended_plugins_loaded'])) {
+ // Optional: merge with any plugins from the external function to ensure none are lost
+ $external_plugins = wp_seoprostack_get_recommended_plugins();
+ $recommended_plugins = array_merge_recursive($external_plugins, $recommended_plugins);
+ $GLOBALS['_wp_seoprostack_recommended_plugins_loaded'] = true;
+ }
+
+ ?>
+
+
+
+
get_description()); ?>
+
+ ' . esc_html__('SEO Plugins', 'seoprostack') . '';
+ echo '
';
+ foreach ($recommended_plugins['seo'] as $plugin_slug) {
+ $this->render_plugin_card($plugin_slug);
+ }
+ echo '
';
+ }
+
+ // Display Cache plugins section
+ if (!empty($recommended_plugins['speed'])) {
+ echo '
' . esc_html__('Cache & Performance', 'seoprostack') . '
';
+ echo '
';
+ foreach ($recommended_plugins['speed'] as $plugin_slug) {
+ $this->render_plugin_card($plugin_slug);
+ }
+ echo '
';
+ }
+
+ // Display Security plugins section
+ if (!empty($recommended_plugins['security'])) {
+ echo '
' . esc_html__('Security', 'seoprostack') . '
';
+ echo '
';
+ foreach ($recommended_plugins['security'] as $plugin_slug) {
+ $this->render_plugin_card($plugin_slug);
+ }
+ echo '
';
+ }
+
+ // Display Image optimization plugins section
+ if (!empty($recommended_plugins['media'])) {
+ echo '
' . esc_html__('Image Optimization', 'seoprostack') . '
';
+ echo '
';
+ foreach ($recommended_plugins['media'] as $plugin_slug) {
+ $this->render_plugin_card($plugin_slug);
+ }
+ echo '
';
+ }
+
+ // Display Backup plugins section
+ if (!empty($recommended_plugins['backup'])) {
+ echo '
' . esc_html__('Backup & Migration', 'seoprostack') . '
';
+ echo '
';
+ foreach ($recommended_plugins['backup'] as $plugin_slug) {
+ $this->render_plugin_card($plugin_slug);
+ }
+ echo '
';
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+ plugin_details[$slug]['name']) ? $this->plugin_details[$slug]['name'] : $this->get_readable_name($slug);
+ $description = isset($this->plugin_details[$slug]['description']) ? $this->plugin_details[$slug]['description'] : '';
+
+ // Check if plugin is installed and active
+ $status = 'not-installed';
+ $status_text = 'Not Installed';
+
+ if (file_exists(WP_PLUGIN_DIR . '/' . $slug)) {
+ $status = 'installed';
+ $status_text = 'Installed';
+
+ include_once ABSPATH . 'wp-admin/includes/plugin.php';
+ if (is_plugin_active($slug . '/' . $slug . '.php') || is_plugin_active($slug . '/index.php')) {
+ $status = 'active';
+ $status_text = 'Active';
+ }
+ }
+
+ ?>
+
+ __('You do not have permission to install plugins.', 'seoprostack')));
+ }
+
+ // Get selected plugins
+ $plugins = isset($_POST['plugins']) ? (array) $_POST['plugins'] : array();
+
+ if (empty($plugins)) {
+ wp_send_json_error(array('message' => __('No plugins selected.', 'seoprostack')));
+ }
+
+ // Include required files for plugin installation
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
+ require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
+ require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
+
+ // Set up the upgrader
+ $skin = new WP_Ajax_Upgrader_Skin();
+ $upgrader = new Plugin_Upgrader($skin);
+
+ $installed = array();
+ $failed = array();
+
+ // Install and activate each plugin
+ foreach ($plugins as $plugin) {
+ // Skip if already active
+ if (is_plugin_active($plugin . '/' . $plugin . '.php') || is_plugin_active($plugin . '/index.php')) {
+ continue;
+ }
+
+ // Get plugin info from wordpress.org
+ $api = plugins_api('plugin_information', array(
+ 'slug' => $plugin,
+ 'fields' => array(
+ 'short_description' => false,
+ 'sections' => false,
+ 'requires' => false,
+ 'rating' => false,
+ 'ratings' => false,
+ 'downloaded' => false,
+ 'last_updated' => false,
+ 'added' => false,
+ 'tags' => false,
+ 'compatibility' => false,
+ 'homepage' => false,
+ 'donate_link' => false,
+ ),
+ ));
+
+ if (is_wp_error($api)) {
+ $failed[] = array(
+ 'plugin' => $plugin,
+ 'message' => $api->get_error_message()
+ );
+ continue;
+ }
+
+ // Install the plugin
+ $result = $upgrader->install($api->download_link);
+
+ if (is_wp_error($result)) {
+ $failed[] = array(
+ 'plugin' => $plugin,
+ 'message' => $result->get_error_message()
+ );
+ continue;
+ }
+
+ if ($result === false) {
+ $failed[] = array(
+ 'plugin' => $plugin,
+ 'message' => __('Failed to install plugin.', 'seoprostack')
+ );
+ continue;
+ }
+
+ // Activate the plugin
+ $activate = activate_plugin(WP_PLUGIN_DIR . '/' . $plugin . '/' . $plugin . '.php');
+ if (is_wp_error($activate)) {
+ // Try alternative file path
+ $activate = activate_plugin(WP_PLUGIN_DIR . '/' . $plugin . '/index.php');
+ if (is_wp_error($activate)) {
+ $failed[] = array(
+ 'plugin' => $plugin,
+ 'message' => $activate->get_error_message()
+ );
+ continue;
+ }
+ }
+
+ $installed[] = $plugin;
+ }
+
+ // Send success response
+ wp_send_json_success(array(
+ 'installed' => $installed,
+ 'failed' => $failed
+ ));
+ }
+}
\ No newline at end of file
diff --git a/admin/settings/tabs/class-seoprostack-tab-theme.php b/admin/settings/tabs/class-seoprostack-tab-theme.php
new file mode 100644
index 0000000..498b652
--- /dev/null
+++ b/admin/settings/tabs/class-seoprostack-tab-theme.php
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+ get_screenshot()) : ?>
+
+
); ?>)
+
+
+
+
display('Name')); ?>
+
display('Version')); ?>
+
display('Author')); ?>
+
display('Description')); ?>
+
+
+
+
+
+
+
+ tab_id;
+ }
+
+ /**
+ * Get the tab title
+ *
+ * @return string The tab title
+ */
+ public function get_title() {
+ return __('Tools', 'seoprostack');
+ }
+
+ /**
+ * Get the tab description
+ *
+ * @return string The tab description
+ */
+ public function get_description() {
+ return __('Useful tools and resources to help improve your website\'s SEO and performance.', 'seoprostack');
+ }
+
+ /**
+ * Get the tools data
+ * This internalizes the data previously retrieved from wp_seoprostack_get_tools()
+ *
+ * @return array Array of tools with their details
+ */
+ public function get_tools() {
+ return array(
+ 'advise' => array(
+ 'name' => 'Advise.so',
+ 'description' => 'Accelerate website growth with AI-powered content optimization and topic recommendations.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://advise.so/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'App',
+ 'url' => 'https://app.advise.so/'
+ )
+ )
+ ),
+ 'seoutils' => array(
+ 'name' => 'SEO Utils',
+ 'description' => 'Rich collection of online SEO tools for keyword research, SERP analysis, and content optimization.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://seoutils.com/',
+ 'primary' => true
+ )
+ )
+ ),
+ 'dataforseo' => array(
+ 'name' => 'DataForSEO',
+ 'description' => 'Comprehensive SEO APIs for rank tracking, SERP analysis, and keyword research.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://dataforseo.com/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Dashboard',
+ 'url' => 'https://app.dataforseo.com/'
+ )
+ )
+ ),
+ // For brevity, I'm including only a few tools here
+ // In production, you would include all tools or dynamically load them
+ 'ahrefs' => array(
+ 'name' => 'Ahrefs',
+ 'description' => 'Comprehensive SEO toolset for backlink analysis, keyword research, and competitor analysis.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://ahrefs.com/',
+ 'primary' => true
+ ),
+ array(
+ 'text' => 'Dashboard',
+ 'url' => 'https://app.ahrefs.com/'
+ )
+ )
+ ),
+ 'localrank' => array(
+ 'name' => 'LocalRank',
+ 'description' => 'Track keyword rankings for multiple locations to better understand local SEO performance.',
+ 'button_group' => array(
+ array(
+ 'text' => 'Home Page',
+ 'url' => 'https://app.localrank.io/',
+ 'primary' => true
+ )
+ )
+ ),
+ // Additional tools would be listed here...
+ );
+ }
+
+ /**
+ * Render the tab content.
+ */
+ public function render() {
+ // Get tools from the internal method
+ $tools = $this->get_tools();
+
+ // For backward compatibility, make tools available through the global function
+ if (function_exists('wp_seoprostack_get_tools') && empty($GLOBALS['_wp_seoprostack_tools_loaded'])) {
+ // Optional: merge with any tools from the external function to ensure none are lost
+ $external_tools = wp_seoprostack_get_tools();
+ $tools = array_merge($external_tools, $tools);
+ $GLOBALS['_wp_seoprostack_tools_loaded'] = true;
+ }
+
+ ?>
+
+
+
+
get_description()); ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ __('You do not have permission to perform this action.', 'seoprostack')));
+ }
+
+ global $wpdb;
+
+ // Optimize database tables
+ $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
+ $optimized = 0;
+
+ foreach ($tables as $table) {
+ if (0 === strpos($table[0], $wpdb->prefix)) {
+ $wpdb->query("OPTIMIZE TABLE {$table[0]}");
+ $optimized++;
+ }
+ }
+
+ // Clean up post revisions
+ $deleted_revisions = $wpdb->query("DELETE FROM $wpdb->posts WHERE post_type = 'revision'");
+
+ // Clean up auto drafts
+ $deleted_drafts = $wpdb->query("DELETE FROM $wpdb->posts WHERE post_status = 'auto-draft'");
+
+ // Clean up orphaned postmeta
+ $deleted_postmeta = $wpdb->query("
+ DELETE pm
+ FROM $wpdb->postmeta pm
+ LEFT JOIN $wpdb->posts p ON p.ID = pm.post_id
+ WHERE p.ID IS NULL
+ ");
+
+ // Send success response
+ wp_send_json_success(array(
+ 'message' => sprintf(
+ __('Database optimization complete. Optimized %d tables, deleted %d revisions, %d auto-drafts, and %d orphaned postmeta entries.', 'seoprostack'),
+ $optimized,
+ $deleted_revisions,
+ $deleted_drafts,
+ $deleted_postmeta
+ )
+ ));
+ }
+}
\ No newline at end of file
diff --git a/admin/settings/tabs/class-seoprostack-tab-workflow.php b/admin/settings/tabs/class-seoprostack-tab-workflow.php
new file mode 100644
index 0000000..4e5c3d4
--- /dev/null
+++ b/admin/settings/tabs/class-seoprostack-tab-workflow.php
@@ -0,0 +1,132 @@
+ true,
+ 'max_width' => 1200,
+ 'max_height' => 1200,
+ 'exclude_urls' => '',
+ 'image_name_pattern' => '%filename%',
+ 'image_alt_pattern' => '%filename%'
+ ));
+ ?>
+
+ actions = array();
+ $this->filters = array();
+ }
+
+ /**
+ * Add a new action to the collection.
+ *
+ * @param string $hook The name of the WordPress action that is being registered.
+ * @param object $component A reference to the instance of the object.
+ * @param string $callback The name of the function definition on the component.
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the callback. Default is 1.
+ */
+ public function add_action($hook, $component, $callback, $priority = 10, $accepted_args = 1) {
+ $this->actions = $this->add($this->actions, $hook, $component, $callback, $priority, $accepted_args);
+ }
+
+ /**
+ * Add a new filter to the collection.
+ *
+ * @param string $hook The name of the WordPress filter that is being registered.
+ * @param object $component A reference to the instance of the object.
+ * @param string $callback The name of the function definition on the component.
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the callback. Default is 1.
+ */
+ public function add_filter($hook, $component, $callback, $priority = 10, $accepted_args = 1) {
+ $this->filters = $this->add($this->filters, $hook, $component, $callback, $priority, $accepted_args);
+ }
+
+ /**
+ * A utility function that is used to register the actions and hooks.
+ *
+ * @param array $hooks The collection of hooks that is being registered.
+ * @param string $hook The name of the WordPress filter that is being registered.
+ * @param object $component A reference to the instance of the object.
+ * @param string $callback The name of the function definition on the component.
+ * @param int $priority The priority at which the function should be fired.
+ * @param int $accepted_args The number of arguments that should be passed to the callback.
+ * @return array The collection of actions and filters registered.
+ */
+ private function add($hooks, $hook, $component, $callback, $priority, $accepted_args) {
+ $hooks[] = array(
+ 'hook' => $hook,
+ 'component' => $component,
+ 'callback' => $callback,
+ 'priority' => $priority,
+ 'accepted_args' => $accepted_args,
+ );
+
+ return $hooks;
+ }
+
+ /**
+ * Register the filters and actions with WordPress.
+ */
+ public function run() {
+ foreach ($this->filters as $hook) {
+ add_filter($hook['hook'], array($hook['component'], $hook['callback']), $hook['priority'], $hook['accepted_args']);
+ }
+
+ foreach ($this->actions as $hook) {
+ add_action($hook['hook'], array($hook['component'], $hook['callback']), $hook['priority'], $hook['accepted_args']);
+ }
+ }
+}
\ No newline at end of file
diff --git a/includes/core/class-seoprostack-plugin.php b/includes/core/class-seoprostack-plugin.php
new file mode 100644
index 0000000..0fabc46
--- /dev/null
+++ b/includes/core/class-seoprostack-plugin.php
@@ -0,0 +1,69 @@
+load_dependencies();
+ $this->define_admin_hooks();
+ $this->define_features();
+ }
+
+ /**
+ * Load the required dependencies for this plugin.
+ */
+ private function load_dependencies() {
+ // The class responsible for orchestrating the actions and filters
+ require_once SEOPROSTACK_PLUGIN_DIR . 'includes/core/class-seoprostack-loader.php';
+ $this->loader = new SEOProStack_Loader();
+ }
+
+ /**
+ * Register all of the hooks related to the admin area.
+ */
+ private function define_admin_hooks() {
+ // Admin functionality
+ require_once SEOPROSTACK_PLUGIN_DIR . 'admin/class-seoprostack-admin.php';
+ $admin = new SEOProStack_Admin();
+ $admin->initialize();
+ }
+
+ /**
+ * Register all of the hooks related to plugin features.
+ */
+ private function define_features() {
+ // Auto Upload feature
+ require_once SEOPROSTACK_PLUGIN_DIR . 'includes/features/auto-upload/class-seoprostack-auto-upload.php';
+ $auto_upload = new SEOProStack_Auto_Upload();
+ }
+
+ /**
+ * Run the loader to execute all of the hooks with WordPress.
+ */
+ public function run() {
+ $this->loader->run();
+ }
+}
\ No newline at end of file
diff --git a/includes/features/auto-upload/class-seoprostack-auto-upload.php b/includes/features/auto-upload/class-seoprostack-auto-upload.php
new file mode 100644
index 0000000..ce292eb
--- /dev/null
+++ b/includes/features/auto-upload/class-seoprostack-auto-upload.php
@@ -0,0 +1,136 @@
+ false));
+
+ // Use new options if they exist, otherwise fall back to old options
+ $options = $seoprostack_options !== null ? $seoprostack_options : $allstars_options;
+
+ if (!$options['auto_upload_images']) {
+ return $content;
+ }
+
+ // Regular expression to find image URLs
+ $pattern = '/
![]()
]+src=[\'"]([^\'"]+)[\'"][^>]*>/i';
+
+ return preg_replace_callback($pattern, array($this, 'process_image_url'), $content);
+ }
+
+ /**
+ * Process individual image URL
+ *
+ * @param array $matches Regex matches
+ * @return string Updated img tag
+ */
+ private function process_image_url($matches) {
+ if (empty($matches[1])) {
+ return $matches[0];
+ }
+
+ $url = $matches[1];
+
+ // Skip if already a local URL
+ if ($this->is_local_url($url)) {
+ return $matches[0];
+ }
+
+ try {
+ $local_url = $this->upload_image($url);
+ if ($local_url) {
+ return str_replace($url, $local_url, $matches[0]);
+ }
+ } catch (Exception $e) {
+ // Fire both actions for backward compatibility
+ do_action('wp_seoprostack_image_upload_error', $url, $e->getMessage());
+ do_action('wp_allstars_image_upload_error', $url, $e->getMessage());
+ }
+
+ return $matches[0];
+ }
+
+ /**
+ * Check if URL is local
+ *
+ * @param string $url URL to check
+ * @return boolean
+ */
+ private function is_local_url($url) {
+ $site_url = parse_url(get_site_url(), PHP_URL_HOST);
+ $image_host = parse_url($url, PHP_URL_HOST);
+ return $site_url === $image_host;
+ }
+
+ /**
+ * Upload external image to media library
+ *
+ * @param string $url External image URL
+ * @return string|false Local URL on success, false on failure
+ */
+ private function upload_image($url) {
+ // Get file info
+ $file_array = array();
+ $file_array['name'] = basename($url);
+
+ // Download file to temp location
+ $file_array['tmp_name'] = download_url($url);
+
+ if (is_wp_error($file_array['tmp_name'])) {
+ throw new Exception('Failed to download image: ' . $file_array['tmp_name']->get_error_message());
+ }
+
+ // Check file type
+ $wp_filetype = wp_check_filetype_and_ext($file_array['tmp_name'], $file_array['name']);
+ if (!$wp_filetype['type']) {
+ unlink($file_array['tmp_name']);
+ throw new Exception('Invalid file type');
+ }
+
+ // Upload the file
+ $attachment_id = media_handle_sideload($file_array, 0);
+
+ if (is_wp_error($attachment_id)) {
+ throw new Exception('Failed to upload image: ' . $attachment_id->get_error_message());
+ }
+
+ return wp_get_attachment_url($attachment_id);
+ }
+
+ /**
+ * Log errors to WordPress debug log
+ *
+ * @param string $url URL that failed
+ * @param string $error Error message
+ */
+ public function log_error($url, $error) {
+ error_log(sprintf(
+ '[SEO Pro Stack] Auto Upload Images Error - URL: %s, Error: %s',
+ $url,
+ $error
+ ));
+ }
+}
\ No newline at end of file
diff --git a/wp-allstars-plugin.php b/wp-allstars-plugin.php
deleted file mode 100644
index 7f4c2aa..0000000
--- a/wp-allstars-plugin.php
+++ /dev/null
@@ -1,97 +0,0 @@
- admin_url( 'admin-ajax.php' ),
-// 'nonce' => wp_create_nonce( 'wp-allstars-nonce' )
-// ] );
-// }
-// add_action( 'admin_enqueue_scripts', 'wp_allstars_localize_script' );
-
-// Admin assets
-function wp_allstars_admin_assets() {
- // Enqueue styles
- wp_enqueue_style(
- 'wp-allstars-admin',
- plugins_url( 'admin/css/wp-allstars-admin.css', __FILE__ ),
- array(),
- WP_ALLSTARS_VERSION
- );
-
- // Enqueue script
- // Enqueue WordPress updates script for theme installation
- wp_enqueue_script('updates');
-
- wp_enqueue_script(
- 'wp-allstars-admin',
- plugins_url( 'admin/js/wp-allstars-admin.js', __FILE__ ),
- array('jquery', 'updates'),
- WP_ALLSTARS_VERSION,
- true
- );
-
- // Localize script for AJAX
- $ajax_data = array(
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
- 'adminUrl' => admin_url(),
- 'nonce' => wp_create_nonce( 'wp-allstars-nonce' ),
- 'updateNonce' => wp_create_nonce( 'updates' )
- );
- wp_localize_script( 'wp-allstars-admin', 'wpAllstars', $ajax_data );
-}
-add_action( 'admin_enqueue_scripts', 'wp_allstars_admin_assets' );
-
-// Initialize classes
-$wp_allstars_auto_upload = new WP_Allstars_Auto_Upload();
\ No newline at end of file
diff --git a/wp-seoprostack-plugin.php b/wp-seoprostack-plugin.php
new file mode 100644
index 0000000..78cd754
--- /dev/null
+++ b/wp-seoprostack-plugin.php
@@ -0,0 +1,96 @@
+run();
+}
+run_seoprostack();
+
+// Admin assets
+function seoprostack_admin_assets() {
+ // Only load on the plugin settings page
+ $screen = get_current_screen();
+ if ($screen->id !== 'settings_page_seoprostack') {
+ return;
+ }
+
+ // Enqueue styles
+ wp_enqueue_style(
+ 'seoprostack-admin',
+ SEOPROSTACK_PLUGIN_URL . 'admin/css/seoprostack-admin.css',
+ array(),
+ SEOPROSTACK_VERSION
+ );
+
+ // Enqueue WordPress updates script for theme installation
+ wp_enqueue_script('updates');
+
+ wp_enqueue_script(
+ 'seoprostack-admin',
+ SEOPROSTACK_PLUGIN_URL . 'admin/js/seoprostack-admin.js',
+ array('jquery', 'updates'),
+ SEOPROSTACK_VERSION,
+ true
+ );
+
+ // Localize script for AJAX
+ $ajax_data = array(
+ 'ajaxurl' => admin_url('admin-ajax.php'),
+ 'adminUrl' => admin_url(),
+ 'nonce' => wp_create_nonce('seoprostack-nonce'),
+ 'updateNonce' => wp_create_nonce('updates')
+ );
+ wp_localize_script('seoprostack-admin', 'seoProStack', $ajax_data);
+}
+add_action('admin_enqueue_scripts', 'seoprostack_admin_assets');
\ No newline at end of file