carbon-fields icon indicating copy to clipboard operation
carbon-fields copied to clipboard

Post meta fields not copying over to different language using WPML

Open ArnoMauriceLieshout opened this issue 5 years ago • 4 comments

Version

  • Carbon Fields:3.1.1
  • WordPress:5.3
  • PHP: 7.3.11

Expected Behavior

When using the overwrite with content form original language or the copy original content the post meta copy's over so you can translate it to the correct language.

Actual Behavior

When using said functions it doesn't copy over anything even after using the wpml-config.xml

Container definition

// Carbon Fields Section Builder
use Carbon_Fields\Container;
use Carbon_Fields\Field;

add_action( 'carbon_fields_register_fields', 'crb_attach_section_builder' );
function crb_attach_section_builder() {

	// -------------------------------------
	// Section builder
	// -------------------------------------
	Container::make( 'post_meta', __( 'Section builder', 'dreamlab' ) )
	->where( 'post_type', 'IN', array( 'post', 'page', 'training', 'review', 'project', 'member' ) )
	->set_context( 'normal' )
	->set_priority( 'high' )
	->add_fields( array(

		// Enable Section Builder
		Field::make( 'checkbox', 'crb_section_builder', __( 'Section builder', 'dreamlab' ) )
		->set_option_value( 'true' )
		->set_default_value( 'false' )
		->set_help_text( __( 'Vink aan om de section builder te gebruiken.', 'dreamlab' ) ),

		// Begin Sections
		Field::make( 'complex', 'section', __( 'Sections', 'dreamlab' ) )
		->set_conditional_logic( array( array(
			'field' => 'crb_section_builder',
			'value' => true,
		) ) )
		->set_collapsed( true )

		// -------------------------------------
		// Test section
		// -------------------------------------
		->add_fields( 'section_test', __( 'Test', 'dreamlab' ), array(
			crb_get_section_title( 'Test', 'For testing purpose' ),

			Field::make( 'text', 'test', __( 'Test field', 'dreamlab' ) ),
			

		) )
		->set_header_template( __( 'Afbeelding', 'dreamlab' ) )

		

		->setup_labels( array(
		'plural_name'   => __( 'Sections', 'dreamlab' ),
		'singular_name' => __( 'Section', 'dreamlab' ),
		) )
	) );

}

Steps to Reproduce the Problem

  • Make sure the Wordpress install contains the classic editor plugin and wpml
  1. Create a page where this container is available
  2. Create a section on the page
  3. Save the page
  4. Copy the page to a secondary language
  5. Overwrite the content with the content form the original language

Comments

To give a little bit of background info.

We have used carbonfields to create a section builder which is a complex field where we can add additional fields which are sections. If it doesn't work or you can't get is to work on a test install it is possible to give acces to our test install.

If I am missing any information or the formatting is wrong please let me know.

ArnoMauriceLieshout avatar Nov 28 '19 14:11 ArnoMauriceLieshout

Hi, I just got into the same issue and found out that WPML considers all meta fields starting with an underscore (_) as « system fields » and thus excludes those from copying.

This happens in the WPML_Custom_Field_Setting_Factory::filter_custom_field_key() method:

class WPML_Custom_Field_Setting_Factory extends WPML_TM_User {
    public $show_system_fields = false;
    private function filter_custom_field_key( $custom_fields_key ) {
        return $this->show_system_fields || '_' !== substr( $custom_fields_key, 0, 1 );
    }
}

ju1ius avatar Jul 08 '22 23:07 ju1ius

It gets even worse: for a term_meta field, WPML synchronizes metadata during the edited_term hook, and carbon-fields during the edited_{$taxonomy} hook.

Since edited_term fires before edited_{$taxonomy}, WPML synchronizes metadata before carbon-fields actually saves the field value. So your translated metadata just received stale values...

ju1ius avatar Jul 09 '22 00:07 ju1ius

So this is what one needs to do in order to make term_meta fields properly synchronize between languages:

add_action('carbon_fields_register_fields', function() {
    $fieldTax = 'some_taxonomy';
    $container = \Carbon_Fields\Container::make('term_meta', 'Foo')
        ->where('term_taxonomy', '=', $fieldTax)
        ->add_fields([
            \Carbon_Fields\Field::make('text', 'bar', 'Bar'),
        ])
    ;
    $properlyHandleTranslations = function(int $termId, int $termTaxonomyId, string $taxonomy) use($container) {
        if ($taxonomy !== $fieldTax) return;
        /** @var \SitePress $sitepress */
        global $sitepress;
        // save field now to fix stale translation metadata
        $container->_save($termId, $termTaxonomyId);
        $action = match (current_filter()) {
            'created_term' => "created_{$taxonomy}",
            'edited_term' => "edited_{$taxonomy}",
        };
        // prevent saving the field twice
        remove_action($action, [$container, '_save'], 10);
        // force WPML to synchronize all metadata
        $sitepress->core_tm()->settings_factory()->show_system_fields = true;
    };
    add_action('created_term', $properlyHandleTranslations, 0, 2);
    add_action('edited_term', $properlyHandleTranslations, 0, 2);
});

Given the amount of hackery required, I think that this claim:

Carbon Fields provide out-of-the-box support for WPML with the small exception of the Theme Options container.

...is unfortunately not true. This library simply does not support WPML out-of-the-box.

ju1ius avatar Jul 09 '22 01:07 ju1ius

Hi, have you found a solution for "postmeta fields", how to translate them with WPML?

AlexShuu avatar Oct 13 '23 01:10 AlexShuu