multisite-global-media icon indicating copy to clipboard operation
multisite-global-media copied to clipboard

Some plugins use wp_get_attachment_url

Open killua99 opened this issue 5 years ago • 14 comments

Provide support for wp_get_attachment_url filter.

Some plugins like ACF does use this function instead wp_get_attachment_image_url to get the attachment URL.

Is too risky support this filter?

killua99 avatar Apr 29 '19 14:04 killua99

ACF image fields support Global Media images in the admin, but not in the functions used to display them in the theme. It's tricky for this plugin to handle wp_get_attachment_url, because it requires a valid post ID.

So, in case it helps, here's a script to add Global Media support to ACF image fields. Drop it in your functions.php or somewhere.

class Global_Media_ACF {

    use \MultisiteGlobalMedia\Helper;

    function __construct(){
        $this->site = new MultisiteGlobalMedia\Site();
        $this->siteSwitcher = new MultisiteGlobalMedia\SingleSwitcher();
        $this->store = acf_get_store( 'values' );

        add_filter('acf/load_value/type=image', array($this, 'acf_load_value'), 10, 3);
    }

    // Fetch ACF file fields across sites when the global prefix is used.
    // We hook into 'load_value' which usually runs just before 'format_value'.
    // Then get the formatted output of the field in the global media site's context,
    // and store it in ACF's cache. So when format_value tries to use this value,
    // it will find the formatted one already in the cache.
    // This works around acf_format_value requiring a valid att ID as input, but
    // returning a string/array as output, so it can't be easily filtered.
    function acf_load_value( $value, $post_id, $field ) {
        if ($this->idPrefixIncludedInAttachmentId((int)$value, $this->site->idSitePrefix())){
            $formatted = $this->stripSiteIdPrefixFromAttachmentId($this->site->idSitePrefix(), $value);
            $this->siteSwitcher->switchToBlog($this->site->id());
            $formatted = acf_format_value( $formatted, $post_id, $field);
            $this->siteSwitcher->restoreBlog();
            $this->store->set( "$post_id:{$field['name']}:formatted", $formatted );
        }
        // This filter doesn't modify the loaded value. Return it as-is.
        return $value;
    }
}
new Global_Media_ACF();

Then in the theme display the image as you'd do with a local image.

mrazzari avatar Jul 09 '19 21:07 mrazzari

This is very cool. And, given, a plugin like 'safe-svg' takes care of helping me to upload SVGs, it works with SVGs!

Still, is there a way to have PDFs added to that?

This is what i would definitely need to get things done well, it's one of the (if not the) last step before i give up with shared media and acf in a multisite evironment.

It's been a long way to get here, to this issue, some days, am i finally stuck near the end or is there a way for PDFs to be made into global media, too?

ararename avatar Jul 15 '19 22:07 ararename

The gotcha is: Global Media images already work in the ACF admin fields, they just don't work in the functions used to display in the theme. But for file fields, such as PDF, ACF doesn't support Global Media in the admin fields either.

I might look into this next month. Can't promise though, as my current project doesn't require it.

mrazzari avatar Jul 16 '19 18:07 mrazzari

Thank you for the feedback. I had built everything on the premises that ACF in conjunction with a Multisite + Multisite Global Media Plugin would work well together for images and files.

My customer now agreed to not use Frank Bültge's and Dominik Schilling's Multisite Global Media Plugin and upload images two times. Good for me.

I really do wonder how to do a mutlisite (for two different languages) without a paid plugin but with the option to have only to upload files (pdfs and images) once for both sites.

ararename avatar Jul 17 '19 09:07 ararename

In context of two different languages should you discuss the topic path, meta data of the media files. For SEO and other meta topics is it often important to have different files, include different file name, description, meta data. So, yes this plugin helps you to save space and reuse the same files - however it is not always the right way for each goal.

bueltge avatar Jul 19 '19 12:07 bueltge

Hello, thank you for your reply. Yes, that is what i found exactly as you say: i do use it in one case, where with the help of the class provided above by Manuel Razzari it should work with images saved to ACF-elements. I am having some problems with images sizes up to now (the featured image does not scale down any more when taken from the global media tab) but hope to get it to work.

On the other site i cannot use it because i do need files to be saved in ACF-elements. As Manuel Razzari states, he might or might not get to looking into it.

Finally, this was not going against your plugin at all, i just found, also as you said, that in some cases combinations of a network shared library in a multisite environment used together with ACF will not work out well. Thank you for this (and your other) plugins (i'm using must_use_loader.php as well :)

ararename avatar Jul 19 '19 14:07 ararename

@mrazzari your code solved my frontend problem but I have another problem in back office.

When I want edit the image, everything is empty. Captura de ecrã 2019-09-25, às 16 25 29 Captura de ecrã 2019-09-25, às 16 29 03

bcoelhodev avatar Sep 25 '19 15:09 bcoelhodev

@bcoelhonqda yeah that happens here as well. I just haven't cared enough to try and fix it.

mrazzari avatar Sep 25 '19 15:09 mrazzari

Hi @mrazzari ! I have tried to drop the code you shared above to be able to use ACF functions in the theme, but I am not able to make it work. I get an error that says: Error thrown - Call to a member function set() on null. There is something can I do? Thank you in advance!

mikem33 avatar Nov 15 '19 10:11 mikem33

Looks like the ACF cache store is not there for you. Not sure what might be going on. Maybe old version?

mrazzari avatar Nov 15 '19 13:11 mrazzari

Yes, it was that! Thank you so much!

mikem33 avatar Nov 15 '19 13:11 mikem33

To get this working for file inputs also, you can just add a second add_filter(...) line matching type file like

add_filter('acf/load_value/type=file', array($this, 'acf_load_value'), 10, 3);

highbelt avatar Sep 24 '20 09:09 highbelt

should this solution also work for the gallery type of ACF ? Because it's not working for me @mrazzari

Leobar00 avatar Jun 17 '22 08:06 Leobar00

should this solution also work for the gallery type of ACF ? Because it's not working for me @mrazzari

Sorry @Leobar00 I haven't touched this code since posting it. Try using this plugin's master branch which does a better job of integrating my snippet.

mrazzari avatar Jun 17 '22 19:06 mrazzari

You can close this issue if is not relevant anymore

killua99 avatar Nov 25 '22 15:11 killua99