0

I have created the following class in order to add a custom metabox for my posts, but the data is not being saved. Anybody can say what's wrong with my code?

class Anotai_Meta_Box {
    public $prefix = 'anotai';

    public function __construct() {
        if ( is_admin() ) {
            add_action( 'load-post.php', array( $this, 'init_metabox' ) );
            add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
        }
    }

    public function fields() {
        return array(
            array( 'nome' => 'Título', 'placeholder' => 'Insira o título do evento' ),
            array( 'nome' => 'Descrição', 'placeholder' => 'Descreva o evento em poucas palavras.', 'nota' => 'Opcional' ),
            array( 'nome' => 'Data', 'placeholder' => 'dd/mm/aaaa' ),
            array( 'nome' => 'Data amigável', 'placeholder' => 'Insira a data de uma maneira mais amigável para as pessoas.' ),
            array( 'nome' => 'Endereço', 'placeholder' => '' )
        );
    }

    public function init_metabox() {
        add_action( 'add_meta_boxes', array( $this, 'add_metabox' ) );
        add_action( 'save_post', array( $this, 'save_metabox', 10, 2 ) );
    }

    public function add_metabox() {
        add_meta_box(
            $this->prefix . 'anotai',
            'Anotaí',
            array( $this, 'render_metabox' ),
            'post',
            'advanced',
            'default'
        );
    }

    public function input( $field, $post_id ) {
        $name = str_replace( '-', '_', sanitize_title( $field['nome'] ) );
        $label = $field['nome'];
        $value = json_decode( get_post_meta( $post_id, 'anotai', true ) );
        $placeholder = $field['placeholder'];
        echo '<tr>';
        echo "  <th><label for='{$name}' class='{$name}_label'>{$label}</label></th>";
        echo "  <td>";
        echo "  <input type='text' autocomplete='off' name='anotai[{$name}]' value='{$value[$name]}' placeholder='{$placeholder}' class='large-text'>";
        echo ( ! empty( $field['nota'] ) ) ? "<span class='description'>{$field['nota']}</span>": '';
        echo "  </td>";
        echo '</tr>';
    }

    public function render_metabox( $post ) {
        var_dump(get_post_meta( $post->ID ));
        wp_nonce_field( 'anotai_nonce_action', 'anotai_nonce' );
        echo '<table class="form-table">';
        foreach ( $this->fields() as $field ) {
            $this->input( $field, $post->ID );
        }
        echo '</table>';
    }

    public function save_metabox( $post_id, $post ) {
        $nonce_name   = $_POST['anotai_nonce'];
        $nonce_action = 'anotai_nonce_action';
        if ( ! isset( $nonce_name ) )
            return;

        if ( ! wp_verify_nonce( $nonce_name, $nonce_action ) )
            return;


        if ( ! current_user_can( 'edit_post', $post_id ) )
            return;

        if ( wp_is_post_autosave( $post_id ) )
            return;

        if ( wp_is_post_revision( $post_id ) )
            return;

        foreach ( $_POST['anotai'] as $key => $value ) {
            $_POST['anotai'][$key] = sanitize_text_field( $value );
        }

        update_post_meta( $post_id, 'anotai', json_encode( $_POST['anotai'] ) );

    }

}

new Anotai_Meta_Box;
2
add_action( 'save_post', array( $this, 'save_metabox', 10, 2 ) );

should be

add_action( 'save_post', array( $this, 'save_metabox' ), 10, 2 );

If you enable debugging, you'll see a call_user_func_array error generated by this.

Also, a few other things-

You should check if $_POST['anotai_nonce'] is set before trying to use it in assignment on the first line of your save_metabox function.

You don't need to json encode the data, arrays will get serialized/unserialized automatically and can be passed directly to the post meta functions.

If you prefix the meta key with an underscore, it'll be hidden from the default Custom Fields meta box.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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