How to save ACF custom field alongside when a plugin auto publishes a post

Viewed 31

To give context to what I am doing, I have a plugin which scrapes data from another website. So I created the two fields in anticipation of the data which goes into the ACF custom fields. Everything is fine except that I am having to manually refresh each post page in admin so that the ACF custom fields are saved to the postmeta table. Right now the data appears to display in the custom fields as placeholder/default. But when I refresh, data is saved in the db. I hope to achieve: Saving data into the database both for the new posts and existing posts.

The code:

<?php

add_filter('acf/load_field/name=application_email', function ($field) {
    $howtoapply = get_field('howtoapply');
    if (get_post_meta($post->ID, 'application_email', true) == '') {

        $apply_link = get_field('howtoapply');

        $link = $apply_link;
        libxml_use_internal_errors(true);
        $dom = new DOMDocument();
        @$dom->loadHTML($link);
        $dom->loadHTML($link);
        foreach ($dom->getElementsByTagName("a") as $a) {
        }

        function cfDecodeEmail($encodedString)
        {
            $k = hexdec(substr($encodedString, 0, 2));
            for ($i = 2, $email = ''; $i < strlen($encodedString) - 1; $i += 2) {
                $email .= chr(hexdec(substr($encodedString, $i, 2)) ^ $k);
            }
            return $email;
        }

        if (!is_null($a) && is_object($a)) {

            $field['value'] = cfDecodeEmail($a->getAttribute('data-cfemail'));
            $GLOBALS[$field['value']] = cfDecodeEmail($a->getAttribute('data-cfemail'));

            if (!add_post_meta(get_the_ID(), 'application_email', $field['value'])) {
                update_post_meta(get_the_ID(), 'application_email', $field['value']);
            }
        } else {
            echo '';
        }
    }

    return $field;
});

With thanks

1 Answers

I believe your issue is this hook us running after the the post_meta fields have already been loaded by Wordpress. This is why you're seeing them on a page refresh.

I believe what you're after is so save the post_meta fields at the point where the ACF fields are updated. so change your hook to acf/update_field/name

<?php

add_filter('acf/update_field/name=application_email', function ($field) {
    $howtoapply = get_field('howtoapply');
    if (get_post_meta($post->ID, 'application_email', true) == '') {

        $apply_link = get_field('howtoapply');

        $link = $apply_link;
        libxml_use_internal_errors(true);
        $dom = new DOMDocument();
        @$dom->loadHTML($link);
        $dom->loadHTML($link);
        foreach ($dom->getElementsByTagName("a") as $a) {
        }

        function cfDecodeEmail($encodedString)
        {
            $k = hexdec(substr($encodedString, 0, 2));
            for ($i = 2, $email = ''; $i < strlen($encodedString) - 1; $i += 2) {
                $email .= chr(hexdec(substr($encodedString, $i, 2)) ^ $k);
            }
            return $email;
        }

        if (!is_null($a) && is_object($a)) {

            $field['value'] = cfDecodeEmail($a->getAttribute('data-cfemail'));
            $GLOBALS[$field['value']] = cfDecodeEmail($a->getAttribute('data-cfemail'));

            if (!add_post_meta(get_the_ID(), 'application_email', $field['value'])) {
                update_post_meta(get_the_ID(), 'application_email', $field['value']);
            }
        } else {
            echo '';
        }
    }

    return $field;
});

You may had to modify the function a function a little because you're depending on another field howtoapply which may not exist, depending on the order of operations.

Related