Polylang + ACF + Flexible Content Layouts

March 5, 2023

Recently, while working with a WordPress site based on a combination of Polylang and ASF, I encountered an unexpected bug. The bug is that when using ASF Flexible Content Layuts when trying to save or update a post or an instance of a custom post type, the Flexible Content structure of the edited post groups unconditionally overwrites the Flexible structures of translation posts, and it is the structure that is overwritten, the content of layouts is not transferred.

Naturally, I did a search on Google and OpenCTP, and to my surprise, I did not find such cases.
Moreover, OpenCTP distinguished itself here – it immediately categorically stated that such behavior is not a bug, but is a specially trained feature provided by the developers to better meet the needs of users)

That is, when you save, say, an English post, and at the same moment its translation, say German, is overwritten, after that you save the German post, trying to correct the result of the previous operation,
and this happens in an endless circle – this is by no means a bug, from the point of view of OpenCPT, but a very convenient implementation feature)

In fairness, it must be said that after pointing out such a contradiction, after several clarifying remarks, the chat admitted its mistake and began to offer options for disabling this “feature”. The translation mode for these ACF groups was initially specified as ‘copy-once’, was reset to ‘ignore’, but this did not help, that is, I had to look for an option to cancel the synchronization of meta fields programmatically.

It should be said that the site is quite old (more than 3 years old), it was once assembled by PM (so they can breathe))) based on a ready-made theme and plugins.
That is, another stupid monkey decided that it had already heard enough of different things at the meetinhgs, and decided to build the site on it’s own.
The site was really assembled, launched and filled with content. Naturally, with such a data and code structure that only a PM who decided to program, or a dumbass, could come up with.
To make it clear, I will only say that it turns out that it is not necessary to use templates for pages that display content in any language, in fact, it is correct to create
page-template-en.php, page-template-de.php, page-template-fr.php, etc. This is just one of the examples, there were dozens of such pinnacles of engineering thought.

At first it worked, various changes were made, including in the code, but – to regret of the stupid monkey, the business turned out to be successful, it grew, developed, the site needed serious functionality updates, and then the monkey had a stack-overflow and was chased with pissing rags from the project.
After that, a standard solution was found – to take a programmer to the project. But not simple, but golden, or rather with a golden tint of skin, shorter it was a Pakistani. Well, in short, they drove him, of course, but he managed to spoil notably.

Returning to the current situation – to make a new site, the businessowners is not ready now, because a new idea and design is not done so quickly (there, in England), it takes time and the designer’s inspiration, again, the stars need to align correctly, in short – not now.
That is, it is necessary to fix the existing lame site, because the functionality has already been created for Flexible Content, it works, it brings profit, but it actually works only in one (main) language of the site.
After several suggestive requests, the chat found the pll_copy_post_metas filter in the bowels of Polylang, with which the problem can be solved.
The solution itself is simple:

function disable_acf_syncing( $metas, $post_id, $source_lang, $target_lang ) {
    $meta_data = $metas;

    foreach ( $meta_data as $i => $data ) {
        if ( preg_match( '/ACF_FC_Group_name_to_be_exluded/', $data  ) ) {
            unset( $metas[ $i ] );
        }
    }

    return $metas;
}
add_filter( 'pll_copy_post_metas', 'disable_acf_syncing', 10, 4 );

The filter comes with an array of meta fields and 3 additional useful arguments. I’m doing the check through preg_match due to the naming of ACF Flexible Content fields – I needed to exclude everything related to a specific Flexible Content group, of course, the check can be done as required by a specific situation.
It should also be noted that with this implementation, you will get an array with unchanged indices at the output, that is, if your check removed elements with indices 0,1,2 from a 5 element array, then the resulting array will be have elements at indexes 3 and 4, not 0 and 1. It didn’t matter to me, but it’s worth remembering the indexes.

Now the site works as expected, meta fields are added and updated independently, as needed by the content manager team. In the future, the site will be rebuit by our team from scratch.

Categorised in: wordpress