Changeset 3371993
- Timestamp:
- 10/02/2025 08:34:34 PM (6 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
extension-access-manager/trunk/extension-access-manager.php
r3371984 r3371993 3 3 Plugin Name: extension access manager 4 4 Description: A custom REST API interface for secure external image uploads and article posting. 5 Version: 1. 15 Version: 1.0 6 6 Author: Haider Mirza 7 7 License: GPLv2 or later … … 12 12 13 13 defined('ABSPATH') || exit; 14 15 @ini_set('max_execution_time', 300); // 5 minutes 16 @ini_set('max_input_time', 300); 17 @ini_set('memory_limit', '5512M'); 18 14 19 15 20 add_action('admin_menu', function () { … … 101 106 'permission_callback' => 'exteacma_check_auth', 102 107 ]); 108 // Add this inside your rest_api_init action 109 register_rest_route('exteacma/v1', '/import-categories', [ 110 'methods' => 'POST', 111 'callback' => 'exteacma_import_categories_handler', 112 'permission_callback' => 'exteacma_check_auth' 113 ]); 103 114 }); 104 115 … … 135 146 136 147 function exteacma_image_upload_handler($request) { 137 $images = $request->get_param('images'); // ← array of URLs or base64 data 138 $results = []; 139 140 if (!is_array($images) || empty($images)) { 141 return new WP_Error('invalid_images', 'Images parameter must be a non-empty array.', ['status' => 400]); 142 } 148 $img_url = $request->get_param('img'); 149 $base64 = $request->get_param('base64'); 150 $filename = sanitize_file_name($request->get_param('filename')); 143 151 144 152 require_once ABSPATH . 'wp-admin/includes/file.php'; … … 146 154 require_once ABSPATH . 'wp-admin/includes/image.php'; 147 155 148 foreach ($images as $index => $image) { 149 $filename = sanitize_file_name($image['filename'] ?? 'image_' . time() . '_' . $index . '.jpg'); 150 $is_base64 = !empty($image['base64']); 151 $is_url = !empty($image['url']); 152 153 if ($is_base64) { 154 $decoded = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $image['base64'])); 155 if (!$decoded) { 156 $results[] = ['index' => $index, 'success' => false, 'error' => 'Base64 decode failed']; 157 continue; 158 } 159 160 $tmp = wp_tempnam($filename); 161 if (!$tmp) { 162 $results[] = ['index' => $index, 'success' => false, 'error' => 'Temp file creation failed']; 163 continue; 164 } 165 166 global $wp_filesystem; 167 if (empty($wp_filesystem)) { 168 require_once ABSPATH . '/wp-admin/includes/file.php'; 169 WP_Filesystem(); 170 } 171 172 $written = $wp_filesystem->put_contents($tmp, $decoded, FS_CHMOD_FILE); 173 if (!$written) { 174 wp_delete_file($tmp); 175 $results[] = ['index' => $index, 'success' => false, 'error' => 'Write to temp failed']; 176 continue; 177 } 178 179 $file_array = ['name' => $filename, 'tmp_name' => $tmp]; 180 $id = media_handle_sideload($file_array, 0); 181 if (is_wp_error($id)) { 182 wp_delete_file($tmp); 183 $results[] = ['index' => $index, 'success' => false, 'error' => $id->get_error_message()]; 184 continue; 185 } 186 187 $results[] = ['index' => $index, 'success' => true, 'url' => wp_get_attachment_url($id)]; 188 } 189 190 elseif ($is_url) { 191 $url = $image['url']; 192 $tmp = exteacma_download_image($url); 193 if (is_wp_error($tmp)) { 194 $results[] = ['index' => $index, 'success' => false, 'error' => $tmp->get_error_message()]; 195 continue; 196 } 197 198 $file_array = ['name' => $filename, 'tmp_name' => $tmp]; 199 $id = media_handle_sideload($file_array, 0); 200 if (is_wp_error($id)) { 201 wp_delete_file($tmp); 202 $results[] = ['index' => $index, 'success' => false, 'error' => $id->get_error_message()]; 203 continue; 204 } 205 206 $results[] = ['index' => $index, 'success' => true, 'url' => wp_get_attachment_url($id)]; 207 } 208 209 else { 210 $results[] = ['index' => $index, 'success' => false, 'error' => 'Invalid image format']; 211 } 212 } 213 214 return ['results' => $results]; 215 } 216 156 if ($img_url && filter_var($img_url, FILTER_VALIDATE_URL)) { 157 $headers = wp_remote_head($img_url); 158 if (is_wp_error($headers)) { 159 return new WP_Error('no_headers', 'Could not get headers.', ['status' => 400]); 160 } 161 162 $content_type = wp_remote_retrieve_header($headers, 'content-type'); 163 if (stripos($content_type, 'image/') !== 0) { 164 return new WP_Error('invalid_image', 'The URL does not point to an image.', ['status' => 400]); 165 } 166 167 $tmp = exteacma_download_image($img_url); 168 if (is_wp_error($tmp)) { 169 return $tmp; 170 } 171 172 $name = basename(wp_parse_url($img_url, PHP_URL_PATH)); 173 $file_array = ['name' => $name, 'tmp_name' => $tmp]; 174 175 $id = media_handle_sideload($file_array, 0); 176 if (is_wp_error($id)) { 177 wp_delete_file($tmp); 178 return new WP_Error('upload_error', $id->get_error_message(), ['status' => 500]); 179 } 180 181 return ['success' => true, 'url' => wp_get_attachment_url($id)]; 182 } 183 184 if ($base64 && $filename) { 185 $decoded = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64)); 186 if (!$decoded) { 187 return new WP_Error('decode_error', 'Base64 decode failed', ['status' => 400]); 188 } 189 190 $tmp = wp_tempnam($filename); 191 if (!$tmp) { 192 return new WP_Error('temp_file_error', 'Could not create temp file.', ['status' => 500]); 193 } 194 195 global $wp_filesystem; 196 if (empty($wp_filesystem)) { 197 require_once ABSPATH . '/wp-admin/includes/file.php'; 198 WP_Filesystem(); 199 } 200 201 $written = $wp_filesystem->put_contents($tmp, $decoded, FS_CHMOD_FILE); 202 if (!$written) { 203 wp_delete_file($tmp); 204 return new WP_Error('write_failed', 'Failed to write image to temp file.', ['status' => 500]); 205 } 206 207 $file_array = ['name' => $filename, 'tmp_name' => $tmp]; 208 $id = media_handle_sideload($file_array, 0); 209 if (is_wp_error($id)) { 210 wp_delete_file($tmp); 211 return new WP_Error('upload_error', $id->get_error_message(), ['status' => 500]); 212 } 213 214 return ['success' => true, 'url' => wp_get_attachment_url($id)]; 215 } 216 217 return new WP_Error('invalid_request', 'Invalid image data.', ['status' => 400]); 218 } 217 219 218 220 function exteacma_download_image($url) { 219 221 $filename = basename(wp_parse_url($url, PHP_URL_PATH)); 220 $response = wp_remote_get($url, ['timeout' => 20]);222 $response = wp_remote_get($url, ['timeout' => 140]); 221 223 222 224 if (is_wp_error($response)) { … … 248 250 return $tmp_file; 249 251 } 252 253 function exteacma_import_categories_handler($request) { 254 $params = $request->get_json_params(); 255 $categories = $params['categories'] ?? []; 256 257 if (empty($categories) || !is_array($categories)) { 258 return new WP_Error('no_categories', 'No categories provided', ['status' => 400]); 259 } 260 261 $created = []; 262 $skipped = []; 263 264 foreach ($categories as $cat) { 265 $cat = sanitize_text_field($cat); 266 if (empty($cat)) { 267 continue; 268 } 269 270 // Try to insert category 271 $term = wp_insert_term($cat, 'category'); 272 if (is_wp_error($term)) { 273 $skipped[] = $cat; 274 } else { 275 $created[] = $cat; 276 } 277 } 278 279 return [ 280 'success' => true, 281 'created' => $created, 282 'skipped' => $skipped 283 ]; 284 }
Note: See TracChangeset
for help on using the changeset viewer.