0

I have a Custom Post Type (Favourites) which I plan on using to talk about my favourite craft products. The meta box field I want to have is a link to an online store listing, so users can buy the product themselves if they so choose.

The following is the definition for both the Custom Post Type and the desired field (it's essentially a text box).

<?php

    function declare_custom_post_type() {
        $theme_name = 'thatannalam';
        $custom_post_type = 'favourites';

        $labels = array(
            'name'               => __('Favourites', $theme_name),
            'singular_name'      => __('Favourite', $theme_name),
            'add_new'            => __( 'Add New Favourite' ),
            'add_new_item'       => __( 'Add New Favourite' ),
            'edit_item'          => __( 'Edit Favourite' ),
            'new_item'           => __( 'Add New Favourite' ),
            'view_item'          => __( 'View Favourite' ),
            'search_items'       => __( 'Search EvFavouriteent' ),
            'not_found'          => __( 'No favourites found' ),
            'not_found_in_trash' => __( 'No favourites found in trash' )
        );

        $args = array(
            'description' => __( 'Movie news and reviews', $theme_name),
            'exclude_from_search' => false,
            'labels' => $labels,
            'has_archive' => true,
            'hierarchical' => false,
            'public' => true,
            'register_meta_box_cb' => 'register_meta_box',
            'rewrite' => array('slug', $custom_post_type),
            'show_in_admin_bar' => true,
            'show_in_menu' => true,
            'show_in_nav_menus' => true,
            'show_in_rest' => true,
            'show_ui' => true,
            'supports' => array('title', 'editor', 'custom-fields')
        );

        register_post_type($custom_post_type, $args);
    }
    add_action('init', 'declare_custom_post_type');

    function register_meta_box() {
        add_meta_box(
            'favourite_details_box',
            'Favourite Details',
            'render_meta_html',
            'favourites',
            'side'
        );
    }

    function render_meta_html() {
        global $post;
        $nonce_key = 'favourite_fields_nonce';
        $link_meta_key = 'product_link_key';

        wp_nonce_field($nonce_key, $nonce_key);

        $link = get_post_meta( $post->ID, $link_meta_key, true );
        echo '<label for="product_link_field" class="widefat">Product Link</label><input type="text" id="product_link_field" name="product_link_field" class="widefat" value="'.$link.'">';
    }

    function save_favourite_meta($post_id, $post) {
        $nonce_key = 'favourite_fields_nonce';
        $link_meta_key = 'product_link_key';
        $link_field_name = 'product_link_field';
        $custom_post_type = 'favourites';

        // verify nonce
        if (!isset($_POST[$nonce_key]) || !wp_verify_nonce($_POST[$nonce_key], $nonce_key))
            return 'nonce not verified';

        // check autosave
        if (wp_is_post_autosave($post_id ))
            return 'autosave';

        //check post revision
        if (wp_is_post_revision($post_id))
            return 'revision';

        // check permissions
        if ( ! current_user_can( 'edit_post', $post_id ) ) {
            return 'cannot edit post';
        }

        $product_link = $_POST[$link_field_name];
        
        if (metadata_exists($custom_post_type, $post_id, $link_meta_key)) {
            update_post_meta($post_id, $link_meta_key, $product_link);
        } else {
            add_post_meta($post_id, $link_meta_key, $product_link);
        }
    }

    add_action( 'save_post', 'save_favourite_meta');
?>

The 2 parts that are messing with my head are:

  • Retrieving a saved value. It's currently returning a blank.
  • Saving a value to the DB. I must be missing something here as I've been getting an "Updating failed." error every time I try to save a record.

1 Answer 1

0

I changed your code and its now working fine in my pc. here is the code

<?php

    function declare_custom_post_type() {
        $theme_name = 'thatannalam';
        $custom_post_type = 'favourites';

        $labels = array(
            'name'               => __('Favourites', $theme_name),
            'singular_name'      => __('Favourite', $theme_name),
            'add_new'            => __( 'Add New Favourite' ),
            'add_new_item'       => __( 'Add New Favourite' ),
            'edit_item'          => __( 'Edit Favourite' ),
            'new_item'           => __( 'Add New Favourite' ),
            'view_item'          => __( 'View Favourite' ),
            'search_items'       => __( 'Search EvFavouriteent' ),
            'not_found'          => __( 'No favourites found' ),
            'not_found_in_trash' => __( 'No favourites found in trash' )
        );

        $args = array(
            'description' => __( 'Movie news and reviews', $theme_name),
            'exclude_from_search' => false,
            'labels' => $labels,
            'has_archive' => true,
            'hierarchical' => false,
            'public' => true,
            'register_meta_box_cb' => 'register_meta_box',
            'rewrite' => array('slug', $custom_post_type),
            'show_in_admin_bar' => true,
            'show_in_menu' => true,
            'show_in_nav_menus' => true,
            'show_in_rest' => true,
            'show_ui' => true,
            'supports' => array('title', 'editor', 'custom-fields')
        );

        register_post_type($custom_post_type, $args);
    }
    add_action('init', 'declare_custom_post_type');

    function register_meta_box() {
        add_meta_box(
            'favourite_details_box',
            'Favourite Details',
            'render_meta_html',
            'favourites',
            'side'
        );
    }

    function render_meta_html() {
        global $post;
        $nonce_key = 'favourite_fields_nonce';
        $link_meta_key = 'product_link_key';

        wp_nonce_field($nonce_key, $nonce_key);

        $link = get_post_meta( $post->ID, $link_meta_key, true );
        echo '<label for="product_link_field" class="widefat">Product Link</label><input type="text" id="product_link_field" name="product_link_field" class="widefat" value="'.$link.'">';
    }

    function save_favourite_meta($post_id, $post) {
        $nonce_key = 'favourite_fields_nonce';
        $link_meta_key = 'product_link_key';
        $link_field_name = 'product_link_field';
        $custom_post_type = 'favourites';

        // verify nonce
        if (!isset($_POST[$nonce_key]) || !wp_verify_nonce($_POST[$nonce_key], $nonce_key))
            return 'nonce not verified';

        // check autosave
        if (wp_is_post_autosave($post_id ))
            return 'autosave';

        //check post revision
        if (wp_is_post_revision($post_id))
            return 'revision';

        // check permissions
        if ( ! current_user_can( 'edit_post', $post_id ) ) {
            return 'cannot edit post';
        }

        $product_link = $_POST[$link_field_name];            
            update_post_meta($post_id, $link_meta_key, $product_link);        
    }

    add_action( 'save_post', 'save_favourite_meta', 10,2);
?>

I changed 2 things:

  1. we must have to pass a number of arguments to add_action() function.
  2. only used update_post_meta() function.

Be careful if you want to use update_post_meta() and add_post_meta() both together. because in your code it saves value multiple times in the database.

1
  • Thanks for that Ravi! It works fine now.
    – Anna Lam
    Commented Nov 29, 2021 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.