@@ -383,15 +383,100 @@ private static function replace_custom_emoji( $text, $activity ) {
383
383
384
384
foreach ( $ activity ['tag ' ] as $ tag ) {
385
385
if ( isset ( $ tag ['type ' ] ) && 'Emoji ' === $ tag ['type ' ] && ! empty ( $ tag ['name ' ] ) && ! empty ( $ tag ['icon ' ]['url ' ] ) ) {
386
- $ text = str_replace (
387
- $ tag ['name ' ],
388
- sprintf (
389
- '<img src="%s" alt="%s" class="emoji" /> ' ,
390
- \esc_url ( $ tag ['icon ' ]['url ' ] ),
391
- \esc_attr ( $ tag ['name ' ] )
392
- ),
393
- $ text
386
+ $ emoji_url = $ tag ['icon ' ]['url ' ];
387
+ $ emoji_name = $ tag ['name ' ];
388
+
389
+ // Check for existing emoji by URL or placeholder.
390
+ $ existing_attachments = \get_posts (
391
+ array (
392
+ 'post_type ' => 'attachment ' ,
393
+ 'posts_per_page ' => -1 ,
394
+ 'fields ' => 'ids ' ,
395
+
396
+ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
397
+ 'meta_query ' => array (
398
+ 'relation ' => 'OR ' ,
399
+ array (
400
+ 'key ' => 'activitypub_emoji_source_url ' ,
401
+ 'value ' => $ emoji_url ,
402
+ ),
403
+ array (
404
+ 'key ' => 'activitypub_emoji_placeholder ' ,
405
+ 'value ' => $ emoji_name ,
406
+ ),
407
+ ),
408
+ )
394
409
);
410
+
411
+ $ attachment_id = 0 ;
412
+ $ existing_attachment = 0 ;
413
+ $ existing_placeholder = 0 ;
414
+
415
+ // Sort through results to identify URL and placeholder matches.
416
+ foreach ( $ existing_attachments as $ post_id ) {
417
+ if ( \get_post_meta ( $ post_id , 'activitypub_emoji_source_url ' , true ) === $ emoji_url ) {
418
+ $ existing_attachment = $ post_id ;
419
+ } elseif ( \get_post_meta ( $ post_id , 'activitypub_emoji_placeholder ' , true ) === $ emoji_name ) {
420
+ $ existing_placeholder = $ post_id ;
421
+ }
422
+ }
423
+
424
+ // If we have a different image for this placeholder, or no existing image, download the new one.
425
+ if ( empty ( $ existing_attachment ) || ! empty ( $ existing_placeholder ) ) {
426
+ if ( ! function_exists ( '\download_url ' ) ) {
427
+ require_once \ABSPATH . 'wp-admin/includes/file.php ' ;
428
+ }
429
+
430
+ $ temp_file = \download_url ( $ emoji_url );
431
+ if ( ! \is_wp_error ( $ temp_file ) ) {
432
+ $ file_array = array (
433
+ 'name ' => \wp_basename ( $ emoji_url ),
434
+ 'tmp_name ' => $ temp_file ,
435
+ );
436
+
437
+ if ( ! function_exists ( '\media_handle_sideload ' ) ) {
438
+ require_once \ABSPATH . 'wp-admin/includes/media.php ' ;
439
+ require_once \ABSPATH . 'wp-admin/includes/image.php ' ;
440
+ }
441
+
442
+ $ attachment_id = \media_handle_sideload ( $ file_array , 0 , $ emoji_name );
443
+
444
+ if ( ! \is_wp_error ( $ attachment_id ) ) {
445
+ \update_post_meta ( $ attachment_id , 'activitypub_emoji_source_url ' , $ emoji_url );
446
+ \update_post_meta ( $ attachment_id , 'activitypub_emoji_placeholder ' , $ emoji_name );
447
+ }
448
+ }
449
+
450
+ if ( \is_file ( $ temp_file ) ) {
451
+ \wp_delete_file ( $ temp_file );
452
+ }
453
+ } else {
454
+ $ attachment_id = $ existing_attachment ;
455
+ }
456
+
457
+ if ( $ attachment_id ) {
458
+ $ image_url = \wp_get_attachment_url ( $ attachment_id );
459
+ $ text = str_replace (
460
+ $ emoji_name ,
461
+ sprintf (
462
+ '<img src="%s" alt="%s" class="emoji" /> ' ,
463
+ \esc_url ( $ image_url ),
464
+ \esc_attr ( $ emoji_name )
465
+ ),
466
+ $ text
467
+ );
468
+ } else {
469
+ // Fallback to the original remote URL if something went wrong.
470
+ $ text = str_replace (
471
+ $ emoji_name ,
472
+ sprintf (
473
+ '<img src="%s" alt="%s" class="emoji" /> ' ,
474
+ \esc_url ( $ emoji_url ),
475
+ \esc_attr ( $ emoji_name )
476
+ ),
477
+ $ text
478
+ );
479
+ }
395
480
}
396
481
}
397
482
0 commit comments