allowed_mime_types) || !in_array(strtolower($extension), $this->allowed_extensions)) { return false; } return true; } public static function get_instance() { if (is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; } public function __construct() { add_action('wp_ajax_aipstx_add_media_library', array($this, 'aipstx_add_media_library')); add_action('wp_ajax_aipstx_ensure_image_and_set_featured', array($this, 'aipstx_ensure_image_and_set_featured')); add_action('wp_ajax_aipstx_add_post_content', array($this, 'aipstx_add_post_content')); } private function download_image($image_url) { $response = wp_remote_get($image_url, array('timeout' => 60, 'sslverify' => false)); if (is_wp_error($response)) { return new \WP_Error('download_failed', 'Failed to download image: ' . $response->get_error_message()); } $image_data = wp_remote_retrieve_body($response); if (empty($image_data)) { return new \WP_Error('empty_image', 'Downloaded image data is empty.'); } return $image_data; } private function get_image_from_data_uri($image_url) { list($type, $data) = explode(';', $image_url); list(, $data) = explode(',', $data); $image_data = base64_decode($data); if (empty($image_data)) { return new \WP_Error('invalid_data_uri', 'Invalid data URI.'); } return $image_data; } private function sanitize_filename($filename) { $filename = iconv('UTF-8', 'ASCII//TRANSLIT', $filename); $filename = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $filename); $filename = strtolower(trim($filename, '-')); $filename = preg_replace("/[\/_|+ -]+/", '_', $filename); return $filename; } private function get_unique_filename($base_name, $extension, $upload_dir) { $counter = 0; $filename = $base_name . '.' . $extension; while (file_exists($upload_dir['path'] . '/' . $filename)) { $counter++; $filename = $base_name . '_' . $counter . '.' . $extension; } return $filename; } public function aipstx_add_media_library() { if (!check_ajax_referer('aipstx_nonce', 'nonce', false)) { wp_send_json_error(array('message' => 'Nonce verification failed.')); return; } // Check user capabilities if (!current_user_can('upload_files')) { wp_send_json_error(array('message' => 'You do not have permission to upload files.')); return; } $image_url = isset($_POST['image_url']) ? sanitize_text_field(wp_unslash($_POST['image_url'])) : ''; $image_name = isset($_POST['image_name']) ? sanitize_text_field(wp_unslash($_POST['image_name'])) : ''; $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0; if (empty($image_url)) { wp_send_json_error(array('message' => 'Invalid image URL.')); return; } if (empty($image_name)) { $image_name = $post_id ? get_the_title($post_id) : 'AI Generated Image'; } $is_data_uri = strpos($image_url, 'data:image') === 0; if ($is_data_uri) { // Data URI format validation if (!preg_match('/^data:image\/(jpeg|png|gif|webp);base64,/i', $image_url, $mime_matches)) { wp_send_json_error(array('message' => 'Invalid image format.')); return; } $image_data = $this->get_image_from_data_uri($image_url); $file_extension = strtolower($mime_matches[1]); $mime_type = 'image/' . $file_extension; } else { $image_data = $this->download_image($image_url); $file_extension = pathinfo(wp_parse_url($image_url, PHP_URL_PATH), PATHINFO_EXTENSION); $file_extension = $file_extension ?: 'jpg'; // Detect file type $finfo = new \finfo(FILEINFO_MIME_TYPE); $mime_type = $finfo->buffer($image_data); } // File type validation if (!$this->validate_image_type($mime_type, $file_extension)) { wp_send_json_error(array('message' => 'Unsupported file format. Only JPG, JPEG, PNG, GIF and WEBP formats are allowed.')); return; } $image_hash = md5($image_data); global $wpdb; $existing_attachment_id = $wpdb->get_var($wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_image_hash' AND meta_value = %s", $image_hash )); if ($existing_attachment_id) { wp_send_json_success(array('attachment_id' => $existing_attachment_id, 'message' => 'Image already exists in the media library.')); return; } $upload_dir = wp_upload_dir(); $filename_base = $this->sanitize_filename($image_name); $filename = $this->get_unique_filename($filename_base, $file_extension, $upload_dir); $file_path = $upload_dir['path'] . '/' . $filename; global $wp_filesystem; if (empty($wp_filesystem)) { require_once (ABSPATH . '/wp-admin/includes/file.php'); WP_Filesystem(); } if (!$wp_filesystem->put_contents($file_path, $image_data, FS_CHMOD_FILE)) { wp_send_json_error(array('message' => 'Error saving file to the server.')); return; } $file_type = wp_check_filetype($filename, null); $attachment = array( 'guid' => $upload_dir['url'] . '/' . $filename, 'post_mime_type' => $file_type['type'], 'post_title' => preg_replace('/\.[^.]+$/', '', $filename), 'post_content' => '', 'post_status' => 'inherit' ); $attach_id = wp_insert_attachment($attachment, $file_path, $post_id); require_once (ABSPATH . 'wp-admin/includes/image.php'); $attach_data = wp_generate_attachment_metadata($attach_id, $file_path); wp_update_attachment_metadata($attach_id, $attach_data); update_post_meta($attach_id, '_wp_attachment_image_alt', $image_name); update_post_meta($attach_id, '_wp_attachment_image_hash', $image_hash); wp_send_json_success(array('attachment_id' => $attach_id, 'message' => 'Image successfully added to media library.')); } public function aipstx_ensure_image_and_set_featured() { if (!check_ajax_referer('aipstx_nonce', 'nonce', false)) { wp_send_json_error(array('message' => 'Nonce verification failed.')); return; } $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0; $image_id = isset($_POST['image_id']) ? intval($_POST['image_id']) : 0; $image_url = isset($_POST['image_url']) ? esc_url_raw(wp_unslash($_POST['image_url'])) : ''; if (!$post_id) { wp_send_json_error(array('message' => 'Invalid post ID.')); return; } if (!$image_id && !$image_url) { wp_send_json_error(array('message' => 'No image ID or URL provided.')); return; } if (!$image_id) { // Add image to media library first $add_media_result = $this->aipstx_add_media_library(); $add_media_response = json_decode($add_media_result, true); if (isset($add_media_response['success']) && $add_media_response['success']) { $image_id = $add_media_response['data']['attachment_id']; } else { wp_send_json_error(array('message' => 'Failed to add image to media library.')); return; } } $result = set_post_thumbnail($post_id, $image_id); if ($result) { $featured_image_url = wp_get_attachment_url($image_id); wp_send_json_success(array('message' => 'Featured image set successfully.', 'featured_image_url' => $featured_image_url)); } else { wp_send_json_error(array('message' => 'Failed to set featured image.')); } } public function aipstx_add_post_content() { if (!check_ajax_referer('aipstx_nonce', 'nonce', false)) { wp_send_json_error(array('message' => 'Nonce verification failed.')); return; } $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0; $image_id = isset($_POST['media_id']) ? intval($_POST['media_id']) : 0; $image_url = isset($_POST['image_url']) ? esc_url_raw(wp_unslash($_POST['image_url'])) : ''; if (!$post_id) { wp_send_json_error(array('message' => 'Invalid post ID.')); return; } if (!$image_id && !$image_url) { wp_send_json_error(array('message' => 'No image ID or URL provided.')); return; } if (!$image_id) { // Add image to media library first $add_media_result = $this->aipstx_add_media_library(); $add_media_response = json_decode($add_media_result, true); if (isset($add_media_response['success']) && $add_media_response['success']) { $image_id = $add_media_response['data']['attachment_id']; } else { wp_send_json_error(array('message' => 'Failed to add image to media library.')); return; } } $post_title = get_the_title($post_id); $image_html = wp_get_attachment_image($image_id, 'full', false, array('alt' => $post_title)); $post_content = get_post_field('post_content', $post_id); $new_post_content = $post_content . $image_html; $update_result = wp_update_post(array( 'ID' => $post_id, 'post_content' => $new_post_content )); if ($update_result) { wp_send_json_success(array('message' => 'Image added to post content successfully.', 'image_html' => $image_html)); } else { wp_send_json_error(array('message' => 'Failed to add image to post content.')); } } } AIPSTX_btn::get_instance(); }