@@ -107,12 +107,23 @@ public function execute()
107107 }
108108
109109 $ cleanUrl = $ parsedUrl ['scheme ' ] . ':// ' . $ parsedUrl ['host ' ] . $ parsedUrl ['path ' ];
110- $ baseUrl = $ this ->storeManager ->getStore ()->getBaseUrl ();
111- $ relativePath = str_replace ($ baseUrl , '' , $ cleanUrl );
112- $ relativePath = ltrim ($ relativePath , '/ ' );
110+
111+ // Derive the relative path from the URL path component directly — the admin
112+ // store's base URL doesn't always match the public storefront URL used by the
113+ // media gallery, so str_replace($baseUrl, ...) can leave the host in the path.
114+ $ relativePath = ltrim ($ parsedUrl ['path ' ], '/ ' );
115+
116+ // Strip leading `pub/` when Magento is served from <docroot>/pub/.
117+ $ relativePath = preg_replace ('#^pub/# ' , '' , $ relativePath );
118+
119+ // Strip the `.renditions/` segment so Cloudinary fetches the original image
120+ // instead of the local PageBuilder/admin-gallery rendition derivative, which
121+ // 404s through the auto-upload mapping (mapping points at the original path).
122+ $ relativePath = preg_replace ('#(^|/)\.renditions/# ' , '$1 ' , $ relativePath );
123+ $ cleanUrl = preg_replace ('#/\.renditions/# ' , '/ ' , $ cleanUrl );
113124
114125 // Create Image object and use UrlGenerator (same as storefront)
115- $ image = Image::fromPath ($ remoteImageUrl , $ relativePath );
126+ $ image = Image::fromPath ($ cleanUrl , $ relativePath );
116127
117128 // Use UrlGenerator which handles all the logic including database mapping
118129 $ cloudinaryUrl = $ this ->urlGenerator ->generateFor ($ image , $ this ->transformation );
0 commit comments