Open web-vitality opened 1 month ago
Hi @web-vitality ,
It might be required to add some additional checks for REST API endpoints. Do you have any details on which endpoints are being used?
Yes of course, i have many endpoints. For example here are some of them.
To pull posts i register an endpoint.
add_action('rest_api_init', 'post');
function post () {
register_rest_route('myendpoint1', '/post/(?P<slug>\S+)', [
'methods' => WP_REST_SERVER::READABLE,
'callback' => 'postRes',
'publicly_queryable' => true,
'permission_callback' => '__return_true',
'args' => array(
'slug' => array(
'required' => true
),
),
] );
}
function postRes($data) {
$post_result = [];
$post = new WP_Query([
'post_type' => 'post',
'name' => $data['slug'],
'post_status' => 'publish',
'posts_per_page' => 1,
]);
while($post->have_posts()){
$post->the_post();
$seo = [];
$post_result = [];
$post_result['id'] = get_the_ID();
$post_result['title'] = get_the_title();
$post_result['text'] = get_the_content();
$post_result['slug'] = get_post_field('post_name', get_post());
$post_result['img'] = get_the_post_thumbnail_url(get_the_ID(), 'medium');
........
............
}
wp_reset_postdata();
return $post_result;
}
For example, I pull array of teachers with ACF fields
add_action('rest_api_init', 'teachers');
function teachers (){
register_rest_route('myendpoint2', '/teachers', [
'methods' => WP_REST_SERVER::READABLE,
'callback' => 'teachersRes',
'publicly_queryable' => true,
'permission_callback' => '__return_true',
] );
}
function teachersRes($data) {
$teachers_result = [];
$teachers = new WP_Query([
'post_type' => 'teachers',
'post_status' => 'publish',
'posts_per_page' => 100,
]);
while($teachers->have_posts()){
$teachers->the_post();
$teachers_result[$loop]['id'] = get_the_ID();
$teachers_result[$loop]['title'] = get_the_title();
$teachers_result[$loop]['text'] = get_the_content();
$teachers_result[$loop]['slug'] = get_post_field('post_name', get_post());
$teachers_result[$loop]['img'] = get_field('teacher')['img'];
........
............
}
wp_reset_postdata();
return $teachers_result;
}
Thanks for the help.
I haven't tested this, but just throwing some ideas.
For the REST API request, you need to have a look at this code. The reason this is so tricky is because of Gutenberg, which uses REST API. If we just replace all images on all API endpoints, then editing a Gutenberg-based post will save Cloudflare Images as content, which makes it really hard to revert back. But if you're not using Gutenberg, you can just return false on that method and see if that helps.
That might actually fix the ACF issues as well.
It doesn't help me. Thanks for trying.
Is it possible to use one of the hooks or functions from your plugin, into which I will pass the URL of the image or the ID of the image (the image will already be uploaded to cloudflare and there will be a post_meta in the database for this image), then this function will return me the value of the link to cloudflare for this image and I will assign the result of execution to my array?
Yes, if you have the URL and image ID, you can do something like this. But, if you're doing this as part of a REST API endpoint, you will also need to adjust that method I linked above.
I'll be able to have a look at this in a few days. Just need to setup a headless test site.
I wrote my custom code. A bit ugly and not neat but working. Here is a partial example if it helps anyone. I call the get_cloudflare_image_url() function, pass the attachment_id, the function returns a ready link to the cloudflare image.
$image_src = get_cloudflare_image_url( attachment_id );
$posts_result[$loop]['post_thumb'] = ( get_cloudflare_image_url(get_the_ID(), 'post_thumb') ?? get_the_post_thumbnail_url(get_the_ID(), 'post_thumb') );
I also use a filter for get_field() of ACF.
add_filter( "acf/format_value/type=image", function ($value, $post_id, $field) {
if ( isset($value['id'] ) ) {
$value['url'] = get_cloudflare_image_url( $value['id'] ) ?? $value['url'];
}
return $value;
}, 10, 3 );
use CF_Images\App\Modules\Cloudflare_Images;
/**
* Get cloudflare image link if exist in DB
*/
function get_cloudflare_image_url($post_id, $size = 'public') {
$cf_image = NULL;
$attachment_id = get_post_thumbnail_id( $post_id );
if ( get_image_sizes( $size ) !== false ) {
$size_tmp = get_image_sizes( $size );
$size = 'w=' . $size_tmp['width'] . ',h=' . $size_tmp['height'] . ',fit=crop';
} else {
$size = 'public';
}
if ( empty($attachment_id) ) {
$attachment_id = $post_id;
}
// if cf-images plugin not active
if ( !class_exists('CF_Images\App\Modules\Cloudflare_Images') ) {
$cf_image_id = get_post_meta( $attachment_id, '_cloudflare_image_id', true );
$cf_image = "https://imagedelivery.net/{HASH}/${cf_image_id}/public";
if ( empty($cf_image_id) ) {
return NULL;
}
return $cf_image;
}
$cf_images = new Cloudflare_Images( 'cloudflare-images' );
list( $hash, $cloudflare_image_id ) = $cf_images->get_hash_id_url_string( (int) $attachment_id );
if ( $cloudflare_image_id ) {
$cf_image = trailingslashit( "https://imagedelivery.net" . "/$hash" ) . $cloudflare_image_id . "/" . $size;
}
return $cf_image;
}
/**
* Get information about available image sizes
*/
function get_image_sizes( $sizetmp = '' ) {
$wp_additional_image_sizes = wp_get_additional_image_sizes();
$sizes = array();
$get_intermediate_image_sizes = get_intermediate_image_sizes();
// Create the full array with sizes and crop info
foreach( $get_intermediate_image_sizes as $_size ) {
if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
$sizes[ $_size ]['width'] = get_option( $_size . '_size_w' );
$sizes[ $_size ]['height'] = get_option( $_size . '_size_h' );
$sizes[ $_size ]['crop'] = (bool) get_option( $_size . '_crop' );
} elseif ( isset( $wp_additional_image_sizes[ $_size ] ) ) {
$sizes[ $_size ] = array(
'width' => $wp_additional_image_sizes[ $_size ]['width'],
'height' => $wp_additional_image_sizes[ $_size ]['height'],
'crop' => $wp_additional_image_sizes[ $_size ]['crop']
);
}
}
// Get only 1 size if found
if ( $sizetmp ) {
if( isset( $sizes[ $sizetmp ] ) ) {
return $sizes[ $sizetmp ];
} else {
return false;
}
}
return $sizes;
}
Hi there! For my project I started to write code for uploading images to cloudflare, but I came across your plugin. Thanks for sharing it! It's a huge help. :) I use WordPress as a headless cms for backend, and on the frontend I use one of the popular frameworks. I have a custom plugin that is responsible for all requests and endpoints and returns the date in the response. I use the REST API. I use new WP_Query for queries. I also use ACF but the links are not changed in the response either. It's important to note that if I use vordpress as a normal system everything works. I don't quite understand if this is even possible how I can use the functionality of your plugin so that I can change the links of images from WordPress to Cloudflare in the response output. I hope I've been clear in my explanation. Thanks.