ABADI.NEWS Social Share Image System
[\d]+)’, array(
‘methods’ => ‘POST’,
‘callback’ => ‘abadi_rest_generate_social_image’,
‘permission_callback’ => function () {
return current_user_can( ‘edit_posts’ );
},
‘args’ => array(
‘post_id’ => array(
‘required’ => true,
‘validate_callback’ => function ( $param ) {
return is_numeric( $param ) && intval( $param ) > 0;
},
‘sanitize_callback’ => ‘absint’,
),
),
) );
} );
function abadi_rest_generate_social_image( WP_REST_Request $request ) {
$post_id = $request->get_param( ‘post_id’ );
$post = get_post( $post_id );
if ( ! $post ) {
return new WP_REST_Response( array(
‘success’ => false,
‘error’ => ‘Post not found.’,
), 404 );
}
if ( ‘post’ !== $post->post_type ) {
return new WP_REST_Response( array(
‘success’ => false,
‘error’ => ‘Invalid post type. Only posts are supported.’,
), 400 );
}
$result = abadi_news_generate_social_share_image( $post_id );
if ( is_wp_error( $result ) ) {
return new WP_REST_Response( array(
‘success’ => false,
‘error’ => $result->get_error_message(),
), 500 );
}
if ( ! $result ) {
return new WP_REST_Response( array(
‘success’ => false,
‘error’ => ‘Image generation failed.’,
), 500 );
}
update_post_meta( $post_id, ‘_abadi_social_share_image’, $result );
update_post_meta( $post_id, ‘_abadi_featured_image_id’, get_post_thumbnail_id( $post_id ) );
return new WP_REST_Response( array(
‘url’ => ‘/wp-content/uploads/social-share/’ . $post_id . ‘.jpg’,
‘success’ => true,
), 200 );
}
// ============================================================
// (2) Image Generation Function
// ============================================================
function abadi_news_generate_social_share_image( $post_id ) {
if ( ! extension_loaded( ‘gd’ ) ) {
return new WP_Error( ‘gd_missing’, ‘GD library is not available on this server.’ );
}
$image_id = get_post_thumbnail_id( $post_id );
if ( ! $image_id ) {
return new WP_Error( ‘no_thumbnail’, ‘Post has no featured image.’ );
}
$image_src = wp_get_attachment_image_src( $image_id, ‘full’ );
if ( ! $image_src || empty( $image_src[0] ) ) {
return new WP_Error( ‘no_image_src’, ‘Could not retrieve featured image URL.’ );
}
$image_url = $image_src[0];
// Download image to temp file
$response = wp_remote_get( $image_url, array( ‘timeout’ => 30 ) );
if ( is_wp_error( $response ) ) {
return new WP_Error( ‘download_failed’, ‘Failed to download featured image: ‘ . $response->get_error_message() );
}
$image_body = wp_remote_retrieve_body( $response );
if ( empty( $image_body ) ) {
return new WP_Error( ‘empty_image’, ‘Downloaded image body is empty.’ );
}
$content_type = wp_remote_retrieve_header( $response, ‘content-type’ );
$is_png = ( strpos( $content_type, ‘png’ ) !== false || preg_match( ‘/\.png$/i’, $image_url ) );
$ext = $is_png ? ‘.png’ : ‘.jpg’;
$temp_file = sys_get_temp_dir() . ‘/abadi_social_’ . $post_id . $ext;
file_put_contents( $temp_file, $image_body );
// Load image with GD
if ( $is_png ) {
$src_image = @imagecreatefrompng( $temp_file );
} else {
$src_image = @imagecreatefromjpeg( $temp_file );
}
@unlink( $temp_file );
if ( ! $src_image ) {
return new WP_Error( ‘gd_load_failed’, ‘GD could not load the image.’ );
}
$src_w = imagesx( $src_image );
$src_h = imagesy( $src_image );
// Canvas target dimensions
$canvas_w = 1200;
$canvas_h = 630;
// Create black canvas (letterbox)
$canvas = imagecreatetruecolor( $canvas_w, $canvas_h );
$black = imagecolorallocate( $canvas, 0, 0, 0 );
imagefilledrectangle( $canvas, 0, 0, $canvas_w – 1, $canvas_h – 1, $black );
// Scale source image to fit canvas maintaining aspect ratio
$scale = min( $canvas_w / $src_w, $canvas_h / $src_h );
$new_w = (int) round( $src_w * $scale );
$new_h = (int) round( $src_h * $scale );
$dst_x = (int) round( ( $canvas_w – $new_w ) / 2 );
$dst_y = (int) round( ( $canvas_h – $new_h ) / 2 );
imagecopyresampled( $canvas, $src_image, $dst_x, $dst_y, 0, 0, $new_w, $new_h, $src_w, $src_h );
imagedestroy( $src_image );
// Determine footer height
if ( $src_w === 1080 || $src_h === 1080 ) {
$footer_pct = 0.14; // 14% for square-ish images
} else {
$footer_pct = 0.12; // 12% default
}
$footer_height = (int) round( $canvas_h * $footer_pct );
$footer_y = $canvas_h – $footer_height;
// Draw gradient footer overlay (simulate gradient with multiple rectangles)
$steps = 20;
for ( $i = 0; $i < $steps; $i++ ) {
$ratio = $i / ( $steps - 1 );
$r = (int) round( 26 + ( 42 - 26 ) * $ratio ); // #1a -> #2a
$g = (int) round( 26 + ( 42 – 26 ) * $ratio );
$b = (int) round( 26 + ( 42 – 26 ) * $ratio );
$color = imagecolorallocate( $canvas, $r, $g, $b );
$rect_y1 = $footer_y + (int) round( $footer_height * $i / $steps );
$rect_y2 = $footer_y + (int) round( $footer_height * ( $i + 1 ) / $steps );
imagefilledrectangle( $canvas, 0, $rect_y1, $canvas_w – 1, $rect_y2, $color );
}
// Render “ABADI.NEWS” text centered in footer
$text = ‘ABADI.NEWS’;
$font_size = (int) round( $footer_height * 0.62 );
$white = imagecolorallocate( $canvas, 255, 255, 255 );
$padding_top = (int) round( $footer_height * 0.19 );
// Try TrueType font first; fall back to built-in GD fonts
$font_path = ABSPATH . ‘wp-includes/fonts/NotoSerif-Bold.ttf’;
$ttf_used = false;
if ( function_exists( ‘imagettftext’ ) && file_exists( $font_path ) ) {
$ttf_size = max( 8, (int) round( $footer_height * 0.48 ) );
$bbox = imagettfbbox( $ttf_size, 0, $font_path, $text );
if ( $bbox ) {
$text_w = abs( $bbox[2] – $bbox[0] );
$text_x = (int) round( ( $canvas_w – $text_w ) / 2 );
$text_y = $footer_y + $padding_top + $ttf_size;
imagettftext( $canvas, $ttf_size, 0, $text_x, $text_y, $white, $font_path, $text );
$ttf_used = true;
}
}
if ( ! $ttf_used ) {
// Use built-in GD font (font 5 is the largest built-in)
$gd_font = 5;
$char_w = imagefontwidth( $gd_font );
$char_h = imagefontheight( $gd_font );
$text_w = $char_w * strlen( $text );
$text_x = (int) round( ( $canvas_w – $text_w ) / 2 );
$text_y = $footer_y + (int) round( ( $footer_height – $char_h ) / 2 );
imagestring( $canvas, $gd_font, $text_x, $text_y, $text, $white );
}
// Prepare output directory
$upload_dir = wp_upload_dir();
$share_dir = $upload_dir[‘basedir’] . ‘/social-share’;
wp_mkdir_p( $share_dir );
$output_file = $share_dir . ‘/’ . $post_id . ‘.jpg’;
$saved = imagejpeg( $canvas, $output_file, 90 );
imagedestroy( $canvas );
if ( ! $saved ) {
return new WP_Error( ‘save_failed’, ‘Could not save social share image to disk.’ );
}
$output_url = $upload_dir[‘baseurl’] . ‘/social-share/’ . $post_id . ‘.jpg’;
return $output_url;
}
// ============================================================
// (3) Post Meta Field Registration
// ============================================================
add_action( ‘rest_api_init’, function () {
register_rest_field( ‘post’, ‘_abadi_social_share_image’, array(
‘get_callback’ => function ( $post ) {
return get_post_meta( $post[‘id’], ‘_abadi_social_share_image’, true );
},
‘update_callback’ => function ( $value, $post ) {
update_post_meta( $post->ID, ‘_abadi_social_share_image’, sanitize_text_field( $value ) );
},
‘schema’ => array(
‘type’ => ‘string’,
‘description’ => ‘ABADI.NEWS generated social share image URL.’,
),
) );
register_rest_field( ‘post’, ‘_abadi_featured_image_id’, array(
‘get_callback’ => function ( $post ) {
return get_post_meta( $post[‘id’], ‘_abadi_featured_image_id’, true );
},
‘update_callback’ => function ( $value, $post ) {
update_post_meta( $post->ID, ‘_abadi_featured_image_id’, absint( $value ) );
},
‘schema’ => array(
‘type’ => ‘integer’,
‘description’ => ‘Featured image attachment ID at time of social share image generation.’,
),
) );
} );
// ============================================================
// (4) Auto-Generation on Post Save
// ============================================================
add_action( ‘save_post’, ‘abadi_auto_generate_social_image’, 10, 2 );
function abadi_auto_generate_social_image( $post_id, $post ) {
// Skip autosaves, revisions, and non-post types
if ( defined( ‘DOING_AUTOSAVE’ ) && DOING_AUTOSAVE ) {
return;
}
if ( wp_is_post_revision( $post_id ) ) {
return;
}
if ( ‘post’ !== $post->post_type ) {
return;
}
$current_image_id = get_post_thumbnail_id( $post_id );
$previous_image_id = get_post_meta( $post_id, ‘_abadi_featured_image_id’, true );
$existing_share = get_post_meta( $post_id, ‘_abadi_social_share_image’, true );
$image_changed = ( (string) $current_image_id !== (string) $previous_image_id );
$image_missing = empty( $existing_share );
if ( $image_changed || $image_missing ) {
if ( ! $current_image_id ) {
return; // No featured image to generate from
}
$result = abadi_news_generate_social_share_image( $post_id );
if ( ! is_wp_error( $result ) && $result ) {
update_post_meta( $post_id, ‘_abadi_social_share_image’, $result );
update_post_meta( $post_id, ‘_abadi_featured_image_id’, $current_image_id );
}
}
}
// ============================================================
// (5) Server-Side Meta Tag Injection
// ============================================================
add_action( ‘wp_head’, ‘abadi_inject_social_meta_tags’, 5 );
function abadi_inject_social_meta_tags() {
if ( ! is_singular( ‘post’ ) ) {
return;
}
$post = get_queried_object();
if ( ! $post instanceof WP_Post ) {
return;
}
// Resolve social share image
$social_image = get_post_meta( $post->ID, ‘_abadi_social_share_image’, true );
if ( empty( $social_image ) ) {
$featured_img = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), ‘full’ );
$social_image = ! empty( $featured_img[0] ) ? $featured_img[0] : ”;
}
if ( empty( $social_image ) ) {
$social_image = ‘/img/abadi_news_fallback.png’;
}
// Resolve description
$description = ”;
if ( ! empty( $post->post_excerpt ) ) {
$description = wp_strip_all_tags( $post->post_excerpt );
} else {
$description = wp_trim_words( wp_strip_all_tags( $post->post_content ), 30, ‘…’ );
}
$title = get_the_title( $post );
$permalink = get_permalink( $post );
echo “\n\n”;
echo ‘‘ . “\n”;
echo ‘‘ . “\n”;
echo ‘‘ . “\n”;
echo ‘‘ . “\n”;
echo ‘‘ . “\n”;
echo ‘‘ . “\n”;
echo ‘‘ . “\n”;
echo ‘‘ . “\n”;
echo ‘‘ . “\n”;
echo “\n\n”;
}





KOMENTAR PEMBACA
Silakan masuk untuk menulis komentar.
MASUK UNTUK BERKOMENTAR