initial commit
This commit is contained in:
parent
e468202f95
commit
423b9a25fb
24 changed files with 6670 additions and 0 deletions
|
|
@ -0,0 +1,376 @@
|
|||
<?php
|
||||
/**
|
||||
* AJAX Handler class - Handles all AJAX requests.
|
||||
*
|
||||
* @package MapleIcons
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class MI_Ajax_Handler
|
||||
*
|
||||
* Handles all AJAX requests for the plugin.
|
||||
*/
|
||||
class MI_Ajax_Handler {
|
||||
|
||||
/**
|
||||
* Constructor - Register AJAX handlers.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Admin AJAX handlers.
|
||||
add_action( 'wp_ajax_mi_download_set', array( $this, 'handle_download_set' ) );
|
||||
add_action( 'wp_ajax_mi_delete_set', array( $this, 'handle_delete_set' ) );
|
||||
add_action( 'wp_ajax_mi_set_active', array( $this, 'handle_set_active' ) );
|
||||
add_action( 'wp_ajax_mi_get_progress', array( $this, 'handle_get_progress' ) );
|
||||
|
||||
// Block editor AJAX handlers.
|
||||
add_action( 'wp_ajax_mi_search_icons', array( $this, 'handle_search_icons' ) );
|
||||
add_action( 'wp_ajax_mi_get_icon_svg', array( $this, 'handle_get_icon_svg' ) );
|
||||
|
||||
// No nopriv handlers - all functionality requires login.
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle download set request.
|
||||
*/
|
||||
public function handle_download_set() {
|
||||
// 1. Nonce verification.
|
||||
if ( ! check_ajax_referer( 'mi_admin_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Capability check.
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Input validation.
|
||||
$slug = isset( $_POST['slug'] ) ? sanitize_key( $_POST['slug'] ) : '';
|
||||
|
||||
if ( empty( $slug ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Icon set slug is required.', 'maple-icons' ) )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Invalid icon set.', 'maple-icons' ) )
|
||||
);
|
||||
}
|
||||
|
||||
// Check if already downloaded.
|
||||
$registry = MI_Icon_Registry::get_instance();
|
||||
if ( $registry->is_downloaded( $slug ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'This icon set is already downloaded.', 'maple-icons' ) )
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Process download.
|
||||
// Increase time limit for large downloads.
|
||||
set_time_limit( 600 ); // 10 minutes.
|
||||
|
||||
$downloader = new MI_Downloader();
|
||||
$result = $downloader->download_set( $slug );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => $result->get_error_message() )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! $result['success'] ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'message' => sprintf(
|
||||
/* translators: %1$d: downloaded count, %2$d: failed count */
|
||||
__( 'Download completed with errors. %1$d downloaded, %2$d failed.', 'maple-icons' ),
|
||||
$result['downloaded'],
|
||||
$result['failed']
|
||||
),
|
||||
'errors' => array_slice( $result['errors'], 0, 10 ), // Limit errors shown.
|
||||
'downloaded' => $result['downloaded'],
|
||||
'failed' => $result['failed'],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Mark as downloaded.
|
||||
$registry->mark_downloaded( $slug, $result['downloaded'] );
|
||||
|
||||
// If no active set, make this one active.
|
||||
if ( ! $registry->get_active_set() ) {
|
||||
$registry->set_active( $slug );
|
||||
}
|
||||
|
||||
$registry->refresh();
|
||||
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'message' => sprintf(
|
||||
/* translators: %d: number of icons */
|
||||
__( 'Successfully downloaded %d icons.', 'maple-icons' ),
|
||||
$result['downloaded']
|
||||
),
|
||||
'icon_count' => $result['downloaded'],
|
||||
'is_active' => $registry->get_active_set() === $slug,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle delete set request.
|
||||
*/
|
||||
public function handle_delete_set() {
|
||||
// 1. Nonce verification.
|
||||
if ( ! check_ajax_referer( 'mi_admin_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Capability check.
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Input validation.
|
||||
$slug = isset( $_POST['slug'] ) ? sanitize_key( $_POST['slug'] ) : '';
|
||||
|
||||
if ( empty( $slug ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Icon set slug is required.', 'maple-icons' ) )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Invalid icon set.', 'maple-icons' ) )
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Delete the set.
|
||||
$registry = MI_Icon_Registry::get_instance();
|
||||
$result = $registry->delete_set( $slug );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => $result->get_error_message() )
|
||||
);
|
||||
}
|
||||
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'message' => __( 'Icon set deleted successfully.', 'maple-icons' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle set active request.
|
||||
*/
|
||||
public function handle_set_active() {
|
||||
// 1. Nonce verification.
|
||||
if ( ! check_ajax_referer( 'mi_admin_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Capability check.
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Input validation.
|
||||
$slug = isset( $_POST['slug'] ) ? sanitize_key( $_POST['slug'] ) : '';
|
||||
|
||||
// Empty slug is allowed (to deactivate).
|
||||
if ( ! empty( $slug ) && ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Invalid icon set.', 'maple-icons' ) )
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Set active.
|
||||
$registry = MI_Icon_Registry::get_instance();
|
||||
$result = $registry->set_active( $slug );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => $result->get_error_message() )
|
||||
);
|
||||
}
|
||||
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'message' => empty( $slug )
|
||||
? __( 'No icon set is now active.', 'maple-icons' )
|
||||
: __( 'Icon set activated.', 'maple-icons' ),
|
||||
'active_set' => $slug,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle get progress request.
|
||||
*/
|
||||
public function handle_get_progress() {
|
||||
// 1. Nonce verification.
|
||||
if ( ! check_ajax_referer( 'mi_admin_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Capability check.
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Input validation.
|
||||
$slug = isset( $_POST['slug'] ) ? sanitize_key( $_POST['slug'] ) : '';
|
||||
|
||||
if ( empty( $slug ) || ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Invalid icon set.', 'maple-icons' ) )
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Get progress.
|
||||
$downloader = new MI_Downloader();
|
||||
$progress = $downloader->get_progress( $slug );
|
||||
|
||||
if ( false === $progress ) {
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'downloading' => false,
|
||||
'completed' => 0,
|
||||
'total' => 0,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'downloading' => true,
|
||||
'completed' => $progress['completed'],
|
||||
'total' => $progress['total'],
|
||||
'percentage' => $progress['total'] > 0
|
||||
? round( ( $progress['completed'] / $progress['total'] ) * 100 )
|
||||
: 0,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle search icons request (for block editor).
|
||||
*/
|
||||
public function handle_search_icons() {
|
||||
// 1. Nonce verification.
|
||||
if ( ! check_ajax_referer( 'mi_block_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Capability check (edit_posts for block usage).
|
||||
if ( ! current_user_can( 'edit_posts' ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Input validation.
|
||||
$query = isset( $_POST['query'] ) ? sanitize_text_field( $_POST['query'] ) : '';
|
||||
$style = isset( $_POST['style'] ) ? sanitize_key( $_POST['style'] ) : '';
|
||||
$limit = isset( $_POST['limit'] ) ? absint( $_POST['limit'] ) : MI_SEARCH_LIMIT;
|
||||
$offset = isset( $_POST['offset'] ) ? absint( $_POST['offset'] ) : 0;
|
||||
|
||||
// Limit the limit.
|
||||
if ( $limit > 100 ) {
|
||||
$limit = 100;
|
||||
}
|
||||
|
||||
// 4. Search.
|
||||
$registry = MI_Icon_Registry::get_instance();
|
||||
$results = $registry->search_icons( $query, $style, $limit, $offset );
|
||||
|
||||
wp_send_json_success( $results );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle get icon SVG request (for block editor).
|
||||
*/
|
||||
public function handle_get_icon_svg() {
|
||||
// 1. Nonce verification.
|
||||
if ( ! check_ajax_referer( 'mi_block_nonce', 'nonce', false ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 2. Capability check.
|
||||
if ( ! current_user_can( 'edit_posts' ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Input validation.
|
||||
$slug = isset( $_POST['set'] ) ? sanitize_key( $_POST['set'] ) : '';
|
||||
$style = isset( $_POST['style'] ) ? sanitize_key( $_POST['style'] ) : '';
|
||||
$name = isset( $_POST['name'] ) ? sanitize_file_name( $_POST['name'] ) : '';
|
||||
|
||||
if ( empty( $slug ) || empty( $style ) || empty( $name ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => __( 'Missing required parameters.', 'maple-icons' ) )
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Get SVG.
|
||||
$registry = MI_Icon_Registry::get_instance();
|
||||
$svg = $registry->get_icon_svg( $slug, $style, $name );
|
||||
|
||||
if ( is_wp_error( $svg ) ) {
|
||||
wp_send_json_error(
|
||||
array( 'message' => $svg->get_error_message() )
|
||||
);
|
||||
}
|
||||
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'svg' => $svg,
|
||||
'set' => $slug,
|
||||
'style' => $style,
|
||||
'name' => $name,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue