Идея
- Необходимо добавить метабокс (MetaBox) на страницу редактирования записи, который будет отображать поле для указания файла на жёстком диске. (
<input type="file">
) - При сохранении записи загруженный файл необходимо сохранить на сервере как “прикреплённый файл” к этой записи.
Код
По умолчанию форма для редактирования записей не имеет атрибут enctype="multipart/form-data"
, который необходим для загрузки файлов. К счастью, существует действие (Action), которое позволяет добавлять пользовательские атрибуты в форму редактирования записей. Следующий код показывает как это сделать.
add_action('post_edit_form_tag', 'post_edit_form_tag'); function post_edit_form_tag() { echo ' enctype="multipart/form-data"'; }
Следующим шагом необходимо создать метабокс (MetaBox), который будет выводить поле для указания файла. Делается это с помощью функции add_meta_box
. Следующий код – это функция, которая используется для нашего метабокса.
function custom_field_document_upload() { global $post; $custom = get_post_custom($post->ID); $download_id = get_post_meta($post->ID, 'document_file_id', true); echo '<p><label for="document_file">Загрузить файл:</label><br />'; echo '<input type="file" name="document_file" id="document_file" /></p>'; echo '</p>'; if(!empty($download_id) && $download_id != '0') { echo '<p><a href="' . wp_get_attachment_url($download_id) . '"> Просмотр файла</a></p>'; } }
Последним шагом нам необходимо сохранить загружаемый файл и ассоциировать его с текущей записью. Для этого воспользуемся действием (Action), которое позволяет нам вклиниться в процесс сохранения записи и выполнения нужного нам кода. В нашем случае – сохранение файла.
add_action('save_post', 'custom_field_document_update'); function custom_field_document_update($post_id) { global $post; if(strtolower($_POST['post_type']) === 'page') { if(!current_user_can('edit_page', $post_id)) { return $post_id; } } else { if(!current_user_can('edit_post', $post_id)) { return $post_id; } } if(!empty($_FILES['document_file'])) { $file = $_FILES['document_file']; $upload = wp_handle_upload($file, array('test_form' => false)); if(!isset($upload['error']) && isset($upload['file'])) { $filetype = wp_check_filetype(basename($upload['file']), null); $title = $file['name']; $ext = strrchr($title, '.'); $title = ($ext !== false) ? substr($title, 0, -strlen($ext)) : $title; $attachment = array( 'post_mime_type' => $wp_filetype['type'], 'post_title' => addslashes($title), 'post_content' => '', 'post_status' => 'inherit', 'post_parent' => $post->ID ); $attach_key = 'document_file_id'; $attach_id = wp_insert_attachment($attachment, $upload['file']); $existing_download = (int) get_post_meta($post->ID, $attach_key, true); if(is_numeric($existing_download)) { wp_delete_attachment($existing_download); } update_post_meta($post->ID, $attach_key, $attach_id); } } }
Этот демонстрационный пример вполне работоспособен и может использоваться. Если немного его расширить, то можно добиться возможности множественной загрузки файлов. Надеюсь пример станет полезным для большинства пользователей WordPress.