// Put this wherever you like; it just needs to run early enough to hook // into these filters. function encode_commas($string) { return str_replace(',', '%2C', $string); } /** * Put Cloudinary URL generation in one place. * * @param $url * @param array $options * * @return bool|mixed|string|string[]|null */ function rewrite_for_cl($url, array $options = []) { // The env var here is the Cloudinary API url you can get in the dashboard. // It looks something like this: // cloudinary://24927894590:b0982nv0su903h89ufhjkfdvnsd@accountname $cl_folder = env('development') ? 'testing' : 'images'; $cl_options = array_merge([ 'quality' => 'auto', 'resource_type' => 'image', 'fetch_format' => 'auto', 'dpr' => 'auto', ], $options); $wp_upload_dir = wp_get_upload_dir(); $to_remove = $wp_upload_dir['baseurl'] ?? false; if ($to_remove) { // Normalize protocol $url = str_replace(['https', 'http'], '', $url); $to_remove = str_replace(['https', 'http'], '', $to_remove); // Turn our local url into our cloudinary directory $image_url = str_replace($to_remove, $cl_folder, $url); // Encode commas so that Lozad doesn't freak out $image_url = encode_commas($image_url); return cloudinary_url($image_url, $cl_options); } return false; } /** * Filter image sources and rewrite them to cloudinary URLs if possible. */ add_filter('wp_get_attachment_image_src', function($image) { if ($image && filter_var($image[0], FILTER_VALIDATE_URL)) { if ($cl_url = rewrite_for_cl($image[0])) { $image[0] = $cl_url; } } return $image; }, 10, 1); /** * Filter srcsets and rewrite them to cloudinary URLs if possible. */ add_filter('wp_calculate_image_srcset', function($sources) { foreach ($sources as &$source) { if($cl_url = rewrite_for_cl($source['url'])) { $source['url'] = encode_commas($cl_url); } } return $sources; }, 10, 1);