Support

Account

Home Forums ACF PRO update_field returning large int instead of bool

Solving

update_field returning large int instead of bool

  • I’m using ACF Pro to create a Learning Management System. I’ve only recently started having problems. The main one that’s giving me the most trouble is that update_field() is not actually updating the field, despite me giving it accurate information and it working on a local environment (but not a WP Engine Dev environment).

    Currently I’m allowing the user to create a new Course (or “Module”), based on a previous one, specifically for their class. They choose which students they’ll be including, the Module to use a template, then the Chapters (or “Documents”) from that Module.

    Then, on the final screen, they review information, and the “Submit” button starts through a series of AJAX calls that sends the information to the server, sends back the pertinent info, then moves on to the next step.

    I’m sending back the results from each delete_field() and update_field command. When replacing values, I am deleting the current value (with delete_field()) before using update_field(). This has helped some of my issues, but not all.

    Here is the pertinent PHP code:

    
    <?php
    // I've made the CPT "Module" its own Class to contain its helper methods 
    $module = new ACF_Module( intval($module_id) );
    
    // I store the Documents (or "Chapters") for each Module (or "Course") as a 
    //     repeater field containing the document_id and the order it should 
    //     appear within the Module.
    $document_ids = json_decode( $_POST['document_ids']);
    $documents_field = [];
    $count = 1;
    
    foreach( $document_ids as $document_id ) {
        $documents_field[] = [
            'document_id' => intval($document_id),
            'order' => floatval($count),
        ];
        $count++;
    }
    
    // In JS, $documents_field_deleted = (bool) true
    $documents_field_deleted = delete_field($module->documents_field, $module->ID);
    
    // In JS, $documents_field_updated = (int) 625785,, or a similarly large number,
    //     which does not correlate to ANY existing post ID or user ID, as the 
    //     newest post_id in this example is 43113 and largest user ID is 1126
    $documents_field_updated = update_field($module->documents_field, $documents_field, $module->ID);
    

    I don’t know that this will matter, but just in case, here’s my JS doing the AJAX calls:

    
    // Triggered when clicking submit button labelled "Next"
    $('#submit').click(function(e){
        e.preventDefault();
    
        // I'm just storing values in hidden <code><input></code> fields. Since these 
        //     classes are all taken on a job-site, where the student is 
        //     monitored, I'm not concerned as much for the user being able to 
        //     change these.
        var nextAction = '';
        actionStep = $('input[name="acf_action_step"]').val();
    
        var payload = {
            action: 'acf_action_function_name',
            action_step: actionStep,
            agency_id: parseInt($('input[name="acf_agency_id"').val()),
            module_id: parseInt($('input[name="acf_module"]').val())
        };
    
        switch (actionStep) {
            case 'module':
                payload.module_title = $('input[name="acf_module_title"]').val();
                nextAction = 'chapters';
                break;
            case 'chapters':
                payload.chapter_ids = $('input[name="acf_chapters"]').val();
                nextAction = 'user';
                break;
            case 'user':
                var user_object = JSON.parse( $('input[name="acf_users"').val() );
                nextAction = 'user';
    
                if( user_object.length == 1 ) {
                    nextAction = 'finish';
                }
    
                payload.user_id = parseInt( user_object.shift() );
                user_ids = JSON.stringify(user_object);
                $('input[name="acf_users"]').val(user_ids);
                break;
            case 'finish':
                $('#submit').prop('disabled', true);
                $('#submit').addClass('disabled');
                return;
            default:
                break;
        }
    
        $.ajax({
            url: ajax_object.ajax_url,
            type: 'post',
            data: payload,
            beforeSend: function(){            
                $('#submit').prop('disabled', true);
                $('#submit').addClass('disabled');
            },
            success: function(response) {
                var response_object = JSON.parse(response);
                progress.append(response_object.message);
    
                if( response_object.new_module_id ) {
                    $('input[name="acf_module"]').val( parseInt(response_object.new_module_id) );
                }
            },
            complete: function(response) {
                $('input[name="acf_action_step"]').val( nextAction );
                $('#submit').prop('disabled', false);
                $('#submit').removeClass('disabled');
            }
        });
    
        return;
    });
    
  • I am assuming since the value is an array you are updating some type of field that has sub fields.

    When you use delete_field() this delete the field and the field key reference for the field and makes the field as if it never existed.

    When using update_field() for any field that does not already have a value in the database you must use field keys. You must use the field key for the repeater and you must supply a value that is an array of field_key => value pairs.

    See the section on updating via field keys on this page https://www.advancedcustomfields.com/resources/update_field/

  • @hube2 That’s good to know. I actually ended up arriving at that solution a while ago, so I am using field keys, but the issue keeps happening.

    I don’t think I can edit my original post anymore, but the ACF_Module class has those field keys stored as parameters (so I don’t have to keep changing it everywhere). So near the end of my PHP code, $module->documents_field is the same as field_6255b86755ad6.

    Here is an example set of data for $documents_field:

    
    $documents_field = [
        [ 'document_id' => 2241, 'module_id' => 201, 'order' => 1.0 ],
        [ 'document_id' => 2242, 'module_id' => 201, 'order' => 2.0 ],
        [ 'document_id' => 2243, 'module_id' => 201, 'order' => 3.0 ],
    ];
    
    $documents_field_deleted = delete_field('field_6255b86755ad6', 201);
    
    $documents_field_updated = update_field('field_6255b86755ad6', $documents_field, 201);
    

    I’m even making sure that each int is an int or float by using the intval() and floatval() functions. But for some reason, this isn’t working.

    Not sure if this helps, but here’s the declaration and constructor for my ACF_Module class:

    
    // ACF_Post is another custom class that just contains the same parameters as the WP_Post object, which isn't extendable
    class ACF_Module extends ACF_Post
    {
        public $documents = [];
        public $post_type = 'acf_module';
    
        public $documents_field = 'field_6255b86755ad6';
    
        public function __construct($post_id, $attr = [], $module_id = -1)
        {
            $post_id = intval($post_id);
    
            parent::__construct($post_id, $attr);        
            $this->documents   = !empty(get_field($this->documents_field, $post_id))   ? get_field($this->documents_field, $post_id) : false;
        }
    // [...]
    }
    
  • ‘document_id’, ‘module_id’, ‘order’ all must be field keys as well.

  • @hube2 That works.

    Also I think I actually fixed the issue by correcting a typo that isn’t included in my code sample above. So this can be closed as “solved”.

    But I am still curious: do you know why update_field() would return an int instead of bool?

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.