Adjuntar archivo PDF a un tipo de contenido personalizado
Estoy tratando de adjuntar un archivo PDF a un tipo de contenido personalizado.
Encontré este fragmento de código en wpsnipp.com.
El código funciona, pero solo para entradas.
Tengo un tipo de contenido personalizado llamado 'events' y no puedo hacer que funcione.
add_action("admin_init", "pdf_init");
add_action('save_post', 'save_pdf_link');
function pdf_init(){
add_meta_box("my-pdf", "Documento PDF", "pdf_link", "post", "normal", "low");
}
function pdf_link(){
global $post;
$custom = get_post_custom($post->ID);
$link = $custom["link"][0];
$count = 0;
echo '<div class="link_header">';
$query_pdf_args = array(
'post_type' => 'attachment',
'post_mime_type' =>'application/pdf',
'post_status' => 'inherit',
'posts_per_page' => -1,
);
$query_pdf = new WP_Query( $query_pdf_args );
$pdf = array();
echo '<select name="link">';
echo '<option class="pdf_select">SELECCIONAR archivo PDF</option>';
foreach ( $query_pdf->posts as $file) {
if($link == $pdf[]= $file->guid){
echo '<option value="'.$pdf[]= $file->guid.'" selected="true">'.$pdf[]= $file->guid.'</option>';
}else{
echo '<option value="'.$pdf[]= $file->guid.'">'.$pdf[]= $file->guid.'</option>';
}
$count++;
}
echo '</select><br /></div>';
echo '<p>Seleccione un archivo PDF de la lista anterior para adjuntarlo a esta entrada.</p>';
echo '<div class="pdf_count"><span>Archivos:</span> <b>'.$count.'</b></div>';
}
function save_pdf_link(){
global $post;
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){ return $post->ID; }
update_post_meta($post->ID, "link", $_POST["link"]);
}
add_action( 'admin_head', 'pdf_css' );
function pdf_css() {
echo '<style type="text/css">
.pdf_select{
font-weight:bold;
background:#e5e5e5;
}
.pdf_count{
font-size:9px;
color:#0066ff;
text-transform:uppercase;
background:#f3f3f3;
border-top:solid 1px #e5e5e5;
padding:6px 6px 6px 12px;
margin:0px -6px -8px -6px;
-moz-border-radius:0px 0px 6px 6px;
-webkit-border-radius:0px 0px 6px 6px;
border-radius:0px 0px 6px 6px;
}
.pdf_count span{color:#666;}
</style>';
}
function pdf_file_url(){
global $wp_query;
$custom = get_post_custom($wp_query->post->ID);
echo $custom['link'][0];
}
Y para mostrar el enlace en el tema:
<? pdf_file_url(); ?>
Cambié el tipo de contenido de 'post' a 'events' y el meta box aparece en la página de 'events'.
Hasta ahora todo bien.
Guarda el PDF la primera vez. Y también muestra el enlace correcto.
Pero luego si intento cambiar el PDF no lo guarda. Muestra el primero de nuevo.

Aquí está mi código que utilicé en mi sitio WordPress para un tipo de publicación personalizada que añade un PDF a la publicación. Funcionó para mí, intenta modificarlo y usarlo. Espero que te ayude.
function add_custom_meta_boxes() {
add_meta_box('wp_custom_attachment', 'Folleto del Hotel', 'wp_custom_attachment', 'hotel_post', 'normal', 'high');
}
add_action('add_meta_boxes', 'add_custom_meta_boxes');
function wp_custom_attachment() {
wp_nonce_field(plugin_basename(__FILE__), 'wp_custom_attachment_nonce');
$html = '<p class="description">';
$html .= 'Sube tu PDF aquí.';
$html .= '</p>';
$html .= '<input type="file" id="wp_custom_attachment" name="wp_custom_attachment" value="" size="25">';
echo $html;
}
add_action('save_post', 'save_custom_meta_data');
function save_custom_meta_data($id) {
if(!empty($_FILES['wp_custom_attachment']['name'])) {
$supported_types = array('application/pdf');
$arr_file_type = wp_check_filetype(basename($_FILES['wp_custom_attachment']['name']));
$uploaded_type = $arr_file_type['type'];
if(in_array($uploaded_type, $supported_types)) {
$upload = wp_upload_bits($_FILES['wp_custom_attachment']['name'], null, file_get_contents($_FILES['wp_custom_attachment']['tmp_name']));
if(isset($upload['error']) && $upload['error'] != 0) {
wp_die('Hubo un error al subir tu archivo. El error es: ' . $upload['error']);
} else {
update_post_meta($id, 'wp_custom_attachment', $upload);
}
}
else {
wp_die("El tipo de archivo que has subido no es un PDF.");
}
}
}
function update_edit_form() {
echo ' enctype="multipart/form-data"';
}
add_action('post_edit_form_tag', 'update_edit_form');
Para obtener el PDF
$hotel_brochure = get_post_meta( $post_id, 'wp_custom_attachment', true );
$hotel_brochure['url']

Funciona. Aunque faltaba esta línea: add_post_meta($id, 'wp_custom_attachment', $upload); encima de esta: update_post_meta($id, 'wp_custom_attachment', $upload); Gracias

Gracias Kuljeet Singh por esta solución, funciona perfectamente (con la observación de belacqua). Tengo una pregunta: ¿Cómo hacer que esta solución almacene la información del archivo subido? Actualmente cuando actualizas el post, el cuadro personalizado te pide subir un archivo pero no indica que ya existe un archivo subido previamente. Gracias de antemano

WordPress 5.6 aquí. Lo probé sin add_post_meta
y funciona. Sin embargo, ten cuidado, aunque este código sobrescribe los metadatos actualizados previamente como se espera, NO sobrescribe el archivo subido anteriormente ya que wp_upload_bits
usa un nombre diferente (algo como file-1.pdf
, file-2.pdf
, file-3.pdf
, y así sucesivamente). Revisa la carpeta wp-content/upload
.

También ten en cuenta que PHP 7 evalúa $upload['error'] != 0
como false
cuando $upload['error']
contiene un mensaje (de tipo string). Ya no es el caso con PHP 8, pero aún así deberías usar verificación estricta de tipos (===
) para evitar comportamientos impredecibles (por cierto, $upload['error']
puede ser un string o false
).

Una última cosa, cita tus fuentes: https://code.tutsplus.com/articles/attaching-files-to-your-posts-using-wordpress-custom-meta-boxes-part-1--wp-22291 :-P Algunos temas adicionales sobre mis dos comentarios anteriores: https://wordpress.stackexchange.com/a/379569/198773.

Acabo de hacer que esto funcione anoche usando el código anterior (y el comentario adicional) y hay algunas cosas que me gustaría agregar aquí. Primero, en la sección "Para obtener el PDF", 'wpcf-brochure' debería cambiarse por 'wp_custom_attachment'. Luego, para responder a la pregunta final del OP, para que aparezca en el backend, esta es la técnica que usé. Antes de la línea que dice "echo $html;" en functions.php, agregué:
$filearray = get_post_meta( get_the_ID(), 'wp_custom_attachment', true );
$this_file = $filearray['url'];
if($this_file != ""){
$html .= '<div>Archivo actual:<br>"' . $this_file . '"</div>';
}

Aquí hay un pequeño impulso para quien quiera corregir y solucionar la respuesta aceptada:
define('PREFIX', 'a-good-prefix-');
echo '<input type="file" name="' . PREFIX . 'attachment">';
add_action('save_post', function ($post_id) {
$key = PREFIX . 'attachment';
if (empty($_FILES[$key]['name'])) return;
if (metadata_exists('post', $post_id, $key)) {
unlink(get_post_meta($post_id, $key, true)['file']);
}
$name = $_FILES[$key]['name'];
$tmp = $_FILES[$key]['tmp_name'];
$bits = file_get_contents($tmp);
$upload = wp_upload_bits($name, null, $bits);
if (isset($upload['error']) && $upload['error'] !== false) {
wp_die('Error de subida: ' . $upload['error']);
} else {
update_post_meta($post_id, $key, $upload);
}
});
Fuentes originales: https://code.tutsplus.com/articles/attaching-files-to-your-posts-using-wordpress-custom-meta-boxes-part-1--wp-22291.
