htmlburger / carbon-fields

WordPress Custom Fields Library ✨
https://carbonfields.net/
Other
1.38k stars 245 forks source link

Programatically updating a complex field in user meta not working #1187

Open basduchambre opened 1 year ago

basduchambre commented 1 year ago

Version

Expected Behavior

Trying to programatically update a complex field for a User. I can update normal fields with update_user_meta() using the carbon fields key prepended by an underscore.

Actual Behavior

Programatically updating the complex field based on the documentation it should update. However the documentation uses carbon_set_post_meta(), but this function does not exists for Users. The workaround is using the WordPress update_user_meta() function.

Container definition

Method used in class:

public function update(\WP_REST_Request $request)
    {
        $parameters = $request->get_params();
        $userId = $parameters['userId'];
        $workExperience = $parameters['workExperience'];
        $result = [];

        if (sizeof($workExperience) === 0) return;

        foreach ($workExperience as $item) {
            $result[] = [
                'company' => $item['company'],
                'position' => $item['position'],
                'start-date' => $item['start-date'],
                'end-date' => $item['end-date'],
                'public' => $item['public'],
                'current-job' => $item['current-job'],
            ];
        }

        try {
            update_user_meta($userId, '_experience', $result);

            return wp_send_json([
                'message' => 'OK'
            ], 200);
        } catch (\Throwable $error) {
            return wp_send_json([
                'message' => 'Something went wrong',
                'error' => $error
            ], 500);
        }
    }

Carbon fields container for user_meta:


        Container::make('user_meta', 'Work experience')
            ->add_fields(array(
                Field::make('complex', 'experience', __('Work experience'))
                    ->add_fields(array(
                        Field::make('text', 'company', __('Company')),
                        Field::make('text', 'position', __('Position')),
                        Field::make('date', 'start-date', __('Start date'))
                            ->set_width(50),
                        Field::make('date', 'end-date', __('End date'))
                            ->set_width(50),
                        Field::make('checkbox', 'public', __('Public on profile?'))
                            ->set_default_value(true)
                            ->set_width(50),
                        Field::make('checkbox', 'current-job', __('Is current job?'))
                            ->set_width(50),
                    ))->setup_labels([
                        'plural_name' => 'work experience',
                        'singular_name' => 'work experience',
                    ])
            ));

Comments

Maybe it is not possible to use update_user_meta() for complex fields? I can not find anyone else experiencing this problem. Again: updating simple text fields is no problem.

basduchambre commented 1 year ago

I did found a workaround, but it requires me to first empty the database with a MySQL query, and then populating the fields using the way WordPress stores information. Not ideal and would be nice if we can get an carbon_set_user_meta() function.

 public function update(\WP_REST_Request $request)
    {
        global $wpdb;
        $parameters = $request->get_params();
        $userId = $parameters['userId'];
        $workExperience = $parameters['workExperience'];

        $query = $wpdb->prepare(
            "DELETE from $wpdb->usermeta 
            where user_id= %d 
            and meta_key like %s",
            $userId,
            '%_experience%'
        );

        if (sizeof($workExperience) === 0) return;

        try {
            // First clear the database
            $wpdb->query($query);

            // Set new work experience
            for ($index = 0; $index < count($workExperience); $index++) {
                $public = $workExperience[$index]['public'] ? 'yes' : 'no';
                $currentJob = $workExperience[$index]['currentJob'] ? 'yes' : 'no';

                update_user_meta($userId, "_experience|company|$index|0|value", $workExperience[$index]['company']);
                update_user_meta($userId, "_experience|position|$index|0|value", $workExperience[$index]['position']);
                update_user_meta($userId, "_experience|start-date|$index|0|value", $workExperience[$index]['startDate']);
                update_user_meta($userId, "_experience|end-date|$index|0|value", $workExperience[$index]['endDate']);
                update_user_meta($userId, "_experience|public|$index|0|value", $public);
                update_user_meta($userId, "_experience|current-job|$index|0|value", $currentJob);
            }

            return wp_send_json([
                'message' => 'OK',
            ], 200);
        } catch (\Throwable $error) {
            return wp_send_json([
                'message' => 'Something went wrong',
                'error' => $error
            ], 500);
        }
    }
basduchambre commented 1 year ago

By the way, if you experience the same issue and trying to use this hacky solution, seperate the 'cleaning' of the database to a different method, since I experience that it may interfere with updating the values.