diff --git a/README.md b/README.md index 0f49271..00c0477 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,19 @@ -# WP Allstars +# SEO Pro Stack -A WordPress plugin that enhances your WordPress experience with curated plugins, themes, and optimization tools. +A WordPress plugin that enhances your WordPress site's SEO capabilities with curated tools, themes, hosting recommendations, and optimization features. ## Description -WP Allstars is a powerful WordPress plugin designed to help site owners and developers optimize their WordPress installations. It provides a curated collection of recommended plugins, themes, and optimization tools all in one place. +SEO Pro Stack is a powerful WordPress plugin designed to help site owners and developers optimize their WordPress installations for better search engine performance. It provides a curated collection of recommended plugins, themes, hosting providers, and optimization tools all in one place. ## Features -- **Curated Plugin Recommendations**: Browse and install recommended free plugins organized by category. -- **Pro Plugin Showcase**: Discover premium plugins with direct links to purchase. -- **Theme Integration**: Easily install and activate the Kadence theme. -- **Workflow Optimization**: Tools to streamline your WordPress workflow. -- **Advanced Settings**: Fine-tune your WordPress installation with advanced configuration options. +- **Pro Plugin Recommendations**: Browse and discover premium SEO and performance plugins with detailed information. +- **Theme Recommendations**: Find SEO-friendly themes that are optimized for performance and user experience. +- **Hosting Recommendations**: Choose the best hosting providers optimized for WordPress and SEO performance. +- **Advanced Settings**: Fine-tune your WordPress installation with SEO-focused configuration options. +- **Tools**: Optimize your database, generate robots.txt, and access other helpful SEO utilities. +- **Auto Upload**: Automatically upload and organize images for better content management. ## Installation @@ -23,90 +24,86 @@ WP Allstars is a powerful WordPress plugin designed to help site owners and deve ## Usage -After activation, you'll find the WP Allstars menu in your WordPress admin sidebar. The plugin includes several tabs: +After activation, you'll find the SEO Pro Stack menu in your WordPress admin sidebar. The plugin includes several tabs: -### General +### Pro Plugins -Basic settings for the plugin, including: -- Auto Upload Images -- Image Optimization -- Cache Management +Discover premium plugins specifically chosen to enhance your site's SEO performance: +- SEO Plugins +- Performance Plugins +- Content Plugins +- Analytics Plugins + +### Theme + +Find and install SEO-optimized themes: +- Fast-loading themes +- Schema-ready themes +- Mobile-optimized themes +- Accessibility-focused themes ### Advanced Advanced configuration options for WordPress optimization: +- Disable unnecessary WordPress features +- Remove query strings from static resources +- Disable XML-RPC, embeds, and emojis +- Remove REST API links and other unnecessary metadata -- Performance Settings -- Security Enhancements -- Development Tools +### Recommended Plugins -### Workflow +Free and beneficial plugins that complement the SEO Pro Stack ecosystem: +- Essential plugin recommendations +- Plugin compatibility information +- Simplified installation process -Tools to improve your WordPress workflow: +### Hosting -- Content Management -- Media Handling -- Site Maintenance +Recommendations for WordPress hosting providers optimized for SEO: +- Managed WordPress hosting +- Performance-focused hosting +- Hosting provider comparisons +- Special offers and discounts -### Free Plugins +### Tools -Browse and install recommended free plugins organized by categories: +Utilities to help optimize your WordPress site: +- Database optimization +- Robots.txt generator +- SEO audit tools +- Cache management -- Minimal -- Admin -- AI -- CMS -- Compliance -- CRM -- Ecommerce -- LMS -- Media -- SEO -- Setup -- Social -- Speed -- Translation -- Advanced -- Debug +## File Structure -### Pro Plugins +The plugin follows a modular structure for better maintainability: -Discover premium plugins with direct links to purchase. +``` +wp-seoprostack-plugin/ +├── admin/ +│ ├── css/ +│ ├── images/ +│ │ ├── hosting/ +│ │ └── themes/ +│ ├── js/ +│ └── settings/ +│ ├── ajax/ +│ └── tabs/ +├── includes/ +│ ├── core/ +│ └── features/ +└── public/ +``` -### Theme +## Requirements -Easily install and activate the Kadence theme. +- WordPress 5.0 or higher +- PHP 7.2 or higher -## Development +## Changelog -### Requirements - -- WordPress 5.8 or higher -- PHP 7.4 or higher - -### Contributing - -1. Fork the repository -2. Create a feature branch: `git checkout -b feature/your-feature-name` -3. Commit your changes: `git commit -am 'Add some feature'` -4. Push to the branch: `git push origin feature/your-feature-name` -5. Submit a pull request - -## License - -This plugin is licensed under the GPL v2 or later. +### 1.0.0 +- Initial release with comprehensive SEO tools and recommendations ## Credits -Developed by [Your Name/Company] - -## Support - -For support, please [create an issue](https://github.com/yourusername/wp-allstars/issues) on the GitHub repository. - -## Debugging - -- Debug mode can be enabled in wp-config.php -- Errors are logged to `wp-content/wp-allstars.log` - -# \ No newline at end of file +Developed by Marcus Quinn \ No newline at end of file diff --git a/admin/class-seoprostack-admin.php b/admin/class-seoprostack-admin.php new file mode 100644 index 0000000..53020ba --- /dev/null +++ b/admin/class-seoprostack-admin.php @@ -0,0 +1,123 @@ +init_ajax_handlers(); + } + + /** + * Register the stylesheets for the admin area. + * + * @param string $hook The current admin page. + */ + public function enqueue_styles($hook) { + // Only load styles on our settings page + if (strpos($hook, 'seoprostack') === false && strpos($hook, 'page=seoprostack') === false) { + return; + } + + wp_enqueue_style( + 'seoprostack-admin', + SEOPROSTACK_PLUGIN_URL . 'admin/css/seoprostack-admin.css', + array(), + SEOPROSTACK_VERSION + ); + + wp_enqueue_style( + 'seoprostack-plugins', + SEOPROSTACK_PLUGIN_URL . 'admin/css/seoprostack-plugins.css', + array(), + SEOPROSTACK_VERSION + ); + } + + /** + * Register the JavaScript for the admin area. + * + * @param string $hook The current admin page. + */ + public function enqueue_scripts($hook) { + // Only load scripts on our settings page + if (strpos($hook, 'seoprostack') === false && strpos($hook, 'page=seoprostack') === false) { + return; + } + + // 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_ajax_nonce'), + 'updateNonce' => wp_create_nonce('updates') + ); + + wp_localize_script('seoprostack-admin', 'seoProStack', $ajax_data); + } + + /** + * Add settings page to the WordPress admin menu. + */ + public function add_settings_page() { + // Initialize settings page + require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/class-seoprostack-settings-page.php'; + $settings_page = new SEOProStack_Settings_Page(); + $settings_page->add_menu_page(); + $settings_page->register_settings(); + } + + /** + * Initialize AJAX handlers. + */ + public function init_ajax_handlers() { + // Pro Plugins AJAX handler + require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/ajax/class-seoprostack-ajax-pro-plugins.php'; + $pro_plugins_ajax = new SEOProStack_AJAX_Pro_Plugins(); + $pro_plugins_ajax->init(); + + // Advanced Settings AJAX handler + require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/ajax/class-seoprostack-ajax-advanced.php'; + $advanced_ajax = new SEOProStack_AJAX_Advanced(); + $advanced_ajax->init(); + + // Tools AJAX handler + require_once SEOPROSTACK_PLUGIN_DIR . 'admin/settings/ajax/class-seoprostack-ajax-tools.php'; + $tools_ajax = new SEOProStack_AJAX_Tools(); + $tools_ajax->init(); + } +} \ No newline at end of file diff --git a/admin/css/wp-allstars-admin.css b/admin/css/seoprostack-admin.css similarity index 59% rename from admin/css/wp-allstars-admin.css rename to admin/css/seoprostack-admin.css index 46b16a7..812d248 100644 --- a/admin/css/wp-allstars-admin.css +++ b/admin/css/seoprostack-admin.css @@ -803,4 +803,575 @@ input:checked + .wp-toggle-slider:before { .wpa-pro-plugin .button { width: 100%; } +} + +/** + * SEO Pro Stack Admin CSS + * + * Styles for the admin settings pages + * + * @package SEO_Pro_Stack + */ + +/* Main Settings Container */ +.seoprostack-wrap { + max-width: none; + margin: 0; + padding-right: 20px; +} + +/* Header Section */ +.seoprostack-header { + background: #fff; + border-bottom: 1px solid #c3c4c7; + box-shadow: 0 1px 0 rgba(0,0,0,.04); + margin: 0 -20px 0 -20px; + padding: 20px; + display: flex; + align-items: center; + justify-content: space-between; + width: auto; + position: relative; +} + +.seoprostack-header h1 { + font-size: 23px; + font-weight: 400; + margin: 0; + padding: 0; + line-height: 1.3; + color: #1d2327; +} + +.seoprostack-header-actions { + display: flex; + align-items: center; + gap: 10px; +} + +.seoprostack-version { + color: #d35400; /* Dark orange */ + font-size: 13px; + font-weight: 400; +} + +.seoprostack-description { + margin-top: 5px; + color: #757575; + font-size: 14px; +} + +/* Navigation Tabs */ +.nav-tab-wrapper, +.wrap h2.nav-tab-wrapper { + border-bottom: 1px solid #c3c4c7; + margin: 0 -20px; + padding: 0 20px; + background: #fff; + position: sticky; + top: 32px; + z-index: 100; +} + +.nav-tab { + background: #f7f7f7; + border-color: #c3c4c7; + color: #555; + margin-bottom: -1px; + margin-right: 5px; +} + +.nav-tab:hover, +.nav-tab:focus { + background: #fff; + color: #d35400; +} + +.nav-tab-active, +.nav-tab-active:hover, +.nav-tab-active:focus { + background: #fff; + border-bottom-color: #fff; + color: #d35400; +} + +/* Settings Container */ +.seoprostack-settings-container { + margin-top: 20px; + display: flex; + flex-direction: column; +} + +.seoprostack-settings-content { + background: #fff; + border: 1px solid #c3c4c7; + border-radius: 4px; + padding: 20px; + margin-bottom: 20px; +} + +/* Setting Sections */ +.seoprostack-setting-section { + margin-bottom: 30px; +} + +.seoprostack-setting-section h2 { + font-size: 18px; + font-weight: 600; + margin-top: 0; + margin-bottom: 15px; + padding-bottom: 10px; + border-bottom: 1px solid #eee; +} + +.seoprostack-setting-section h3 { + font-size: 16px; + font-weight: 600; + margin-top: 20px; + margin-bottom: 10px; +} + +.seoprostack-setting-section p.description { + color: #757575; + font-size: 13px; + margin-bottom: 15px; + max-width: 760px; +} + +/* Setting Rows */ +.seoprostack-setting-row { + margin-bottom: 15px; + padding: 10px; + border-radius: 4px; + transition: background-color 0.3s; +} + +.seoprostack-setting-row:hover { + background-color: #f9f9f9; +} + +.seoprostack-setting-row label { + display: block; + margin-bottom: 8px; + font-size: 14px; + font-weight: 600; +} + +.seoprostack-setting-row input[type="text"], +.seoprostack-setting-row input[type="number"], +.seoprostack-setting-row select, +.seoprostack-setting-row textarea { + width: 100%; + max-width: 500px; +} + +.seoprostack-setting-row .description { + display: block; + margin-top: 5px; + color: #757575; + font-size: 13px; +} + +/* Toggle Sections */ +.seoprostack-toggle { + border: 1px solid #ddd; + border-radius: 4px; + margin-bottom: 15px; + overflow: hidden; +} + +.seoprostack-toggle-header { + background: #f9f9f9; + padding: 15px; + cursor: pointer; + border-bottom: 1px solid #ddd; + transition: background-color 0.3s; +} + +.seoprostack-toggle-header:hover { + background: #f5f5f5; +} + +.seoprostack-toggle-header.active { + background: #e9e9e9; +} + +.seoprostack-toggle-main { + display: flex; + justify-content: space-between; + align-items: center; +} + +.seoprostack-toggle-left h3 { + margin: 0; + font-size: 15px; + font-weight: 600; +} + +.seoprostack-toggle-left p { + margin: 5px 0 0; + color: #757575; + font-size: 13px; +} + +.seoprostack-toggle-settings { + padding: 15px; + background: #fff; +} + +/* Toggle Switch */ +.wp-toggle-switch { + position: relative; + display: inline-block; + width: 50px; + height: 24px; +} + +.wp-toggle-switch input { + opacity: 0; + width: 0; + height: 0; +} + +.toggle-label { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + transition: .4s; + border-radius: 24px; +} + +.toggle-label:before { + position: absolute; + content: ""; + height: 16px; + width: 16px; + left: 4px; + bottom: 4px; + background-color: white; + transition: .4s; + border-radius: 50%; +} + +input:checked + .toggle-label { + background-color: #d35400; +} + +input:focus + .toggle-label { + box-shadow: 0 0 1px #d35400; +} + +input:checked + .toggle-label:before { + transform: translateX(26px); +} + +/* Checkbox Styling */ +.seoprostack-checkbox-label { + display: flex; + align-items: center; + font-weight: 600; + margin-bottom: 5px; +} + +.seoprostack-checkbox-label input[type="checkbox"] { + margin-right: 8px; +} + +/* Action Buttons */ +.seoprostack-setting-actions { + margin-top: 20px; + display: flex; + align-items: center; +} + +.seoprostack-setting-actions .button-primary { + background: #d35400; + border-color: #aa4400; +} + +.seoprostack-setting-actions .button-primary:hover, +.seoprostack-setting-actions .button-primary:focus { + background: #aa4400; + border-color: #803300; +} + +.seoprostack-setting-actions .spinner { + float: none; + margin-left: 10px; +} + +/* Notices */ +.seoprostack-notice { + padding: 10px 15px; + margin: 15px 0; + border-radius: 4px; + border-left: 4px solid; +} + +.seoprostack-notice-success { + background-color: #f0fff1; + border-left-color: #46b450; +} + +.seoprostack-notice-error { + background-color: #ffeaea; + border-left-color: #dc3232; +} + +.seoprostack-notice-warning { + background-color: #fef8ee; + border-left-color: #ffb900; +} + +.seoprostack-notice-info { + background-color: #f0f6fc; + border-left-color: #00a0d2; +} + +/* Theme Cards */ +.seoprostack-theme-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 20px; + margin-top: 20px; +} + +.seoprostack-theme-card { + background: #fff; + border: 1px solid #ddd; + border-radius: 8px; + overflow: hidden; + box-shadow: 0 1px 3px rgba(0,0,0,0.1); + transition: transform 0.3s, box-shadow 0.3s; +} + +.seoprostack-theme-card:hover { + transform: translateY(-5px); + box-shadow: 0 5px 15px rgba(0,0,0,0.1); +} + +.seoprostack-theme-card-header { + height: 200px; + overflow: hidden; +} + +.seoprostack-theme-card-header img { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 0.5s; +} + +.seoprostack-theme-card:hover .seoprostack-theme-card-header img { + transform: scale(1.05); +} + +.seoprostack-theme-card-content { + padding: 15px; +} + +.seoprostack-theme-card-content h4 { + margin: 0 0 10px; + font-size: 16px; + font-weight: 600; +} + +.seoprostack-theme-card-content p { + margin: 0 0 15px; + color: #666; + font-size: 14px; + line-height: 1.5; +} + +/* Hosting Cards */ +.seoprostack-hosting-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 20px; + margin-top: 20px; +} + +.seoprostack-hosting-card { + background: #fff; + border: 1px solid #ddd; + border-radius: 8px; + overflow: hidden; + box-shadow: 0 1px 3px rgba(0,0,0,0.1); + transition: transform 0.3s, box-shadow 0.3s; +} + +.seoprostack-hosting-card:hover { + transform: translateY(-5px); + box-shadow: 0 5px 15px rgba(0,0,0,0.1); +} + +.seoprostack-hosting-card-header { + padding: 15px; + text-align: center; + border-bottom: 1px solid #eee; +} + +.seoprostack-hosting-card-header img { + max-width: 160px; + max-height: 60px; +} + +.seoprostack-hosting-card-content { + padding: 15px; +} + +.seoprostack-hosting-card-content h4 { + margin: 0 0 10px; + font-size: 16px; + font-weight: 600; +} + +.seoprostack-hosting-card-content p { + margin: 0 0 15px; + color: #666; + font-size: 14px; + line-height: 1.5; +} + +/* Server Info */ +.seoprostack-info-table { + width: 100%; + border-collapse: collapse; + margin-top: 15px; +} + +.seoprostack-info-table th, +.seoprostack-info-table td { + padding: 10px; + border-bottom: 1px solid #eee; + text-align: left; +} + +.seoprostack-info-table th { + font-weight: 600; + width: 20%; +} + +.seoprostack-info-note { + color: #666; + font-size: 13px; +} + +.seoprostack-status-icon { + display: inline-block; + width: 16px; + height: 16px; + border-radius: 50%; + margin-left: 5px; + vertical-align: middle; +} + +.seoprostack-status-good { + background-color: #46b450; +} + +.seoprostack-status-warning { + background-color: #ffb900; +} + +.seoprostack-status-bad { + background-color: #dc3232; +} + +/* Tools Grid */ +.seoprostack-tools-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 20px; + margin-top: 20px; +} + +.seoprostack-tool-card { + background: #fff; + border: 1px solid #ddd; + border-radius: 8px; + overflow: hidden; + box-shadow: 0 1px 3px rgba(0,0,0,0.1); + transition: transform 0.3s, box-shadow 0.3s; +} + +.seoprostack-tool-card:hover { + transform: translateY(-5px); + box-shadow: 0 5px 15px rgba(0,0,0,0.1); +} + +.seoprostack-tool-card-header { + padding: 20px; + text-align: center; + background: #f7f7f7; +} + +.seoprostack-tool-card-header .dashicons { + font-size: 32px; + width: 32px; + height: 32px; + color: #d35400; +} + +.seoprostack-tool-card-content { + padding: 15px; +} + +.seoprostack-tool-card-content h3 { + margin: 0 0 10px; + font-size: 16px; + font-weight: 600; +} + +.seoprostack-tool-card-content p { + margin: 0 0 15px; + color: #666; + font-size: 14px; + line-height: 1.5; +} + +/* DB Actions */ +.seoprostack-db-actions { + margin-top: 15px; + display: flex; + align-items: center; +} + +.seoprostack-db-actions .spinner { + float: none; + margin-left: 10px; +} + +/* Loading States */ +.loading::after { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(255,255,255,0.7); + z-index: 1; +} + +/* Responsive */ +@media screen and (max-width: 782px) { + .seoprostack-theme-grid, + .seoprostack-hosting-grid, + .seoprostack-tools-grid { + grid-template-columns: 1fr; + } + + .seoprostack-header { + flex-direction: column; + align-items: flex-start; + } + + .seoprostack-header-actions { + margin-top: 10px; + } } \ No newline at end of file diff --git a/admin/css/wp-allstars-plugins.css b/admin/css/seoprostack-plugins.css similarity index 100% rename from admin/css/wp-allstars-plugins.css rename to admin/css/seoprostack-plugins.css diff --git a/admin/images/themes/kadence.png b/admin/images/themes/kadence.png new file mode 100644 index 0000000..66b051a Binary files /dev/null and b/admin/images/themes/kadence.png differ diff --git a/admin/js/seoprostack-admin.js b/admin/js/seoprostack-admin.js new file mode 100644 index 0000000..e38aab6 --- /dev/null +++ b/admin/js/seoprostack-admin.js @@ -0,0 +1,364 @@ +/** + * SEO Pro Stack Admin JavaScript + */ +(function($) { + 'use strict'; + + $(document).ready(function() { + // Toggle sections + $('.seoprostack-toggle-header').on('click', function() { + $(this).toggleClass('active'); + $(this).next('.seoprostack-toggle-settings').slideToggle(300); + }); + + // Tabs functionality (if not using WP default tabs) + $('.seoprostack-tab-nav a').on('click', function(e) { + e.preventDefault(); + var targetTab = $(this).attr('href').substring(1); + + // Update active tab + $('.seoprostack-tab-nav a').removeClass('active'); + $(this).addClass('active'); + + // Show target tab content + $('.seoprostack-tab-content').hide(); + $('#' + targetTab).show(); + + // Update URL without refreshing + if (history.pushState) { + var newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?page=seoprostack&tab=' + targetTab; + window.history.pushState({path: newUrl}, '', newUrl); + } + }); + + // Pro Plugins Tab + if ($('#pro-plugins').length) { + // Category filter + $('.seoprostack-category-filter a').on('click', function(e) { + e.preventDefault(); + + var category = $(this).data('category'); + + // Update active filter + $('.seoprostack-category-filter a').removeClass('active'); + $(this).addClass('active'); + + // Show loading + $('#seoprostack-plugins-grid').addClass('loading'); + + // Load plugins + $.ajax({ + url: seoProStack.ajaxurl, + type: 'POST', + data: { + action: 'seoprostack_get_pro_plugins', + category: category, + nonce: seoProStack.nonce + }, + success: function(response) { + $('#seoprostack-plugins-grid').removeClass('loading'); + + if (response.success) { + renderPlugins(response.data.plugins); + } else { + $('#seoprostack-plugins-grid').html('
' + response.data.message + '
'); + } + }, + error: function() { + $('#seoprostack-plugins-grid').removeClass('loading'); + $('#seoprostack-plugins-grid').html('
Error connecting to server
'); + } + }); + }); + + // Activate plugin + $(document).on('click', '.seoprostack-activate-plugin', function(e) { + e.preventDefault(); + + var $button = $(this); + var plugin = $button.data('plugin'); + var $card = $button.closest('.seoprostack-plugin-card'); + + // Show loading + $button.prop('disabled', true).text('Activating...'); + + // Send activation request + $.ajax({ + url: seoProStack.ajaxurl, + type: 'POST', + data: { + action: 'seoprostack_activate_plugin', + plugin: plugin, + nonce: seoProStack.nonce + }, + success: function(response) { + if (response.success) { + // Update UI + $button.text('Activated').addClass('button-disabled'); + $card.find('.plugin-status').removeClass('not-installed installed').addClass('active').text('Active'); + } else { + $button.prop('disabled', false).text('Activate'); + alert(response.data.message); + } + }, + error: function() { + $button.prop('disabled', false).text('Activate'); + alert('Error connecting to server'); + } + }); + }); + + // Render plugins + function renderPlugins(plugins) { + var html = ''; + + if (plugins.length === 0) { + html = '
No plugins found in this category
'; + } else { + plugins.forEach(function(plugin) { + var statusClass = plugin.active ? 'active' : (plugin.status === 'installed' ? 'installed' : 'not-installed'); + var statusText = plugin.active ? 'Active' : (plugin.status === 'installed' ? 'Installed' : 'Not Installed'); + var buttonText = plugin.active ? 'Activated' : 'Activate'; + var buttonDisabled = plugin.active ? ' button-disabled' : ''; + + html += '
'; + html += '
'; + html += '' + statusText + ''; + html += '
'; + html += '
'; + html += '

