Changeset 3418364
- Timestamp:
- 12/12/2025 02:40:03 PM (4 months ago)
- Location:
- instarank/trunk
- Files:
-
- 3 edited
-
api/endpoints.php (modified) (3 diffs)
-
instarank.php (modified) (2 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
instarank/trunk/api/endpoints.php
r3416669 r3418364 411 411 'methods' => 'POST', 412 412 'callback' => [$this, 'update_image_alt_text'], 413 'permission_callback' => [$this, 'verify_api_key'] 414 ]); 415 416 // Find media attachment by URL 417 register_rest_route('instarank/v1', '/media/find-by-url', [ 418 'methods' => 'POST', 419 'callback' => [$this, 'find_attachment_by_url'], 420 'permission_callback' => [$this, 'verify_api_key'] 421 ]); 422 423 // Update alt text by image URL 424 register_rest_route('instarank/v1', '/media/update-alt-by-url', [ 425 'methods' => 'POST', 426 'callback' => [$this, 'update_alt_text_by_url'], 413 427 'permission_callback' => [$this, 'verify_api_key'] 414 428 ]); … … 4184 4198 update_post_meta($attachment_id, '_wp_attachment_image_alt', sanitize_text_field($alt_text)); 4185 4199 4186 // Send webhook notification4187 $webhook = new InstaRank_Webhook_Sender();4188 $webhook->send_event('image_alt_updated', [4189 'attachment_id' => $attachment_id,4190 'alt_text' => $alt_text4191 ]);4192 4193 4200 return [ 4194 4201 'success' => true, … … 4196 4203 'alt_text' => $alt_text 4197 4204 ]; 4205 } 4206 4207 /** 4208 * Find attachment by URL 4209 * 4210 * POST /wp-json/instarank/v1/media/find-by-url 4211 * Body: { "url": "https://example.com/wp-content/uploads/2023/01/image.jpg" } 4212 */ 4213 public function find_attachment_by_url($request) { 4214 $url = $request->get_param('url'); 4215 4216 if (empty($url)) { 4217 return new WP_Error('invalid_url', 'URL is required', ['status' => 400]); 4218 } 4219 4220 // Try to find attachment by URL 4221 $attachment_id = attachment_url_to_postid($url); 4222 4223 if ($attachment_id) { 4224 return [ 4225 'success' => true, 4226 'attachment_id' => $attachment_id, 4227 'url' => $url 4228 ]; 4229 } 4230 4231 global $wpdb; 4232 $filename = basename(wp_parse_url($url, PHP_URL_PATH)); 4233 4234 // Try alternative: search by exact filename in guid 4235 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 4236 $attachment_id = $wpdb->get_var($wpdb->prepare( 4237 "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND guid LIKE %s LIMIT 1", 4238 '%' . $wpdb->esc_like($filename) 4239 )); 4240 4241 if ($attachment_id) { 4242 return [ 4243 'success' => true, 4244 'attachment_id' => intval($attachment_id), 4245 'url' => $url, 4246 'matched_by' => 'filename' 4247 ]; 4248 } 4249 4250 // Try to strip size suffix from filename (e.g., image-150x150.jpg -> image.jpg) 4251 $filename_base = preg_replace('/-\d+x\d+(\.[a-zA-Z]+)$/', '$1', $filename); 4252 if ($filename_base !== $filename) { 4253 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 4254 $attachment_id = $wpdb->get_var($wpdb->prepare( 4255 "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND guid LIKE %s LIMIT 1", 4256 '%' . $wpdb->esc_like($filename_base) 4257 )); 4258 4259 if ($attachment_id) { 4260 return [ 4261 'success' => true, 4262 'attachment_id' => intval($attachment_id), 4263 'url' => $url, 4264 'matched_by' => 'filename_base' 4265 ]; 4266 } 4267 } 4268 4269 // Try searching by post_title (filename without extension) 4270 $title_search = pathinfo($filename_base, PATHINFO_FILENAME); 4271 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 4272 $attachment_id = $wpdb->get_var($wpdb->prepare( 4273 "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_title = %s LIMIT 1", 4274 $title_search 4275 )); 4276 4277 if ($attachment_id) { 4278 return [ 4279 'success' => true, 4280 'attachment_id' => intval($attachment_id), 4281 'url' => $url, 4282 'matched_by' => 'post_title' 4283 ]; 4284 } 4285 4286 // Try searching in _wp_attached_file meta 4287 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 4288 $attachment_id = $wpdb->get_var($wpdb->prepare( 4289 "SELECT post_id FROM {$wpdb->postmeta} 4290 WHERE meta_key = '_wp_attached_file' AND meta_value LIKE %s LIMIT 1", 4291 '%' . $wpdb->esc_like($filename_base) 4292 )); 4293 4294 if ($attachment_id) { 4295 return [ 4296 'success' => true, 4297 'attachment_id' => intval($attachment_id), 4298 'url' => $url, 4299 'matched_by' => 'attached_file_meta' 4300 ]; 4301 } 4302 4303 return new WP_Error('not_found', 'Attachment not found for URL', ['status' => 404]); 4304 } 4305 4306 /** 4307 * Update alt text by image URL 4308 * 4309 * POST /wp-json/instarank/v1/media/update-alt-by-url 4310 * Body: { "url": "https://example.com/wp-content/uploads/image.jpg", "alt_text": "New alt text" } 4311 */ 4312 public function update_alt_text_by_url($request) { 4313 $url = $request->get_param('url'); 4314 $alt_text = $request->get_param('alt_text'); 4315 4316 if (empty($url)) { 4317 return new WP_Error('invalid_url', 'URL is required', ['status' => 400]); 4318 } 4319 4320 // Find attachment ID by URL using comprehensive search 4321 $attachment_id = $this->find_attachment_id_by_url($url); 4322 4323 if (!$attachment_id) { 4324 return new WP_Error('not_found', 'Attachment not found for URL', ['status' => 404]); 4325 } 4326 4327 // Verify it's an image 4328 if (!wp_attachment_is_image($attachment_id)) { 4329 return new WP_Error('invalid_attachment', 'URL does not point to an image attachment', ['status' => 400]); 4330 } 4331 4332 // Update alt text 4333 update_post_meta($attachment_id, '_wp_attachment_image_alt', sanitize_text_field($alt_text)); 4334 4335 return [ 4336 'success' => true, 4337 'attachment_id' => intval($attachment_id), 4338 'url' => $url, 4339 'alt_text' => $alt_text 4340 ]; 4341 } 4342 4343 /** 4344 * Helper function to find attachment ID by URL with multiple fallback strategies 4345 * 4346 * @param string $url The image URL 4347 * @return int|false Attachment ID or false if not found 4348 */ 4349 private function find_attachment_id_by_url($url) { 4350 // Try standard WordPress function first 4351 $attachment_id = attachment_url_to_postid($url); 4352 if ($attachment_id) { 4353 return $attachment_id; 4354 } 4355 4356 global $wpdb; 4357 $filename = basename(wp_parse_url($url, PHP_URL_PATH)); 4358 4359 // Try exact filename in guid 4360 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 4361 $attachment_id = $wpdb->get_var($wpdb->prepare( 4362 "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND guid LIKE %s LIMIT 1", 4363 '%' . $wpdb->esc_like($filename) 4364 )); 4365 if ($attachment_id) { 4366 return intval($attachment_id); 4367 } 4368 4369 // Try to strip size suffix (e.g., image-150x150.jpg -> image.jpg) 4370 $filename_base = preg_replace('/-\d+x\d+(\.[a-zA-Z]+)$/', '$1', $filename); 4371 if ($filename_base !== $filename) { 4372 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 4373 $attachment_id = $wpdb->get_var($wpdb->prepare( 4374 "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND guid LIKE %s LIMIT 1", 4375 '%' . $wpdb->esc_like($filename_base) 4376 )); 4377 if ($attachment_id) { 4378 return intval($attachment_id); 4379 } 4380 } 4381 4382 // Try searching by post_title 4383 $title_search = pathinfo($filename_base, PATHINFO_FILENAME); 4384 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 4385 $attachment_id = $wpdb->get_var($wpdb->prepare( 4386 "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_title = %s LIMIT 1", 4387 $title_search 4388 )); 4389 if ($attachment_id) { 4390 return intval($attachment_id); 4391 } 4392 4393 // Try searching in _wp_attached_file meta 4394 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 4395 $attachment_id = $wpdb->get_var($wpdb->prepare( 4396 "SELECT post_id FROM {$wpdb->postmeta} 4397 WHERE meta_key = '_wp_attached_file' AND meta_value LIKE %s LIMIT 1", 4398 '%' . $wpdb->esc_like($filename_base) 4399 )); 4400 if ($attachment_id) { 4401 return intval($attachment_id); 4402 } 4403 4404 return false; 4198 4405 } 4199 4406 -
instarank/trunk/instarank.php
r3416669 r3418364 4 4 * Plugin URI: https://instarank.com/wordpress-plugin 5 5 * Description: Connect your WordPress site to InstaRank for AI-powered SEO optimization, schema markup generation, and programmatic SEO. Create and sync custom post types, automatically apply SEO improvements, and generate structured data with InstaRank's AI engine. 6 * Version: 2.0. 16 * Version: 2.0.2 7 7 * Author: InstaRank 8 8 * Author URI: https://instarank.com … … 18 18 19 19 // Define plugin constants 20 define('INSTARANK_VERSION', '2.0. 1');20 define('INSTARANK_VERSION', '2.0.2'); 21 21 define('INSTARANK_PLUGIN_DIR', plugin_dir_path(__FILE__)); 22 22 define('INSTARANK_PLUGIN_URL', plugin_dir_url(__FILE__)); -
instarank/trunk/readme.txt
r3416669 r3418364 4 4 Requires at least: 5.6 5 5 Tested up to: 6.9 6 Stable tag: 2.0. 16 Stable tag: 2.0.2 7 7 Requires PHP: 7.4 8 8 License: GPLv2 or later … … 169 169 170 170 == Changelog == 171 172 = 2.0.2 = 173 * Feature: Enhanced image optimization with priority ordering and push to WordPress 174 * Feature: Dark mode theme support in SaaS platform 175 * Fix: Dynamic origin for OAuth callbacks to prevent localhost redirect issues 176 * Enhancement: Improved image handling and TypeScript definitions for better consistency 171 177 172 178 = 2.0.1 =
Note: See TracChangeset
for help on using the changeset viewer.