Support

Account

Home Forums Backend Issues (wp-admin) Validate_value fails with get_field_object is used

Solved

Validate_value fails with get_field_object is used

  • I’m making a filter for a custom post type that has two fields; start date and end date. I don’t want the end date to be a date before the start date, so I made a filter:

    <?php
    add_filter('acf/validate_value/key=end_Date', 'validationEndDate', 10, 4);
    
        public function validationEndDate($valid, $value, $field, $input)
        {
            // bail early if value is already invalid
            if (
                !$valid
                OR $field['type'] != 'date_time_picker'
                OR empty($value)
            ) {
                return $valid;
            }
    
            $startDate = $_POST['acf']['field_5a44cac20461f'] ?? null;
    
            if(empty($startDate)) {
                return $valid;
            }
    
            if(strtotime($startDate) > strtotime($value)){
                $valid = __("The date must be before the start date.");
            }
    
            return $valid;
        }
    

    This code is working and have the expected behavior. However to make this code more reusable I tried to make use of get_field_object() (changes I made from the code above):

    <?php
            $startDateObj = get_field_object('start_date', false, false, false);
            $key = $startDateObj['key'] ?? null;
            $startDate = $_POST['acf'][$key] ?? null;
    

    The issue with his code is that I get redirected to /wp-admin/post.php with the following text and saves the value that shouldn’t be valid:

    Validation failed

    The date must be before the start date.

    But if I add the old implementation after get_field_object(), it works as expected and will not redirect to post.php (added only the last row:

    <?php
            $startDateObj = get_field_object('start_date', false, false, false);
            $key = $startDateObj['key'] ?? null;
            $startDate = $_POST['acf'][$key] ?? null;
    
            $startDate = $_POST['acf']['field_5a44cac20461f'] ?? null;
    

    I find this wired and I have no clue why it behaves in this way. Especially when both methods returns the expected value:

    <?php
            echo 'Obj start date: ';
            var_dump($_POST['acf'][$key]);
            echo '<br>';
    
            echo 'Static start date: ';
            var_dump($_POST['acf']['field_5a44cac20461f']);
    

    Result:

    Obj start date: string(19) “2018-10-09 00:00:00”
    Static start date: string(19) “2018-10-09 00:00:00”

    Does any know what’s the issue?

    Wordpress 4.9.9
    ACF Pro 5.7.9

  • The reason that you’re getting the validation error page is that the validation is causing a PHP error during the AJAX validation request and making the AJAX fail.

    Your error is here

    
    $startDateObj = get_field_object('start_date', false, false, false);
    

    Since the field has never been saved, get_field_object() using the field name fails and returns false. You must use the field key. Since the value of $startDateObj is false this line is causing a PHP error

    
    $key = $startDateObj['key'] ?? null;
    

    Because ‘key’ is an undefined index, in a value that is not an array.

  • There is no PHP errors and wp_debug is enabled. If I run this:

    <?php
            $startDateObj = get_field_object('start_date', false, false, false);
            echo 'Obj<br>';
            var_dump($startDateObj);
    
            $key = $startDateObj['key'] ?? null;
    
            echo 'Key<br>';
            var_dump($key);
    
            $startDate = $_POST['acf'][$key] ?? null;
    
            echo 'StartDate<br>';
            var_dump($_POST['acf'][$key]);
            exit;
    

    Results in this:

    Obj
    array(22) {
    [“ID”]=>
    int(0)
    [“key”]=>
    string(19) “field_5a44cac20461f”
    [“label”]=>
    string(10) “Start date”
    [“name”]=>
    string(10) “start_date”
    [“prefix”]=>
    string(3) “acf”
    [“type”]=>
    string(16) “date_time_picker”
    [“value”]=>
    NULL
    [“menu_order”]=>
    int(1)
    [“instructions”]=>
    string(0) “”
    [“required”]=>
    int(1)
    [“id”]=>
    string(0) “”
    [“class”]=>
    string(0) “”
    [“conditional_logic”]=>
    array(1) {
    [0]=>
    array(1) {
    [0]=>
    array(3) {
    [“field”]=>
    string(19) “field_5b33474da2033”
    [“operator”]=>
    string(2) “==”
    [“value”]=>
    string(5) “theme”
    }
    }
    }
    [“parent”]=>
    string(19) “group_5a44bc8cad892”
    [“wrapper”]=>
    array(3) {
    [“width”]=>
    string(2) “50”
    [“class”]=>
    string(0) “”
    [“id”]=>
    string(0) “”
    }
    [“_name”]=>
    string(10) “start_date”
    [“_prepare”]=>
    int(0)
    [“_valid”]=>
    int(1)
    [“admin_only”]=>
    int(0)
    [“display_format”]=>
    string(12) “F j, Y H:i:s”
    [“return_format”]=>
    string(11) “Y-m-d H:i:s”
    [“first_day”]=>
    int(1)
    }

    Key
    string(19) “field_5a44cac20461f”

    StartDate
    string(19) “2018-10-09 00:00:00”

    I’m updating an existing post.

  • The page you mention is only shown when ACF gets some unexpected response from the AJAX request. This is usually caused by some type of error, but any unexpected output will cause it. It can be very hard to track it down. My suggestion would be to back up to where it’s working correctly and then add 1 thing/line at a time to see what line causes the issue and then figure out what’s wrong with it.

  • I have figured out what’s wrong:

    $startDateObj = get_field_object('start_date', false, false, false) ?? null;
    $key = $startDateObj['key'] ?? null;
    $startDate = $_POST['acf'][$key] ?? null;
    
    if(empty($startDate)) {
        return $valid;
    }

    On the ajax call, it will be return as valid because get_field_object() returns false, therefor $key and $startDate will both have value null (not undefined index) and in the end empty($startDate) will be true. Which means it will pass the Ajax validation but, will fail when it runs the PHP validation because get_field_object() will not return false.

    Is there a way to fetch fields structure without relying on existing post? To have a list of static keys is not a good solution is in this case and I woludn’t want to add a custom javascript validation on top of AFC.

  • the ACF hook passes the current field, but it will not help you get a value from another field.

    If the field has been set before you need to supply the field name and then post ID. The post ID is available in one of the other $_POST values, I don’t recall at the moment what the index is.

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

You must be logged in to reply to this topic.