WordPress custom upload field error

You can use the great wordpress media manager. I’ve prepared a plugin to attach PDF files to noraml posts. You can download it here.

The php:

<?php

/*
Plugin Name: PDF Metabox
Plugin URI: https://github.com/CybMeta/cyb-pdf-metabox
Description: Displays a metabox to attach a PDF file to current post. 
Author: Juan Padial
Version: 1.0.2
Author URI: http://cybmeta.com
*/

class PDF_Metabox
{

    /**
     * This is our constructor
     *
     * @return PDF_Metabox
     */
    public function __construct() {

        add_action( 'post_mime_types',         array( $this, 'pdf_mime_type'    )    );
        add_action( 'add_meta_boxes',          array( $this, 'admin_scripts'   ), 5 );
        add_action( 'add_meta_boxes',          array( $this, 'metabox_add'     )    );
        add_action( 'save_post',               array( $this, 'pdf_save_postdata') );
        add_action( 'wp_ajax_refresh_pdf',     array( $this, 'refresh_pdf' )    );

    }

    public function pdf_mime_type() {
            $post_mime_types['application/pdf'] = array( __( 'PDFs' ), __( 'Manage PDFs' ), _n_noop( 'PDF <span class="count">(%s)</span>', 'PDFs <span class="count">(%s)</span>' ) );
            return $post_mime_types;
    }

    public function admin_scripts() {

        wp_register_script( 'pdf-metabox-js', plugins_url( '/lib/js/pdf-metabox.js', __FILE__ ) , array( 'jquery' ), '1.0.2', true );

    }

    public function metabox_add() {
        // Filterable metabox settings. 
        $post_types     = array( 'post');
        $context="normal";
        $priority       = 'low';

        // Loop through all post types
        foreach( $post_types as $post_type ) {

                // Add Metabox
                add_meta_box( 'pdf_metabox', __( 'PDF', 'pdf-metabox' ), array( $this, 'pdf_metabox' ), $post_type, $context, $priority );
                // Add Necessary Scripts and Styles
                wp_enqueue_media();
                wp_enqueue_script( 'pdf-metabox-js' );

        }
    }


    public function pdf_metabox( $post ) {
        $original_post = $post;
        echo $this->pdf_metabox_html( $post->ID );
        $post = $original_post;
    }

    public function pdf_item( $id ) {
           if(!$id) return;
           $pdf_url = esc_url_raw(wp_get_attachment_url($id));
            $pdf="<object data="".$pdf_url.'" type="application/pdf" height="580" width="100%">
                <iframe src="https://docs.google.com/viewer?url=".$pdf_url."&amp;embedded=true" width="100%" height="580" frameborder="0"></iframe>
                <p><a href="'.$pdf_url.'">'.get_the_title($id).'</a></p>
            </object>';

           return $pdf;

    }


    public function pdf_metabox_html( $post_id ) {

            $current_value="";
        $post_meta = get_post_custom($post_id);
        if( isset($post_meta['pdf-id'][0] ) ) $current_value = $post_meta['pdf-id'][0];
        $return = '';
        //Nonce for verification
                wp_nonce_field( plugin_basename( __FILE__ ), 'pdf_noncename' );

        $return  .= '<p>';
        $return  .= '<a title="'.__( 'PDF', 'pdf-metabox' ).'" class="button button-primary insert-pdf-button" id="insert-pdf-button" href="#" style="float:left">'.__( 'Upload PDF', 'pdf-metabox' ).'</a><span id="pdf-spinner" class="spinner" style="float:left"></span></p>';
        $return  .= '<div style="clear:both"></div>';
        $return  .= '<input type="hidden" name="pdf-id" id="pdf-id" value="'.$current_value.'">';
        $return  .= '<div style="clear:both"></div>';

                $return .= '<div id="pdf-wrapper">';

                $pdf = $this->pdf_item( $current_value );
        if( empty( $pdf ) ) {
            $return .= '<p>No pdf.</p>';
                } else {
               $return .= $pdf;
        }

                $return .= '</div>';

        return $return;
    }


