535 lines
18 KiB
PHP
535 lines
18 KiB
PHP
<?php
|
|
/**
|
|
* Admin Class
|
|
*
|
|
* Handles all admin functionality including settings pages and AJAX handlers.
|
|
*
|
|
* @package Instagram_Gallery_Sync_Pro
|
|
*/
|
|
|
|
// Prevent direct access
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Class IGSP_Admin
|
|
*/
|
|
class IGSP_Admin
|
|
{
|
|
|
|
/**
|
|
* Settings page slug
|
|
*
|
|
* @var string
|
|
*/
|
|
const PAGE_SLUG = 'instagram-gallery-sync-pro';
|
|
|
|
/**
|
|
* Initialize admin
|
|
*
|
|
* @return void
|
|
*/
|
|
public function init()
|
|
{
|
|
// Add admin menu
|
|
add_action('admin_menu', array($this, 'add_admin_menu'));
|
|
|
|
// Register settings
|
|
add_action('admin_init', array($this, 'register_settings'));
|
|
|
|
// Enqueue admin assets
|
|
add_action('admin_enqueue_scripts', array($this, 'enqueue_assets'));
|
|
|
|
// AJAX handlers
|
|
add_action('wp_ajax_igsp_manual_sync', array($this, 'ajax_manual_sync'));
|
|
add_action('wp_ajax_igsp_clear_cache', array($this, 'ajax_clear_cache'));
|
|
add_action('wp_ajax_igsp_reset_data', array($this, 'ajax_reset_data'));
|
|
add_action('wp_ajax_igsp_get_sync_status', array($this, 'ajax_get_sync_status'));
|
|
add_action('wp_ajax_igsp_clear_logs', array($this, 'ajax_clear_logs'));
|
|
add_action('wp_ajax_igsp_delete_post', array($this, 'ajax_delete_post'));
|
|
add_action('wp_ajax_igsp_toggle_post', array($this, 'ajax_toggle_post'));
|
|
add_action('wp_ajax_igsp_add_manual_post', array($this, 'ajax_add_manual_post'));
|
|
|
|
// Add settings link to plugins page
|
|
add_filter('plugin_action_links_' . IGSP_PLUGIN_BASENAME, array($this, 'add_settings_link'));
|
|
}
|
|
|
|
/**
|
|
* Add admin menu
|
|
*
|
|
* @return void
|
|
*/
|
|
public function add_admin_menu()
|
|
{
|
|
add_menu_page(
|
|
__('Instagram Gallery', 'instagram-gallery-sync-pro'),
|
|
__('Instagram Gallery', 'instagram-gallery-sync-pro'),
|
|
'manage_options',
|
|
self::PAGE_SLUG,
|
|
array($this, 'render_settings_page'),
|
|
'dashicons-instagram',
|
|
30
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Register settings
|
|
*
|
|
* @return void
|
|
*/
|
|
public function register_settings()
|
|
{
|
|
// Instagram settings
|
|
register_setting('igsp_instagram_settings', 'igsp_username', 'sanitize_text_field');
|
|
register_setting('igsp_instagram_settings', 'igsp_max_images', 'absint');
|
|
register_setting('igsp_instagram_settings', 'igsp_save_locally', 'sanitize_text_field');
|
|
register_setting('igsp_instagram_settings', 'igsp_image_quality', 'sanitize_text_field');
|
|
register_setting('igsp_instagram_settings', 'igsp_sync_interval', 'sanitize_text_field');
|
|
|
|
// Layout settings
|
|
register_setting('igsp_layout_settings', 'igsp_layout_type', 'sanitize_text_field');
|
|
register_setting('igsp_layout_settings', 'igsp_layout_type_tablet', 'sanitize_text_field');
|
|
register_setting('igsp_layout_settings', 'igsp_layout_type_mobile', 'sanitize_text_field');
|
|
register_setting('igsp_layout_settings', 'igsp_columns_desktop', 'absint');
|
|
register_setting('igsp_layout_settings', 'igsp_columns_tablet', 'absint');
|
|
register_setting('igsp_layout_settings', 'igsp_columns_mobile', 'absint');
|
|
register_setting('igsp_layout_settings', 'igsp_spacing', 'absint');
|
|
register_setting('igsp_layout_settings', 'igsp_padding', 'absint');
|
|
register_setting('igsp_layout_settings', 'igsp_aspect_ratio', 'sanitize_text_field');
|
|
register_setting('igsp_layout_settings', 'igsp_object_fit', 'sanitize_text_field');
|
|
register_setting('igsp_layout_settings', 'igsp_border_radius', 'absint');
|
|
register_setting('igsp_layout_settings', 'igsp_hover_effect', 'sanitize_text_field');
|
|
|
|
// Slider settings
|
|
register_setting('igsp_layout_settings', 'igsp_slider_autoplay', 'sanitize_text_field');
|
|
register_setting('igsp_layout_settings', 'igsp_slider_delay', 'absint');
|
|
register_setting('igsp_layout_settings', 'igsp_slider_pause_hover', 'sanitize_text_field');
|
|
|
|
// Display settings
|
|
register_setting('igsp_display_settings', 'igsp_display_limit', 'absint');
|
|
register_setting('igsp_display_settings', 'igsp_order', 'sanitize_text_field');
|
|
register_setting('igsp_display_settings', 'igsp_show_caption', 'sanitize_text_field');
|
|
register_setting('igsp_display_settings', 'igsp_caption_position', 'sanitize_text_field');
|
|
register_setting('igsp_display_settings', 'igsp_show_instagram_btn', 'sanitize_text_field');
|
|
register_setting('igsp_display_settings', 'igsp_instagram_btn_text', 'sanitize_text_field');
|
|
register_setting('igsp_display_settings', 'igsp_link_behavior', 'sanitize_text_field');
|
|
register_setting('igsp_display_settings', 'igsp_lightbox', 'sanitize_text_field');
|
|
register_setting('igsp_display_settings', 'igsp_lazy_loading', 'sanitize_text_field');
|
|
register_setting('igsp_display_settings', 'igsp_loader_type', 'sanitize_text_field');
|
|
|
|
// Styling settings
|
|
register_setting('igsp_styling_settings', 'igsp_primary_color', 'sanitize_hex_color');
|
|
register_setting('igsp_styling_settings', 'igsp_hover_color', 'sanitize_hex_color');
|
|
register_setting('igsp_styling_settings', 'igsp_text_color', 'sanitize_hex_color');
|
|
register_setting('igsp_styling_settings', 'igsp_caption_font_size', 'absint');
|
|
register_setting('igsp_styling_settings', 'igsp_custom_css', array($this, 'sanitize_css'));
|
|
register_setting('igsp_styling_settings', 'igsp_css_prefix', 'sanitize_text_field');
|
|
|
|
// Advanced settings
|
|
register_setting('igsp_advanced_settings', 'igsp_debug_mode', 'sanitize_text_field');
|
|
register_setting('igsp_advanced_settings', 'igsp_cache_duration', 'absint');
|
|
register_setting('igsp_advanced_settings', 'igsp_request_timeout', 'absint');
|
|
register_setting('igsp_advanced_settings', 'igsp_user_agent', 'sanitize_text_field');
|
|
register_setting('igsp_advanced_settings', 'igsp_proxy_host', 'sanitize_text_field');
|
|
register_setting('igsp_advanced_settings', 'igsp_proxy_port', 'absint');
|
|
register_setting('igsp_advanced_settings', 'igsp_auto_delete_days', 'absint');
|
|
}
|
|
|
|
/**
|
|
* Sanitize CSS input
|
|
*
|
|
* @param string $css CSS string
|
|
* @return string
|
|
*/
|
|
public function sanitize_css($css)
|
|
{
|
|
// Remove any script tags
|
|
$css = preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', '', $css);
|
|
|
|
// Remove javascript: URLs
|
|
$css = preg_replace('/javascript\s*:/i', '', $css);
|
|
|
|
// Remove expression()
|
|
$css = preg_replace('/expression\s*\(/i', '', $css);
|
|
|
|
// Remove behavior: (IE specific)
|
|
$css = preg_replace('/behavior\s*:/i', '', $css);
|
|
|
|
return wp_strip_all_tags($css);
|
|
}
|
|
|
|
/**
|
|
* Enqueue admin assets
|
|
*
|
|
* @param string $hook Current page hook
|
|
* @return void
|
|
*/
|
|
public function enqueue_assets($hook)
|
|
{
|
|
if (strpos($hook, self::PAGE_SLUG) === false) {
|
|
return;
|
|
}
|
|
|
|
// Admin CSS
|
|
wp_enqueue_style(
|
|
'igsp-admin-style',
|
|
IGSP_PLUGIN_URL . 'admin/css/admin-style.css',
|
|
array(),
|
|
IGSP_VERSION . '.' . time()
|
|
);
|
|
|
|
// WordPress components
|
|
wp_enqueue_style('wp-color-picker');
|
|
|
|
// WordPress Media Library
|
|
wp_enqueue_media();
|
|
|
|
// Admin JS
|
|
wp_enqueue_script(
|
|
'igsp-admin-script',
|
|
IGSP_PLUGIN_URL . 'admin/js/admin-script.js',
|
|
array('jquery', 'wp-color-picker', 'media-upload'),
|
|
IGSP_VERSION . '.' . time(),
|
|
true
|
|
);
|
|
|
|
// AJAX Sync JS
|
|
wp_enqueue_script(
|
|
'igsp-ajax-sync',
|
|
IGSP_PLUGIN_URL . 'admin/js/ajax-sync.js',
|
|
array('jquery'),
|
|
IGSP_VERSION . '.' . time(),
|
|
true
|
|
);
|
|
|
|
// Localize script
|
|
wp_localize_script('igsp-admin-script', 'igspAdmin', array(
|
|
'ajaxUrl' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('igsp_admin_nonce'),
|
|
'strings' => array(
|
|
'syncing' => __('Syncing...', 'instagram-gallery-sync-pro'),
|
|
'syncComplete' => __('Sync complete!', 'instagram-gallery-sync-pro'),
|
|
'syncError' => __('Sync failed. Check logs for details.', 'instagram-gallery-sync-pro'),
|
|
'confirmReset' => __('Are you sure? This will delete ALL Instagram data including images. This action cannot be undone.', 'instagram-gallery-sync-pro'),
|
|
'confirmClearLogs' => __('Are you sure you want to clear all logs?', 'instagram-gallery-sync-pro'),
|
|
'confirmDeletePost' => __('Are you sure you want to delete this post?', 'instagram-gallery-sync-pro'),
|
|
'processing' => __('Processing...', 'instagram-gallery-sync-pro'),
|
|
'done' => __('Done!', 'instagram-gallery-sync-pro'),
|
|
'postAdded' => __('Post added successfully!', 'instagram-gallery-sync-pro'),
|
|
'postDeleted' => __('Post deleted.', 'instagram-gallery-sync-pro'),
|
|
'selectImage' => __('Select Image', 'instagram-gallery-sync-pro'),
|
|
'useImage' => __('Use this image', 'instagram-gallery-sync-pro'),
|
|
),
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Render settings page
|
|
*
|
|
* @return void
|
|
*/
|
|
public function render_settings_page()
|
|
{
|
|
// Check permissions
|
|
if (!current_user_can('manage_options')) {
|
|
wp_die(__('You do not have sufficient permissions to access this page.', 'instagram-gallery-sync-pro'));
|
|
}
|
|
|
|
include IGSP_PLUGIN_DIR . 'admin/views/settings-page.php';
|
|
}
|
|
|
|
/**
|
|
* Add settings link to plugins page
|
|
*
|
|
* @param array $links Existing links
|
|
* @return array
|
|
*/
|
|
public function add_settings_link($links)
|
|
{
|
|
$settings_link = sprintf(
|
|
'<a href="%s">%s</a>',
|
|
admin_url('admin.php?page=' . self::PAGE_SLUG),
|
|
__('Settings', 'instagram-gallery-sync-pro')
|
|
);
|
|
|
|
array_unshift($links, $settings_link);
|
|
|
|
return $links;
|
|
}
|
|
|
|
/**
|
|
* AJAX: Manual sync
|
|
*
|
|
* @return void
|
|
*/
|
|
public function ajax_manual_sync()
|
|
{
|
|
check_ajax_referer('igsp_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => __('Permission denied.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
$cron = new IGSP_Cron();
|
|
$result = $cron->manual_sync();
|
|
|
|
if ($result['success']) {
|
|
wp_send_json_success($result);
|
|
} else {
|
|
wp_send_json_error($result);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* AJAX: Clear cache
|
|
*
|
|
* @return void
|
|
*/
|
|
public function ajax_clear_cache()
|
|
{
|
|
check_ajax_referer('igsp_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => __('Permission denied.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
igsp()->clear_transients();
|
|
|
|
wp_send_json_success(array('message' => __('Cache cleared successfully.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
/**
|
|
* AJAX: Reset all data
|
|
*
|
|
* @return void
|
|
*/
|
|
public function ajax_reset_data()
|
|
{
|
|
check_ajax_referer('igsp_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => __('Permission denied.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
// Delete all posts from database
|
|
$database = new IGSP_Database();
|
|
$database->delete_all_posts();
|
|
|
|
// Clear all images
|
|
$image_handler = new IGSP_Image_Handler();
|
|
$image_handler->clear_all_images();
|
|
|
|
// Clear logs
|
|
$logger = new IGSP_Logger();
|
|
$logger->clear_logs();
|
|
|
|
// Clear transients
|
|
igsp()->clear_transients();
|
|
|
|
// Reset last sync
|
|
update_option('igsp_last_sync', '');
|
|
|
|
wp_send_json_success(array('message' => __('All data has been reset.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
/**
|
|
* AJAX: Get sync status
|
|
*
|
|
* @return void
|
|
*/
|
|
public function ajax_get_sync_status()
|
|
{
|
|
check_ajax_referer('igsp_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => __('Permission denied.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
$cron = new IGSP_Cron();
|
|
$status = $cron->get_sync_status();
|
|
|
|
wp_send_json_success($status);
|
|
}
|
|
|
|
/**
|
|
* AJAX: Clear logs
|
|
*
|
|
* @return void
|
|
*/
|
|
public function ajax_clear_logs()
|
|
{
|
|
check_ajax_referer('igsp_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => __('Permission denied.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
$logger = new IGSP_Logger();
|
|
$logger->clear_logs();
|
|
|
|
wp_send_json_success(array('message' => __('Logs cleared successfully.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
/**
|
|
* Get current tab
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_current_tab()
|
|
{
|
|
return isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : 'instagram';
|
|
}
|
|
|
|
/**
|
|
* Get tabs configuration
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_tabs()
|
|
{
|
|
return array(
|
|
'instagram' => array(
|
|
'title' => __('Instagram', 'instagram-gallery-sync-pro'),
|
|
'icon' => 'dashicons-instagram',
|
|
),
|
|
'posts' => array(
|
|
'title' => __('Posts', 'instagram-gallery-sync-pro'),
|
|
'icon' => 'dashicons-images-alt2',
|
|
),
|
|
'layout' => array(
|
|
'title' => __('Layout', 'instagram-gallery-sync-pro'),
|
|
'icon' => 'dashicons-grid-view',
|
|
),
|
|
'display' => array(
|
|
'title' => __('Display', 'instagram-gallery-sync-pro'),
|
|
'icon' => 'dashicons-visibility',
|
|
),
|
|
'styling' => array(
|
|
'title' => __('Styling', 'instagram-gallery-sync-pro'),
|
|
'icon' => 'dashicons-art',
|
|
),
|
|
'advanced' => array(
|
|
'title' => __('Advanced', 'instagram-gallery-sync-pro'),
|
|
'icon' => 'dashicons-admin-generic',
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* AJAX: Delete single post
|
|
*
|
|
* @return void
|
|
*/
|
|
public function ajax_delete_post()
|
|
{
|
|
check_ajax_referer('igsp_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => __('Permission denied.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
$post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0;
|
|
|
|
if (!$post_id) {
|
|
wp_send_json_error(array('message' => __('Invalid post ID.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
$database = new IGSP_Database();
|
|
$result = $database->delete_post($post_id);
|
|
|
|
if ($result) {
|
|
// Clear gallery cache
|
|
igsp()->clear_transients();
|
|
wp_send_json_success(array('message' => __('Post deleted successfully.', 'instagram-gallery-sync-pro')));
|
|
} else {
|
|
wp_send_json_error(array('message' => __('Failed to delete post.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* AJAX: Toggle post active/inactive
|
|
*
|
|
* @return void
|
|
*/
|
|
public function ajax_toggle_post()
|
|
{
|
|
check_ajax_referer('igsp_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => __('Permission denied.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
$post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0;
|
|
|
|
if (!$post_id) {
|
|
wp_send_json_error(array('message' => __('Invalid post ID.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
$database = new IGSP_Database();
|
|
$result = $database->toggle_post_active($post_id);
|
|
|
|
if ($result) {
|
|
$post = $database->get_post($post_id);
|
|
igsp()->clear_transients();
|
|
wp_send_json_success(array(
|
|
'message' => __('Post status updated.', 'instagram-gallery-sync-pro'),
|
|
'is_active' => (bool) $post->is_active,
|
|
));
|
|
} else {
|
|
wp_send_json_error(array('message' => __('Failed to update post status.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* AJAX: Add manual post
|
|
*
|
|
* @return void
|
|
*/
|
|
public function ajax_add_manual_post()
|
|
{
|
|
check_ajax_referer('igsp_admin_nonce', 'nonce');
|
|
|
|
if (!current_user_can('manage_options')) {
|
|
wp_send_json_error(array('message' => __('Permission denied.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
$attachment_id = isset($_POST['attachment_id']) ? absint($_POST['attachment_id']) : 0;
|
|
$post_url = isset($_POST['post_url']) ? esc_url_raw($_POST['post_url']) : '';
|
|
$caption = isset($_POST['caption']) ? wp_kses_post($_POST['caption']) : '';
|
|
$posted_at = isset($_POST['posted_at']) ? sanitize_text_field($_POST['posted_at']) : '';
|
|
|
|
if (!$attachment_id) {
|
|
wp_send_json_error(array('message' => __('Please select an image.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
|
|
// Copy from Media Library to plugin upload directory
|
|
$image_handler = new IGSP_Image_Handler();
|
|
$image_result = $image_handler->save_from_media_library($attachment_id);
|
|
|
|
if (is_wp_error($image_result)) {
|
|
wp_send_json_error(array('message' => $image_result->get_error_message()));
|
|
}
|
|
|
|
// Insert into database
|
|
$database = new IGSP_Database();
|
|
$result = $database->insert_manual_post(array(
|
|
'image_local_path' => $image_result['local_path'],
|
|
'image_thumbnail_path' => $image_result['thumbnail_path'],
|
|
'post_url' => $post_url,
|
|
'caption' => $caption,
|
|
'posted_at' => $posted_at,
|
|
'file_size' => $image_result['file_size'],
|
|
'image_width' => $image_result['width'],
|
|
'image_height' => $image_result['height'],
|
|
));
|
|
|
|
if ($result) {
|
|
igsp()->clear_transients();
|
|
wp_send_json_success(array('message' => __('Post added successfully!', 'instagram-gallery-sync-pro')));
|
|
} else {
|
|
wp_send_json_error(array('message' => __('Failed to add post.', 'instagram-gallery-sync-pro')));
|
|
}
|
|
}
|
|
}
|