Статьи

Вложение файлов в ваши сообщения с помощью пользовательских мета-боксов WordPress, часть 1

В следующих двух статьях мы рассмотрим, как мы можем использовать API WordPress для определения наших собственных пользовательских мета-блоков для присоединения документа (такого как PDF) к нашим страницам WordPress. Мы также рассмотрим, как правильно удалять файлы, если мы решим удалить их из наших сообщений.

Несколько месяцев назад Кристофер Дэвис продемонстрировал, как создавать собственные WordPress записи / мета-боксы (http://wp.tutsplus.com/tutorials/plugins/how-to-create-custom-wordpress-writemeta-boxes/). Как упоминалось в его статье, пользовательские мета-блоки являются невероятно мощными функциями, которые позволяют нам добавлять различные фрагменты дополнительной информации в наши посты и страницы WordPress.

Конечно, мы не ограничены текстом или параметрами, такими как переключатели или флажки. Мы также можем прикреплять изображения и файлы к сообщениям, страницам и другим типам сообщений, используя преимущества пользовательских мета-блоков; однако работа с типами файлов требует немного больше кода для правильной обработки загрузки и удаления файла.

Прежде чем начать, важно отметить, что эта серия предполагает, что мы работаем с темой Twentyeleven . Несмотря на то, что код будет работать с любой темой WordPress, это гарантирует, что мы все работаем с одной и той же кодовой базой, и должно упростить выполнение этого руководства.


Во-первых, давайте создадим мета-поле поста. В частности, мета-бокс должен …

  • Быть доступным как на постах, так и на страницах
  • Появляются рядом с редактором постов
  • Принять входной файл

На этом этапе найдите functions.php в корне каталога тем Twentyeleven. Мы будем вносить все наши изменения в конец файла. Мы начнем с определения функции с именем add_custom_meta_boxes, и она будет зарегистрирована с помощью ловушки add_meta_boxes.

1
2
3
4
function add_custom_meta_boxes() {
 
} // end add_custom_meta_boxes
add_action(‘add_meta_boxes’, ‘add_custom_meta_boxes’);

Далее давайте определим наш собственный мета-блок. Сначала мы напишем код, после которого я объясню, что делает код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
function add_custom_meta_boxes() {
 
    // Define the custom attachment for posts
    add_meta_box(
        ‘wp_custom_attachment’,
        ‘Custom Attachment’,
        ‘wp_custom_attachment’,
        ‘post’,
        ‘side’
    );
     
    // Define the custom attachment for pages
    add_meta_box(
        ‘wp_custom_attachment’,
        ‘Custom Attachment’,
        ‘wp_custom_attachment’,
        ‘page’,
        ‘side’
    );
 
} // end add_custom_meta_boxes
add_action(‘add_meta_boxes’, ‘add_custom_meta_boxes’);

Обратите внимание, что следующие два вызова add_meta_box практически идентичны.

  • Первый параметр — это идентификатор мета-блока. Это используется при сохранении значения.
  • Вторым параметром является метка. Это значение отображается в заголовке над мета-окном записи
  • Третье значение — это функция обратного вызова, которая используется для определения разметки, отображаемой в мета-блоке. Мы вернемся к этому на мгновение.
  • Четвертое значение сообщает WordPress тип сообщения, в котором должен отображаться этот пользовательский мета-блок. Поскольку мы хотим, чтобы это было как на постах, так и на страницах, мы определили это дважды.
  • Последний параметр определяет, где мы хотим, чтобы мета-поле появилось. Это может быть либо сторона, продвинутый, либо нормальный. Мы выбрали сторону, чтобы она отображалась рядом с редактором постов.

На этом этапе пользовательский метабокс ничего не делает. На самом деле, он даже ничего не отображает:

Это связано с тем, что мы не определили функцию обратного вызова, которая генерирует разметку для мета-блока. Для этого нам нужно определить функцию с именем, которое мы перечислили выше. В частности: ‘wp_custom_attachment.’

Входные данные должны принимать PDF, поэтому мы дадим краткое описание и соответствующий элемент ввода для приема файлов:

01
02
03
04
05
06
07
08
09
10
11
12
function wp_custom_attachment() {
 
    wp_nonce_field(plugin_basename(__FILE__), ‘wp_custom_attachment_nonce’);
     
    $html = ‘<p class=»description»>’;
        $html .= ‘Upload your PDF here.’;
    $html .= ‘</p>’;
    $html .= ‘<input type=»file» id=»wp_custom_attachment» name=»wp_custom_attachment» value=»» size=»25″ />’;
     
    echo $html;
 
} // end wp_custom_attachment

Первая строка кода определяет одноразовое значение для правильной проверки и защиты нашей загрузки.

Далее мы просто устанавливаем разметку для отображения поля ввода.

На данный момент у нас есть пользовательский метабокс, который выглядит прилично, но на самом деле не работает.


Теперь мы готовы сохранить файл. Во-первых, нам нужно создать функцию, которая подключается к хуку save_post. Давайте определим это сейчас:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function save_custom_meta_data($id) {
 
    /* — security verification — */
    if(!wp_verify_nonce($_POST[‘wp_custom_attachment_nonce’], plugin_basename(__FILE__))) {
      return $id;
    } // end if
       
    if(defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE) {
      return $id;
    } // end if
       
    if(‘page’ == $_POST[‘post_type’]) {
      if(!current_user_can(‘edit_page’, $id)) {
        return $id;
      } // end if
    } else {
        if(!current_user_can(‘edit_page’, $id)) {
            return $id;
        } // end if
    } // end if
    /* — end security verification — */
     
} // end save_custom_meta_data
add_action(‘save_post’, ‘save_custom_meta_data’);

Хотя эта функция на самом деле не сохраняет значение — по крайней мере, пока — она ​​включает в себя немного кода, который гарантирует, что мы готовы сохранить файл. В частности, функция обеспечивает наличие ожидаемого одноразового значения, отсутствие автоматического сохранения и наличие у пользователя, пытающегося сохранить данные, разрешений для этого.

Теперь мы готовы начать проверку и сохранение файла. Когда дело доходит до сохранения пользовательских метаданных на основе файлов, необходимо ввести дополнительный код, чтобы правильно обрабатывать особенности загрузки файлов. Сначала мы определим код, а затем объясним. Функция должна выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
function save_custom_meta_data($id) {
 
    /* — security verification — */
    if(!wp_verify_nonce($_POST[‘wp_custom_attachment_nonce’], plugin_basename(__FILE__))) {
      return $id;
    } // end if
       
    if(defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE) {
      return $id;
    } // end if
       
    if(‘page’ == $_POST[‘post_type’]) {
      if(!current_user_can(‘edit_page’, $id)) {
        return $id;
      } // end if
    } else {
        if(!current_user_can(‘edit_page’, $id)) {
            return $id;
        } // end if
    } // end if
    /* — end security verification — */
     
    // Make sure the file array isn’t empty
    if(!empty($_FILES[‘wp_custom_attachment’][‘name’])) {
         
        // Setup the array of supported file types.
        $supported_types = array(‘application/pdf’);
         
        // Get the file type of the upload
        $arr_file_type = wp_check_filetype(basename($_FILES[‘wp_custom_attachment’][‘name’]));
        $uploaded_type = $arr_file_type[‘type’];
         
        // Check if the type is supported.
        if(in_array($uploaded_type, $supported_types)) {
 
            // Use the WordPress API to upload the file
            $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(‘There was an error uploading your file. The error is: ‘ . $upload[‘error’]);
            } else {
                add_post_meta($id, ‘wp_custom_attachment’, $upload);
                update_post_meta($id, ‘wp_custom_attachment’, $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_custom_meta_data
add_action(‘save_post’, ‘save_custom_meta_data’);

Новый блок кода делает несколько вещей. Комментарии были предоставлены для ясности, но вот что происходит:

  • Сначала убедитесь, что массив файлов не пуст
  • Затем мы устанавливаем массив для поддерживаемых типов файлов и проверяем, что загруженный файл относится к этому типу.
  • Далее мы используем wp_upload_bits для копирования файла на сервер
  • Наконец, если будут какие-либо ошибки, мы остановим выполнение и покажем их пользователю.

Примечание о wp_upload_bits (http://codex.wordpress.org/Function_Reference/wp_upload_bits). Эта функция является альтернативой wp_handle_upload (http://codex.wordpress.org/Function_Reference/wp_handle_upload). По моему опыту, wp_handle_upload привел к некоторым проблемам с определенными конфигурациями сервера, так что он дает ложный отрицательный результат. Под этим я подразумеваю, что он утверждает, что у него есть проблема с загрузкой файла, когда на самом деле файл был загружен.


На данный момент мы должны быть готовы предоставить ссылку на файл на наших сообщениях и наших страницах. В каталоге Twentyeleven Theme найдите два файла: single.php и page.php. Каждый файл содержит строку кода, которая выглядит следующим образом:

1
get_template_part( ‘content’, ‘single’ );

Чуть ниже этой строки нам потребуется запросить мета-информацию о пользовательских записях, выполнив это:

1
echo get_post_meta(get_the_ID(), ‘wp_custom_attachment’, true);

В частности, эта функция запрашивает метаданные записи, идентифицированные как «wp_custom_attachment», связанные с этим идентификатором записи. Ясно, верно? Последний параметр сообщает WordPress, что мы хотим вернуть результат в строковом формате (альтернатива — в формате массива, и это выходит за рамки этого урока).

Последний блок кода должен выглядеть так:

1
get_template_part( ‘content’, ‘single’ );
1
echo get_post_meta(get_the_ID(), ‘wp_custom_attachment’, true);

Теперь попробуйте загрузить файл для страницы или сообщения. Загрузите пост и страницу в вашем браузере. Если все прошло правильно, вы заметите, что … упс … у вас нет пути к файлу.


Проблема заключается в том, что по умолчанию элемент формы, используемый для сохранения всей информации о публикации и связанных с ней данных, не принимает типы файлов. Это можно исправить, добавив еще одну функцию, которая подключается к жизненному циклу страницы WordPress:

1
2
3
4
function update_edit_form() {
    echo ‘ enctype=»multipart/form-data»‘;
} // end update_edit_form
add_action(‘post_edit_form_tag’, ‘update_edit_form’);

Это добавит атрибут enctype к элементу формы редактора сообщений, чтобы загрузка файлов не поддерживалась.

Теперь давайте попробуем загрузить файл еще раз. Найдите свое сообщение или страницу в пользовательском мета-поле и попробуйте загрузить PDF. Если все идет хорошо, вы сможете перейти к записи и / или странице и увидеть URL-адрес файла.


Последний шаг самый простой. Затем вернитесь к файлам single.php и page.php и оберните вызов пользовательского запроса метаданных в привязку так, чтобы он выглядел следующим образом:

1
2
<?php get_template_part( ‘content’, ‘single’ );
<?php $img = get_post_meta(get_the_ID(), ‘wp_custom_attachment’, true);
1
2
3
<a href=»<?php echo $img[‘url’]; ?>»>
    Download PDF Here
</a>

К этому моменту вы сможете прикрепить пользовательский PDF-файл к своей странице, и в нижней части содержимого страницы появится ссылка с ссылкой для загрузки. В следующем посте мы рассмотрим, как мы можем предоставить более качественные стили для привязки загрузки, а также удалим файл со страницы с помощью API WordPress.

А пока попробуйте поэкспериментировать с настройкой метабокса еще дальше. Например, попытайтесь включить пользовательскую метку для предоставления содержимого для ссылки.