cloudinary / cloudinary_wordpress

Cloudinary's WordPress plugin
GNU General Public License v2.0
38 stars 28 forks source link

Old URL used when uploading media from the WordPress APP via the block editor #902

Closed alexstandiford closed 10 months ago

alexstandiford commented 1 year ago

Hi! I love the problem this plugin solves, and appreciate y'alls work!

Bug Description

When I upload media via the WordPress app, and then publish a post using that uploaded image using the block editor, it uses the local WordPress URL instead of the Cloudinary URL. In my case, I'm using "Cloudinary only", so that URL doesn't work because the file gets forward to Cloudinary right away.

It seems like the actual image has the correct URL, however, the image data inside the image gallery block is not bound to the image ID, and is instead has a hardcoded href that's generated on-upload. I think this is the source of the problem.

I am able to resolve the problem by manually going onto the site through a web browser and re-building every image block. Doing so forces the URLs to be updated.

Expected Behaviour

I expect to be able to freely upload media from the app, it forward it to Cloudinary, and when published the post uses the correct URLs.

Steps to reproduce

  1. Ensure that Cloudinary only is set in your settings.
  2. Open the WordPress app
  3. Create a new post
  4. In the post, use the image block to upload a new file.
  5. Click Publish
  6. Observe the broken image URL

Additional context

I want to stress that I think the issue here isn't that the image ID is disassociated with the Cloudinary URL. I was able to prove that's correct by checking the admin interface for the image URL, and also cross-referencing it with the REST API image URL that's provided. The issue is that when the post is saved, the href value in the blocks seems to be stored as an attribute, which is used instead of looking up the image URL by the ID. This results in the app providing the incorrect URL in this data, thereby causing the issue.

A potential solution could be to do a find/replace in post content after an image is moved to Cloudinary, looking for these hardcoded references.

I understand that this may be something that's not always easy to implement, so if it's going to be difficult to solve this problem directly, I would really appreciate a little guidance on how I could potentially hook into the moment Cloudinary uploads these files. If one doesn't exist, I think a do_action would be really helpful if it happened just after the file is migrated to Cloudinary, ideally with the image ID, the old URL, and the new URL to enable this change to be made for people who are able to make this customization on their own sites.

Here's my system report:

