Rename plugin to wp-seoprostack-plugin, update file structure

This commit is contained in:
Marcus Quinn
2025-03-24 02:48:06 +00:00
parent 18b0a2c246
commit aee3cb91e2
35 changed files with 5455 additions and 655 deletions

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