Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm creating a custom upload field for a wordpress theme that uploads pdf files.The code is:

function custom_news_meta_box($post)
{
    $file_name = get_post_meta($post->ID, 'file_name', true);
    $pdf = get_post_meta($post->ID, 'pdf', true);

    wp_nonce_field('news_meta_nonce', 'news_nonce');
    ?>
    <p>
        <label for="file_name">File Name: </label>
        <input type="text" name="file_name" id="file_name" value="<?php echo $file_name; ?>"/>
    </p>
    <p>
        <label for="pdf">PDF: </label>
        <input type="file" name="pdf" id="pdf" value="<?php echo $pdf; ?>"/>
    </p>
<?php
}

function save_news($post_id)
{
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;

    if (!isset($_POST['news_nonce']) || !wp_verify_nonce($_POST['news_nonce'], 'news_meta_nonce')) return;

    if (isset($_POST['file_name']) && !empty($_POST['file_name'])) {
        update_post_meta($post_id, 'file_name', esc_html($_POST['file_name']));

        if ($_FILES['pdf']['name'] && !$_FILES['pdf']['error']) {
            if (strtolower($_FILES['extension']) != 'pdf') {
                $_SESSION['pdf_error'] = true;
                return;
            }

            if (!file_exists(THEMEROOT . '/downloads/' . $_FILES['pdf']['name'])) {
                move_uploaded_file($_FILES['pdf']['tmp_name'], $_POST['file_name']);
            }

            update_post_meta($post_id, 'pdf', esc_html($_POST['file_name']));
        }
    }
}

The problem is when i update the page the $_FILES is an empty array.I've tried to add multipart/form-data tag to the form

add_action('post_edit_form_tag', 'add_post_enctype');

function add_post_enctype() {
    echo ' enctype="multipart/form-data"';
}

but when i update the page it redirect to post.php.Any solution to my problem?

share|improve this question
    
where is your form tag ? –  pr1nc3 Sep 2 '13 at 11:08
    
should I add a custom form tag? –  Antonio Papa Sep 2 '13 at 11:12
    
excuse me, i can't see in your code the action hook to 'save_post', have you missed it in your code or is it a typo? –  iEmanuele Sep 2 '13 at 13:24
    
i did used it thats not the problem –  Antonio Papa Sep 2 '13 at 13:59

2 Answers 2

up vote 1 down vote accepted

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: http://tobonico.com/
Description: Displays a metabox to attach a PDF file to current post. 
Author: Juan Padial
Version: 1.0
Author URI: http://tobonico.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' ), null, 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 = '<a href="'.wp_get_attachment_url($id).'">'.get_the_title($id).'</a>';

       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.
            jQuery('div#pdf-wrapper').html(obj.pdf);
            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 of this property',
                       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.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;
?>
share|improve this answer
    
Looks very complex how should i use it? –  Antonio Papa Sep 2 '13 at 13:46
    
Download the files in the link at the beginning of the answer and install as any other plugin. You will have a meta box to upload PDF to your posts through the wordpress Media Manager. –  cybmeta Sep 2 '13 at 13:59
    
Great the popup showed but I'm getting this error when I upload the pdf "An error occurred in the upload. Please try again later." –  Antonio Papa Sep 2 '13 at 14:13
    
It is working fine here. The upload process is totally handle by Wodrpess, no by the code I wrote. Can you check your logs and post a little more specific error message? If you go to the normal media manager you can upload PDFs? –  cybmeta Sep 2 '13 at 14:23
    
<pre class='xdebug-var-dump' dir='ltr'> <b>array</b> <i>(size=3)</i> 'a' <font color='#888a85'>=&gt;</font> <small>boolean</small> <font color='#75507b'>true</font> 'pdf_error' <font color='#888a85'>=&gt;</font> <small>boolean</small> <font color='#75507b'>false</font> 'file' <font color='#888a85'>=&gt;</font> <font color='#3465a4'>null</font> </pre>{"success":true,"pdf":""} Unexpected token < –  Antonio Papa Sep 2 '13 at 14:31

I recommend use the WordPress API to upload the file.

function save_news($post_id) {

   if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;

   if (!isset($_POST['news_nonce']) || !wp_verify_nonce($_POST['news_nonce'], 'news_meta_nonce')) return;

   // Make sure the file array isn't empty  
   if(!empty($_FILES['pdf']['name'])) { 

      // Setup the array of supported file types. In this case, it's just PDF.  
      $supported_types = array('application/pdf');  

      // Get the file type of the upload  
      $arr_file_type = wp_check_filetype(basename($_FILES['pdf']['name']));  
      $uploaded_type = $arr_file_type['type'];  

      // Check if the type is supported. If not, throw an error.  
      if(in_array($uploaded_type, $supported_types)) {  

          // Use the WordPress API to upload the file  
          $upload = wp_upload_bits($_FILES['pdf']['name'], null, file_get_contents($_FILES['pdf']['tmp_name']));  

          if(isset($upload['error']) && $upload['error'] != 0) {  
             wp_die('There was an error uploading your file. The error is: ' . $upload['error']);  
          } else {  
            add_post_meta($post_id, 'pdf', $upload);  
            update_post_meta($post_id, 'pdf', $upload);       
          } // end if/else  

       } else {  
          wp_die("The file type that you've uploaded is not a PDF.");  
       } // end if/else  

     } // end if  

 } // end save_news
share|improve this answer
    
still does'nt work... the $_FILES is null –  Antonio Papa Sep 2 '13 at 11:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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