{
    "system_status": {
        "home": "https://content.standiford.us",
        "wordpress": "6.3.1",
        "php": "8.1.14",
        "php_extensions": [
            "Core",
            "date",
            "libxml",
            "openssl",
            "pcre",
            "zlib",
            "filter",
            "hash",
            "json",
            "Reflection",
            "SPL",
            "session",
            "standard",
            "sodium",
            "cgi-fcgi",
            "mysqlnd",
            "PDO",
            "xml",
            "bcmath",
            "calendar",
            "ctype",
            "curl",
            "dom",
            "mbstring",
            "FFI",
            "fileinfo",
            "ftp",
            "gd",
            "gettext",
            "iconv",
            "igbinary",
            "imagick",
            "intl",
            "exif",
            "mysqli",
            "pdo_mysql",
            "Phar",
            "posix",
            "readline",
            "redis",
            "shmop",
            "SimpleXML",
            "soap",
            "sockets",
            "sysvmsg",
            "sysvsem",
            "sysvshm",
            "tokenizer",
            "xmlreader",
            "xmlwriter",
            "xsl",
            "zip",
            "Zend OPcache"
        ]
    },
    "theme_status": {
        "name": "Twenty Twenty-One",
        "version": "1.8",
        "author": "the WordPress team",
        "author_url": "https://wordpress.org/",
        "child_theme": false
    },
    "plugins_report": {
        "must_use": [
            "mu-plugins/config.php",
            "mu-plugins/index.php",
            "mu-plugins/spinupwp-debug-log-path.php"
        ],
        "plugins": {
            "add-wpgraphql-seo/wp-graphql-yoast-seo.php": {
                "Name": "Add WPGraphQL SEO",
                "PluginURI": "https://github.com/ashhitch/wp-graphql-yoast-seo",
                "Version": "4.22.5",
                "Description": "A WPGraphQL Extension that adds support for Yoast SEO",
                "Author": "Ash Hitchcock",
                "AuthorURI": "https://www.ashleyhitchcock.com",
                "TextDomain": "wp-graphql-yoast-seo",
                "DomainPath": "/languages",
                "Network": false,
                "RequiresWP": "",
                "RequiresPHP": "",
                "UpdateURI": "",
                "Title": "Add WPGraphQL SEO",
                "AuthorName": "Ash Hitchcock",
                "slug": "add-wpgraphql-seo/wp-graphql-yoast-seo.php"
            },
            "cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php": {
                "Name": "Cloudinary",
                "PluginURI": "https://cloudinary.com/documentation/wordpress_integration",
                "Version": "3.1.4",
                "Description": "With the Cloudinary plugin, you can upload and manage your media assets in the cloud, then deliver them to your users through a fast content delivery network, improving your website\u2019s loading speed and overall user experience. Apply multiple transformations and take advantage of a full digital asset management solution without leaving WordPress.",
                "Author": "Cloudinary Ltd., XWP",
                "AuthorURI": "https://cloudinary.com/",
                "TextDomain": "cloudinary",
                "DomainPath": "/languages",
                "Network": false,
                "RequiresWP": "",
                "RequiresPHP": "",
                "UpdateURI": "",
                "Title": "Cloudinary",
                "AuthorName": "Cloudinary Ltd., XWP",
                "slug": "cloudinary-image-management-and-manipulation-in-the-cloud-cdn/cloudinary.php"
            },
            "headless-mode/headless-mode.php": {
                "Name": "Headless Mode",
                "PluginURI": "",
                "Version": "0.4.0",
                "Description": "This plugin disables access to the front end of your site unless the logged-in user can edit posts. It also automatically accepts requests to REST API or WP_GRAPHQL endpoints.",
                "Author": "Josh Pollock, Jason Bahl, and Ben Meredith",
                "AuthorURI": "https://github.com/Shelob9/headless-mode",
                "TextDomain": "headless-mode",
                "DomainPath": "",
                "Network": false,
                "RequiresWP": "",
                "RequiresPHP": "",
                "UpdateURI": "",
                "Title": "Headless Mode",
                "AuthorName": "Josh Pollock, Jason Bahl, and Ben Meredith",
                "slug": "headless-mode/headless-mode.php"
            },
            "mailgun/mailgun.php": {
                "Name": "Mailgun",
                "PluginURI": "http://wordpress.org/extend/plugins/mailgun/",
                "Version": "1.9.5",
                "Description": "Mailgun integration for WordPress",
                "Author": "Mailgun",
                "AuthorURI": "http://www.mailgun.com/",
                "TextDomain": "mailgun",
                "DomainPath": "/languages/.",
                "Network": false,
                "RequiresWP": "",
                "RequiresPHP": "",
                "UpdateURI": "",
                "Title": "Mailgun",
                "AuthorName": "Mailgun",
                "slug": "mailgun/mailgun.php"
            },
            "make-paths-relative/make-paths-relative.php": {
                "Name": "Make Paths Relative",
                "PluginURI": "https://www.yasglobal.com/web-design-development/wordpress/make-paths-relative/",
                "Version": "1.3.0",
                "Description": "This plugin converts the URL(Links) to relative instead of absolute.",
                "Author": "YAS Global Team",
                "AuthorURI": "https://www.linkedin.com/in/sami-ahmed-siddiqui/",
                "TextDomain": "make-paths-relative",
                "DomainPath": "/languages/",
                "Network": false,
                "RequiresWP": "",
                "RequiresPHP": "",
                "UpdateURI": "",
                "Title": "Make Paths Relative",
                "AuthorName": "YAS Global Team",
                "slug": "make-paths-relative/make-paths-relative.php"
            },
            "share-on-mastodon/share-on-mastodon.php": {
                "Name": "Share on Mastodon",
                "PluginURI": "https://jan.boddez.net/wordpress/share-on-mastodon",
                "Version": "0.17.0",
                "Description": "Easily share WordPress posts on Mastodon.",
                "Author": "Jan Boddez",
                "AuthorURI": "https://jan.boddez.net/",
                "TextDomain": "share-on-mastodon",
                "DomainPath": "",
                "Network": false,
                "RequiresWP": "",
                "RequiresPHP": "",
                "UpdateURI": "",
                "Title": "Share on Mastodon",
                "AuthorName": "Jan Boddez",
                "slug": "share-on-mastodon/share-on-mastodon.php"
            },
            "spinupwp/spinupwp.php": {
                "Name": "SpinupWP",
                "PluginURI": "https://spinupwp.com",
                "Version": "1.5.1",
                "Description": "SpinupWP helper plugin.",
                "Author": "SpinupWP",
                "AuthorURI": "",
                "TextDomain": "spinupwp",
                "DomainPath": "",
                "Network": true,
                "RequiresWP": "",
                "RequiresPHP": "7.1",
                "UpdateURI": "",
                "Title": "SpinupWP",
                "AuthorName": "SpinupWP",
                "slug": "spinupwp/spinupwp.php"
            },
            "wordpress-seo/wp-seo.php": {
                "Name": "Yoast SEO",
                "PluginURI": "https://yoa.st/1uj",
                "Version": "21.1",
                "Description": "The first true all-in-one SEO solution for WordPress, including on-page content analysis, XML sitemaps and much more.",
                "Author": "Team Yoast",
                "AuthorURI": "https://yoa.st/1uk",
                "TextDomain": "wordpress-seo",
                "DomainPath": "/languages/",
                "Network": false,
                "RequiresWP": "6.1",
                "RequiresPHP": "7.2.5",
                "UpdateURI": "",
                "Title": "Yoast SEO",
                "AuthorName": "Team Yoast",
                "slug": "wordpress-seo/wp-seo.php"
            },
            "wp-graphql-gutenberg/plugin.php": {
                "Name": "WP GraphQL Gutenberg",
                "PluginURI": "https://github.com/pristas-peter/wp-graphql-gutenberg",
                "Version": "0.3.11",
                "Description": "Enable blocks in WP GraphQL.",
                "Author": "pristas-peter",
                "AuthorURI": "",
                "TextDomain": "wp-graphql-gutenberg",
                "DomainPath": "",
                "Network": false,
                "RequiresWP": "5.4",
                "RequiresPHP": "",
                "UpdateURI": "",
                "Title": "WP GraphQL Gutenberg",
                "AuthorName": "pristas-peter",
                "slug": "wp-graphql-gutenberg/plugin.php"
            },
            "wp-graphql/wp-graphql.php": {
                "Name": "WPGraphQL",
                "PluginURI": "https://github.com/wp-graphql/wp-graphql",
                "Version": "1.16.0",
                "Description": "GraphQL API for WordPress",
                "Author": "WPGraphQL",
                "AuthorURI": "http://www.wpgraphql.com",
                "TextDomain": "wp-graphql",
                "DomainPath": "/languages/",
                "Network": false,
                "RequiresWP": "5.0",
                "RequiresPHP": "7.1",
                "UpdateURI": "",
                "Title": "WPGraphQL",
                "AuthorName": "WPGraphQL",
                "slug": "wp-graphql/wp-graphql.php"
            }
        }
    },
    "config_report": {
        "cloudinary_usage": "",
        "cloudinary_last_usage": {
            "plan": "Free",
            "last_updated": "2023-09-14",
            "date_requested": "2023-09-15T00:00:00Z",
            "transformations": {
                "usage": 3355,
                "credits_usage": 3.36
            },
            "objects": {
                "usage": 1558
            },
            "bandwidth": {
                "usage": 142134902,
                "credits_usage": 0.13
            },
            "storage": {
                "usage": 1683275860,
                "credits_usage": 1.57
            },
            "requests": 1293,
            "credits": {
                "usage": 5.06,
                "limit": 25,
                "used_percent": 20.24
            },
            "resources": 602,
            "derived_resources": 956,
            "cloudinary_ai": {
                "usage": 0,
                "limit": 200
            },
            "object_detection": {
                "usage": 0,
                "limit": 5000
            },
            "media_limits": {
                "image_max_size_bytes": 10485760,
                "video_max_size_bytes": 104857600,
                "raw_max_size_bytes": 10485760,
                "image_max_px": 25000000,
                "asset_max_total_px": 50000000
            },
            "max_image_size": 10485760,
            "max_video_size": 104857600
        },
        "cloudinary_connection_signature": "4c5dc26e0ea25dd86cb64112dfebaf3d",
        "cloudinary_settings_version": "3.1.4",
        "cloudinary_status": {
            "status": "ok"
        },
        "cloudinary_history": {
            "Free": {
                "08-09-2023": {
                    "plan": "Free",
                    "last_updated": "2023-09-14",
                    "date_requested": "2023-09-08T00:00:00Z",
                    "transformations": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "objects": {
                        "usage": 0
                    },
                    "bandwidth": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "storage": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "requests": 0,
                    "credits": {
                        "usage": 0
                    },
                    "resources": 0,
                    "derived_resources": 0,
                    "media_limits": {
                        "image_max_size_bytes": 10485760,
                        "video_max_size_bytes": 104857600,
                        "raw_max_size_bytes": 10485760,
                        "image_max_px": 25000000,
                        "asset_max_total_px": 50000000
                    }
                },
                "09-09-2023": {
                    "plan": "Free",
                    "last_updated": "2023-09-14",
                    "date_requested": "2023-09-09T00:00:00Z",
                    "transformations": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "objects": {
                        "usage": 0
                    },
                    "bandwidth": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "storage": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "requests": 0,
                    "credits": {
                        "usage": 0
                    },
                    "resources": 0,
                    "derived_resources": 0,
                    "media_limits": {
                        "image_max_size_bytes": 10485760,
                        "video_max_size_bytes": 104857600,
                        "raw_max_size_bytes": 10485760,
                        "image_max_px": 25000000,
                        "asset_max_total_px": 50000000
                    }
                },
                "10-09-2023": {
                    "plan": "Free",
                    "last_updated": "2023-09-14",
                    "date_requested": "2023-09-10T00:00:00Z",
                    "transformations": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "objects": {
                        "usage": 0
                    },
                    "bandwidth": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "storage": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "requests": 0,
                    "credits": {
                        "usage": 0
                    },
                    "resources": 0,
                    "derived_resources": 0,
                    "media_limits": {
                        "image_max_size_bytes": 10485760,
                        "video_max_size_bytes": 104857600,
                        "raw_max_size_bytes": 10485760,
                        "image_max_px": 25000000,
                        "asset_max_total_px": 50000000
                    }
                },
                "11-09-2023": {
                    "plan": "Free",
                    "last_updated": "2023-09-14",
                    "date_requested": "2023-09-11T00:00:00Z",
                    "transformations": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "objects": {
                        "usage": 0
                    },
                    "bandwidth": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "storage": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "requests": 0,
                    "credits": {
                        "usage": 0
                    },
                    "resources": 0,
                    "derived_resources": 0,
                    "media_limits": {
                        "image_max_size_bytes": 10485760,
                        "video_max_size_bytes": 104857600,
                        "raw_max_size_bytes": 10485760,
                        "image_max_px": 25000000,
                        "asset_max_total_px": 50000000
                    }
                },
                "12-09-2023": {
                    "plan": "Free",
                    "last_updated": "2023-09-14",
                    "date_requested": "2023-09-12T00:00:00Z",
                    "transformations": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "objects": {
                        "usage": 0
                    },
                    "bandwidth": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "storage": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "requests": 0,
                    "credits": {
                        "usage": 0
                    },
                    "resources": 0,
                    "derived_resources": 0,
                    "media_limits": {
                        "image_max_size_bytes": 10485760,
                        "video_max_size_bytes": 104857600,
                        "raw_max_size_bytes": 10485760,
                        "image_max_px": 25000000,
                        "asset_max_total_px": 50000000
                    }
                },
                "13-09-2023": {
                    "plan": "Free",
                    "last_updated": "2023-09-14",
                    "date_requested": "2023-09-13T00:00:00Z",
                    "transformations": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "objects": {
                        "usage": 0
                    },
                    "bandwidth": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "storage": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "requests": 0,
                    "credits": {
                        "usage": 0
                    },
                    "resources": 0,
                    "derived_resources": 0,
                    "media_limits": {
                        "image_max_size_bytes": 10485760,
                        "video_max_size_bytes": 104857600,
                        "raw_max_size_bytes": 10485760,
                        "image_max_px": 25000000,
                        "asset_max_total_px": 50000000
                    }
                },
                "14-09-2023": {
                    "plan": "Free",
                    "last_updated": "2023-09-14",
                    "date_requested": "2023-09-14T00:00:00Z",
                    "transformations": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "objects": {
                        "usage": 0
                    },
                    "bandwidth": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "storage": {
                        "usage": 0,
                        "credits_usage": 0
                    },
                    "requests": 0,
                    "credits": {
                        "usage": 0
                    },
                    "resources": 0,
                    "derived_resources": 0,
                    "media_limits": {
                        "image_max_size_bytes": 10485760,
                        "video_max_size_bytes": 104857600,
                        "raw_max_size_bytes": 10485760,
                        "image_max_px": 25000000,
                        "asset_max_total_px": 50000000
                    }
                }
            }
        },
        "rest_api_notices": "",
        "sync_media": {
            "auto_sync": "on",
            "cloudinary_folder": "",
            "offload": "cld"
        },
        "site_cache": {
            "cache": {
                "enable": "some",
                "cld_purge_all": "",
                "assets": {
                    "plugins": {
                        "enabled": "off",
                        "paths": {
                            "wp-graphql-yoast-seo": "off",
                            "cloudinary": "off",
                            "headless-mode": "off",
                            "mailgun": "off",
                            "make-paths-relative": "off",
                            "share-on-mastodon": "off",
                            "spinupwp": "off",
                            "wp-seo": "off",
                            "plugin": "off",
                            "wp-graphql": "off"
                        }
                    },
                    "themes": {
                        "enabled": "off",
                        "paths": {
                            "twentytwentyone": "off"
                        }
                    },
                    "wordpress": {
                        "enabled": "off",
                        "paths": {
                            "wp_admin": "off",
                            "wp_includes": "off"
                        }
                    },
                    "content": {
                        "enabled": "on",
                        "paths": {
                            "wp_content": "on"
                        }
                    }
                }
            }
        },
        "additional_domains": {
            "cache_external": {
                "external_assets": "off",
                "uploadable_domains": []
            }
        },
        "media_display": {
            "image_delivery": "on",
            "image_optimization": "on",
            "image_format": "auto",
            "image_quality": "auto",
            "image_freeform": "",
            "svg_support": "off",
            "crop_sizes": "",
            "image_preview": "https://res.cloudinary.com/demo/image/upload/w_600/sample.jpg",
            "video_delivery": "on",
            "video_player": "wp",
            "video_controls": "on",
            "video_loop": "off",
            "video_autoplay_mode": "off",
            "video_optimization": "on",
            "video_format": "auto",
            "video_quality": "auto",
            "video_freeform": "",
            "video_preview": "",
            "use_lazy_load": "on",
            "lazy_threshold": "100px",
            "lazy_custom_color": "rgba(153,153,153,0.5)",
            "lazy_animate": "on",
            "lazy_placeholder": "blur",
            "dpr": "2X",
            "lazyload_preview": "https://res.cloudinary.com/demo/image/upload/w_600/sample.jpg",
            "enable_breakpoints": "on",
            "pixel_step": 200,
            "breakpoints": "",
            "max_width": 2048,
            "min_width": 200,
            "breakpoints_preview": "https://res.cloudinary.com/demo/image/upload/w_600/sample.jpg"
        },
        "gallery": {
            "transition": "fade",
            "aspectRatio": "3:4",
            "navigation": "always",
            "zoom": true,
            "carouselLocation": "top",
            "carouselOffset": 5,
            "carouselStyle": "thumbnails",
            "displayProps": {
                "mode": "classic",
                "columns": 1
            },
            "indicatorProps": {
                "shape": "round"
            },
            "themeProps": {
                "primary": "#cf2e2e",
                "onPrimary": "#000000",
                "active": "#777777"
            },
            "zoomProps": {
                "type": "popup",
                "viewerPosition": "bottom",
                "trigger": "click"
            },
            "thumbnailProps": {
                "width": 64,
                "height": 64,
                "navigationShape": "radius",
                "selectedStyle": "gradient",
                "selectedBorderPosition": "all",
                "selectedBorderWidth": 4,
                "mediaSymbolShape": "round"
            },
            "cloudName": "dzfhknihi",
            "container": "",
            "queryParam": "AA"
        },
        "cron_system": {
            "cron_system": {
                "enable_cron": "on",
                "tasks": []
            }
        },
        "setup": {
            "reporting": {
                "enable_report": "on"
            }
        },
        "extensions": {
            "media-library": "off"
        }
    },
    "debug_log": [
        "Debug log is empty"
    ]
}
wissam-khalili commented 1 year ago

Hi @alexstandiford,

Thank you for your input. We will review your request and we will keep you posted.

Regards, Wissam

wissam-khalili commented 1 year ago

Hi @alexstandiford ,

I saw that you have sent us the following comment, but I don't see it in the thread here: It seems that the issue is somehow related to my cache. When I flush the cache, the site works as-expected again. I'm getting ns_binding_aborted as a response on the image request until I flush the cache.

What is the current status? Is the issue fixed?

We would like to understand better how the caching layer interferes with our logic.

Regards, Wissam

alexstandiford commented 1 year ago

Hi @alexstandiford ,

I saw that you have sent us the following comment, but I don't see it in the thread here:

It seems that the issue is somehow related to my cache. When I flush the cache, the site works as-expected again. I'm getting ns_binding_aborted as a response on the image request until I flush the cache.

What is the current status? Is the issue fixed?

We would like to understand better how the caching layer interferes with our logic.

Regards,

Wissam

I added that, but realized it was untrue. This is a separate issue I'm having, and removed hoping it wouldn't cause confusion. Please disregard this. The issue remains as I described originally, where a post created using the app does not properly update to use the Cloudinary URL.