Because cats have 9 lives, but servers don't - so they need backup-restore! Complete backup solution with S3/MinIO support. - Full WordPress backup (files + database) - S3 / MinIO / S3-compatible storage backends - Scheduled automatic backups - Disaster recovery / one-click restore - Backup integrity validation - Cat-themed admin interface Includes build.sh and .distignore for WordPress-installable release ZIPs.
663 lines
24 KiB
PHP
663 lines
24 KiB
PHP
<?php
|
|
/**
|
|
* Admin Interface Manager
|
|
*
|
|
* Handles WordPress admin integration for TigerStyle Life9 backup plugin
|
|
* Registers admin pages and loads Astro-generated assets
|
|
*
|
|
* @package TigerStyleLife9
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
// Exit if accessed directly
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Admin interface management class
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
class TigerStyle_Life9_Admin {
|
|
|
|
/**
|
|
* Plugin instance
|
|
*
|
|
* @var TigerStyle_Life9
|
|
*/
|
|
private $plugin;
|
|
|
|
/**
|
|
* Security instance
|
|
*
|
|
* @var TigerStyle_Life9_Security
|
|
*/
|
|
private $security;
|
|
|
|
/**
|
|
* Asset manifest
|
|
*
|
|
* @var array
|
|
*/
|
|
private $asset_manifest = [];
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param TigerStyle_Life9 $plugin Plugin instance
|
|
*/
|
|
public function __construct($plugin) {
|
|
$this->plugin = $plugin;
|
|
$this->security = $plugin->get_security();
|
|
|
|
$this->load_asset_manifest();
|
|
$this->init_hooks();
|
|
}
|
|
|
|
/**
|
|
* Initialize WordPress hooks
|
|
*/
|
|
private function init_hooks() {
|
|
add_action('admin_menu', [$this, 'register_admin_pages']);
|
|
add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']);
|
|
add_action('admin_init', [$this, 'handle_admin_actions']);
|
|
add_action('wp_ajax_tigerstyle_life9_render_page', [$this, 'render_astro_page']);
|
|
|
|
// Add admin notices
|
|
add_action('admin_notices', [$this, 'display_admin_notices']);
|
|
|
|
// Add plugin action links
|
|
add_filter('plugin_action_links_' . TIGERSTYLE_LIFE9_BASENAME, [$this, 'add_plugin_action_links']);
|
|
}
|
|
|
|
/**
|
|
* Load Astro asset manifest
|
|
*/
|
|
private function load_asset_manifest() {
|
|
$manifest_path = TIGERSTYLE_LIFE9_PATH . 'admin/assets/dist/manifest.json';
|
|
|
|
if (file_exists($manifest_path)) {
|
|
$manifest_content = file_get_contents($manifest_path);
|
|
$this->asset_manifest = json_decode($manifest_content, true) ?: [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register admin menu pages
|
|
*/
|
|
public function register_admin_pages() {
|
|
// Check user capability
|
|
if (!current_user_can('manage_options')) {
|
|
return;
|
|
}
|
|
|
|
// Main menu page
|
|
add_menu_page(
|
|
'🐾 Life Tracker Dashboard', // Page title
|
|
'TigerStyle Life9', // Menu title
|
|
'manage_options', // Capability
|
|
'tigerstyle-life9', // Menu slug
|
|
[$this, 'render_dashboard_page'], // Callback
|
|
'dashicons-backup', // Icon (more appropriate for backups)
|
|
30 // Position
|
|
);
|
|
|
|
// Life Saving page
|
|
add_submenu_page(
|
|
'tigerstyle-life9', // Parent slug
|
|
'💾 Save a Life', // Page title
|
|
'💾 Save a Life', // Menu title
|
|
'manage_options', // Capability
|
|
'tigerstyle-life9-backup', // Menu slug
|
|
[$this, 'render_backup_page'] // Callback
|
|
);
|
|
|
|
// Life Revival page
|
|
add_submenu_page(
|
|
'tigerstyle-life9', // Parent slug
|
|
'🔄 Revive a Life', // Page title
|
|
'🔄 Revive a Life', // Menu title
|
|
'manage_options', // Capability
|
|
'tigerstyle-life9-restore', // Menu slug
|
|
[$this, 'render_restore_page'] // Callback
|
|
);
|
|
|
|
// Life Chronicles page
|
|
add_submenu_page(
|
|
'tigerstyle-life9', // Parent slug
|
|
'📚 Life Chronicles', // Page title
|
|
'📚 Life Chronicles', // Menu title
|
|
'manage_options', // Capability
|
|
'tigerstyle-life9-backups', // Menu slug
|
|
[$this, 'render_backups_page'] // Callback
|
|
);
|
|
|
|
// Territory Settings page
|
|
add_submenu_page(
|
|
'tigerstyle-life9', // Parent slug
|
|
'🏠 Territory Settings', // Page title
|
|
'🏠 Territory Settings', // Menu title
|
|
'manage_options', // Capability
|
|
'tigerstyle-life9-settings', // Menu slug
|
|
[$this, 'render_settings_page'] // Callback
|
|
);
|
|
|
|
// Rename first submenu to cat-themed name
|
|
global $submenu;
|
|
if (isset($submenu['tigerstyle-life9'])) {
|
|
$submenu['tigerstyle-life9'][0][0] = '🐾 Life Tracker';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Enqueue admin assets
|
|
*
|
|
* @param string $hook_suffix Current admin page hook suffix
|
|
*/
|
|
public function enqueue_admin_assets($hook_suffix) {
|
|
// Only load on our admin pages
|
|
if (!$this->is_tigerstyle_admin_page($hook_suffix)) {
|
|
return;
|
|
}
|
|
|
|
// Enqueue WordPress core dependencies
|
|
wp_enqueue_script('jquery');
|
|
wp_enqueue_media();
|
|
|
|
// Enqueue Alpine.js
|
|
wp_enqueue_script(
|
|
'alpine-js',
|
|
'https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js',
|
|
[],
|
|
'3.13.3',
|
|
true
|
|
);
|
|
|
|
// Defer Alpine.js execution
|
|
add_filter('script_loader_tag', function($tag, $handle) {
|
|
if ($handle === 'alpine-js') {
|
|
return str_replace(' src', ' defer src', $tag);
|
|
}
|
|
return $tag;
|
|
}, 10, 2);
|
|
|
|
// Enqueue Astro-generated assets
|
|
$this->enqueue_astro_assets();
|
|
|
|
// Enqueue admin styles
|
|
wp_enqueue_style(
|
|
'tigerstyle-life9-admin',
|
|
TIGERSTYLE_LIFE9_URL . 'admin/assets/css/admin.css',
|
|
[],
|
|
TIGERSTYLE_LIFE9_VERSION
|
|
);
|
|
|
|
// Localize script for AJAX with cat-themed messages
|
|
wp_localize_script('jquery', 'tigerStyleLife9', [
|
|
'ajaxUrl' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('tigerstyle_life9_ajax'),
|
|
'pluginUrl' => TIGERSTYLE_LIFE9_URL,
|
|
'currentPage' => $this->get_current_page_slug($hook_suffix),
|
|
'capabilities' => [
|
|
'backup' => current_user_can('manage_options'),
|
|
'restore' => current_user_can('manage_options'),
|
|
'settings' => current_user_can('manage_options')
|
|
],
|
|
'strings' => [
|
|
'confirmDelete' => __('😿 Are you sure you want to permanently lose this life? This cannot be undone!', 'tigerstyle-life9'),
|
|
'confirmRestore' => __('🔄 This will revive your site to this saved life. Current state will be overwritten. Ready to pounce?', 'tigerstyle-life9'),
|
|
'processing' => __('🐾 Stalking through the process...', 'tigerstyle-life9'),
|
|
'error' => __('😿 Oops! Cat got stuck. Please try again.', 'tigerstyle-life9'),
|
|
'scanning' => __('🔍 Stalking through your files...', 'tigerstyle-life9'),
|
|
'compressing' => __('📦 Packing your territory efficiently...', 'tigerstyle-life9'),
|
|
'uploading' => __('☁️ Moving to your backup lair...', 'tigerstyle-life9'),
|
|
'completed' => __('😻 Mission accomplished! Life saved successfully.', 'tigerstyle-life9'),
|
|
'warning' => __('⚠️ Something smells fishy in your files...', 'tigerstyle-life9'),
|
|
'ninthLife' => __('🛡️ Nine lives protection activated!', 'tigerstyle-life9'),
|
|
'territoryScan' => __('🏠 Territory backup complete - domain secured!', 'tigerstyle-life9'),
|
|
'memoryPreservation' => __('🧠 Preserving digital memories...', 'tigerstyle-life9'),
|
|
'catReflexes' => __('⚡ Pouncing on database changes...', 'tigerstyle-life9')
|
|
]
|
|
]);
|
|
|
|
// Add Alpine.js WordPress integration helper
|
|
$this->add_alpine_wordpress_helper();
|
|
}
|
|
|
|
/**
|
|
* Enqueue Astro-generated assets
|
|
*/
|
|
private function enqueue_astro_assets() {
|
|
if (empty($this->asset_manifest)) {
|
|
return;
|
|
}
|
|
|
|
// Enqueue CSS files
|
|
foreach ($this->asset_manifest as $file => $data) {
|
|
if (isset($data['isEntry']) && $data['isEntry'] && isset($data['css'])) {
|
|
foreach ($data['css'] as $css_file) {
|
|
wp_enqueue_style(
|
|
'tigerstyle-astro-' . basename($css_file, '.css'),
|
|
TIGERSTYLE_LIFE9_URL . 'admin/assets/dist/' . $css_file,
|
|
[],
|
|
TIGERSTYLE_LIFE9_VERSION
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Enqueue JS files
|
|
foreach ($this->asset_manifest as $file => $data) {
|
|
if (isset($data['isEntry']) && $data['isEntry']) {
|
|
wp_enqueue_script(
|
|
'tigerstyle-astro-' . basename($file, '.js'),
|
|
TIGERSTYLE_LIFE9_URL . 'admin/assets/dist/' . $file,
|
|
['jquery', 'alpine-js'],
|
|
TIGERSTYLE_LIFE9_VERSION,
|
|
true
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add Alpine.js WordPress helper
|
|
*/
|
|
private function add_alpine_wordpress_helper() {
|
|
?>
|
|
<script>
|
|
// Alpine.js WordPress integration helper
|
|
document.addEventListener('alpine:init', () => {
|
|
Alpine.magic('wp', () => ({
|
|
ajax: async (action, data = {}) => {
|
|
const formData = new FormData();
|
|
formData.append('action', 'tigerstyle_life9_' + action);
|
|
formData.append('_wpnonce', tigerStyleLife9.nonce);
|
|
|
|
// Append data
|
|
Object.keys(data).forEach(key => {
|
|
if (data[key] instanceof File) {
|
|
formData.append(key, data[key]);
|
|
} else if (typeof data[key] === 'object') {
|
|
formData.append(key, JSON.stringify(data[key]));
|
|
} else {
|
|
formData.append(key, data[key]);
|
|
}
|
|
});
|
|
|
|
const response = await fetch(tigerStyleLife9.ajaxUrl, {
|
|
method: 'POST',
|
|
body: formData,
|
|
credentials: 'same-origin'
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const result = await response.json();
|
|
|
|
if (!result.success) {
|
|
throw new Error(result.data || 'Request failed');
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
nonce: tigerStyleLife9.nonce,
|
|
adminUrl: tigerStyleLife9.ajaxUrl,
|
|
pluginUrl: tigerStyleLife9.pluginUrl,
|
|
currentPage: tigerStyleLife9.currentPage,
|
|
capabilities: tigerStyleLife9.capabilities,
|
|
strings: tigerStyleLife9.strings
|
|
}));
|
|
});
|
|
</script>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Check if current page is a TigerStyle admin page
|
|
*
|
|
* @param string $hook_suffix Current hook suffix
|
|
* @return bool
|
|
*/
|
|
private function is_tigerstyle_admin_page($hook_suffix) {
|
|
$tigerstyle_pages = [
|
|
'toplevel_page_tigerstyle-life9',
|
|
'tigerstyle-life9_page_tigerstyle-life9-backup',
|
|
'tigerstyle-life9_page_tigerstyle-life9-restore',
|
|
'tigerstyle-life9_page_tigerstyle-life9-backups',
|
|
'tigerstyle-life9_page_tigerstyle-life9-settings'
|
|
];
|
|
|
|
return in_array($hook_suffix, $tigerstyle_pages);
|
|
}
|
|
|
|
/**
|
|
* Get current page slug from hook suffix
|
|
*
|
|
* @param string $hook_suffix Hook suffix
|
|
* @return string Page slug
|
|
*/
|
|
private function get_current_page_slug($hook_suffix) {
|
|
$page_map = [
|
|
'toplevel_page_tigerstyle-life9' => 'dashboard',
|
|
'tigerstyle-life9_page_tigerstyle-life9-backup' => 'backup',
|
|
'tigerstyle-life9_page_tigerstyle-life9-restore' => 'restore',
|
|
'tigerstyle-life9_page_tigerstyle-life9-backups' => 'backups',
|
|
'tigerstyle-life9_page_tigerstyle-life9-settings' => 'settings'
|
|
];
|
|
|
|
return $page_map[$hook_suffix] ?? 'dashboard';
|
|
}
|
|
|
|
/**
|
|
* Render dashboard page
|
|
*/
|
|
public function render_dashboard_page() {
|
|
$this->render_page('admin-dashboard');
|
|
}
|
|
|
|
/**
|
|
* Render backup page
|
|
*/
|
|
public function render_backup_page() {
|
|
$this->render_page('backup');
|
|
}
|
|
|
|
/**
|
|
* Render restore page
|
|
*/
|
|
public function render_restore_page() {
|
|
$this->render_page('restore');
|
|
}
|
|
|
|
/**
|
|
* Render backups management page
|
|
*/
|
|
public function render_backups_page() {
|
|
$this->render_page('backups');
|
|
}
|
|
|
|
/**
|
|
* Render settings page
|
|
*/
|
|
public function render_settings_page() {
|
|
$this->render_page('settings');
|
|
}
|
|
|
|
/**
|
|
* Render Astro page
|
|
*
|
|
* @param string $page_name Page name
|
|
*/
|
|
private function render_page($page_name) {
|
|
// Security check
|
|
if (!current_user_can('manage_options')) {
|
|
wp_die(__('You do not have sufficient permissions to access this page.', 'tigerstyle-life9'));
|
|
}
|
|
|
|
// Verify nonce for AJAX requests
|
|
if (wp_doing_ajax()) {
|
|
check_ajax_referer('tigerstyle_life9_ajax', '_wpnonce');
|
|
}
|
|
|
|
// For now, render the Astro pages as PHP templates
|
|
// In a production version, you would use a proper Astro SSR setup
|
|
$astro_file = TIGERSTYLE_LIFE9_PATH . "src/astro/pages/{$page_name}.astro";
|
|
|
|
if (file_exists($astro_file)) {
|
|
// Convert Astro to WordPress-compatible output
|
|
$this->render_astro_as_php($astro_file, $page_name);
|
|
} else {
|
|
// Fallback if Astro file doesn't exist
|
|
$this->render_fallback_page($page_name);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render Astro file as PHP (simplified conversion)
|
|
*
|
|
* @param string $astro_file Path to Astro file
|
|
* @param string $page_name Page name for context
|
|
*/
|
|
private function render_astro_as_php($astro_file, $page_name) {
|
|
// Read the Astro file content
|
|
$astro_content = file_get_contents($astro_file);
|
|
|
|
// Extract the HTML content (everything after the ---)
|
|
$parts = preg_split('/^---$/m', $astro_content);
|
|
$html_content = isset($parts[2]) ? $parts[2] : (isset($parts[1]) ? $parts[1] : $astro_content);
|
|
|
|
// Process template variables
|
|
$html_content = str_replace('{{PLUGIN_URL}}', TIGERSTYLE_LIFE9_URL, $html_content);
|
|
$html_content = str_replace('{{ADMIN_URL}}', admin_url(), $html_content);
|
|
$html_content = str_replace('{{AJAX_URL}}', admin_url('admin-ajax.php'), $html_content);
|
|
|
|
// Add WordPress admin wrapper
|
|
echo '<div class="wrap tigerstyle-life9-admin">';
|
|
echo $html_content;
|
|
echo '</div>';
|
|
}
|
|
|
|
/**
|
|
* Process Astro-generated content
|
|
*
|
|
* @param string $content HTML content
|
|
* @return string Processed content
|
|
*/
|
|
private function process_astro_content($content) {
|
|
// Extract scripts and styles for proper WordPress handling
|
|
$content = preg_replace('/<script[^>]*>.*?<\/script>/is', '', $content);
|
|
$content = preg_replace('/<link[^>]*rel=["\']stylesheet["\'][^>]*>/i', '', $content);
|
|
|
|
// Add WordPress admin wrapper if not present
|
|
if (strpos($content, 'class="wrap"') === false) {
|
|
$content = '<div class="wrap tigerstyle-life9-admin">' . $content . '</div>';
|
|
}
|
|
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Render fallback page when Astro build is not available
|
|
*
|
|
* @param string $page_name Page name
|
|
*/
|
|
private function render_fallback_page($page_name) {
|
|
?>
|
|
<div class="wrap tigerstyle-life9-admin">
|
|
<div class="tigerstyle-header">
|
|
<h1 class="wp-heading-inline">
|
|
<span class="tigerstyle-icon">🛡️</span>
|
|
TigerStyle Life9 - <?php echo esc_html(ucfirst($page_name)); ?>
|
|
</h1>
|
|
</div>
|
|
|
|
<div class="notice notice-warning">
|
|
<h3>⚠️ Development Mode</h3>
|
|
<p>The Astro frontend is not built yet. Please run the build process:</p>
|
|
<ol>
|
|
<li>Navigate to the plugin directory: <code><?php echo esc_html(TIGERSTYLE_LIFE9_PATH); ?></code></li>
|
|
<li>Install dependencies: <code>npm install</code></li>
|
|
<li>Build the frontend: <code>npm run build</code></li>
|
|
</ol>
|
|
</div>
|
|
|
|
<div class="tigerstyle-card">
|
|
<h3><?php echo esc_html(ucfirst($page_name)); ?> Page</h3>
|
|
<p>This page will display the <?php echo esc_html($page_name); ?> interface once the frontend is built.</p>
|
|
|
|
<?php if ($page_name === 'backup'): ?>
|
|
<p>The backup interface will allow you to:</p>
|
|
<ul>
|
|
<li>Select what to backup (files, database, media)</li>
|
|
<li>Configure encryption settings</li>
|
|
<li>Choose storage destination</li>
|
|
<li>Monitor backup progress in real-time</li>
|
|
</ul>
|
|
<?php elseif ($page_name === 'restore'): ?>
|
|
<p>The restore interface will allow you to:</p>
|
|
<ul>
|
|
<li>Select backup source (existing, upload, or URL)</li>
|
|
<li>Decrypt and validate backups</li>
|
|
<li>Choose what to restore</li>
|
|
<li>Monitor restore progress with safety checks</li>
|
|
</ul>
|
|
<?php elseif ($page_name === 'settings'): ?>
|
|
<p>The settings interface will allow you to:</p>
|
|
<ul>
|
|
<li>Configure security and encryption settings</li>
|
|
<li>Set up storage backends (local, S3, Google Drive)</li>
|
|
<li>Schedule automatic backups</li>
|
|
<li>Manage notifications and advanced options</li>
|
|
</ul>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Handle admin actions
|
|
*/
|
|
public function handle_admin_actions() {
|
|
// Handle any admin-specific actions here
|
|
if (isset($_GET['tigerstyle_action'])) {
|
|
$action = sanitize_text_field($_GET['tigerstyle_action']);
|
|
|
|
// Verify nonce
|
|
if (!wp_verify_nonce($_GET['_wpnonce'] ?? '', 'tigerstyle_action_' . $action)) {
|
|
wp_die(__('Security check failed', 'tigerstyle-life9'));
|
|
}
|
|
|
|
switch ($action) {
|
|
case 'clear_cache':
|
|
$this->clear_plugin_cache();
|
|
break;
|
|
case 'rebuild_assets':
|
|
$this->rebuild_astro_assets();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* AJAX handler for rendering Astro pages
|
|
*/
|
|
public function render_astro_page() {
|
|
check_ajax_referer('tigerstyle_life9_ajax', '_wpnonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_die(__('Insufficient permissions', 'tigerstyle-life9'), 403);
|
|
}
|
|
|
|
$page = sanitize_text_field($_POST['page'] ?? '');
|
|
|
|
if (empty($page)) {
|
|
wp_send_json_error('Invalid page');
|
|
}
|
|
|
|
// Capture page output
|
|
ob_start();
|
|
$this->render_page($page);
|
|
$content = ob_get_clean();
|
|
|
|
wp_send_json_success(['content' => $content]);
|
|
}
|
|
|
|
/**
|
|
* Display admin notices
|
|
*/
|
|
public function display_admin_notices() {
|
|
// Only show on our admin pages
|
|
$screen = get_current_screen();
|
|
if (!$screen || strpos($screen->id, 'tigerstyle-life9') === false) {
|
|
return;
|
|
}
|
|
|
|
// Check if Astro build exists
|
|
$build_exists = file_exists(TIGERSTYLE_LIFE9_PATH . 'admin/assets/dist/manifest.json');
|
|
|
|
if (!$build_exists && current_user_can('manage_options')) {
|
|
?>
|
|
<div class="notice notice-info">
|
|
<h3>🚀 Welcome to TigerStyle Life9!</h3>
|
|
<p>To get started, please build the admin interface:</p>
|
|
<ol>
|
|
<li>Open terminal in plugin directory: <code><?php echo esc_html(TIGERSTYLE_LIFE9_PATH); ?></code></li>
|
|
<li>Install dependencies: <code>npm install</code></li>
|
|
<li>Build interface: <code>npm run build</code></li>
|
|
</ol>
|
|
<p>After building, refresh this page to see the full interface.</p>
|
|
</div>
|
|
<?php
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add plugin action links
|
|
*
|
|
* @param array $links Existing links
|
|
* @return array Modified links
|
|
*/
|
|
public function add_plugin_action_links($links) {
|
|
$tigerstyle_links = [
|
|
'<a href="' . admin_url('admin.php?page=tigerstyle-life9-backup') . '">' . __('Create Backup', 'tigerstyle-life9') . '</a>',
|
|
'<a href="' . admin_url('admin.php?page=tigerstyle-life9-settings') . '">' . __('Settings', 'tigerstyle-life9') . '</a>'
|
|
];
|
|
|
|
return array_merge($tigerstyle_links, $links);
|
|
}
|
|
|
|
/**
|
|
* Clear plugin cache
|
|
*/
|
|
private function clear_plugin_cache() {
|
|
// Clear any cached data
|
|
delete_transient('tigerstyle_life9_system_info');
|
|
delete_transient('tigerstyle_life9_backup_list');
|
|
|
|
// Reload asset manifest
|
|
$this->load_asset_manifest();
|
|
|
|
// Add success notice
|
|
add_action('admin_notices', function() {
|
|
echo '<div class="notice notice-success is-dismissible">';
|
|
echo '<p>' . __('Cache cleared successfully!', 'tigerstyle-life9') . '</p>';
|
|
echo '</div>';
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Rebuild Astro assets
|
|
*/
|
|
private function rebuild_astro_assets() {
|
|
// This could trigger a rebuild process
|
|
// For now, just clear the manifest to force reload
|
|
$this->asset_manifest = [];
|
|
|
|
add_action('admin_notices', function() {
|
|
echo '<div class="notice notice-info">';
|
|
echo '<p>' . __('Asset rebuild triggered. Please run npm run build to update the interface.', 'tigerstyle-life9') . '</p>';
|
|
echo '</div>';
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get plugin capabilities for current user
|
|
*
|
|
* @return array Capabilities array
|
|
*/
|
|
public function get_user_capabilities() {
|
|
return [
|
|
'backup' => current_user_can('manage_options'),
|
|
'restore' => current_user_can('manage_options'),
|
|
'settings' => current_user_can('manage_options'),
|
|
'view_backups' => current_user_can('manage_options'),
|
|
'delete_backups' => current_user_can('manage_options')
|
|
];
|
|
}
|
|
}
|