StoutLogic / acf-builder

An Advanced Custom Field Configuration Builder
GNU General Public License v2.0
788 stars 61 forks source link

Issue with WPML may require moving away from acf-builder. Is there a way to get JSON/PHP to import into ACF Pro UI? #184

Open cjezowicz opened 5 months ago

cjezowicz commented 5 months ago

We've used StoutLogic / acf-builder on almost all of our projects for the past few years. However this is the first time we've been asked to add translation functionality to an existing site. We chose WPML because it seemed to support everything we needed out of the box. During implementation we ran into an issue where translations would not find the ACF field groups and instead display Notice: Undefined variable: content_blocks in /var/www/html/web/app/uploads/cache/bf12783b09440d36e34dfe9a69b1e37c0cd6fa9b.php on line 2

We're working with WPML to see if there is a resolution to this issue: https://wpml.org/forums/topic/translating-acf-fields-3 and we've since found a post with a similar if not same issue that we're running into: https://wpml.org/forums/topic/repeaters-flexible-content-generated-with-acf_add_local_field-and-wpml/

This brings me to my actual question/issue. Is there any migration tools, processes, or procedures that can take the StoutLogic / acf-builder ACF fields and convert them to JSON OR import then back into ACF PRO as database values?

stevep commented 5 months ago

I don't have much experience with WPML but ACF Builder isn't doing anything much different than if you were to register your acf fields manually. It is just building the field group config array you plug in directly to acf_add_local_field_group

https://www.advancedcustomfields.com/resources/register-fields-via-php/#add-within-an-action

And with that said, any way that currently exists to transform field groups registered with PHP to JSON should be apply here as well. I haven't tried it but could look at: https://github.com/underlost/acf-php-to-json/

Looking at the code of that plugin, this line should return all the field groups you define with ACF Builder and register with acf_add_local_field_group:

 $groups = acf_get_local_field_groups();

Being mindful of when the field group registration happens in the code, and when that function is called

coreyhicks commented 5 months ago

@stevep I too am trying to solve this issue and gave the script you suggested a try.

It works, but the output for the flexible content field differs slightly from what ACF generates, which is what seems to be keeping ACF Builder from working out of the box with WPML. Specifically, ACF is generating a key for each flexible content layout whereas ACF Builder is not:

ACF generated json:

"layouts": {
    "layout_65fdaa7564ba4": {
        "key": "layout_65fdaa7564ba4",
        "name": "test_layout",

ACF Builder generated json:

"layouts": [
    {
        "key": "flexible_content_test",
        "name": "test_layout",

Dropping in this quick and dirty test confirmed that adding the layout keys resolves the issue but, obviously, accounting for nested flexible content fields would require a bit more doing:

add_action( 'init', function () {
    $groups = acf_get_local_field_groups();
    foreach ($groups as $group) {
        // Fetch the fields for the given group key
        $fields = acf_get_fields($group['key']);

        // Remove unecessary key value pair with key "ID"
        unset($group['ID']);

        // Quick and dirty loop to test flexible content layout keys
        $new_fields = [];
        foreach ($fields as $field) {
            if ($field['type'] == 'flexible_content') {
                if (!empty($field['layouts'])) {
                    $layouts = [];
                    foreach ($field['layouts'] as $layout) {
                        $key = 'layout_' . $layout['name'];
                        $layouts[$key] = $layout;
                    }
                    $field['layouts'] = $layouts;
                }
            }
            $new_fields[] = $field;
        }

        // Add the fields as an array to the group
        $group['fields'] = $new_fields;

        $json = json_encode($group, JSON_PRETTY_PRINT);

        // Add field group json to Local JSON directory
        $file = 'path/to/local/json/' . $group['key'] . '.json';
        file_put_contents($file, $json );
    }
});

Do you see any reason not to generate a key automatically when ->addLayout('my_layout') is called? It would require more testing but, in theory, that could eliminate the need for the json conversion all together.

stevep commented 5 months ago

@coreyhicks That is interesting. Great find! Your comment is marked as resolved, but did that indeed fix the issue for you with WPML?

I'm wondering what implications this change would have, and if it might be a breaking change for any external packages depending on ACF Builder.