StoutLogic / acf-builder

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

post_object field empty when using WPML language #165

Open Jelmerkeij opened 1 year ago

Jelmerkeij commented 1 year ago

I've added a post_object field to select a page on an options page:

$fields = new FieldsBuilder( __( 'Settings' ) );

$fields
    ->addTab( __( 'Pages' ) )
    ->addGroup( 'custom_pages', [ 'label' => __( 'Custom pages' ) ] )
    ->addPostObject( 'my_custom_page',
        [
            'label' => 'My custom page',
            'post_type' => 'page',
            'return_format' => 'post_id'
        ]
    )
    ->endGroup();

This works fine under the default language, but after installing WPML and choosing the second language in the CMS the selectlist comes up empty when searching for posts (pages).

Creating the same field through the 'default' ACF UI this works though.

After some experimenting I found that there's a difference: Fields added through ACF UI are added to the database and I think WPML does something with this info.

The default ACF UI field sends its request when searching for posts like this:

action: acf/fields/post_object/query
s: priv
paged: 1
field_key: field_63a0514701ad3
nonce: b73c2b26a5
post_id: options
lang: en

The field added through the Stoutlogic ACF Builder sends it POST form-data like this:

action: acf/fields/post_object/query
s: priv
paged: 1
field_key: field_settings_custom_pages_my_custom_page
nonce: b73c2b26a5
post_id: options_nl
lang: nl

Now in the posts table in the database, there exists a post for field_63a0514701ad3 having the post_type acf-field. But these do not exists for our fields added through the Stoutlogic ACF builder. After adding field_settings_custom_pages_my_custom_page in the database as post_type acf_field results appear in the selectlist.

Is there any way to navigate this issue? In the original language it isn't in the database either of course but it still returns posts when searching in the select list.

Edit: Well, the language of the original (EN) and 2nd language (NL) are also sent to the query in the post variables post_id and lang.

I've tried this as well but to no avail: https://github.com/StoutLogic/acf-builder/issues/99

stevep commented 1 year ago

Hi @Jelmerkeij

I haven't tried this, nor do I have experience with WPML, but does this mean that if you were to utilize ACF's built in export to JSON or PHP, that those fields would not work with WPML as well?

Can you try to export the field group you built in the UI as PHP, delete (or disable) the UI version and then include that generated PHP in your code? Does it work? Can you compare that field config code with the code generated by $fields->build() ?

Jelmerkeij commented 1 year ago

@stevep Thanks for getting back to me. That's an interesting approach I didn't take yet :-)

When using the exported PHP it works! I have created a new testing field and removed the acf-field post from the database to make sure it wasn't using that. Is there a way to view the PHP code that's generated by the ACF Builder so I can compare? At first sight I do not see any difference except for the key field to include a hashed string like 63a0514701ad4.

I do not see any clear difference between this and the parameters passed into the ACF builder and I've tried passing in the exact same parameters as exported by ACF.

Code as used for the builder:

$fields->addPostObject('set_testpage',[
            'label' => 'Set test page',
            'aria-label' => '',
            'type' => 'post_object',
            'instructions' => '',
            'required' => 0,
            'conditional_logic' => 0,
            'wrapper' => array(
                'width' => '',
                'class' => '',
                'id' => '',
            ),
            'post_type' => array(
                0 => 'page',
            ),
            'taxonomy' => '',
            'return_format' => 'object',
            'multiple' => 0,
            'allow_null' => 0,
            'ui' => 1,
        ]);

Code as exported by ACF:

acf_add_local_field_group(array(
        'key' => 'group_63a0514530035',
        'title' => 'testgroup',
        'fields' => array(
            array(
                'key' => 'field_63a0514701ad4',
                'label' => 'Set test page',
                'name' => 'set_test_page',
                'aria-label' => '',
                'type' => 'post_object',
                'instructions' => '',
                'required' => 0,
                'conditional_logic' => 0,
                'wrapper' => array(
                    'width' => '',
                    'class' => '',
                    'id' => '',
                ),
                'post_type' => array(
                    0 => 'page',
                ),
                'taxonomy' => '',
                'return_format' => 'object',
                'multiple' => 0,
                'allow_null' => 0,
                'ui' => 1,
            ),
        ),
        'location' => array(
            array(
                array(
                    'param' => 'options_page',
                    'operator' => '==',
                    'value' => 'acf-options-dm-assessment-settings',
                ),
            ),
        ),
        'menu_order' => 0,
        'position' => 'normal',
        'style' => 'default',
        'label_placement' => 'top',
        'instruction_placement' => 'label',
        'hide_on_screen' => '',
        'active' => true,
        'description' => '',
        'show_in_rest' => 0,
    ));
stevep commented 1 year ago

@Jelmerkeij To get the code generated by ACF Builder do print_r($fields->build())

Jelmerkeij commented 1 year ago

@stevep Thanks for the pointer. This morning I've tried all sorts of stuff again and can't get it to work. Even when the output of $fields->build() and input of acf_add_local_field_group() is the same.

This needs some more debugging on my side but since time is not on my side for this project I have resorted to using acf_add_local_field_group() in this particular case. If I ever find the cause and/or solution I'll report back. Thanks for your help so far!

Jelmerkeij commented 1 year ago

This morning I've experienced a similar problem. I am not sure if this is related to the problem I've posted about december last year and at the moment I cannot check or confirm this.

I've named my FieldGroup "Pagina's" (Dutch plural of "Pagina" (page):

$fields = new FieldsBuilder( 'Pagina\'s' );

Now, when WordPress is posting to admin_ajax.php to get the options of the posts (pages) to select it'll post this payload:

action: acf/fields/post_object/query
...
field_key: field_pagina's_privacy <-- The quote is the problem
...
post_id: options

The 'quote' in 'pagina's' caused this problem. Renaming the field name to a name without the quote fixed it:

// Use the `title` groupconfig to show whatever title we want on the frontend and do
// not try to do it with FieldsBuilder `name` argument :-)
$fields = new FieldsBuilder( 'Pages', [ 'title' => 'Pagina\'s' ] );

I hope somebody in the same situation will find this additional info useful.