' + plugin.name + ' v' + plugin.version + '

'; + html += '

' + plugin.description + '

'; + html += ''; + html += '
'; + html += '
'; + }); + } + + $('#seoprostack-plugins-grid').html(html); + } + + // Load initial plugins + $('.seoprostack-category-filter a.active').trigger('click'); + } + + // Advanced Tab Form + if ($('#seoprostack-advanced-settings-form').length) { + $('#seoprostack-advanced-settings-form').on('submit', function(e) { + e.preventDefault(); + + var $form = $(this); + var $button = $('#seoprostack-save-advanced-settings'); + var $spinner = $button.next('.spinner'); + var $response = $('#advanced-settings-response'); + + // Show loading + $button.prop('disabled', true); + $spinner.css('visibility', 'visible'); + + // Get form data + var formData = $form.serializeArray(); + var data = { + action: 'seoprostack_save_advanced_settings', + nonce: seoProStack.nonce + }; + + // Convert form data to proper format + $.each(formData, function(i, field) { + data[field.name] = field.value; + }); + + // Add checkbox fields that might not be in formData + $form.find('input[type="checkbox"]').each(function() { + var name = $(this).attr('name'); + if (data[name] === undefined) { + data[name] = 'no'; + } + }); + + // Send AJAX request + $.post(seoProStack.ajaxurl, data, function(response) { + // Hide loading + $button.prop('disabled', false); + $spinner.css('visibility', 'hidden'); + + // Show response + if (response.success) { + $response.html('
' + response.data.message + '
'); + } else { + $response.html('
' + response.data.message + '
'); + } + + // Hide response after delay + setTimeout(function() { + $response.find('.seoprostack-notice').fadeOut(500, function() { + $(this).remove(); + }); + }, 3000); + }).fail(function() { + // Hide loading + $button.prop('disabled', false); + $spinner.css('visibility', 'hidden'); + + // Show error + $response.html('
Error connecting to server
'); + }); + }); + } + + // Tools Tab + if ($('#tools').length) { + // Database Optimization + $('#seoprostack-optimize-db').on('click', function(e) { + e.preventDefault(); + + var $button = $(this); + var $spinner = $button.next('.spinner'); + var $response = $('#db-optimize-response'); + + // Show loading + $button.prop('disabled', true); + $spinner.css('visibility', 'visible'); + + // Send AJAX request + $.ajax({ + url: seoProStack.ajaxurl, + type: 'POST', + data: { + action: 'seoprostack_optimize_database', + nonce: seoProStack.nonce + }, + success: function(response) { + // Hide loading + $button.prop('disabled', false); + $spinner.css('visibility', 'hidden'); + + // Show response + if (response.success) { + $response.html('
' + response.data.message + '
'); + + // Update stats if provided + if (response.data.stats) { + updateDbStats(response.data.stats); + } + } else { + $response.html('
' + response.data.message + '
'); + } + + // Hide response after delay + setTimeout(function() { + $response.find('.seoprostack-notice').fadeOut(500, function() { + $(this).remove(); + }); + }, 5000); + }, + error: function() { + // Hide loading + $button.prop('disabled', false); + $spinner.css('visibility', 'hidden'); + + // Show error + $response.html('
Error connecting to server
'); + } + }); + }); + + // Function to update database stats + function updateDbStats(stats) { + if (stats.total_cleaned) { + $('#db-total-cleaned').text(stats.total_cleaned); + } + if (stats.db_size_before) { + $('#db-size-before').text(stats.db_size_before); + } + if (stats.db_size_after) { + $('#db-size-after').text(stats.db_size_after); + } + if (stats.savings_percentage) { + $('#db-savings').text(stats.savings_percentage + '%'); + } + } + + // Generate Robots.txt + $('#seoprostack-generate-robots').on('click', function(e) { + e.preventDefault(); + + var $button = $(this); + var $spinner = $button.next('.spinner'); + var $response = $('#robots-response'); + var $content = $('#robots-content'); + + // Show loading + $button.prop('disabled', true); + $spinner.css('visibility', 'visible'); + + // Send AJAX request + $.ajax({ + url: seoProStack.ajaxurl, + type: 'POST', + data: { + action: 'seoprostack_generate_robots', + nonce: seoProStack.nonce + }, + success: function(response) { + // Hide loading + $button.prop('disabled', false); + $spinner.css('visibility', 'hidden'); + + // Show response + if (response.success) { + $response.html('
' + response.data.message + '
'); + + // Display robots.txt content + if (response.data.content) { + $content.val(response.data.content); + $content.closest('.seoprostack-setting-row').show(); + } + } else { + $response.html('
' + response.data.message + '
'); + } + }, + error: function() { + // Hide loading + $button.prop('disabled', false); + $spinner.css('visibility', 'hidden'); + + // Show error + $response.html('
Error connecting to server
'); + } + }); + }); + + // Copy to Clipboard Functionality + $('.seoprostack-copy-to-clipboard').on('click', function(e) { + e.preventDefault(); + + var targetId = $(this).data('target'); + var $target = $('#' + targetId); + var $button = $(this); + var originalText = $button.text(); + + // Copy to clipboard + $target.select(); + document.execCommand('copy'); + + // Update button text + $button.text('Copied!'); + + // Reset button text + setTimeout(function() { + $button.text(originalText); + }, 2000); + }); + } + }); + +})(jQuery); \ No newline at end of file diff --git a/admin/js/wp-allstars-admin.js b/admin/js/wp-allstars-admin.js deleted file mode 100644 index 0969cd7..0000000 --- a/admin/js/wp-allstars-admin.js +++ /dev/null @@ -1,327 +0,0 @@ -// Define loadTheme in the global scope so it can be called from inline scripts -var loadTheme; - -jQuery(document).ready(function($) { - // Function to show notification - function showNotification(message, $element, isError = false) { - // Remove any existing notifications - $('.wp-setting-notification').remove(); - - // Create notification element - var $notification = $('' + message + ''); - - // If element is provided, show notification next to it - if ($element && $element.length) { - $element.after($notification); - } else { - // Fallback to header if no element provided - $('.wp-allstars-header h1').after($notification); - } - - // Fade out after delay - setTimeout(function() { - $notification.fadeOut(300, function() { - $(this).remove(); - }); - - }, 2000); - } - - // Handle option updates - function updateOption(option, value) { - return $.ajax({ - url: ajaxurl, - type: 'POST', - data: { - action: 'wp_allstars_update_option', - option: option, - value: value, - nonce: wpAllstars.nonce - } - }).then(function(response) { - if (!response.success) { - throw new Error(response.data || 'Error saving setting'); - } - return response; - }); - - } - - // Handle toggle switch clicks - $('.wp-toggle-switch').on('click', function(e) { - e.stopPropagation(); - var $checkbox = $(this).find('input[type="checkbox"]'); - var isChecked = $checkbox.is(':checked'); - $checkbox.prop('checked', !isChecked).trigger('change'); - }); - - - // Prevent label clicks from toggling the checkbox directly - $('.wp-setting-label, .wp-allstars-toggle-left label').on('click', function(e) { - e.preventDefault(); - e.stopPropagation(); - }); - - - // Handle checkbox changes - $('.wp-toggle-switch input[type="checkbox"]').on('change', function(e) { - e.stopPropagation(); - var $input = $(this); - var option = $input.attr('name'); - var value = $input.is(':checked') ? 1 : 0; - var $label = $input.closest('.wp-setting-left, .wp-allstars-toggle-left').find('label'); - - updateOption(option, value) - .then(function() { - showNotification('Saved', $label); - }) - .catch(function() { - showNotification('Error saving settings', $label, true); - }); - - }); - - - // Handle text input changes - $('.wp-allstars-setting-row input[type="text"], .wp-allstars-setting-row input[type="number"], .wp-allstars-setting-row textarea').on('change', function() { - var $input = $(this); - var option = $input.attr('name'); - var value = $input.val(); - var $label = $input.closest('.wp-allstars-setting-row').find('label').first(); - - updateOption(option, value) - .then(function() { - showNotification('Saved', $label); - }) - .catch(function(error) { - console.error('Error:', error); - showNotification('Error saving setting', $label, true); - }); - - }); - - - // Toggle expandable panels - $('.wp-allstars-toggle-header').on('click', function(e) { - if (!$(e.target).closest('.wp-toggle-switch').length && - !$(e.target).closest('label').length) { - var $settings = $(this).closest('.wp-allstars-toggle').find('.wp-allstars-toggle-settings'); - var isExpanded = $(this).attr('aria-expanded') === 'true'; - - $(this).attr('aria-expanded', !isExpanded); - $settings.slideToggle(200); - } - }); - - - // Set initial panel states - $('.wp-allstars-toggle-header').each(function() { - var $settings = $(this).closest('.wp-allstars-toggle').find('.wp-allstars-toggle-settings'); - var isExpanded = $(this).attr('aria-expanded') === 'true'; - - if (!isExpanded) { - $settings.hide(); - } - }); - - - // Remove JavaScript-based tab switching - let the native WordPress tab links work - - // Plugin category filters - if ($('#wpa-plugin-filters').length) { - $('#wpa-plugin-filters a').on('click', function(e) { - e.preventDefault(); - var category = $(this).data('category'); - - // Update active filter - $('#wpa-plugin-filters a').removeClass('current'); - $(this).addClass('current'); - - // Load plugins for the selected category - loadPlugins(category); - }); - - - // Load initial plugins if we're on the recommended tab - if ($('#recommended').is(':visible') && $('#wpa-plugin-list').is(':empty')) { - loadPlugins('minimal'); - } - } - - // Load theme tab content if we're on the theme tab - if ($('#theme').is(':visible') && $('#wpa-theme-list').length && $('#wpa-theme-list').is(':empty')) { - loadTheme(); - } - - // Function to load plugins - function loadPlugins(category) { - var $container = $('#wpa-plugin-list'); - var $loadingOverlay = $('
'); - - // Show loading overlay - $container.css('position', 'relative').append($loadingOverlay); - - // Clear existing plugins - $container.empty().append($loadingOverlay); - - // AJAX request to get plugins - $.ajax({ - url: ajaxurl, - type: 'POST', - data: { - action: 'wp_allstars_get_plugins', - category: category, - _wpnonce: wpAllstars.nonce - }, - success: function(response) { - // Remove loading overlay - $loadingOverlay.remove(); - - if (response.success) { - // Append plugins HTML - $container.html(response.data); - - // Initialize plugin action buttons - initPluginActions(); - - // Individual plugin card spinners have been removed - } else { - // Show error message - $container.html('

' + response.data + '

'); - } - }, - error: function(xhr, status, error) { - // Remove loading overlay - $loadingOverlay.remove(); - - // Show error message - $container.html('

Failed to load plugins. Please try again. Error: ' + error + '

'); - console.error('AJAX Error:', xhr.responseText); - } - }); - - } - - // Theme handlers are initialized directly from the inline script - // We don't need a separate loadTheme function anymore - - // Initialize plugin action buttons - function initPluginActions() { - // Remove any existing event handlers to prevent duplicates - $('.plugin-card .install-now').off('click'); - $('.plugin-card .update-now').off('click'); - $('.plugin-card .activate-now').off('click'); - - // Install plugin - $('.plugin-card .install-now').on('click', function(e) { - e.preventDefault(); - var $button = $(this); - var slug = $button.data('slug'); - - $button.addClass('updating-message').text('Installing...'); - - wp.updates.installPlugin({ - slug: slug, - success: function(response) { - $button.removeClass('updating-message').addClass('updated-message').text('Installed!'); - setTimeout(function() { - // Replace the button with an activate button - var $parent = $button.parent(); - $button.remove(); - $parent.html('Activate'); - - // Re-initialize the event handlers - initPluginActions(); - }, 1000); - }, - error: function(response) { - $button.removeClass('updating-message').text('Install Now'); - alert(response.errorMessage); - } - }); - }); - - // Update plugin - $('.plugin-card .update-now').on('click', function(e) { - e.preventDefault(); - var $button = $(this); - var slug = $button.data('slug'); - - $button.addClass('updating-message').text('Updating...'); - - wp.updates.updatePlugin({ - slug: slug, - success: function() { - $button.removeClass('updating-message').addClass('updated-message').text('Updated!'); - setTimeout(function() { - $button.removeClass('update-now updated-message') - .addClass('button-disabled') - .text('Active'); - }, 1000); - }, - error: function(response) { - $button.removeClass('updating-message').text('Update Now'); - alert(response.errorMessage); - } - }); - }); - - // Activate plugin - $('.plugin-card .activate-now').on('click', function(e) { - e.preventDefault(); - var $button = $(this); - var url = $button.attr('href'); - var slug = $button.data('slug'); - - $button.addClass('updating-message').text('Activating...'); - - $.ajax({ - url: url, - dataType: 'html', - success: function() { - $button.removeClass('updating-message').addClass('updated-message').text('Activated!'); - setTimeout(function() { - // Replace the button with an active button - var $parent = $button.parent(); - $button.remove(); - $parent.html(''); - }, 1000); - }, - error: function() { - $button.removeClass('updating-message').text('Activate'); - alert('Failed to activate plugin. Please try again or activate from the Plugins page.'); - } - }); - }); - } - - // Initialize theme handlers - function initThemeHandlers() { - console.log('Initializing theme handlers'); - // Remove any existing event handlers to prevent duplicates - $('.theme-actions .install-now').off('click'); - $('.theme-actions .activate-now').off('click'); - - // Install theme - use standard WordPress behavior - $('.theme-actions .install-now').on('click', function(e) { - // We're not preventing default here - let the standard WordPress installer handle it - // Just add the updating message - var $button = $(this); - var slug = $button.data('slug'); - $button.addClass('updating-message').text('Installing...'); - console.log('Installing theme using standard WordPress URL:', $button.attr('href')); - // The rest will be handled by WordPress core - }); - - // Activate theme - use standard WordPress behavior - $('.theme-actions .activate-now').on('click', function(e) { - // We're not preventing default here - let the standard WordPress activation handle it - // Just add the updating message - var $button = $(this); - var slug = $button.data('slug'); - $button.addClass('updating-message').text('Activating...'); - console.log('Activating theme using standard WordPress URL:', $button.attr('href')); - // The rest will be handled by WordPress core - }); - } -}); \ No newline at end of file diff --git a/admin/partials/theme-panel.php b/admin/partials/theme-panel.php index b2ccf54..404b71f 100644 --- a/admin/partials/theme-panel.php +++ b/admin/partials/theme-panel.php @@ -1,8 +1,9 @@ get_stylesheet() === 'kadence'); - $nonce = wp_create_nonce('wp-allstars-nonce'); + $nonce = wp_create_nonce('wp-seoprostack-nonce'); if ($is_active): ?> + + + + + + +
+
+

+

+ +
+
+
+

+

+
+ +
+
+

+

+
+ +
+
+

+

+
+
+ +
+

+
    +
  1. +
  2. +
  3. +
  4. +
+
+
+
+ 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']); ?> + + +
+
+ +
+

+

+ +
+ $provider) : ?> +
+
+

+
+
+

+ +
    + +
  • + +
+ +
+ +
+ +
+
+
+
+ =') ? '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()) : ?> +
+ <?php echo esc_attr($current_theme->display('Name')); ?> +
+ +
+

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()); ?>

+ +
+ $tool) : ?> +
+
+ +
+
+

+

+ + + + + + + +
+
+ +
+ +
+

+

+ +
+ +
+ + +
+ + +
+
+
+ __('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%' + )); + ?> +
+
+ + +
+

+

+ +
+
+
+
+
+ + /> + +
+ +
+
+

+ +

+
+ +
+
+ + +

+
+ +
+ + +

+
+ +
+ + +

+
+ +
+ + +

+ %filename%, %post_id%, %postname%, %timestamp%, %date%, %year%, %month%, %day% +

+
+ +
+ + +

+ %filename%, %post_title%, %post_id%, %postname%, %timestamp% +

+
+
+
+ +
+ +
+
+
+
+ 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