Прикрепление PDF файла к произвольному типу записи
Я пытаюсь прикрепить PDF файл к произвольному типу записи.
Я нашел этот код на wpsnipp.com.
Код работает, но только для обычных записей.
У меня есть произвольный тип записи с названием 'events', и я не могу заставить его работать.
add_action("admin_init", "pdf_init");
add_action('save_post', 'save_pdf_link');
function pdf_init(){
add_meta_box("my-pdf", "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">ВЫБЕРИТЕ 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>Выберите PDF файл из списка выше, чтобы прикрепить его к этой записи.</p>';
echo '<div class="pdf_count"><span>Файлов:</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];
}
А для отображения ссылки в теме:
<? pdf_file_url(); ?>
Я изменил тип записи с 'post' на 'events', и метабокс появляется на странице 'events'.
Пока всё хорошо.
Он сохраняет PDF при первом добавлении. И также корректно отображает ссылку.
Но когда я пытаюсь изменить PDF, он не сохраняет изменения. Он продолжает отображать первый файл.

Вот мой код, который я использовал на своем сайте WordPress для добавления PDF к записям пользовательского типа. Он работает для меня, попробуйте изменить и использовать его. Надеюсь, это поможет.
function add_custom_meta_boxes() {
add_meta_box('wp_custom_attachment', 'Брошюра отеля', '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 .= 'Загрузите ваш PDF файл здесь.';
$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('Произошла ошибка при загрузке вашего файла. Ошибка: ' . $upload['error']);
} else {
update_post_meta($id, 'wp_custom_attachment', $upload);
}
}
else {
wp_die("Тип загружаемого файла не является PDF.");
}
}
}
function update_edit_form() {
echo ' enctype="multipart/form-data"';
}
add_action('post_edit_form_tag', 'update_edit_form');
Чтобы получить PDF:
$hotel_brochure = get_post_meta( $post_id, 'wp_custom_attachment', true );
$hotel_brochure['url']

Это работает. Однако не хватало этой строки: add_post_meta($id, 'wp_custom_attachment', $upload); перед этой: update_post_meta($id, 'wp_custom_attachment', $upload); Спасибо

Спасибо Kuljeet Singh за это решение, оно работает идеально (с замечанием belacqua). У меня есть вопрос: как сделать, чтобы это решение сохраняло информацию о загруженном файле. В данный момент, когда вы обновляете пост, кастомное поле просит загрузить файл, но не показывает, что файл уже был загружен. Заранее спасибо

У меня Wordpress 5.6. Я попробовал без add_post_meta
, и это работает. Однако будьте осторожны: хотя этот код перезаписывает ранее обновленные метаданные, как и ожидалось, он НЕ перезаписывает ранее загруженный файл, поскольку wp_upload_bits
использует другое имя (например, file-1.pdf
, file-2.pdf
, file-3.pdf
и так далее). Проверьте папку wp-content/upload
.

Также обратите внимание, что PHP 7 интерпретирует $upload['error'] != 0
как false
, когда $upload['error']
содержит сообщение (тип string). В PHP 8 это больше не так, но всё равно следует использовать строгую проверку типов (===
), чтобы избежать непредсказуемого поведения (кстати, $upload['error']
может быть строкой или false
).

Последнее замечание - указывайте источники: https://code.tutsplus.com/articles/attaching-files-to-your-posts-using-wordpress-custom-meta-boxes-part-1--wp-22291 :-P Дополнительная информация по моим двум комментариям выше: https://wordpress.stackexchange.com/a/379569/198773.

Я только что заставил это работать прошлой ночью, используя приведенный выше код (и дополнительный комментарий), и хотел бы добавить здесь несколько моментов. Во-первых, в разделе "To get the PDF" 'wpcf-brochure' следует заменить на 'wp_custom_attachment'. Затем, чтобы ответить на последний вопрос автора, вот техника, которую я использовал для отображения в бэкенде. Перед строкой с "echo $html;" в functions.php добавьте:
$filearray = get_post_meta( get_the_ID(), 'wp_custom_attachment', true );
$this_file = $filearray['url'];
if($this_file != ""){
$html .= '<div>Текущий файл:<br>"' . $this_file . '"</div>';
}

Вот небольшое улучшение для тех, кто хочет исправить и исправить принятый ответ:
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('Ошибка загрузки: ' . $upload['error']);
} else {
update_post_meta($post_id, $key, $upload);
}
});
Оригинальные источники: https://code.tutsplus.com/articles/attaching-files-to-your-posts-using-wordpress-custom-meta-boxes-part-1--wp-22291.
