Загрузка книг в формате FB2 и создание из них нод в Drupal

За загрузку файлов и последующий их разбор будет отвечать модуль «FB2Upload». Вот его .info файл:

name = FB2Upload
description = Creating nodes from uploaded *.fb2 books. You must have content type "Book".
core = 7.x
version = 7.x-1.x-dev
package = FB2

Загрузка книги производится аналогично загрузке любого другого файла. За нее отвечают 3 хука:
fb2upload_page_form — собственно, сама форма загрузки.
fb2upload_page_form_validate — проверка переданных пользователем данных.
fb2upload_page_form_submit — разбор FB2 и создание ноды.

Так как FB2 — это обычный XML, будем использовать для его разбора DOM парсер. Вот весь код модуля:

< ?php
function fb2upload_menu() {
  $items = array();
  $items['fb2upload'] = array(
    'title' => 'FB2 Upload',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('fb2upload_page_form'),
    'access callback' => TRUE,
  );
  return $items;
}
 
function fb2upload_page_form()
{
  $form = array();
  $form['file'] = array(
    '#type' => 'file',
    '#title' => 'Книга',
    '#description' => 'Выберете файл электронной книги формата FB2 (*.fb2) для загрузки',
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Отправить',
  );
  return $form;
}
 
function fb2upload_page_form_validate($form, &$form_state) {
  $validators = array(
    'file_validate_extensions' => array('fb2'), // Проверка на расширения
    'file_validate_size' => array(2 * 1024 * 1024), // Проверка на размер файла (максимум 2mb)
  );
  // Загружаем файл в sites/default/files (по умолчанию)
  if ($file = file_save_upload('file', $validators, 'public://')) {
    $form_state['values']['file'] = $file; // передаём информацию о файле в ф-ю fb2upload_form_submit()
  }
  else {
    form_set_error('file', 'Файл не был загружен');
  }
}
function fb2upload_page_form_submit($form, &$form_state) {
  $file = $form_state['values']['file'];
  $file->status = FILE_STATUS_PERMANENT; // Изменяем статус файла на "Постоянный"
  file_save($file); // Сохраняем новый статус
  $book = new DOMDocument();
  $book->strictErrorChecking = false;
  $book->recover = true;
  $load = $book->load($file->uri,LIBXML_NOERROR);
  //Создаем ноду
  $new_node = new StdClass();
  $new_node->type = 'book';
  $new_node->status = 1;
  $new_node->promote = 1;
  $new_node->title = $book->getElementsByTagName('book-title')->item(0)->nodeValue;
  $new_node->comment = 0;
  $new_node->sticky = 0;
  $new_node->created = time();
  $new_node->changed = time();
  $new_node->language = 'ru';
  $new_node->body['und'][0]['value'] = $book->getElementsByTagName('annotation')->item(0)->nodeValue;
  $new_node->body['und'][0]['format'] = 'full_html';
  global $user;
  $new_node->uid = $user->uid;
  $new_node->field_file['und'][0]['fid'] = $file->fid;
  $new_node->field_file['und'][0]['display'] = 1;
  $new_node->field_file['und'][0]['alt'] = 'Скачать книгу '.$book->getElementsByTagName('book-title')->item(0)->nodeValue;
  $new_node->field_file['und'][0]['title'] = $book->getElementsByTagName('book-title')->item(0)->nodeValue;
  $title_info = $book->getElementsByTagName('title-info')->item(0);
  $authors_list = $title_info->getElementsByTagName('author');
  foreach ($authors_list as $element) {
    $authors[] =  $element->getElementsByTagName('first-name')->item(0)->nodeValue." ".
      $element->getElementsByTagName('middle-name')->item(0)->nodeValue." ".
      $element->getElementsByTagName('last-name')->item(0)->nodeValue." ";
  }
  $new_node->field_autor['und'][0]['value'] = implode(", ", $authors);
  node_save($new_node);
  drupal_set_message('Книга загружена: ');
}

Все самое интересное происходит в хуке обработки формы fb2upload_page_form_submit, а именно: мы создаем новый элемент DOM $book и вытаскиваем с его помощью нужные нам данные. Затем строкой $new_node = new StdClass(); мы создаем новую ноду и на следующей строке задаем ей тип «book». Этот тип содержимого придется создавать вручную в админке друпала, определив ему дополнительные поля «autor» и «file». Затем указываем остальные параметры ноды, а именно:
$new_node->type — тип материала
$new_node->title — Заголовок материала
$new_node->status — 1 (Опубликовано), 0 (Неопубликовано)
$new_node->promote — 1 (Закреплено на главной), 0 (Не закреплено на главной)
$new_node->comment — 0 (Запрещено комментировать), 1 (Только чтение комментариев), 2 (Разрешено комментировать)
$new_node->sticky — 1 (Закреплять вверху списков), 0 (Не закреплять)
$new_node->created — Таймштамп создания ноды
$new_node->changed — Таймштамп последнего обновления ноды
$new_node->body[‘und’][0][‘value’] — Содержимое материала
$new_node->uid — ID пользователя, который будет считаться автором. Если поставить 0, то автором будеть считатья «Гость».
$new_node->language — язык материала.
$new_node->body[‘und’][0][‘format’] — Формат ввода, рекомендую всегда явно указывать, иначе HMTL код может необработаться и выдаваться простым текстом.
Созданные дополнительно поля «file» и «autor» заполняются аналогично. Таким же способом можно извлечь и записать в ноду и другие данные книги, например, ее жанр.

2 комментария

  1. Поясните пожалуйста — ——-Затем указываем остальные параметры ноды, а именно:————-

    Нужно создать node—book.tpl.php или что делать с данными переменными?

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *