Rename plugin to wp-seoprostack-plugin, update file structure
This commit is contained in:
132
admin/settings/ajax/class-seoprostack-ajax-advanced.php
Normal file
132
admin/settings/ajax/class-seoprostack-ajax-advanced.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* The Advanced Settings AJAX handler.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/AJAX
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Advanced Settings AJAX handler.
|
||||
*/
|
||||
class SEOProStack_AJAX_Advanced {
|
||||
|
||||
/**
|
||||
* Initialize the AJAX handlers.
|
||||
*/
|
||||
public function init() {
|
||||
add_action('wp_ajax_seoprostack_save_advanced_settings', array($this, 'save_advanced_settings'));
|
||||
add_action('wp_ajax_seoprostack_optimize_database', array($this, 'optimize_database'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save advanced settings.
|
||||
*/
|
||||
public function save_advanced_settings() {
|
||||
// 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 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
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
65
admin/settings/ajax/class-seoprostack-ajax-plugins.php
Normal file
65
admin/settings/ajax/class-seoprostack-ajax-plugins.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* AJAX handler for plugin-related functionality.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/AJAX
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for plugins.
|
||||
*/
|
||||
class SEOProStack_AJAX_Plugins {
|
||||
|
||||
/**
|
||||
* Get list of installed plugins.
|
||||
*/
|
||||
public function get_plugins() {
|
||||
// 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('manage_options')) {
|
||||
wp_send_json_error('You do not have permission to view plugins.');
|
||||
return;
|
||||
}
|
||||
|
||||
$installed_plugins = get_plugins();
|
||||
$active_plugins = get_option('active_plugins');
|
||||
$plugin_list = array();
|
||||
|
||||
// Create the plugins array
|
||||
foreach ($installed_plugins as $path => $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);
|
||||
}
|
||||
}
|
194
admin/settings/ajax/class-seoprostack-ajax-pro-plugins.php
Normal file
194
admin/settings/ajax/class-seoprostack-ajax-pro-plugins.php
Normal file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* The Pro Plugins AJAX handler.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/AJAX
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Pro Plugins AJAX handler.
|
||||
*/
|
||||
class SEOProStack_AJAX_Pro_Plugins {
|
||||
|
||||
/**
|
||||
* Initialize the AJAX handlers.
|
||||
*/
|
||||
public function init() {
|
||||
add_action('wp_ajax_seoprostack_get_pro_plugins', array($this, 'get_pro_plugins'));
|
||||
add_action('wp_ajax_seoprostack_activate_plugin', array($this, 'activate_plugin'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of pro plugins.
|
||||
*/
|
||||
public function get_pro_plugins() {
|
||||
// Verify nonce
|
||||
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'seoprostack_ajax_nonce')) {
|
||||
wp_send_json_error(array('message' => '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);
|
||||
}
|
||||
}
|
119
admin/settings/ajax/class-seoprostack-ajax-settings.php
Normal file
119
admin/settings/ajax/class-seoprostack-ajax-settings.php
Normal file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
* AJAX handler for settings functionality.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/AJAX
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for settings.
|
||||
*/
|
||||
class SEOProStack_AJAX_Settings {
|
||||
|
||||
/**
|
||||
* Initialize the class
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action('wp_ajax_seoprostack_update_option', array($this, 'update_option'));
|
||||
add_action('wp_ajax_seoprostack_get_options', array($this, 'get_options'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a plugin option via AJAX.
|
||||
*/
|
||||
public function update_option() {
|
||||
// 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 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
|
||||
));
|
||||
}
|
||||
}
|
93
admin/settings/ajax/class-seoprostack-ajax-themes.php
Normal file
93
admin/settings/ajax/class-seoprostack-ajax-themes.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
/**
|
||||
* AJAX handler for theme-related functionality.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/AJAX
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for themes.
|
||||
*/
|
||||
class SEOProStack_AJAX_Themes {
|
||||
|
||||
/**
|
||||
* Get list of available themes.
|
||||
*/
|
||||
public function get_themes() {
|
||||
// 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('manage_options')) {
|
||||
wp_send_json_error('You do not have permission to view themes.');
|
||||
return;
|
||||
}
|
||||
|
||||
$themes = wp_get_themes();
|
||||
$current_theme = wp_get_theme();
|
||||
$theme_list = array();
|
||||
|
||||
foreach ($themes as $theme_slug => $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')),
|
||||
));
|
||||
}
|
||||
}
|
77
admin/settings/ajax/class-seoprostack-ajax-tools.php
Normal file
77
admin/settings/ajax/class-seoprostack-ajax-tools.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* The Tools AJAX handler.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/AJAX
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Tools AJAX handler.
|
||||
*/
|
||||
class SEOProStack_AJAX_Tools {
|
||||
|
||||
/**
|
||||
* Initialize the AJAX handlers.
|
||||
*/
|
||||
public function init() {
|
||||
add_action('wp_ajax_seoprostack_generate_robots', array($this, 'generate_robots'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate robots.txt file content.
|
||||
*/
|
||||
public function generate_robots() {
|
||||
// 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 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
|
||||
));
|
||||
}
|
||||
}
|
193
admin/settings/class-seoprostack-settings-page.php
Normal file
193
admin/settings/class-seoprostack-settings-page.php
Normal file
@ -0,0 +1,193 @@
|
||||
<?php
|
||||
/**
|
||||
* The admin settings page class.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The admin settings page class.
|
||||
*/
|
||||
class SEOProStack_Settings_Page {
|
||||
|
||||
/**
|
||||
* Register the settings page.
|
||||
*/
|
||||
public function add_menu_page() {
|
||||
add_options_page(
|
||||
'SEO Pro Stack Settings', // Page title
|
||||
'SEO Pro Stack', // Menu title
|
||||
'manage_options', // Capability
|
||||
'seoprostack', // Menu slug
|
||||
array($this, 'render_settings_page') // Function to display the page
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register settings.
|
||||
*/
|
||||
public function register_settings() {
|
||||
register_setting('seoprostack_settings', 'seoprostack_workflow_options');
|
||||
register_setting('seoprostack_settings', 'seoprostack_advanced_options');
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the settings page.
|
||||
*/
|
||||
public function render_settings_page() {
|
||||
$active_tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'general';
|
||||
$tabs = $this->get_tabs();
|
||||
|
||||
?>
|
||||
<div class="wrap seoprostack-wrap">
|
||||
<div class="seoprostack-header">
|
||||
<h1><?php echo esc_html('SEO Pro Stack'); ?></h1>
|
||||
<p class="seoprostack-description"><?php echo esc_html('Speed up your WordPress site with our optimization tools.'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-settings-container">
|
||||
<div class="seoprostack-nav">
|
||||
<h2 class="nav-tab-wrapper">
|
||||
<?php foreach ($tabs as $tab_id => $tab) : ?>
|
||||
<a href="?page=seoprostack&tab=<?php echo esc_attr($tab_id); ?>"
|
||||
class="nav-tab <?php echo $active_tab === $tab_id ? 'nav-tab-active' : ''; ?>">
|
||||
<?php echo esc_html($tab['label']); ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-settings-content">
|
||||
<?php
|
||||
if (isset($tabs[$active_tab]) && isset($tabs[$active_tab]['callback'])) {
|
||||
call_user_func($tabs[$active_tab]['callback']);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available tabs.
|
||||
*
|
||||
* @return array Array of tab configurations.
|
||||
*/
|
||||
private function get_tabs() {
|
||||
$tabs = array(
|
||||
'general' => 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();
|
||||
}
|
||||
}
|
229
admin/settings/data/hosting-providers.php
Normal file
229
admin/settings/data/hosting-providers.php
Normal file
@ -0,0 +1,229 @@
|
||||
<?php
|
||||
/**
|
||||
* Hosting providers data for SEO Pro Stack
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/Data
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define hosting providers
|
||||
*
|
||||
* @return array Array of hosting providers with their details
|
||||
*/
|
||||
function wp_seoprostack_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'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Alias for backward compatibility with the old codebase
|
||||
function wp_allstars_get_hosting_providers() {
|
||||
return wp_seoprostack_get_hosting_providers();
|
||||
}
|
183
admin/settings/data/recommended-plugins.php
Normal file
183
admin/settings/data/recommended-plugins.php
Normal file
@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/**
|
||||
* Recommended plugins data for SEO Pro Stack
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/Data
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define recommended plugins
|
||||
*
|
||||
* @return array Array of recommended plugins categorized by use case
|
||||
*/
|
||||
function wp_seoprostack_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'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
373
admin/settings/data/tools.php
Normal file
373
admin/settings/data/tools.php
Normal file
@ -0,0 +1,373 @@
|
||||
<?php
|
||||
/**
|
||||
* Tools data for SEO Pro Stack
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/Data
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define tools
|
||||
*
|
||||
* @return array Array of tools with their details
|
||||
*/
|
||||
function wp_seoprostack_get_tools() {
|
||||
return array(
|
||||
'advise' => 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();
|
||||
}
|
159
admin/settings/tabs/class-seoprostack-tab-advanced.php
Normal file
159
admin/settings/tabs/class-seoprostack-tab-advanced.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/**
|
||||
* The Advanced tab for plugin settings.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/Tabs
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Advanced tab for plugin settings.
|
||||
*/
|
||||
class SEOProStack_Tab_Advanced {
|
||||
|
||||
/**
|
||||
* Render the tab content.
|
||||
*/
|
||||
public function render() {
|
||||
// Get current settings
|
||||
$settings = get_option('seoprostack_advanced_settings', array(
|
||||
'disable_emojis' => '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'
|
||||
));
|
||||
?>
|
||||
<div class="seoprostack-settings-content tab-content" id="advanced">
|
||||
<div class="seoprostack-setting-section">
|
||||
<h2><?php esc_html_e('Advanced Settings', 'seoprostack'); ?></h2>
|
||||
<p class="description"><?php esc_html_e('These settings help optimize your WordPress site for better performance. Use with caution and test thoroughly after making changes.', 'seoprostack'); ?></p>
|
||||
|
||||
<div id="advanced-settings-response"></div>
|
||||
|
||||
<form id="seoprostack-advanced-settings-form">
|
||||
<div class="seoprostack-toggle">
|
||||
<div class="seoprostack-toggle-header">
|
||||
<div class="seoprostack-toggle-main">
|
||||
<div class="seoprostack-toggle-left">
|
||||
<h3><?php esc_html_e('WordPress Cleanup', 'seoprostack'); ?></h3>
|
||||
<p><?php esc_html_e('Remove unnecessary code from WordPress header', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
<div class="seoprostack-toggle-right">
|
||||
<label class="wp-toggle-switch">
|
||||
<input type="checkbox" class="seoprostack-toggle-switch" <?php checked(true, true); ?>>
|
||||
<span class="toggle-label"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="seoprostack-toggle-settings" style="display: block;">
|
||||
<div class="seoprostack-setting-row">
|
||||
<label class="seoprostack-checkbox-label">
|
||||
<input type="checkbox" name="disable_emojis" value="yes" <?php checked('yes', $settings['disable_emojis']); ?>>
|
||||
<?php esc_html_e('Disable WordPress Emojis', 'seoprostack'); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e('Removes the WordPress emoji script and related code from loading on your site.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-row">
|
||||
<label class="seoprostack-checkbox-label">
|
||||
<input type="checkbox" name="disable_embeds" value="yes" <?php checked('yes', $settings['disable_embeds']); ?>>
|
||||
<?php esc_html_e('Disable WordPress Embeds', 'seoprostack'); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e('Disables the WordPress embed functionality, removing the related JavaScript file.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-row">
|
||||
<label class="seoprostack-checkbox-label">
|
||||
<input type="checkbox" name="remove_query_strings" value="yes" <?php checked('yes', $settings['remove_query_strings']); ?>>
|
||||
<?php esc_html_e('Remove Query Strings from Static Resources', 'seoprostack'); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e('Removes query strings from static resources like CSS and JavaScript files, improving caching.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-row">
|
||||
<label class="seoprostack-checkbox-label">
|
||||
<input type="checkbox" name="disable_xmlrpc" value="yes" <?php checked('yes', $settings['disable_xmlrpc']); ?>>
|
||||
<?php esc_html_e('Disable XML-RPC', 'seoprostack'); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e('Disables the XML-RPC API, which could be a security vulnerability if not used.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-row">
|
||||
<label class="seoprostack-checkbox-label">
|
||||
<input type="checkbox" name="remove_shortlink" value="yes" <?php checked('yes', $settings['remove_shortlink']); ?>>
|
||||
<?php esc_html_e('Remove Shortlink', 'seoprostack'); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e('Removes the shortlink tag from the header.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-toggle">
|
||||
<div class="seoprostack-toggle-header">
|
||||
<div class="seoprostack-toggle-main">
|
||||
<div class="seoprostack-toggle-left">
|
||||
<h3><?php esc_html_e('Performance Optimization', 'seoprostack'); ?></h3>
|
||||
<p><?php esc_html_e('Enable additional performance optimizations', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
<div class="seoprostack-toggle-right">
|
||||
<label class="wp-toggle-switch">
|
||||
<input type="checkbox" class="seoprostack-toggle-switch" <?php checked(true, true); ?>>
|
||||
<span class="toggle-label"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="seoprostack-toggle-settings" style="display: block;">
|
||||
<div class="seoprostack-setting-row">
|
||||
<label class="seoprostack-checkbox-label">
|
||||
<input type="checkbox" name="minify_html" value="yes" <?php checked('yes', $settings['minify_html']); ?>>
|
||||
<?php esc_html_e('Minify HTML', 'seoprostack'); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e('Removes unnecessary whitespace from HTML to reduce file size.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-row">
|
||||
<label class="seoprostack-checkbox-label">
|
||||
<input type="checkbox" name="minify_css" value="yes" <?php checked('yes', $settings['minify_css']); ?>>
|
||||
<?php esc_html_e('Minify CSS', 'seoprostack'); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e('Combines and minifies CSS files to reduce HTTP requests and file size.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-row">
|
||||
<label class="seoprostack-checkbox-label">
|
||||
<input type="checkbox" name="minify_js" value="yes" <?php checked('yes', $settings['minify_js']); ?>>
|
||||
<?php esc_html_e('Minify JavaScript', 'seoprostack'); ?>
|
||||
</label>
|
||||
<p class="description"><?php esc_html_e('Combines and minifies JavaScript files to reduce HTTP requests and file size.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-actions">
|
||||
<button type="submit" class="button button-primary" id="seoprostack-save-advanced-settings">
|
||||
<?php esc_html_e('Save Advanced Settings', 'seoprostack'); ?>
|
||||
</button>
|
||||
<span class="spinner"></span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
62
admin/settings/tabs/class-seoprostack-tab-general.php
Normal file
62
admin/settings/tabs/class-seoprostack-tab-general.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* The General tab for plugin settings.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/Tabs
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The General tab for plugin settings.
|
||||
*/
|
||||
class SEOProStack_Tab_General {
|
||||
|
||||
/**
|
||||
* Render the tab content.
|
||||
*/
|
||||
public function render() {
|
||||
?>
|
||||
<div class="seoprostack-settings-content tab-content" id="general">
|
||||
<div class="seoprostack-settings-section">
|
||||
<h2><?php esc_html_e('Welcome to SEO Pro Stack', 'seoprostack'); ?></h2>
|
||||
<p><?php esc_html_e('SEO Pro Stack helps you optimize your WordPress site for better search engine rankings and faster performance.', 'seoprostack'); ?></p>
|
||||
|
||||
<div class="seoprostack-welcome-cards">
|
||||
<div class="seoprostack-card">
|
||||
<div class="seoprostack-card-icon dashicons dashicons-performance"></div>
|
||||
<h3><?php esc_html_e('Optimize Performance', 'seoprostack'); ?></h3>
|
||||
<p><?php esc_html_e('Speed up your site with our performance optimization tools.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-card">
|
||||
<div class="seoprostack-card-icon dashicons dashicons-admin-plugins"></div>
|
||||
<h3><?php esc_html_e('Recommended Plugins', 'seoprostack'); ?></h3>
|
||||
<p><?php esc_html_e('Discover plugins that enhance your site\'s SEO and performance.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-card">
|
||||
<div class="seoprostack-card-icon dashicons dashicons-admin-appearance"></div>
|
||||
<h3><?php esc_html_e('Theme Optimization', 'seoprostack'); ?></h3>
|
||||
<p><?php esc_html_e('Find and activate SEO-friendly themes for your site.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-quick-start">
|
||||
<h3><?php esc_html_e('Quick Start Guide', 'seoprostack'); ?></h3>
|
||||
<ol>
|
||||
<li><?php esc_html_e('Configure auto-upload settings in the Workflow tab', 'seoprostack'); ?></li>
|
||||
<li><?php esc_html_e('Explore recommended plugins in the Free Plugins tab', 'seoprostack'); ?></li>
|
||||
<li><?php esc_html_e('Check out premium plugins in the Pro Plugins tab', 'seoprostack'); ?></li>
|
||||
<li><?php esc_html_e('Find an SEO-optimized theme in the Theme tab', 'seoprostack'); ?></li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
462
admin/settings/tabs/class-seoprostack-tab-hosting.php
Normal file
462
admin/settings/tabs/class-seoprostack-tab-hosting.php
Normal file
@ -0,0 +1,462 @@
|
||||
<?php
|
||||
/**
|
||||
* The Hosting tab for plugin settings.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/Tabs
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Hosting tab for plugin settings.
|
||||
* Self-contained class with integrated data and functionality
|
||||
*/
|
||||
class SEOProStack_Tab_Hosting {
|
||||
|
||||
/**
|
||||
* Tab identifier
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $tab_id = 'hosting';
|
||||
|
||||
/**
|
||||
* Initialize the class.
|
||||
* Register any hooks or actions here.
|
||||
*/
|
||||
public function __construct() {
|
||||
// If needed, register hooks or actions here
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 __('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;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="seoprostack-settings-content tab-content" id="<?php echo esc_attr($this->get_tab_id()); ?>">
|
||||
<div class="seoprostack-setting-section">
|
||||
<h2><?php esc_html_e('Hosting Information', 'seoprostack'); ?></h2>
|
||||
<p class="description"><?php echo esc_html($this->get_description()); ?></p>
|
||||
|
||||
<div class="seoprostack-server-info">
|
||||
<h3><?php esc_html_e('Server Environment', 'seoprostack'); ?></h3>
|
||||
<table class="seoprostack-info-table">
|
||||
<tr>
|
||||
<th><?php esc_html_e('PHP Version', 'seoprostack'); ?></th>
|
||||
<td>
|
||||
<?php echo esc_html($server_info['php_version']); ?>
|
||||
<?php echo $this->get_status_icon($server_info['php_status']); ?>
|
||||
</td>
|
||||
<td class="seoprostack-info-note">
|
||||
<?php echo esc_html($server_info['php_note']); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e('MySQL Version', 'seoprostack'); ?></th>
|
||||
<td>
|
||||
<?php echo esc_html($server_info['mysql_version']); ?>
|
||||
<?php echo $this->get_status_icon($server_info['mysql_status']); ?>
|
||||
</td>
|
||||
<td class="seoprostack-info-note">
|
||||
<?php echo esc_html($server_info['mysql_note']); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e('WordPress Version', 'seoprostack'); ?></th>
|
||||
<td>
|
||||
<?php echo esc_html($server_info['wp_version']); ?>
|
||||
<?php echo $this->get_status_icon($server_info['wp_status']); ?>
|
||||
</td>
|
||||
<td class="seoprostack-info-note">
|
||||
<?php echo esc_html($server_info['wp_note']); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e('Memory Limit', 'seoprostack'); ?></th>
|
||||
<td>
|
||||
<?php echo esc_html($server_info['memory_limit']); ?>
|
||||
<?php echo $this->get_status_icon($server_info['memory_status']); ?>
|
||||
</td>
|
||||
<td class="seoprostack-info-note">
|
||||
<?php echo esc_html($server_info['memory_note']); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e('Max Execution Time', 'seoprostack'); ?></th>
|
||||
<td>
|
||||
<?php echo esc_html($server_info['max_execution_time']); ?> seconds
|
||||
<?php echo $this->get_status_icon($server_info['execution_status']); ?>
|
||||
</td>
|
||||
<td class="seoprostack-info-note">
|
||||
<?php echo esc_html($server_info['execution_note']); ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-hosting-recommendations">
|
||||
<h3><?php esc_html_e('Recommended Hosting Providers', 'seoprostack'); ?></h3>
|
||||
<p><?php esc_html_e('These hosting providers offer excellent performance for WordPress sites and are recommended for optimal SEO results.', 'seoprostack'); ?></p>
|
||||
|
||||
<div class="seoprostack-hosting-grid">
|
||||
<?php foreach ($hosting_providers as $key => $provider) : ?>
|
||||
<div class="seoprostack-hosting-card">
|
||||
<div class="seoprostack-hosting-card-header">
|
||||
<h4><?php echo esc_html($provider['name']); ?></h4>
|
||||
</div>
|
||||
<div class="seoprostack-hosting-card-content">
|
||||
<p><?php echo esc_html($provider['description']); ?></p>
|
||||
<?php if (!empty($provider['features'])) : ?>
|
||||
<ul class="seoprostack-hosting-features">
|
||||
<?php foreach ($provider['features'] as $feature) : ?>
|
||||
<li><?php echo esc_html($feature); ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="seoprostack-hosting-card-footer">
|
||||
<?php foreach ($provider['button_group'] as $button) : ?>
|
||||
<a href="<?php echo esc_url($button['url']); ?>" class="seoprostack-button<?php echo ($button['primary']) ? ' primary' : ''; ?>" target="_blank">
|
||||
<?php echo esc_html($button['text']); ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get server information.
|
||||
*
|
||||
* @return array Server information.
|
||||
*/
|
||||
private function get_server_info() {
|
||||
global $wpdb;
|
||||
|
||||
// PHP version
|
||||
$php_version = phpversion();
|
||||
$php_status = version_compare($php_version, '7.4', '>=') ? '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 '<span class="seoprostack-status-icon good dashicons dashicons-yes-alt"></span>';
|
||||
case 'warning':
|
||||
return '<span class="seoprostack-status-icon warning dashicons dashicons-warning"></span>';
|
||||
case 'bad':
|
||||
return '<span class="seoprostack-status-icon bad dashicons dashicons-dismiss"></span>';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
176
admin/settings/tabs/class-seoprostack-tab-pro-plugins.php
Normal file
176
admin/settings/tabs/class-seoprostack-tab-pro-plugins.php
Normal file
@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/**
|
||||
* The Pro Plugins tab for plugin settings.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/Tabs
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Pro Plugins tab for plugin settings.
|
||||
*/
|
||||
class SEOProStack_Tab_Pro_Plugins {
|
||||
|
||||
/**
|
||||
* Render the tab content.
|
||||
*/
|
||||
public function render() {
|
||||
?>
|
||||
<div class="seoprostack-settings-content tab-content" id="pro-plugins">
|
||||
<div class="seoprostack-setting-section">
|
||||
<h2><?php esc_html_e('Premium WordPress Plugins', 'seoprostack'); ?></h2>
|
||||
<p class="description"><?php esc_html_e('These premium plugins enhance your WordPress site with advanced features and functionality.', 'seoprostack'); ?></p>
|
||||
|
||||
<div class="seoprostack-plugin-filters" id="seoprostack-plugin-filters">
|
||||
<a href="#" class="button current" data-category="all"><?php esc_html_e('All', 'seoprostack'); ?></a>
|
||||
<a href="#" class="button" data-category="seo"><?php esc_html_e('SEO', 'seoprostack'); ?></a>
|
||||
<a href="#" class="button" data-category="performance"><?php esc_html_e('Performance', 'seoprostack'); ?></a>
|
||||
<a href="#" class="button" data-category="analytics"><?php esc_html_e('Analytics', 'seoprostack'); ?></a>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-loading" style="text-align: center; padding: 30px; display: none;">
|
||||
<span class="spinner is-active"></span>
|
||||
<p><?php esc_html_e('Loading plugins...', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-plugin-list" id="seoprostack-plugin-list">
|
||||
<!-- Plugins will be loaded here via AJAX -->
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-no-plugins" style="display: none;">
|
||||
<p><?php esc_html_e('No plugins found matching your criteria.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function($) {
|
||||
// Function to load plugins
|
||||
function loadProPlugins(category) {
|
||||
var $container = $('#seoprostack-plugin-list');
|
||||
var $loading = $('.seoprostack-loading');
|
||||
var $noPlugins = $('.seoprostack-no-plugins');
|
||||
|
||||
// Reset container and show loading
|
||||
$container.empty();
|
||||
$noPlugins.hide();
|
||||
$loading.show();
|
||||
|
||||
// Make AJAX request
|
||||
$.ajax({
|
||||
url: seoProStack.ajaxurl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'seoprostack_get_pro_plugins',
|
||||
category: category,
|
||||
nonce: seoProStack.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
$loading.hide();
|
||||
|
||||
if (response.success && response.data.plugins && response.data.plugins.length > 0) {
|
||||
// Render plugins
|
||||
$.each(response.data.plugins, function(index, plugin) {
|
||||
var $pluginCard = $('<div class="seoprostack-plugin-card" />');
|
||||
|
||||
// Plugin header
|
||||
var $header = $('<div class="seoprostack-plugin-header" />');
|
||||
$header.append('<h3>' + plugin.name + '</h3>');
|
||||
$header.append('<span class="seoprostack-plugin-version">v' + plugin.version + '</span>');
|
||||
$pluginCard.append($header);
|
||||
|
||||
// Plugin content
|
||||
var $content = $('<div class="seoprostack-plugin-content" />');
|
||||
$content.append('<p>' + plugin.description + '</p>');
|
||||
|
||||
// Plugin actions
|
||||
var $actions = $('<div class="seoprostack-plugin-actions" />');
|
||||
|
||||
if (plugin.status === 'installed') {
|
||||
if (plugin.active) {
|
||||
$actions.append('<span class="button button-disabled">Active</span>');
|
||||
} else {
|
||||
$actions.append('<a href="#" class="button activate-plugin" data-plugin="' + plugin.path + '">Activate</a>');
|
||||
}
|
||||
} else {
|
||||
$actions.append('<a href="' + plugin.url + '" class="button button-primary" target="_blank">Get Plugin</a>');
|
||||
}
|
||||
|
||||
$content.append($actions);
|
||||
$pluginCard.append($content);
|
||||
|
||||
// Add card to container
|
||||
$container.append($pluginCard);
|
||||
});
|
||||
} else {
|
||||
$noPlugins.show();
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
$loading.hide();
|
||||
$noPlugins.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Handle category filter clicks
|
||||
$('#seoprostack-plugin-filters a').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Update active filter
|
||||
$('#seoprostack-plugin-filters a').removeClass('current');
|
||||
$(this).addClass('current');
|
||||
|
||||
// Load plugins
|
||||
var category = $(this).data('category');
|
||||
loadProPlugins(category);
|
||||
});
|
||||
|
||||
// Load initial plugins
|
||||
loadProPlugins('all');
|
||||
|
||||
// Delegate plugin activation
|
||||
$(document).on('click', '.activate-plugin', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var $button = $(this);
|
||||
var pluginPath = $button.data('plugin');
|
||||
|
||||
$button.text('Activating...').addClass('updating-message');
|
||||
|
||||
$.ajax({
|
||||
url: seoProStack.ajaxurl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'seoprostack_activate_plugin',
|
||||
plugin: pluginPath,
|
||||
nonce: seoProStack.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
$button.removeClass('updating-message')
|
||||
.removeClass('activate-plugin')
|
||||
.addClass('button-disabled')
|
||||
.text('Active')
|
||||
.prop('disabled', true);
|
||||
} else {
|
||||
$button.removeClass('updating-message').text('Activate');
|
||||
alert(response.data.message || 'Error activating plugin');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
$button.removeClass('updating-message').text('Activate');
|
||||
alert('Error connecting to server');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
@ -0,0 +1,617 @@
|
||||
<?php
|
||||
/**
|
||||
* The Recommended Plugins tab for plugin settings.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/Tabs
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Recommended Plugins tab for plugin settings.
|
||||
* Self-contained class with integrated data and functionality
|
||||
*/
|
||||
class SEOProStack_Tab_Recommended_Plugins {
|
||||
|
||||
/**
|
||||
* Tab identifier
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $tab_id = 'recommended-plugins';
|
||||
|
||||
/**
|
||||
* Plugin details cache.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $plugin_details = array();
|
||||
|
||||
/**
|
||||
* Initialize the class.
|
||||
* Register any hooks or actions here.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Register AJAX handler for plugin installation
|
||||
add_action('wp_ajax_seoprostack_install_plugins', array($this, 'ajax_install_plugins'));
|
||||
|
||||
// Define plugin names and descriptions for common plugins
|
||||
$this->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;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="seoprostack-settings-content tab-content" id="<?php echo esc_attr($this->get_tab_id()); ?>">
|
||||
<div class="seoprostack-setting-section">
|
||||
<h2><?php esc_html_e('Recommended Free Plugins', 'seoprostack'); ?></h2>
|
||||
<p class="description"><?php echo esc_html($this->get_description()); ?></p>
|
||||
|
||||
<?php
|
||||
// Display SEO plugins section
|
||||
if (!empty($recommended_plugins['seo'])) {
|
||||
echo '<h3>' . esc_html__('SEO Plugins', 'seoprostack') . '</h3>';
|
||||
echo '<div class="seoprostack-plugin-grid">';
|
||||
foreach ($recommended_plugins['seo'] as $plugin_slug) {
|
||||
$this->render_plugin_card($plugin_slug);
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
// Display Cache plugins section
|
||||
if (!empty($recommended_plugins['speed'])) {
|
||||
echo '<h3>' . esc_html__('Cache & Performance', 'seoprostack') . '</h3>';
|
||||
echo '<div class="seoprostack-plugin-grid">';
|
||||
foreach ($recommended_plugins['speed'] as $plugin_slug) {
|
||||
$this->render_plugin_card($plugin_slug);
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
// Display Security plugins section
|
||||
if (!empty($recommended_plugins['security'])) {
|
||||
echo '<h3>' . esc_html__('Security', 'seoprostack') . '</h3>';
|
||||
echo '<div class="seoprostack-plugin-grid">';
|
||||
foreach ($recommended_plugins['security'] as $plugin_slug) {
|
||||
$this->render_plugin_card($plugin_slug);
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
// Display Image optimization plugins section
|
||||
if (!empty($recommended_plugins['media'])) {
|
||||
echo '<h3>' . esc_html__('Image Optimization', 'seoprostack') . '</h3>';
|
||||
echo '<div class="seoprostack-plugin-grid">';
|
||||
foreach ($recommended_plugins['media'] as $plugin_slug) {
|
||||
$this->render_plugin_card($plugin_slug);
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
// Display Backup plugins section
|
||||
if (!empty($recommended_plugins['backup'])) {
|
||||
echo '<h3>' . esc_html__('Backup & Migration', 'seoprostack') . '</h3>';
|
||||
echo '<div class="seoprostack-plugin-grid">';
|
||||
foreach ($recommended_plugins['backup'] as $plugin_slug) {
|
||||
$this->render_plugin_card($plugin_slug);
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="seoprostack-bulk-actions">
|
||||
<button class="button button-primary" id="seoprostack-install-selected">
|
||||
<?php esc_html_e('Install Selected Plugins', 'seoprostack'); ?>
|
||||
</button>
|
||||
<span class="spinner"></span>
|
||||
</div>
|
||||
|
||||
<div id="seoprostack-install-response"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function($) {
|
||||
// Handle bulk installation
|
||||
$('#seoprostack-install-selected').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var $button = $(this);
|
||||
var $spinner = $button.next('.spinner');
|
||||
var $response = $('#seoprostack-install-response');
|
||||
var selected = [];
|
||||
|
||||
// Get selected plugins
|
||||
$('.seoprostack-plugin-check:checked').each(function() {
|
||||
selected.push($(this).val());
|
||||
});
|
||||
|
||||
if (selected.length === 0) {
|
||||
$response.html('<div class="seoprostack-notice seoprostack-notice-warning">Please select at least one plugin to install</div>');
|
||||
return;
|
||||
}
|
||||
|
||||
// Show loading
|
||||
$button.prop('disabled', true);
|
||||
$spinner.css('visibility', 'visible');
|
||||
$response.html('<div class="seoprostack-notice seoprostack-notice-loading">Installing plugins...</div>');
|
||||
|
||||
// Send AJAX request
|
||||
$.ajax({
|
||||
url: wpSeoProStack.ajaxurl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'seoprostack_install_plugins',
|
||||
plugins: selected,
|
||||
nonce: wpSeoProStack.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
// Hide loading
|
||||
$button.prop('disabled', false);
|
||||
$spinner.css('visibility', 'hidden');
|
||||
|
||||
if (response.success) {
|
||||
var html = '<div class="seoprostack-notice seoprostack-notice-success">';
|
||||
html += '<p>Installation completed:</p><ul>';
|
||||
|
||||
$.each(response.data.installed, function(i, plugin) {
|
||||
html += '<li>' + plugin + ' installed and activated successfully</li>';
|
||||
// Update UI
|
||||
$('.seoprostack-plugin-card[data-slug="' + plugin + '"]')
|
||||
.find('.plugin-status')
|
||||
.removeClass('not-installed')
|
||||
.addClass('active')
|
||||
.text('Active');
|
||||
});
|
||||
|
||||
if (response.data.failed.length > 0) {
|
||||
html += '</ul><p>Installation failed:</p><ul>';
|
||||
$.each(response.data.failed, function(i, fail) {
|
||||
html += '<li>' + fail.plugin + ': ' + fail.message + '</li>';
|
||||
});
|
||||
}
|
||||
|
||||
html += '</ul></div>';
|
||||
$response.html(html);
|
||||
} else {
|
||||
$response.html('<div class="seoprostack-notice seoprostack-notice-error">' + response.data.message + '</div>');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
// Hide loading
|
||||
$button.prop('disabled', false);
|
||||
$spinner.css('visibility', 'hidden');
|
||||
|
||||
// Show error
|
||||
$response.html('<div class="seoprostack-notice seoprostack-notice-error">Error connecting to server</div>');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a plugin card.
|
||||
*
|
||||
* @param string $slug The plugin slug.
|
||||
*/
|
||||
private function render_plugin_card($slug) {
|
||||
// Get plugin details
|
||||
$name = isset($this->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';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="seoprostack-plugin-card" data-slug="<?php echo esc_attr($slug); ?>">
|
||||
<div class="seoprostack-plugin-card-header">
|
||||
<label class="seoprostack-checkbox-container">
|
||||
<input type="checkbox" class="seoprostack-plugin-check" value="<?php echo esc_attr($slug); ?>" <?php disabled($status === 'active', true); ?>>
|
||||
<span class="seoprostack-checkbox-checkmark"></span>
|
||||
</label>
|
||||
|
||||
<span class="plugin-status <?php echo esc_attr($status); ?>"><?php echo esc_html($status_text); ?></span>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-plugin-card-content">
|
||||
<h3><?php echo esc_html($name); ?></h3>
|
||||
<?php if (!empty($description)) : ?>
|
||||
<p><?php echo esc_html($description); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="seoprostack-plugin-card-footer">
|
||||
<a href="https://wordpress.org/plugins/<?php echo esc_attr($slug); ?>/" class="button button-secondary" target="_blank">
|
||||
<?php esc_html_e('View Details', 'seoprostack'); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a readable name from a plugin slug.
|
||||
*
|
||||
* @param string $slug The plugin slug.
|
||||
* @return string The readable name.
|
||||
*/
|
||||
private function get_readable_name($slug) {
|
||||
$name = str_replace(array('-', '_'), ' ', $slug);
|
||||
return ucwords($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for plugin installation
|
||||
*/
|
||||
public function ajax_install_plugins() {
|
||||
// Check nonce for security
|
||||
check_ajax_referer('wp-seoprostack-nonce', 'nonce');
|
||||
|
||||
// Ensure user has permission
|
||||
if (!current_user_can('install_plugins')) {
|
||||
wp_send_json_error(array('message' => __('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
|
||||
));
|
||||
}
|
||||
}
|
92
admin/settings/tabs/class-seoprostack-tab-theme.php
Normal file
92
admin/settings/tabs/class-seoprostack-tab-theme.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* The Theme tab for plugin settings.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/Tabs
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Theme tab for plugin settings.
|
||||
*/
|
||||
class SEOProStack_Tab_Theme {
|
||||
|
||||
/**
|
||||
* Render the tab content.
|
||||
*/
|
||||
public function render() {
|
||||
// Get current theme
|
||||
$current_theme = wp_get_theme();
|
||||
?>
|
||||
<div class="seoprostack-settings-content tab-content" id="theme">
|
||||
<div class="seoprostack-setting-section">
|
||||
<h2><?php esc_html_e('Theme Recommendations', 'seoprostack'); ?></h2>
|
||||
<p class="description"><?php esc_html_e('These themes are fast, SEO-friendly, and work well with SEO Pro Stack.', 'seoprostack'); ?></p>
|
||||
|
||||
<div class="seoprostack-theme-info">
|
||||
<h3><?php esc_html_e('Your Current Theme', 'seoprostack'); ?></h3>
|
||||
<div class="seoprostack-current-theme">
|
||||
<?php if ($current_theme->get_screenshot()) : ?>
|
||||
<div class="seoprostack-theme-screenshot">
|
||||
<img src="<?php echo esc_url($current_theme->get_screenshot()); ?>" alt="<?php echo esc_attr($current_theme->display('Name')); ?>">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="seoprostack-theme-details">
|
||||
<h4><?php echo esc_html($current_theme->display('Name')); ?></h4>
|
||||
<div class="seoprostack-theme-version"><?php printf(esc_html__('Version: %s', 'seoprostack'), $current_theme->display('Version')); ?></div>
|
||||
<div class="seoprostack-theme-author"><?php printf(esc_html__('By %s', 'seoprostack'), $current_theme->display('Author')); ?></div>
|
||||
<p class="description"><?php echo esc_html($current_theme->display('Description')); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-recommended-themes">
|
||||
<h3><?php esc_html_e('Recommended Themes', 'seoprostack'); ?></h3>
|
||||
<div class="seoprostack-theme-grid">
|
||||
<!-- Astra Theme -->
|
||||
<div class="seoprostack-theme-card">
|
||||
<div class="seoprostack-theme-card-header">
|
||||
<img src="<?php echo esc_url(SEOPROSTACK_PLUGIN_URL . 'admin/images/themes/astra.jpg'); ?>" alt="Astra Theme">
|
||||
</div>
|
||||
<div class="seoprostack-theme-card-content">
|
||||
<h4>Astra</h4>
|
||||
<p><?php esc_html_e('Fast, lightweight and customizable WordPress theme suitable for blogs, personal portfolios and business websites.', 'seoprostack'); ?></p>
|
||||
<a href="https://wpastra.com/" class="button" target="_blank"><?php esc_html_e('Learn More', 'seoprostack'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- GeneratePress Theme -->
|
||||
<div class="seoprostack-theme-card">
|
||||
<div class="seoprostack-theme-card-header">
|
||||
<img src="<?php echo esc_url(SEOPROSTACK_PLUGIN_URL . 'admin/images/themes/generatepress.jpg'); ?>" alt="GeneratePress Theme">
|
||||
</div>
|
||||
<div class="seoprostack-theme-card-content">
|
||||
<h4>GeneratePress</h4>
|
||||
<p><?php esc_html_e('Lightweight WordPress theme focused on speed, stability, and accessibility.', 'seoprostack'); ?></p>
|
||||
<a href="https://generatepress.com/" class="button" target="_blank"><?php esc_html_e('Learn More', 'seoprostack'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Kadence Theme -->
|
||||
<div class="seoprostack-theme-card">
|
||||
<div class="seoprostack-theme-card-header">
|
||||
<img src="<?php echo esc_url(SEOPROSTACK_PLUGIN_URL . 'admin/images/themes/kadence.jpg'); ?>" alt="Kadence Theme">
|
||||
</div>
|
||||
<div class="seoprostack-theme-card-content">
|
||||
<h4>Kadence</h4>
|
||||
<p><?php esc_html_e('Fast, lightweight, and extremely customizable WordPress theme.', 'seoprostack'); ?></p>
|
||||
<a href="https://www.kadencewp.com/kadence-theme/" class="button" target="_blank"><?php esc_html_e('Learn More', 'seoprostack'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
299
admin/settings/tabs/class-seoprostack-tab-tools.php
Normal file
299
admin/settings/tabs/class-seoprostack-tab-tools.php
Normal file
@ -0,0 +1,299 @@
|
||||
<?php
|
||||
/**
|
||||
* The Tools tab for plugin settings.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/Tabs
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Tools tab for plugin settings.
|
||||
* Self-contained class with integrated data and functionality
|
||||
*/
|
||||
class SEOProStack_Tab_Tools {
|
||||
|
||||
/**
|
||||
* Tab identifier
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $tab_id = 'tools';
|
||||
|
||||
/**
|
||||
* Initialize the class.
|
||||
* Register any hooks or actions here.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Register AJAX handler for database optimization
|
||||
add_action('wp_ajax_seoprostack_optimize_database', array($this, 'ajax_optimize_database'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 __('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;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="seoprostack-settings-content tab-content" id="<?php echo esc_attr($this->get_tab_id()); ?>">
|
||||
<div class="seoprostack-setting-section">
|
||||
<h2><?php esc_html_e('SEO Tools', 'seoprostack'); ?></h2>
|
||||
<p class="description"><?php echo esc_html($this->get_description()); ?></p>
|
||||
|
||||
<div class="seoprostack-tools-grid">
|
||||
<?php foreach ($tools as $key => $tool) : ?>
|
||||
<div class="seoprostack-tool-card">
|
||||
<div class="seoprostack-tool-card-header">
|
||||
<span class="dashicons dashicons-admin-tools"></span>
|
||||
</div>
|
||||
<div class="seoprostack-tool-card-content">
|
||||
<h3><?php echo esc_html($tool['name']); ?></h3>
|
||||
<p><?php echo esc_html($tool['description']); ?></p>
|
||||
<?php if (!empty($tool['button_group'])) : ?>
|
||||
<?php foreach ($tool['button_group'] as $button) : ?>
|
||||
<a href="<?php echo esc_url($button['url']); ?>" class="button<?php echo ($button['primary']) ? ' button-primary' : ''; ?>" target="_blank">
|
||||
<?php echo esc_html($button['text']); ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-section">
|
||||
<h3><?php esc_html_e('Database Optimization', 'seoprostack'); ?></h3>
|
||||
<p class="description"><?php esc_html_e('Clean up your WordPress database to improve performance.', 'seoprostack'); ?></p>
|
||||
|
||||
<div id="seoprostack-db-cleanup-response"></div>
|
||||
|
||||
<div class="seoprostack-db-actions">
|
||||
<button type="button" class="button button-primary" id="seoprostack-optimize-db">
|
||||
<?php esc_html_e('Optimize Database', 'seoprostack'); ?>
|
||||
</button>
|
||||
<span class="spinner"></span>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function($) {
|
||||
$('#seoprostack-optimize-db').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var $button = $(this);
|
||||
var $spinner = $button.next('.spinner');
|
||||
var $response = $('#seoprostack-db-cleanup-response');
|
||||
|
||||
// Show loading
|
||||
$button.prop('disabled', true);
|
||||
$spinner.css('visibility', 'visible');
|
||||
|
||||
// Send AJAX request
|
||||
$.ajax({
|
||||
url: wpSeoProStack.ajaxurl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'seoprostack_optimize_database',
|
||||
nonce: wpSeoProStack.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
// Hide loading
|
||||
$button.prop('disabled', false);
|
||||
$spinner.css('visibility', 'hidden');
|
||||
|
||||
if (response.success) {
|
||||
$response.html('<div class="seoprostack-notice seoprostack-notice-success">' + response.data.message + '</div>');
|
||||
} else {
|
||||
$response.html('<div class="seoprostack-notice seoprostack-notice-error">' + response.data.message + '</div>');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
// Hide loading
|
||||
$button.prop('disabled', false);
|
||||
$spinner.css('visibility', 'hidden');
|
||||
|
||||
// Show error
|
||||
$response.html('<div class="seoprostack-notice seoprostack-notice-error">Error connecting to server</div>');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for database optimization
|
||||
*/
|
||||
public function ajax_optimize_database() {
|
||||
// Check nonce for security
|
||||
check_ajax_referer('wp-seoprostack-nonce', 'nonce');
|
||||
|
||||
// Ensure user has permission
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_send_json_error(array('message' => __('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
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
132
admin/settings/tabs/class-seoprostack-tab-workflow.php
Normal file
132
admin/settings/tabs/class-seoprostack-tab-workflow.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* The Workflow tab for plugin settings.
|
||||
*
|
||||
* @package SEO_Pro_Stack
|
||||
* @subpackage SEO_Pro_Stack/Admin/Settings/Tabs
|
||||
*/
|
||||
|
||||
// If this file is called directly, abort.
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Workflow tab for plugin settings.
|
||||
*/
|
||||
class SEOProStack_Tab_Workflow {
|
||||
|
||||
/**
|
||||
* Render the tab content.
|
||||
*/
|
||||
public function render() {
|
||||
$options = get_option('seoprostack_workflow_options', array(
|
||||
'auto_upload_images' => true,
|
||||
'max_width' => 1200,
|
||||
'max_height' => 1200,
|
||||
'exclude_urls' => '',
|
||||
'image_name_pattern' => '%filename%',
|
||||
'image_alt_pattern' => '%filename%'
|
||||
));
|
||||
?>
|
||||
<div class="seoprostack-settings-content tab-content" id="workflow">
|
||||
<form method="post" action="options.php" id="seoprostack-workflow-form">
|
||||
<?php settings_fields('seoprostack_settings'); ?>
|
||||
|
||||
<div class="seoprostack-setting-section">
|
||||
<h2><?php esc_html_e('Image Auto-Upload Settings', 'seoprostack'); ?></h2>
|
||||
<p class="description"><?php esc_html_e('Configure how external images are automatically uploaded to your media library.', 'seoprostack'); ?></p>
|
||||
|
||||
<div class="seoprostack-toggle">
|
||||
<div class="seoprostack-toggle-header">
|
||||
<div class="seoprostack-toggle-main">
|
||||
<div class="seoprostack-toggle-left">
|
||||
<div class="wp-toggle-switch">
|
||||
<input type="checkbox"
|
||||
id="auto_upload_images"
|
||||
name="seoprostack_workflow_options[auto_upload_images]"
|
||||
value="1"
|
||||
<?php checked(isset($options['auto_upload_images']) ? $options['auto_upload_images'] : true); ?>
|
||||
/>
|
||||
<label for="auto_upload_images" class="toggle-label"></label>
|
||||
</div>
|
||||
<label for="auto_upload_images">
|
||||
<?php esc_html_e('Enable Auto Upload Images', 'seoprostack'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<p class="seoprostack-setting-description">
|
||||
<?php esc_html_e('Import images that have external URLs into your Media Library when saving content. Consider disabling during large data imports with many external image URLs.', 'seoprostack'); ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-toggle-settings">
|
||||
<div class="seoprostack-setting-row">
|
||||
<label for="max_width"><?php esc_html_e('Max Width', 'seoprostack'); ?></label>
|
||||
<input type="number"
|
||||
id="max_width"
|
||||
name="seoprostack_workflow_options[max_width]"
|
||||
value="<?php echo esc_attr(isset($options['max_width']) ? $options['max_width'] : 1200); ?>"
|
||||
/>
|
||||
<p class="description"><?php esc_html_e('Maximum width for uploaded images in pixels.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-row">
|
||||
<label for="max_height"><?php esc_html_e('Max Height', 'seoprostack'); ?></label>
|
||||
<input type="number"
|
||||
id="max_height"
|
||||
name="seoprostack_workflow_options[max_height]"
|
||||
value="<?php echo esc_attr(isset($options['max_height']) ? $options['max_height'] : 1200); ?>"
|
||||
/>
|
||||
<p class="description"><?php esc_html_e('Maximum height for uploaded images in pixels.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-row">
|
||||
<label for="exclude_urls"><?php esc_html_e('Exclude URLs', 'seoprostack'); ?></label>
|
||||
<textarea id="exclude_urls"
|
||||
name="seoprostack_workflow_options[exclude_urls]"
|
||||
rows="3"
|
||||
class="large-text"
|
||||
><?php echo esc_textarea(isset($options['exclude_urls']) ? $options['exclude_urls'] : ''); ?></textarea>
|
||||
<p class="description"><?php esc_html_e('Enter domains to exclude (one per line). Images from these domains will not be imported.', 'seoprostack'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-row">
|
||||
<label for="image_name_pattern"><?php esc_html_e('Image Name Pattern', 'seoprostack'); ?></label>
|
||||
<input type="text"
|
||||
id="image_name_pattern"
|
||||
name="seoprostack_workflow_options[image_name_pattern]"
|
||||
value="<?php echo esc_attr(isset($options['image_name_pattern']) ? $options['image_name_pattern'] : '%filename%'); ?>"
|
||||
class="regular-text"
|
||||
/>
|
||||
<p class="description">
|
||||
<?php esc_html_e('Available patterns:', 'seoprostack'); ?> %filename%, %post_id%, %postname%, %timestamp%, %date%, %year%, %month%, %day%
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-row">
|
||||
<label for="image_alt_pattern"><?php esc_html_e('Image Alt Pattern', 'seoprostack'); ?></label>
|
||||
<input type="text"
|
||||
id="image_alt_pattern"
|
||||
name="seoprostack_workflow_options[image_alt_pattern]"
|
||||
value="<?php echo esc_attr(isset($options['image_alt_pattern']) ? $options['image_alt_pattern'] : '%filename%'); ?>"
|
||||
class="regular-text"
|
||||
/>
|
||||
<p class="description">
|
||||
<?php esc_html_e('Available patterns:', 'seoprostack'); ?> %filename%, %post_title%, %post_id%, %postname%, %timestamp%
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="seoprostack-setting-actions">
|
||||
<button type="submit" class="button button-primary">
|
||||
<?php esc_html_e('Save Changes', 'seoprostack'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user