        public function pdf_save_postdata($post_id){

               // First we need to check if the current user is authorised to do this action.
           //Currently capabilities of property post type is the same as normal post type
          if ( isset($_POST['post_type']) && 'post' == $_POST['post_type'] ) {
            if ( !current_user_can( 'edit_post', $post_id ) ) return;
           }

         // Secondly we need to check if the user intended to change this value.
         if ( !isset( $_POST['pdf_noncename'] ) || ! wp_verify_nonce( $_POST['pdf_noncename'], plugin_basename( __FILE__ ) ) )
            return;

            // Thirdly we can save the value to the database
        if(isset($_POST['pdf-id']) ):
                //Don't forget sanitize
            update_post_meta($post_id, 'pdf-id', sanitize_text_field( $_POST['pdf-id'] ) );
        else:
            if (isset($post_id)) {
              delete_post_meta($post_id, 'pdf-id');
            }
        endif;  

        }


    public function refresh_pdf() {
             if(isset($_POST['id'])){
        $item = $_POST['id'];
        if($item != '' && $item !=0){
          $pdf = $this->pdf_item( $item );
          $ret = array();

          if( !empty( $pdf ) ) {
            $ret['success'] = true;
            $ret['pdf'] = $pdf;
          } else {
            $ret['success'] = false;
          }
        } else {
           //Is success but the $_POST['ids'] is empty, maybe deleting deattiching files so:
           $ret['success'] = true;
               $ret['pdf'] = '';
        }
          } else {
            $ret['success'] = false;
          }

          echo json_encode( $ret );
          die();

    }

}


// Instantiate our class
$PDF_Metabox = new PDF_Metabox();

?>

The javascript:

// **************************************************************
// Refresh pdf function - fired when a new pdf is selectd
// **************************************************************

function Refresh_PDF(the_ids){
                jQuery('#pdf-spinner').css('display','inline');

        var data = {
            action: 'refresh_pdf',
            id: the_ids
        };

        jQuery.post(ajaxurl, data, function(response) {
            var obj;
            try {
                obj = jQuery.parseJSON(response);
            }
            catch(e) {  // bad JSON catch
                // add some error messaging ?
                }

            if(obj.success === true) { // it worked. AS IT SHOULD.
                if( obj.pdf != '' ) {
                    jQuery('div#pdf-wrapper').html(obj.pdf);
                } else {
                    jQuery('div#pdf-wrapper').html('');
                }
                jQuery('#pdf-spinner').css('display','none');
                // add some success messaging ?
            }
            else {  // something else went wrong
                // add some error messaging ?
            }
        });
}

// **************************************************************
// now start the engine
// **************************************************************

jQuery(document).ready( function($) {

      jQuery('#insert-pdf-button').click(function(e) {

             e.preventDefault();
             var frame = wp.media({
                           title : 'Pick the PDF to attach to this entry',
                           frame: 'select',
                           multiple : false,
                           library : {
                                     type : 'application/pdf'
                                     },
                           button : { text : 'Insert' }
                       });

                       frame.on('close',function() {
                          // get selections and save to hidden input plus other AJAX stuff etc.
                          var selection = frame.state().get('selection');
                          var pdf_ids = new Array();
                          var my_index = 0;
                          selection.each(function(attachment) {
                             pdf_ids[my_index] = attachment['id'];
                             my_index++;
                          });
                          var ids = pdf_ids.join(",");
                          jQuery('#pdf-id').val(ids);
                          Refresh_PDF(ids);
                       });

                      frame.on('open',function() {
                        var selection = frame.state().get('selection');
                        ids = jQuery('#pdf-id').val().split(',');
                        ids.forEach(function(id) {
                          attachment = wp.media.attachment(id);
                          attachment.fetch();
                          selection.add( attachment ? [ attachment ] : [] );
                        });
                      });

                      frame.on('toolbar:create:select',function() {
                        frame.state().set('filterable', 'uploaded');
                      });

                    frame.open();
     })

});

The plugin stores the ID of the attached PDF file in the meta field “pdf-id”. To get it in the front end you can use different ways. For example, if you are inside the loop you can use:

<?php 
$post_meta = get_post_custom(get_the_ID());
    $pdf_id   = $post_meta['pdf-id'][0];
    $pdf_url  = wp_get_attachment_url($pdf_id);
    echo $pdf_url;
?>

Leave a Comment